Challenge 2: Build a Content Consumption Pipeline

Click here to download today’s training graph.


Hopefully, you’ve been able to spot patterns in your notes and fetch them using queries. Search is an important use case for queries, but there’s much more possible with them. For the rest of this week, we’ll leverage our knowledge of queries to manage processes.

A process is nothing more than a series of steps to achieve a goal. The goal of today’s challenge is to build a collection of content you can dive into when it’s relevant or when you have time.

While there are many apps and services to capture content for later consumption, we’ll build our own barebones structure right within Logseq. Using browser extensions or Logseq plugins, you can gradually automate this content collection process.

To design and build better processes, it’s useful to know a thing or two about Systems Thinking. If this term is new for you, first read these notes (make sure you’re running the latest version of the training graph).

In Systems Thinking, there are three main components: inputs, movements, and outputs. If you’re clear on your goal (the output) and know what materials you’re working with (the inputs), it becomes much easier to define the steps to get to the goal (the movements).

Let’s see how we can apply Systems Thinking to our content consumption pipeline.

Systems Thinking applied to content collection

Input

  • Content you wish to consume.

Movements

  • Find a piece of content (tweet, article, video, etc.) you want to consume and think about later.
  • Copy the URL of the content from the browser’s address bar.
  • Run template in Logseq and paste URL.
    • You can automate this step using some text expansion tool on your device.
  • Resurface content when it’s opportunistic to consume and digest (taking notes of your insights).

Output

  • Highlights and notes that can be used for output (memos, blog articles, papers).

Introducing tasks

To help us manage the (short) process of capturing and revisiting content, we’ll mark every piece of content as a task.

If you’ve been using Logseq for more than a few days, you’re probably already familiar with the TODO or LATER keywords. When placed at the beginning of a block, a keyword turns the block into a task.

Apart from TODO and LATER, there are also other keywords that denote the status of the task: NOW, DOING, and DONE. These are part of two different “flavors” or workflows of task management that Logseq ships with.

The two possible task workflows are:

  • LATERNOWDONE (the default workflow)
  • TODODOINGDONE

To change your preferred task workflow, go to the Editor tab in Settings:

What’s nice about the keywords is that we can use them as values in the task query filter, like so: {{query (task todo) }}. Replace the todo keyword with any of the other available values for tasks.

It’s important to note that when using the task filter in a query, the query will only look for the search terms on a per-block basis. In other words: it will not look across an entire branch to find matching terms. This is similar to how block properties work.

Speaking of which…

Correction: this is how block properties work

In Friday’s lesson, I had incorrectly stated that block properties are applied to the whole branch they’re a parent of. However, some alert community members pointed out that block properties only apply to the block they’re part of. I’ve updated Friday’s lesson accordingly (see the section about the property filter).

If you’re looking to combine properties with other filters in a query, make sure the properties you’re querying on are page properties. To apply a property to an entire page, make sure it’s placed in the first block of the page.

Exercise

For today’s challenge, you need to build a series of queries that each represent one step in the content consumption process. The goal is to end up with useful highlights and notes from content. The starting point for each piece of content is getting collected.

Follow the instructions below to get a minimum variable workflow. Experiment by collecting more resources, adding properties, and creating different combinations of queries.

Build a capture template

  • Create a template to quickly collect and categorize content, containing:
    • The TODO keyword
    • The title of the content
    • The URL to the content
    • An author:: property
    • A type:: property
    • A tags:: property

Build a collection of content

  • Use the template you’ve built to collect some content. Make sure to at least add values to the type:: and tags:: properties.

Build a process to consume content

  • For each tag value used, write a query that fetches all TODOs.
  • To create inboxes for different contexts (reading, listening, watching), split out the collected content based on type.
  • Think of what steps you’d take to consume a piece of content. Add these as values to a status property, or use the built-in task statuses. Write a query for each step in the process.

Questions? Insights?

If you have any questions or insights related to today’s challenge, please post them in this forum thread.

3 Likes

I am really enjoying these challenges. The number one benefit that I’m noticing is that I’ve learned how to troubleshoot my queries more effectively. In the course on the Boolean Logic, @Ramses taught us to start with the simplest query and then work outwards.

When I’m not getting the expected results from a query, I start with the simplest query and then work outwards, and am actually having success! This is a huge breakthrough for me.

Thank you, @Ramses!

3 Likes

This is the key! Even though it’s not necessary to become a coder, it does help to use some of the techniques that coders use. One such trick is to start with the smallest working piece of code, and then keep adding small functionality while testing the code continuously.

Thank you for sharing your insight, @AgedLace :pray:

2 Likes

Can sort-by only be used for dates? I would have thought something like {{query (todo todo (sort-by property type))}} would give a list of block with the todo status sorted into the tags used in their block properties under the type key. Or have I just got some syntax wrong?

Your syntax is wrong in three ways:

  1. You need to use the and filter because you’re using more than one filter value.
  2. You need to separate the (task todo) and (sort-by) values. By the way, it’s no longer (todo); it’s now (task) (as in: (task todo), (task doing), (task done))
  3. After sort-by you need to enter the key, which is type (not property, because that’s the name of a query filter).

Your query should be:
{{query (and (task todo) (sort-by type asc)) }}

Keep in mind that the type:: property has to be part of the same block as the TODO if you want it to appear in the query results.

2 Likes

Challenge 2 — Content Consumption Pipeline (my solution, with GTD namespaces)

Plan / Approach

  • I keep task keywords (TODO / DOING / DONE) to make each item a real task (so (task ...) queries work).
  • I use a GTD status property as a page-ref namespace: [[gtd/inbox]], [[gtd/next]], etc.
  • I store type:: and tags:: as page refs (e.g., [[Article]], [[Video]]) so property filters work reliably.

1) Build a capture template

I created a block template called capture (right-click the parent bullet → Make template).

Template block:

  • TODO ${1}
    url:: ${2}
    author:: [[${3}]]
    type:: [[Article]] ;; change to [[Video]] / [[Podcast]]
    status:: [[gtd/inbox]] ;; GTD namespace
    tags:: [[inbox]] [[${4}]]

Note: I keep all properties on the same block as the TODO keyword.


2) Build a collection of content (invented examples)

  • TODO Data Visualization Basics (Crash Course)
    url:: https://example.com/dataviz
    author:: [[Mina Kwon]]
    type:: [[Video]]
    status:: [[gtd/inbox]]
    tags:: [[learning]] [[data]]

  • TODO The Short Guide to Better Sleep
    url:: https://example.com/sleep
    author:: [[Jordan Ellis]]
    type:: [[Article]]
    status:: [[gtd/next]]
    tags:: [[health]] [[reading]]

  • TODO Podcast: How Cities Reduce Traffic
    url:: https://example.com/traffic
    author:: [[Luca Romano]]
    type:: [[Podcast]]
    status:: [[gtd/waiting-for]]
    tags:: [[urbanism]] [[audio]]

  • TODO Notes on “Deep Focus Sessions”
    url:: https://example.com/focus
    author:: [[Aisha Patel]]
    type:: [[Article]]
    status:: [[gtd/someday-maybe]]
    tags:: [[productivity]] [[reading]]

  • TODO Video: Intro to Personal Finance (Budgeting)
    url:: https://example.com/budget
    author:: [[Noah Chen]]
    type:: [[Video]]
    status:: [[gtd/next]]
    tags:: [[finance]] [[learning]]


3) Build a process to consume content (queries)

I use inline simple queries ({{query ...}}) and build the pipeline around GTD status:: + task keywords.

3A) GTD pipeline (by status::)

GTD Inbox (triage)

{{query (and (task todo) (property status gtd/inbox))}}

GTD Next Actions

{{query (and (task todo) (property status gtd/next))}}

GTD Waiting For

{{query (and (task todo) (property status gtd/waiting-for))}}

GTD Someday/Maybe

{{query (and (task todo) (property status gtd/someday-maybe))}}

3B) “Inboxes by context” (by type::, scoped to GTD Next)

Next: Reading (Article)

{{query (and (task todo) (property status gtd/next) (property type Article))}}

Next: Watching (Video)

{{query (and (task todo) (property status gtd/next) (property type Video))}}

Next: Listening (Podcast)

{{query (and (task todo) (property status gtd/next) (property type Podcast))}}

3C) “One query per topic tag”

Topic: productivity

{{query (and (task todo) [[productivity]])}}

Topic: finance

{{query (and (task todo) [[finance]])}}

3D) Work-in-progress and completed (keywords)

In progress

{{query (task doing)}}

Done

{{query (task done)}}


Why namespaces for GTD status?

Using gtd/... keeps statuses grouped under the gtd page (hierarchy), so it scales cleanly as I add more GTD lists later.