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 ?date
s from referenced journal-pages and ?date
s 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.