550 lines
26 KiB
Markdown
550 lines
26 KiB
Markdown
---
|
|
id: id-generated-by-omnivore
|
|
title: Grouping - Tasks User Guide - Obsidian Publish
|
|
tags:
|
|
- obsidian-tasks
|
|
state: ARCHIVED
|
|
date_saved: 2023-07-16 10:23:40
|
|
date_read: 2023-07-16 12:18:14
|
|
date_archived: 2023-07-16T10:05:16.592Z
|
|
---
|
|
|
|
# Grouping - Tasks User Guide - Obsidian Publish
|
|
|
|
#Omnivore
|
|
|
|
[Read on Omnivore](https://omnivore.app/)
|
|
[Read Original](https://publish.obsidian.md/tasks/Queries/Grouping)
|
|
|
|
## Webpage
|
|
|
|
## Grouping
|
|
|
|
## Contents
|
|
|
|
This page is long. Here are some links to the main sections:
|
|
|
|
* [Basics](https://publish.obsidian.md/tasks/Queries/Grouping#Basics)
|
|
* [Custom Groups](https://publish.obsidian.md/tasks/Queries/Grouping#Custom%20Groups)
|
|
* [Group by Task Statuses](https://publish.obsidian.md/tasks/Queries/Grouping#Group%20by%20Task%20Statuses)
|
|
* [Group by Dates in Tasks](https://publish.obsidian.md/tasks/Queries/Grouping#Group%20by%20Dates%20in%20Tasks)
|
|
* [Group by Other Task Properties](https://publish.obsidian.md/tasks/Queries/Grouping#Group%20by%20Other%20Task%20Properties)
|
|
* [Group by File Properties](https://publish.obsidian.md/tasks/Queries/Grouping#Group%20by%20File%20Properties)
|
|
* [Multiple groups](https://publish.obsidian.md/tasks/Queries/Grouping#Multiple%20groups)
|
|
* [Refining groups](https://publish.obsidian.md/tasks/Queries/Grouping#Refining%20groups)
|
|
* [Notes](https://publish.obsidian.md/tasks/Queries/Grouping#Notes)
|
|
* [Screenshots](https://publish.obsidian.md/tasks/Queries/Grouping#Screenshots)
|
|
* [Examples](https://publish.obsidian.md/tasks/Queries/Grouping#Examples)
|
|
|
|
## Basics
|
|
|
|
Introduced in Tasks 1.6.0.
|
|
|
|
By default, Tasks displays tasks in a single list.
|
|
|
|
To divide the matching tasks up with headings, you can add `group by` lines to the query.
|
|
|
|
## Custom Groups
|
|
|
|
`group by function` was introduced in Tasks 4.0.0.
|
|
|
|
Tasks provides many built-in grouping options, but sometimes they don't quite do what is wanted by all users.
|
|
|
|
Now Tasks has a powerful mechanism for you to create your own **custom groups**, offering incredible flexibility.
|
|
|
|
There are many examples of the custom grouping instruction `group by function` in the documentation below, with explanations, for when the `group by` instructions built in to Tasks do not satisfy your preferences.
|
|
|
|
You can find out more about this very powerful facility in [Custom Grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping).
|
|
|
|
## Group by Task Statuses
|
|
|
|
For more information, including adding your own customised statuses, see [Statuses](https://publish.obsidian.md/tasks/Getting+Started/Statuses).
|
|
|
|
### Status
|
|
|
|
* `group by status` (Done or Todo, which is capitalized for visibility in the headings)
|
|
* Note that the Done group is displayed before the Todo group, which differs from the Sorting ordering of this property.
|
|
* `Done` is used for tasks status types `DONE`, `CANCELLED` and `NON_TASK`
|
|
* `Todo` is used for status types with type `TODO` and `IN_PROGRESS`
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by status** is now possible.
|
|
|
|
* `group by function task.isDone ? "Action Required" : "Nothing To Do"`
|
|
* Use JavaScript's ternary operator to choose what to do for true (after the ?) and false (after the :) values.
|
|
|
|
### Status Name
|
|
|
|
* `group by status.name`
|
|
* This groups by the names you give to your custom statuses, in alphabetical order.
|
|
|
|
`group by status.name` was introduced in Tasks 1.23.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by status names** is now possible.
|
|
|
|
* `group by function task.status.name`
|
|
* Identical to "group by status.name".
|
|
* `group by function task.status.name.toUpperCase()`
|
|
* Convert the status names to capitals.
|
|
|
|
### Status Type
|
|
|
|
* `group by status.type`
|
|
* This groups by the types you have given to your custom statuses.
|
|
* The groups will appear in this order, and with these group names:
|
|
* `IN_PROGRESS`
|
|
* `TODO`
|
|
* `DONE`
|
|
* `CANCELLED`
|
|
* `NON_TASK`
|
|
|
|
`group by status.type` was introduced in Tasks 1.23.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by status types** is now possible.
|
|
|
|
* `group by function task.status.type`
|
|
* Unlike "group by status.type", this sorts the status types in alphabetical order.
|
|
|
|
### Status Symbol
|
|
|
|
There is no built-in instruction to group by status symbols.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by status symbol** is now possible.
|
|
|
|
* `group by function "Status symbol: " + task.status.symbol.replace(" ", "space")`
|
|
* Group by the status symbol, making space characters visible.
|
|
|
|
### Next Status Symbol
|
|
|
|
There is no built-in instruction to group by next status symbols.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by next status symbol** is now possible.
|
|
|
|
* `group by function "Next status symbol: " + task.status.nextSymbol.replace(" ", "space")`
|
|
* Group by the next status symbol, making space characters visible.
|
|
|
|
## Group by Dates in Tasks
|
|
|
|
### Due Date
|
|
|
|
* `group by due`
|
|
* The due date of the task, including the week-day, or `No due date`.
|
|
|
|
* `due` grouping option was introduced in Tasks 1.7.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by due date** is now possible.
|
|
|
|
These examples all use `task.due` property, which is a `TasksDate` object. You can see the current [TasksDate source code](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/src/Scripting/TasksDate.ts), to explore its capabilities.
|
|
|
|
* `group by function task.due.format("YYYY-MM-DD dddd")`
|
|
* Like "group by due", except it uses no heading, instead of a heading "No due date", if there is no due date.
|
|
* `group by function task.due.formatAsDate()`
|
|
* Format date as YYYY-MM-DD or empty string (so no heading) if there is no due date.
|
|
* `group by function task.due.formatAsDateAndTime()`
|
|
* Format date as YYYY-MM-DD HH:mm or empty string if no due date.
|
|
* Note:
|
|
* This is shown for demonstration purposes.
|
|
* Currently the Tasks plugin does not support storing of times.
|
|
* Do not add times to your tasks, as it will break the reading of task data.
|
|
* `group by function task.due.format("YYYY[%%]-MM[%%] MMM", "no due date")`
|
|
* Group by month, for example `2023%%-05%% May` ...
|
|
* ... which gets rendered by Obsidian as `2023 May`.
|
|
* Or show a default heading "no due date" if no date.
|
|
* The hidden month number is added, commented-out between two `%%` strings, to control the sort order of headings.
|
|
* To escape characters in format strings, you can wrap the characters in square brackets (here, `[%%]`).
|
|
* `group by function task.due.format("YYYY[%%]-MM[%%] MMM [- Week] WW")`
|
|
* Group by month and week number, for example `2023%%-05%% May - Week 22` ...
|
|
* ... which gets rendered by Obsidian as `2023 May - Week 22`.
|
|
* If the month number is not embedded, in some years the first or last week of the year is displayed in a non-logical order.
|
|
|
|
DON'T PANIC! For users who are comfortable with JavaScript, these more complicated examples may also be of interest:
|
|
|
|
* `group by function task.due.moment?.fromNow() || ""`
|
|
* Group by the time from now, for example "8 days ago".
|
|
* Because Moment.fromNow() is not provided by TasksDate, we need special code for when there is no date value.
|
|
* Whilst interesting, the alphabetical sort order makes the headings a little hard to read.
|
|
* `group by function task.due.format("dddd")`
|
|
* Group by day of the week (Monday, Tuesday, etc).
|
|
* The day names are sorted alphabetically.
|
|
* `group by function task.due.format("[%%]d[%%]dddd")`
|
|
* Group by day of the week (Sunday, Monday, Tuesday, etc).
|
|
* The day names are sorted in date order, starting with Sunday.
|
|
* `group by function task.due.moment ? ( task.due.moment.day() === 0 ? task.due.format("[%%][8][%%]dddd") : task.due.format("[%%]d[%%]dddd") ) : "Undated"`
|
|
* Group by day of the week (Monday, Tuesday, etc).
|
|
* The day names are sorted in date order, starting with Monday.
|
|
* Tasks without due dates are displayed at the end, under a heading "Undated".
|
|
* This is best understood by pasting it in to a Tasks block in Obsidian and then deleting parts of the expression.
|
|
* The key technique is to say that if the day is Sunday (`0`), then force it to be displayed as date number `8`, so it comes after the other days of the week.
|
|
* `group by function (!task.due.moment) ? '%%4%% Undated' : result = task.due.moment.isBefore(moment(), 'day') ? '%%1%% Overdue' : result = task.due.moment.isSame(moment(), 'day') ? '%%2%% Today' : '%%3%% Future'`
|
|
* Group task due dates in to 4 broad categories: `Overdue`, `Today`, `Future` and `Undated`, displayed in that order.
|
|
* Try this on a line before `group by due` if there are a lot of due date headings, and you would like them to be broken down in to some kind of structure.
|
|
* A limitation of Tasks expressions is that they each need to fit on a single line, so this uses nested ternary operators, making it powerful but very hard to read.
|
|
* In fact, for ease of development and testing, it was written in a full-fledged development environment as a series of if/else blocks, and then automatically refactored in these nested ternary operators.
|
|
* `group by function (!task.due.moment) ? '%%4%% ==Undated==' : result = task.due.moment.isBefore(moment(), 'day') ? '%%1%% ==Overdue==' : result = task.due.moment.isSame(moment(), 'day') ? '%%2%% ==Today==' : '%%3%% ==Future=='`
|
|
* As above, but the headings `Overdue`, `Today`, `Future` and `Undated` are highlighted.
|
|
* See the sample screenshot below.
|
|
|
|

|
|
|
|
Sample image showing tasks grouped first by highlighted words `Overdue`, `Today`, `Future` and `Undated`, and then by individual due date.
|
|
|
|
### Done Date
|
|
|
|
* `group by done`
|
|
* The done date of the task, including the week-day, or `No done date`.
|
|
|
|
* `done` grouping option was introduced in Tasks 1.7.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by done date** is now possible.
|
|
|
|
* `group by function task.done.format("YYYY-MM-DD dddd")`
|
|
* Like "group by done", except it uses an empty string instead of "No done date" if there is no done date.
|
|
|
|
### Scheduled Date
|
|
|
|
* `group by scheduled`
|
|
* The scheduled date of the task, including the week-day, or `No scheduled date`.
|
|
|
|
* `scheduled` grouping option was introduced in Tasks 1.7.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by scheduled date** is now possible.
|
|
|
|
* `group by function task.scheduled.format("YYYY-MM-DD dddd")`
|
|
* Like "group by scheduled", except it uses an empty string instead of "No scheduled date" if there is no scheduled date.
|
|
|
|
### Start Date
|
|
|
|
* `group by start`
|
|
* The start date of the task, including the week-day, or `No start date`.
|
|
|
|
* `start` grouping option was introduced in Tasks 1.7.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by start date** is now possible.
|
|
|
|
* `group by function task.start.format("YYYY-MM-DD dddd")`
|
|
* Like "group by start", except it uses an empty string instead of "No start date" if there is no start date.
|
|
|
|
* `group by created`
|
|
* The created date of the task, including the week-day, or `No created date`.
|
|
|
|
`created` grouping option was introduced in Tasks 2.0.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by created date** is now possible.
|
|
|
|
* `group by function task.created.format("YYYY-MM-DD dddd")`
|
|
* Like "group by created", except it uses an empty string instead of "No created date" if there is no created date.
|
|
|
|
### Happens
|
|
|
|
* `group by happens`
|
|
* The earliest of start date, scheduled date, and due date, including the week-day, or `No happens date` if none of those are set.
|
|
|
|
`happens` grouping option was introduced in Tasks 1.11.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by happens date** is now possible.
|
|
|
|
* `group by function task.happens.format("YYYY-MM-DD dddd")`
|
|
* Like "group by happens", except it uses an empty string instead of "No happens date" if there is no happens date.
|
|
|
|
## Group by Other Task Properties
|
|
|
|
As well as the date-related groups above, groups can be created from properties in individual tasks.
|
|
|
|
### Description
|
|
|
|
There is no built-in instruction to group by description.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by description** is now possible.
|
|
|
|
* `group by function task.description`
|
|
* group by description.
|
|
* This might be useful for finding completed recurrences of the same task.
|
|
* `group by function task.description.toUpperCase()`
|
|
* Convert the description to capitals.
|
|
* `group by function task.description.slice(0, 25)`
|
|
* Truncate descriptions to at most their first 25 characters, and group by that string.
|
|
* `group by function task.description.replace('short', '==short==')`
|
|
* Highlight the word "short" in any group descriptions.
|
|
|
|
### Description without tags
|
|
|
|
Since Tasks 4.2.0, it is possible to remove tags from the descriptions in custom groups, for use in **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping)**.
|
|
|
|
The value `task.descriptionWithoutTags` returns a copy of the description with all the tags removed, so that you can group together any tasks whose descriptions differ only by their tags.
|
|
|
|
* `group by function task.descriptionWithoutTags`
|
|
* Like `group by description`, but it removes any tags from the group headings.
|
|
* This might be useful for finding completed recurrences of the same task, even if the tags differ in some recurrences.
|
|
|
|
### Priority
|
|
|
|
* `group by priority`
|
|
* The priority of the task, namely one of:
|
|
* `Highest priority`
|
|
* `High priority`
|
|
* `Medium priority`
|
|
* `Normal priority`
|
|
* `Low priority`
|
|
* `Lowest priority`
|
|
|
|
* `priority` grouping option was introduced in Tasks 1.11.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by priority name and number** is now possible.
|
|
|
|
Using the priority name:
|
|
|
|
* `group by function task.priorityName`
|
|
* Group by the task's priority name.
|
|
* The priority names are displayed in alphabetical order.
|
|
* Note that the default priority is called 'Normal', as opposed to with `group by priority` which calls the default 'None'.
|
|
* `group by function '%%' + task.priorityNumber.toString() + '%%' + task.priorityName +' priority'`
|
|
* Group by the task's priority name.
|
|
* The hidden priority number ensures that the headings are written from highest to lowest priority.
|
|
* Note that the default priority is called 'Normal', as opposed to with `group by priority` which calls the default 'None'.
|
|
|
|
Using the priority number:
|
|
|
|
* `group by function task.priorityNumber`
|
|
* Group by the task's priority number, where Highest is 0 and Lowest is 5.
|
|
|
|
### Urgency
|
|
|
|
* `group by urgency` ([urgency](https://publish.obsidian.md/tasks/Advanced/Urgency))
|
|
* The groups run from the highest urgency to the lowest.
|
|
* You can reverse this with `group by urgency reverse`.
|
|
|
|
* `urgency` grouping option was introduced in Tasks 3.6.0.
|
|
* In Tasks 4.0.0 the order of `group by urgency` was reversed, to put most urgent tasks first. Add or remove the word `reverse` to get the original order.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by urgency** is now possible.
|
|
|
|
* `group by function task.urgency.toFixed(3)`
|
|
* Show the urgency to 3 decimal places, unlike the built-in "group by urgency" which uses 2.
|
|
|
|
### Recurrence
|
|
|
|
* `group by recurring`
|
|
* Whether the task is recurring: either `Recurring` or `Not Recurring`.
|
|
* `group by recurrence`
|
|
* The recurrence rule of the task, for example `every week on Sunday`, or `None` for non-recurring tasks.
|
|
* Note that the text displayed is generated programmatically and standardised, and so may not exactly match the text in any manually typed tasks. For example, a task with `🔁 every Sunday` is grouped in `every week on Sunday`.
|
|
|
|
* `recurring` and `recurrence` grouping options were introduced in Tasks 1.11.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by recurrence** is now possible.
|
|
|
|
* `group by function task.isRecurring ? "Recurring" : "Non-Recurring"`
|
|
* Use JavaScript's ternary operator to choose what to do for true (after the ?) and false (after the :) values.
|
|
|
|
* `group by function task.recurrenceRule.replace('when done', '==when done==')`
|
|
* Group by recurrence rule, highlighting any occurrences of the words "when done".
|
|
|
|
### Tags
|
|
|
|
* `group by tags`
|
|
* The tags of the tasks or `(No tags)`. If the task has multiple tags, it will show up under every tag.
|
|
|
|
* `tags` grouping option was introduced in Tasks 1.10.0.
|
|
|
|
* `group by function task.tags`
|
|
* Like "group by tags" except that tasks with no tags have no heading instead of "(No tags)".
|
|
* `group by function task.tags.join(", ")`
|
|
* Tasks with multiple tags are listed once, with a heading that combines all the tags.
|
|
* Separating with commas means the tags are clickable in the headings.
|
|
* `group by function task.tags.sort().join(", ")`
|
|
* As above, but sorting the tags first ensures that the final headings are independent of order of tags in the tasks.
|
|
* `group by function task.tags.filter( (tag) => tag.includes("#context/") )`
|
|
* Only create headings for tags that contain "#context/".
|
|
* `group by function task.tags.filter( (tag) => ! tag.includes("#tag") )`
|
|
* Create headings for all tags that do not contain "#tag".
|
|
|
|
These are more complicated examples, which you might like to copy if you use tasks with [nested tags](https://help.obsidian.md/Editing+and+formatting/Tags#Nested+tags) and wish to group them at different tag nesting levels.
|
|
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[0].replace('#', '') )`
|
|
* `#tag/subtag/sub-sub-tag` gives **`tag`**.
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[1] ? tag.split('/').slice(1, 2) : '')`
|
|
* `#tag/subtag/sub-sub-tag` gives **`subtag`**.
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[2] ? tag.split('/').slice(2, 3) : '')`
|
|
* `#tag/subtag/sub-sub-tag` gives **`sub-sub-tag`**.
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[3] ? tag.split('/').slice(3, 4) : '')`
|
|
* `#tag/subtag/sub-sub-tag` gives no heading, as there is no value at the 4th level.
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[0] )`
|
|
* `#tag/subtag/sub-sub-tag` gives **`#tag`**.
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[1] ? tag.split('/').slice(0, 2).join('/') : '')`
|
|
* `#tag/subtag/sub-sub-tag` gives **`#tag/subtag`**.
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[2] ? tag.split('/').slice(0, 3).join('/') : '')`
|
|
* `#tag/subtag/sub-sub-tag` gives **`#tag/subtag/sub-sub-tag`**.
|
|
* `group by function task.tags.map( (tag) => tag.split('/')[3] ? tag.split('/').slice(0, 4).join('/') : '')`
|
|
* `#tag/subtag/sub-sub-tag` gives no heading, as there is no value at the 4th level.
|
|
|
|
### Original Markdown
|
|
|
|
There is no built-in instruction to group by the original markdown line.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by original markdown line** is now possible.
|
|
|
|
For example, this could be used to extract information from `task.originalMarkdown` that Tasks does not parse, to use for grouping tasks.
|
|
|
|
* ``` group by function '``' + task.originalMarkdown + '``' ```
|
|
* Group by the raw text of the task's original line in the MarkDown file as code.
|
|
* Note the pairs of backtick characters ('\`'), to preserve even single backtick characters in the task line.
|
|
* It's important to prevent the task checkbox (for example, '\[ \]') from being rendered in the heading, as it gets very confusing if there are checkboxes on both headings and tasks.
|
|
* `group by function task.originalMarkdown.replace(/^[^\[\]]+\[.\] */, '')`
|
|
* An alternative to formatting the markdown line as code is to remove everything up to the end of the checkbox.
|
|
* Then render the rest of the task line as normal markdown.
|
|
|
|
## Group by File Properties
|
|
|
|
### File Path
|
|
|
|
* `group by path` (the path to the file that contains the task, that is, the folder and the filename)
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by file path** is now possible.
|
|
|
|
* `group by function task.file.path`
|
|
* Like 'group by path' but includes the file extension.
|
|
|
|
### Root
|
|
|
|
* `group by root` (the top-level folder of the file that contains the task, that is, the first directory in the path, which will be `/` for files in root of the vault)
|
|
|
|
`root` grouping option was introduced in Tasks 1.11.0.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by root folder** is now possible.
|
|
|
|
* `group by function task.file.root`
|
|
* Same as 'group by root'.
|
|
|
|
### Folder
|
|
|
|
* `group by folder` (the folder to the file that contains the task, which always ends in `/` and will be exactly `/` for files in root of the vault)
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by folder** is now possible.
|
|
|
|
* `group by function task.file.folder`
|
|
* Same as 'group by folder'.
|
|
* `group by function task.file.folder.slice(0, -1).split('/').pop() + '/'`
|
|
* Group by the immediate parent folder of the file containing task.
|
|
* Here's how it works:
|
|
* '.slice(0, -1)' removes the trailing slash ('/') from the original folder.
|
|
* '.split('/')' divides the remaining path up in to an array of folder names.
|
|
* '.pop()' returns the last folder name, that is, the parent of the file containing the task.
|
|
* Then the trailing slash is added back, to ensure we do not get an empty string for files in the top level of the vault.
|
|
|
|
### File Name
|
|
|
|
* `group by filename` (the link to the file that contains the task, without the `.md` extension)
|
|
* Note that tasks from different notes with the same file name will be grouped together in the same group.
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by file name** is now possible.
|
|
|
|
* `group by function task.file.filename`
|
|
* Like 'group by filename' but does not link to the file.
|
|
* `group by function '[[' + task.file.filename.replace('.md', '') + ( task.hasHeading ? ('#' + task.heading) : '') + ']]'`
|
|
* Like 'group by backlink' but links to the heading in the file.
|
|
|
|
### Backlink
|
|
|
|
* `group by backlink` (the text that would be shown in the task's [backlink](https://publish.obsidian.md/tasks/Queries/Backlinks), combining the task's file name and heading, but with no link added)
|
|
|
|
### Heading
|
|
|
|
* `group by heading` (the heading preceding the task, or `(No heading)` if there are no headings in the file)
|
|
|
|
Since Tasks 4.0.0, **[custom grouping](https://publish.obsidian.md/tasks/Scripting/Custom+Grouping) by heading** is now possible.
|
|
|
|
* `group by function (task.heading + '.md' === task.file.filename) ? '' : task.heading`
|
|
* Group by heading, but only if the heading differs from the file name.
|
|
* This works well immediately after a 'group by filename' line.
|
|
* Note the three equals signs '===': these are important for safety in JavaScript.
|
|
|
|
## Multiple groups
|
|
|
|
You can add multiple `group by` query options, each on an extra line. This will create nested groups. The first group has the highest priority.
|
|
|
|
Each subsequent `group by` will generate a new heading-level within the existing grouping:
|
|
|
|
* First `group by` is displayed as `h4` headings
|
|
* Second `group by` is displayed as `h5` headings
|
|
* Third and subsequent `group by` are displayed as `h6` headings
|
|
|
|
Headings are displayed in case-sensitive alphabetical order, not the original order.
|
|
|
|
## Refining groups
|
|
|
|
### Reversing groups
|
|
|
|
Reversing of group headings was introduced in Tasks 3.7.0.
|
|
|
|
After the name of the property that you want to group by, you can add the `reverse` keyword. If given, the group headings will be reversed for that property.
|
|
|
|
For example:
|
|
|
|
* `group by due` will sort the group headings:
|
|
* from **oldest** due date first...
|
|
* to **newest** due date last
|
|
* `group by due reverse` will sort the group headings:
|
|
* from **newest** due date first...
|
|
* to **oldest** due date last
|
|
|
|
The `reverse` keyword controls the order that group headings are displayed.
|
|
|
|
The [sort by](https://publish.obsidian.md/tasks/Queries/Sorting) facility, by contrast, controls the order in which displays are displayed _inside_ each group.
|
|
|
|
### Limiting group size
|
|
|
|
You can limit the number of tasks in each group, perhaps to work on the most important things first.
|
|
|
|
## Notes
|
|
|
|
The order of operations ensures that grouping does not modify which tasks are displayed, for example when the `limit` options are used:
|
|
|
|
1. all the filter instructions are run
|
|
2. then any sorting instructions are run
|
|
3. then any `limit` instructions are run
|
|
4. then any grouping instructions are run
|
|
5. then any `limit groups` instructions are run
|
|
|
|
## Screenshots
|
|
|
|
### Before
|
|
|
|
Here is an example Tasks result, without any `group by` commands:
|
|
|
|

|
|
|
|
Tasks not grouped.
|
|
|
|
### After
|
|
|
|
And here is what this might look like, when grouped by folder, filename and heading:
|
|
|
|

|
|
|
|
Tasks grouped.
|
|
|
|
## Examples
|
|
|
|
Give me three levels of grouping, to indicate the locations of my tasks:
|
|
|
|
```routeros
|
|
```tasks
|
|
not done
|
|
group by folder
|
|
group by filename
|
|
group by heading
|
|
```
|
|
|
|
```
|
|
|
|
Show me tasks I need to do today - and put today's tasks first, for visibility:
|
|
|
|
```routeros
|
|
```tasks
|
|
not done
|
|
due before tomorrow
|
|
group by due reverse
|
|
```
|
|
|
|
```
|
|
|
|
Grouping |