Skip to content

Commit c0d0d04

Browse files
authored
Merge pull request #3569 from obsidian-tasks-group/docs-for-outlinks
docs: Initial documentation for Links feature
2 parents 9515340 + 07f3ef6 commit c0d0d04

21 files changed

+421
-126
lines changed

docs/Getting Started/About Getting Started.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ publish: true
4545
- Then adjust your searches, perhaps to see tasks that are [[Filters#Blocking Tasks|blocking others]], or hide ones that are [[Filters#Blocked Tasks|blocked]] and cannot yet be done.
4646
- [[Obsidian Properties]]
4747
- Learn how to use data in Obsidian [Properties](https://help.obsidian.md/Editing+and+formatting/Properties) in your queries, for example to only search tasks in Kanban plugin files.
48+
- [[Links]]
49+
- Learn how to search for tasks based upon [Links between notes](https://help.obsidian.md/link-notes).
4850

4951
## Easy editing of tasks
5052

docs/Getting Started/Links.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
publish: true
3+
---
4+
5+
# Links
6+
7+
> [!released]
8+
> Use of Links in searches was introduced in Tasks X.Y.Z.
9+
10+
> [!Tip]
11+
> This documentation was written a little more quickly than usual, because to the need to release a fix for a bug in iOS and iPadOS versions [18.6](https://github.com/obsidian-tasks-group/obsidian-tasks/issues/3546) and [26 Public Beta 2](https://github.com/obsidian-tasks-group/obsidian-tasks/issues/3560).
12+
>
13+
> We plan to refine this page, based on user feedback after its initial release.
14+
15+
## How does Tasks treat Links?
16+
17+
You might want to start with the [[#Links Query Examples|examples below]] for an idea of *what* Tasks can do with Links.
18+
19+
This section describes the *how*...
20+
21+
- Links can be used in Tasks searches with the following instructions:
22+
- `filter by function`
23+
- `sort by function`
24+
- `group by function`
25+
- Links recognises these styles on links in your notes:
26+
- `[[filename|optional alias]]`
27+
- `[alias](filename.md)`
28+
- Headings and nested headings in the links are also supported.
29+
30+
The following values are available:
31+
32+
| Value | Return Type | Notes |
33+
| --------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
34+
| **`task`** | | |
35+
| `task.outlinks` | `Link[]` | Returns a list of links in the task's line.<br>It does not contain links in any nested tasks or list items. |
36+
| `task.file.outlinksInProperties` | `Link[]` | Returns all the links in the task file's [[Obsidian Properties]]. |
37+
| `task.file.outlinksInBody` | `Link[]` | Returns all the links in the body of the note containing the task.<br>Naturally, this includes any links on the task line itself. |
38+
| `task.file.outlinks` | `Link[]` | Returns all the links anywhere in the task's file.<br>It contains all the links in `task.file.outlinksInProperties` and `task.file.outlinksInBody`. |
39+
| **`query`** | | |
40+
| `query.file.outlinksInProperties` | `Link[]` | Returns all the links in the query file's [[Obsidian Properties]]. |
41+
| `query.file.outlinksInBody` | `Link[]` | Returns all the links in the body of the note containing the query. |
42+
| `query.file.outlinks` | `Link[]` | Returns all the links anywhere in the query's file.<br>It contains all the links in `query.file.outlinksInProperties` and `query.file.outlinksInBody` |
43+
44+
The return values are all arrays of `Link` objects.
45+
46+
## Link class
47+
48+
> [!NOTE] Documentation coming soon
49+
> Documentation coming soon. In the meantime, you can see the comments in [Link.ts](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/src/Task/Link.ts) on GitHub.
50+
51+
## Links Query Examples
52+
53+
> [!NOTE] Documentation coming soon
54+
> In the meantime, you can see some examples in [Accessing Links](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/resources/sample_vaults/Tasks-Demo/How%20To/Access%20links.md) on GitHub.
55+
56+
## Limitations of Links Handling and Searches
57+
58+
- Currently, searching of links is only possible via [[About Scripting|custom searches]].
59+
- Tasks does not yet treat [Embeds](https://help.obsidian.md/embeds) as links. This will be fixed soon.
60+
- Tasks does not yet provide an `inlinks` concept, that is, links *to* a particular file.
61+
- `Link.destinationPath` is calculated when the file containing the task is read.
62+
- This will either have been during Obsidian startup, or when the file was last modified during the current session.
63+
- For performance reasons, if files are moved to different folders during an Obsidian session, any tasks that link to the moved files are not updated.
64+
- The workaround is to run the built-in `Reload app without saving` command.

docs/Quick Reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ This table summarizes the filters and other options available inside a `tasks` b
5050
| **[[Filters#Description\|Description]]**, **[[Filters#Tags\|Tags]]** and other odds and ends | | | | |
5151
| `description (includes, does not include) <string>`<br>`description (regex matches, regex does not match) /regex/i` | `sort by description` | | | `task.description`<br>`task.descriptionWithoutTags` |
5252
| `has tags`<br>`no tags`<br>`tag (includes, does not include) <tag>`<br>`tags (include, do not include) <tag>`<br>`tag (regex matches, regex does not match) /regex/i`<br>`tags (regex matches, regex does not match) /regex/i` | `sort by tag`<br>`sort by tag <tag_number>` | `group by tags` | `hide tags` | `task.tags` |
53+
| **[[Links]]** | | | | `task.outlinks`<br>`task.file.outlinks`<br>`task.file.outlinksInBody`<br>`task.file.outlinksInProperties` |
5354
| | | | `show tree` | |
5455
| | | | | `task.originalMarkdown`<br>`task.lineNumber` |
5556
| | `sort by random` | | | |

docs/Scripting/Query Properties.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ This page documents all the available pieces of information in Queries that you
3838
| `query.file.hasProperty('non_existent_property')` | `boolean` | `false` |
3939
| `query.file.property('task_instruction')` | `string` | `'group by filename'` |
4040
| `query.file.property('non_existent_property')` | `null` | `null` |
41+
| `query.file.outlinksInProperties` | `Link[]` | `['Test Data/link_in_yaml.md']` |
42+
| `query.file.outlinksInBody` | `Link[]` | `['Test Data/link_in_file_body_with_custom_display_text.md']` |
43+
| `query.file.outlinks` | `Link[]` | `['Test Data/link_in_yaml.md', 'Test Data/link_in_file_body_with_custom_display_text.md']` |
4144

4245
<!-- placeholder to force blank line after included text --><!-- endInclude -->
4346

@@ -48,6 +51,14 @@ This page documents all the available pieces of information in Queries that you
4851
1. `query.file.filenameWithoutExtension` was added in Tasks 4.8.0.
4952
1. `query.file.hasProperty()` was added in Tasks 7.15.0.
5053
1. `query.file.property()` was added in Tasks 7.15.0.
54+
1. Accessing links:
55+
- The 3 `outlinks` methods were added in Tasks X.Y.Z.
56+
- They all return an array of `Link` objects.
57+
- For details, see [[Links]].
58+
- The table above shows the result of `link.destinationPath`
59+
- `query.file.outlinksInProperties` returns all the links in the query file's [[Obsidian Properties]].
60+
- `query.file.outlinksInBody` returns all the links in the body of the note containing the query.
61+
- `query.file.outlinks` returns all this links in both [[Obsidian Properties]] and the body of the note containing the query.
5162

5263
## Values for Query Search Properties
5364

docs/Scripting/Task Properties.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,29 @@ These are described in full in [[Obsidian Properties]].
235235
1. `task.file.hasProperty()` and `task.file.property()` were added in Tasks 7.7.0
236236
1. `task.file.hasProperty('property name')` returns true if the property `'property name'` is both present in the file and has a non-`null` value.
237237
1. `task.file.property('property name')` returns either the value in the file, or `null` if there is no value.
238+
239+
## Values for Links
240+
241+
> [!released]
242+
> Access to the Links was introduced in Tasks X.Y.Z.
243+
244+
These are described in full in [[Links]].
245+
246+
<!-- placeholder to force blank line before included text --><!-- include: TaskProperties.test.task_links.approved.md -->
247+
248+
| Field | Type 1 | Example 1 |
249+
| ----- | ----- | ----- |
250+
| `task.outlinks` | `Link[]` | `['Test Data/link_in_task_wikilink.md']` |
251+
| `task.file.outlinksInProperties` | `Link[]` | `['Test Data/link_in_yaml.md', 'Test Data/links_everywhere.md']` |
252+
| `task.file.outlinksInBody` | `Link[]` | `['Test Data/link_in_file_body.md', 'Test Data/link_in_heading.md', 'Test Data/link_in_task_wikilink.md']` |
253+
| `task.file.outlinks` | `Link[]` | `['Test Data/link_in_yaml.md', 'Test Data/links_everywhere.md', 'Test Data/link_in_file_body.md', 'Test Data/link_in_heading.md', 'Test Data/link_in_task_wikilink.md']` |
254+
255+
<!-- placeholder to force blank line after included text --><!-- endInclude -->
256+
257+
1. These all return an array of `Link` objects.
258+
1. The table above shows the result of `link.destinationPath`
259+
1. `task.outlinks` contains any links in the task description.
260+
- It does not contain links in any nested tasks or list items.
261+
1. `task.file.outlinksInProperties` returns all the links in the task file's [[Obsidian Properties]].
262+
1. `task.file.outlinksInBody` returns all the links in the body of the note containing the task. Naturally, this includes any links on the task line itself.
263+
1. `task.file.outlinks` returns all this links in both [[Obsidian Properties]] and the body of the note containing the task.

docs/Support and Help/Known Limitations.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ This page gathers together all the documentation on known limitations of the plu
8787

8888
![[Custom Sorting#Limitations of Custom Sorting]]
8989

90+
## Queries: Links
91+
92+
![[Links#Limitations of Links Handling and Searches]]
93+
9094
## Queries: Presets
9195

9296
![[Presets#Limitations]]

docs/What is New/Changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ _In recent [Tasks releases](https://github.com/obsidian-tasks-group/obsidian-tas
1212

1313
## 7.x releases
1414

15+
- X.Y.Z:
16+
- Add support for [[Links]] in custom filters, sorting and grouping.
17+
- The Tasks API can now edit existing task lines with [[Tasks Api#`editTaskLineModal(taskLine string) Promise<string>;`|editTaskLineModal()]].
1518
- 7.20.0:
1619
- Add [[Presets]] feature to save commonly used task query instructions.
1720
- Document [[Missing tags, aliases and cssclasses in some Obsidian 1.9.x versions]] - for Insider users of Obsidian 1.9.x.

resources/sample_vaults/Tasks-Demo/How To/Access links.md

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ TQ_extra_instructions:
55

66
# Accessing Links
77

8-
> [!Warning]
9-
>
10-
> - The queries in this file are **experimental**, and **may not continue to work**.
11-
> - For example, once the Obsidian Bases facility is finalised, we *may* update the vocabulary used here to match that of Obsidian.
8+
These facilities were introduced in Tasks X.Y.Z.
129

1310
## Filtering
1411

@@ -18,56 +15,56 @@ TQ_extra_instructions:
1815
```tasks
1916
# Task line has a link
2017
filter by function task.outlinks.length > 0
21-
limit groups 1
18+
limit 10
2219
```
2320
````
2421

2522
```tasks
2623
# Task line has a link
2724
filter by function task.outlinks.length > 0
28-
limit groups 1
25+
limit 10
2926
```
3027

3128
### `task.file.outlinksInProperties`: Tasks in files whose properties/frontmatter contains a link
3229

3330
````text
3431
```tasks
3532
filter by function task.file.outlinksInProperties.length > 0
36-
limit groups 1
33+
limit 10
3734
```
3835
````
3936

4037
```tasks
4138
filter by function task.file.outlinksInProperties.length > 0
42-
limit groups 1
39+
limit 10
4340
```
4441

4542
### `task.file.outlinksInBody`: Tasks in files whose markdown body contains a link
4643

4744
````text
4845
```tasks
4946
filter by function task.file.outlinksInBody.length > 0
50-
limit groups 1
47+
limit 10
5148
```
5249
````
5350

5451
```tasks
5552
filter by function task.file.outlinksInBody.length > 0
56-
limit groups 1
53+
limit 10
5754
```
5855

5956
### `task.file.outlinks`: Tasks in files whose file contains a link anywhere
6057

6158
````text
6259
```tasks
6360
filter by function task.file.outlinks.length > 0
64-
limit groups 1
61+
limit 10
6562
```
6663
````
6764

6865
```tasks
6966
filter by function task.file.outlinks.length > 0
70-
limit groups 1
67+
limit 10
7168
```
7269

7370
### Task lines that contain broken links
@@ -90,12 +87,12 @@ This should match one task, in [[Link to Access links file]].
9087

9188
````text
9289
```tasks
93-
filter by function task.outlinks.some(link => link.destinationPath === query.file.path)
90+
filter by function task.outlinks.some(link => link.linksTo(query.file))
9491
```
9592
````
9693

9794
```tasks
98-
filter by function task.outlinks.some(link => link.destinationPath === query.file.path)
95+
filter by function task.outlinks.some(link => link.linksTo(query.file))
9996
```
10097

10198
#### Tasks - version 2
@@ -104,12 +101,12 @@ This should match one task, in [[Link to Access links file]].
104101

105102
````text
106103
```tasks
107-
filter by function task.outlinks.some(link => link.linksTo(query.file))
104+
filter by function task.outlinks.some(link => link.destinationPath === query.file.path)
108105
```
109106
````
110107

111108
```tasks
112-
filter by function task.outlinks.some(link => link.linksTo(query.file))
109+
filter by function task.outlinks.some(link => link.destinationPath === query.file.path)
113110
```
114111

115112
#### Dataview version
@@ -157,3 +154,10 @@ group by function task.outlinks.map(link => link.destinationPath).sort().join('
157154
filter by function task.outlinks.length > 0
158155
group by function task.outlinks.map(link => link.destinationPath).sort().join(' · ')
159156
```
157+
158+
### Demonstrate link.displayText
159+
160+
```tasks
161+
filter by function task.outlinks.length > 0
162+
group by function task.outlinks.map(link => `\`${link.originalMarkdown}\` -><br> \`${link.displayText}\``)
163+
```

resources/sample_vaults/Tasks-Demo/Test Data/query_using_properties.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ task_instructions_with_continuation_line: |
1313
path \
1414
includes query_using_properties
1515
task_instruction_with_spaces: " path includes query_using_properties "
16+
link-in-frontmatter: "[[link_in_yaml]]"
1617
---
1718

1819
# query_using_properties
1920

2021
- [ ] #task Task in 'query_using_properties'
2122

23+
Example link in body of a file, for documentation purposes: [[link_in_file_body_with_custom_display_text]].
24+
2225
## Use a one-line property: task_instruction
2326

2427
Read a Tasks instruction from a property in this file, and embed it in to any number of queries in the file:

src/Task/Link.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export class Link {
2121
* Return the original Markdown, exactly as specified in the original markdown.
2222
* For "[ab](cd.md)", it would return "[ab](cd.md)".
2323
*
24+
* **Tip**: For use in `group by function`, {@link markdown} will also work for header-only links,
25+
* like `[[#heading in this file]]`.
26+
*
2427
* See also {@link markdown}
2528
*/
2629
public get originalMarkdown(): string {
@@ -52,7 +55,9 @@ export class Link {
5255
* Return the destination, exactly as specified in the original markdown.
5356
* For "[ab](cd.md)", it would return "cd.md".
5457
*
55-
* It is not able to supply the full path of the link destination.
58+
* **Tip**: Use {@link destinationPath} instead.
59+
*
60+
* This method is not able to supply the full path of the link destination.
5661
* Note that if you have two files called `cd.md`, Tasks does not yet do anything
5762
* to select the closest file of that name.
5863
*
@@ -65,17 +70,37 @@ export class Link {
6570
return this.rawLink.link;
6671
}
6772

73+
/**
74+
* The actual full path that Obsidian would navigate to if the user clicked on the link,
75+
* or `null` if the link is to a non-existent file.
76+
*
77+
* For "[[link_in_file_body]]", it might return "Test Data/link_in_file_body.md".
78+
*
79+
* Note that this value is not usually configured correctly in tests.
80+
* See {@link LinkResolver} docs for more info.
81+
*/
6882
public get destinationPath(): string | null {
6983
return this._destinationPath;
7084
}
7185

7286
/**
87+
* For "[[Styling of Queries]]", it would return "Styling of Queries"
88+
* For "[[link_in_task_wikilink|alias]]", it would return "alias"
7389
* For "[ab](cd.md)", it would return "ab".
90+
* For "[[Project Search#Search 1]]", it would return "Project Search > Search 1"
7491
*/
7592
public get displayText(): string | undefined {
7693
return this.rawLink.displayText;
7794
}
7895

96+
/**
97+
* Returns true if this link points to the given value
98+
* - Pass in `query.file` or `task.file` for the most precise results.
99+
* - If supplying a string, it is case-sensitive, and it will return true if:
100+
* - the string matches the link destination's filename (it ignores `.md` file extension)
101+
* - or the string matches the link destination's full path (it ignores `.md` file extension)
102+
* @param destination
103+
*/
79104
public linksTo(destination: string | TasksFile): boolean {
80105
if (typeof destination === 'string') {
81106
const removeMd = /\.md$/;

0 commit comments

Comments
 (0)