A query that displays blocks arranged in chronological order

I would like a query that rearranges the blocks of the current page in chronological order. How should I write it?

Specifically, it should check the SCHEDULED DATE property of the block or the date of the journal page referenced by that block and list the blocks in that order.

If a block mentions multiple dates, it can appear multiple times, and blocks without a date don’t need to be displayed. Moreover, only the specific block should be displayed in the results, without any parent or child blocks.

This is an advanced query that should be able to do what you want. It uses or-join to distinguish between ?dates from referenced journal-pages and ?dates from scheduled tasks.
In :result-transform, it uses the inbuilt sort-by function. To get a nice display behavior, it uses (pull ?b [*]) in the :find statement, as well as for in :result-transform to strip off the ?date information after sorting…

{
 :title [:h1 "Order blocks by referenced date"]

 :query
 [
  :find (pull ?b [*]) ?date
  :keys block date
  :in $ ?current-page

  :where
   [?p :block/name ?current-page]
   [?b :block/page ?p]
   (or-join [?b ?date]
    (and 
      [?b :block/refs ?ref]
      [?ref :block/journal? true]
      [?ref :block/journal-day ?date]
     )
     [?b :block/scheduled ?date]
    )
  ]
 :inputs [:current-page]
 :result-transform (fn [result] (for [row (sort-by :date result)] (get row :block)))
}

As you can see in the following screenshot, the query can:

  • sort by referenced or scheduled date
  • blocks with multiple references are displayed multiple times
  • scheduled blocks with journal page references are displayed twice
  • omits blocks that do not have SCHEDULED property or reference to journal page

3 Likes

Thank you so much. This is exactly the solution I was looking for. I will make good use of it.

I’ve learned a lot thanks to you.