Getting Things Done in Obsidian

This guide provides a way of setting up Obsidian for GTD, inspired by the way Things works.

Getting Things Done in Obsidian
Photo by Andrew Neel / Unsplash

Getting Things Done is a methodology for managing life’s many inputs and to provide clear mental space to focus. To get started, there is no better way than reading the actual book. I have been using this framework close to 15 years, and many of them were spent in OmniFocus, and in later years, Things  has been my companion. To be completely fair, I was using Things before OmniFocus, and scrolling all the way back in the archive reveals that the first completed action was on August 30, 2008.

Fast-forward into 2023, and I have been looking into using Obsidian for meeting notes among other things. Being able to move my GTD system into the same app could provide some great benefits, such as automatically populating agendas in the meeting notes for a specific meeting. I am currently on parental leave, which means having less active projects, makes for a great time to experiment with something like this.

The system itself is essentially a bunch of notes, bound together using Dataview, an excellent plugin that provides a query language for notes and tasks within Obisidian. The GTD pages have a common menu for easy navigation and look something like this.

This is the general file structure of the project

The way this is set up is very close to how I have been managing my lists in Things, and the views we are about to create will reflect that. The sections below describe each view in more detail and the queries used.

Creating a project

What makes a project a project is the metadata contained within the frontmatter of the note, as well as the location. These fields are what is later queried for in the different views.

state: active, someday, done, dropped (the different project states)
org: different organization of life, eg. personal, work, side business etc.
area: general areas of responsibility for the project, like personal, family, health
start: an optional field if the project has a specific start date
due: an optional field if the project has a specific deadline
reviewed: set to the current date when the project is created. Currently unused, but I have been experimenting with having a view for seeing what to review like in OmniFocus.
period: If the review period is something other than 7 days, this can be set here.
category: Project (this is the field that I have configured the metadata menu plugin to use for different types.)
prio: set to 1 by default and currently unused. This may be used to sort the project list if necessary.

Metadata menu plugin

The metadata menu plugin is used to create structure to metadata, eg. frontmatter fields. You can install and configure a project template using the frontmatter fields above. Another benefit this brings is autocomplete for the various fields, such as the org and area.

Templater plugin

The templater plugin is a great helper in automating project creation. Install it, and configure a template to look like this:

---
state: active
org: personal
area: personal
start: 
due: 
reviewed: <% tp.date.now("YYYY-MM-DD") %>
period: 
category: Project
prio: 1
---
![[Filters#Menu]]
<% await tp.file.move("GTD/Projects/" + tp.file.title) %>

When this template is applied to a note, it will automatically add all metadata, set the reviewed date, as well as move the project to the correct folder, which in my case is GTD/Projects.

The way I usually create new projects is by clicking the new note button in Obsidian and give it a name. Then I press cmd + p (or drag down from the top on the iPhone) and type “Tem”, at which point the “Templater: Open insert template modal” should be at the top. Choosing it should reveal the template above, and selecting it will make it a project by assigning the metadata and move the note to the right folder. You can then adjust the metadata as needed and add actions below.

I haven’t mentioned the ![[Filters#Menu]] line yet, but that is how I navigate between the different views. More on that in the Navigation section below.

Project overview

Once you have a few projects in the project folder, the next step is to create a view that automatically shows the projects you have, in order to get a nice overview. The view relies on the dataview plugin, so the first step is to get that installed.

Next, create a file called Projects In your GTD/ folder and add a section for showing active projects:

dataview
TABLE
    length(filter(file.tasks, (t) => !t.completed)) AS ☑️,
    area
FROM "GTD/Projects"
WHERE category = "Project"
AND state = "active"
AND start <= date(today)
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
SORT org, area, file.name

Next, do the same thing for scheduled projects, e.g. projects with a start date that is in the future:

dataview
TABLE
    length(filter(file.tasks, (t) => !t.completed)) AS ☑️,
    start
FROM "GTD/Projects"
WHERE category = "Project"
AND state = "active"
AND start > date(today)
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
SORT org, area, file.name

Finally, do a section for Someday projects. This can of course be moved into its own page if needed:

dataview
TABLE
    area
FROM "GTD/Projects"
WHERE category = "Project"
AND state = "someday"
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
SORT org, file.name

Now you should have a page similar to the screenshot below. It shows you all projects that you have created, together with the number of next actions and area.

Recurring projects

A limitation to this setup compared to Things and other “real” task managers, is that it doesn’t support recurring actions. The way I have been handling this so far is to create a special single action project for this, one for each org, called  + Personal recurring.

I have put actions under a heading for each cadence, and if I see a completed action during the weekly review, I copy/paste it and change the start date to what the heading states. The finished action can be moved into a separate section at the bottom.

This works as long as you do your Weekly Review weekly, and also don’t have anything that needs to repeat more than once a week. A workaround could be to use the calendar for keeping track of this, if you have recurring deadlines.

Single actions

As mentioned in the introduction, the foundational element is a project, meaning there can be no standalone actions. To solve this, similar to the recurring tasks, I have a single actions project for each org called + Personal SAL. The reason for choosing “SAL” over “actions” or similar is just because I want to quickly be able to search for it when adding an action.

Contexts

Now we are getting to a place where the rubber hits the road — contexts. This is where the project lists and actions created previously actually come into practice. A context shows all available actions which mentions that specific context.

The query for a @mac context looks like this, and is added to GTD/Contexts/@mac:

dataview
TASK from "GTD/Projects"
WHERE category = "Project"
AND state = "active"
AND start <= date(today)
AND contains(text, "[["+this.file.name+"]]")
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
AND !completed
SORT due desc, text asc
GROUP BY file.link

This means that if I have an action in one of my projects that looks like this, it will show up in the list.

- [ ] An action that needs to be completed on the [[@mac]]

A pro-tip is to use the shortcut ribbon at the bottom to quickly have the link created, as you can just click the button and start typing the name of the context you want to apply. You can also assign multiple contexts if there is something that can be done both on the Mac and on an iPad for instance.

The most used contexts are linked directly in the menu, but for the rest, I have a simple page that links all notes within the context folder. The query looks like this:

dataview
list
from "GTD/Contexts"
sort file.name

Today

The Today view shows any action that has a [[Today]] link assigned, as well as any actions that are due or overdue. It behaves similar to the Today view of Things, but I have chosen not to include tasks that have just become available for now.

We have reviewed how to set a due date for projects, but to set a due date for an action, just include [due:: 2023-02-14] in the text. Similarity for start dates, just add [start:: 2023-02-10]. If you have future actions that you don’t want showing up anywhere, you can add [start:: someday] and they will only be visible in the project list.

This view can be achieved using this query:

dataview
TASK from "GTD/Projects"
WHERE category = "Project"
AND state = "active"
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
AND !completed
AND start <= date(today)
AND (
  (due != null and due <= date(today))
  OR contains(text, "[[Today]]")
  )
GROUP BY file.link
SORT name

Upcoming

The upcoming view shows future deadlines for actions and projects, currently grouped per day, looks like this:

dataview
TASK from "GTD/Projects"
WHERE category = "Project"
AND state = "active"
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
AND !completed
AND due != null
GROUP BY due
SORT file.link

Under this, I have a project deadlines section that lists all project deadlines. Normally, actions for due projects are visible in the query above, however, this provides a good high-level view. It’s also valuable if the project doesn’t have any actions, but is still due.

dataview
list due
FROM "GTD/Projects"
WHERE category = "Project"
AND state = "active"
AND start <= date(today)
AND due != null
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
SORT due

The page will look something like this:

Inbox

I have set a default folder for all new notes in the Obsidian settings, which is +Inbox in the root folder. I don’t want random files in the root, so this makes it a lot tidier. I also have an inbox view to show everything listed there, as well as any unprocessed stuff from my daily and meeting notes. It also includes a link to the inbox in the Drafts app, that I’m currently evaluating.

The inbox section query looks like this:

dataview
list
from "+Inbox"
sort file.mtime desc

The daily notes and meeting notes section looks like this:

dataview
TASK from "Notes/Meetings" OR "Notes/Dailies"
WHERE !completed
GROUP BY file.link

Archive

The Archive view shows all completed tasks. There are two sections in this view, where the first shows the past four days grouped by day, and the second shows everything after, grouped by month. This makes it easy to go back a day or two to see what has been completed, while still seeing the bigger picture. It can of course be expanded to show finished projects only or other things.

dataview
TASK from "GTD/Projects"
WHERE category = "Project"
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
AND done > (date(now) - dur(4 days))
AND completed
SORT done desc
GROUP BY dateformat(date(done), "yyyy-MM-dd") AS fulldate
SORT fulldate desc
dataview
TASK from "GTD/Projects"
WHERE category = "Project"
AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)
AND done <= (date(now) - dur(4 days))
AND completed
SORT done desc
GROUP BY dateformat(date(done), "yyyy-MM")

Filtering on organization

One thing I like about Things is the way tagging and tag inheritance works. It allows me to filter on, for example, only personal areas and projects, which can be great on the weekend and in the evening. In order to do something similar in Obsidian, I have created a Filters file, which contains this:

## Filters
%% personal work %%
filter-org:: 

If I set filter-org to personal for instance, all GTD views will be updated to only show projects and actions from the personal org. If left empty, it will show everything.

If you want to add another org, or change the name of the ones I have defined, you need to update this line in the view queries above:

AND contains(default([[Filters]].filter-org, ["personal", "work"]), org)

In order to easily navigate between views, projects, and everything else, I have created a menu. It’s part of the Filters note, but could of course have been created somewhere else. All views contain the following line just after the frontmatter:

![[Filters#Menu]]

This allows me to update the menu as needed, and easily add it to new places, such as new projects. It currently looks like this:

###### Menu
[[Inbox]] • [[Today]] • [[Upcoming]] • [[Archive]] • [[Filters]]
[[Contexts]] • [[Projects]] • [[Horizons]] • `="[[" + dateformat(date(today), "yyyy-MM-dd") + "|Daily note]]"`
[[@mac]] | [[@iPad]] | [[@tablet]] | [[@iPhone]] | [[@home]]

---

Improvements

While implementing this, the first goal is to have something that works up to horizon 1 level, e.g., projects. There are plenty of improvements I have noticed as I’m setting this up, and I have been keeping track of them. Some of them are:

  • Add a place for checklists
  • Add a place for templates – Use Templater for this, since you can automate setting dates and other things.
  • Consider handling single actions like projects, e.g., in separate files
  • Automatically show relevant contexts in the menu depending on external factors, such as time, day, or location
  • Find some way of automating recurring actions
  • Move finished items in single action lists to another file or sub-heading automatically
  • Move Someday out of the project overview
  • Worried about database size. May move archived projects per year outside the system. In Things, I have tasks dating back from 2008. Can this setup handle that?

Conclusion

In conclusion, I think I’m starting to get to a point where I have a workable system. There is still some minutia that needs to be sorted around quickly adding something to a list. I’m currently testing text transporter, which can be used to move a task from the inbox to a project list, and it is working quite well so far.

My main worry about this setup, is the potential for friction and drag in the system. It’s easy to manage a GTD setup with plenty of bells and whistles when you are on top of your game, but it needs to be as workable on a Thursday afternoon after a three-hour workshop when your mind has checked out as well. Time will tell if I continue on this path or revert to Things.

Kudos

A big thank you to mostlymaths.net  | Project and task management with Obsidian and Dataview for the inspiration to set this up, and of course to the plugin developers for dataview, templater and the others mentioned.

Join the conversation on Twitter and Mastodon/Fediverse.