Yes, with some caveats.
The query will always run. However upon refresh it may or may not show content.
I use it to show start of day and end of day reflection. So most of the time this query shows “no matched results”. But at specific times it does.
#+BEGIN_QUERY
{:title [:h4 "🧘🏽♀️ Reflectie"]
:query [:find (pull ?b [*])
:in $ ?now ?o ?a
:where
[?p :block/name "reflectie"]
[?b :block/page ?p]
[?b :block/content ?c] ;blocks on page reflectie with certain content
(or ; different rules to validate against
(and
[(<= ?now ?o)] ; now is before 13:00
[(clojure.string/includes? ?c "Begin van de dag")] ;block includes this content
)
(and
[(<= ?a ?now)] ; now is after 17:30
[(clojure.string/includes? ?c "Eind van de dag")] ;block includes this content
)
) ;If none of this is true, show nothing
]
:result-transform (fn [r] (map (fn [m] (assoc m :block/collapsed? true)) r)) ;show the block collapsed
:inputs [:right-now-ms :today-1300 :today-1730] ;the time now, at 13:00 and 17:30
}
#+END_QUERY
You can change the conditions as you wish obviously. Hopefully this provides a good starting point.
If you need more specific help, let me know!
Ps. Let me mention that I have an extremely complex set up using the same idea.
It has 7 inputs, one is today, the rest is times. Showing different things at different times, but also based on other conditions…
Hi thank you for this. I’ve been playing around with the code, I get it to work, but not to show up between the appropriate hours I want it to show up. If I write “:today” in inputs the query shows results, which confirms my code works overall, but when I use your inputs it doesn’t work. Here’s something I tried:
:inputs [:right-now-ms :today-0700 :today-1700] ;display reults from 07:00 to 17:00
Also not working.
I also tried: :inputs [:today-0700 :today-1700] ;display reults from 07:00 to 17:00.
Hi, what does the rest of the query look like?
I cannot help you based on this information alone I’m afraid.
What is in :inputs corresponds with what is behind :in $
So in my example we have :in $ ?now ?o ?a :inputs [:right-now-ms :today-1300 :today-1730]
Meaning ?now will have the value of :right-now-ms, ?o will have the value of :today-1300 and ?a has the value of :today-1730.
These are then used together, for example here: [(<= ?now ?o)] to determine if that is true or false. In this case is it right now (on your device) before or at 1300.
So yeah, without more details, this is all I can tell you.
So 2 things. 1 you put the blocks on the maison page in variable ?b, but you pull ?h.
And you don’t need the and or or, because there is only 1 condition.
Here’s what it should look like:
#+BEGIN_QUERY
{:title [:h4 "🧘🏽♀️ Reflectie"]
:query [:find (pull ?h [*])
:in $ ?now ?a
:where
[?h :block/marker ?marker]
[(contains? #{"NOW" "LATER"} ?marker)]
[?p :block/name "maison"]
[?h :block/page ?p]
[(>= ?a ?now)] ; now is before 18:00
]
:result-transform (fn [r] (map (fn [m] (assoc m :block/collapsed? true)) r)) ;show the block collapsed
:inputs [:right-now-ms :today-1800] ;the time now and at 18:00
:collapsed? true
}
#+END_QUERY
I’m not going to say it is flawless and probably it requires better testing, so here’s me saying, try it!
#+BEGIN_QUERY
{:title [:h3 "⚡️ Lopend"]
:query [:find ?project (count ?b) (sum ?count) ;count ?b is required to show the correct sum of ?count
:keys project block taken ;define keys to use in the view below
:where
[?t :block/name "taskcount"] ;page named taskcount
[?p :block/tags ?t] ;get all pages tagged with taskcount
[?p :block/journal? false] ;that aren't journals
[?p :block/original-name ?project] ;put the original page name in variable ?project
[?b :block/page ?p] ;get blocks on the found pages
;Anything above this line can be edited to fit what you need to find in terms of a project name and related tasks!
(or
(and
[?b :block/marker "TODO"] ;block is a task
[(* 1 1) ?count] ;set count to 1
)
(and
(not [?b :block/marker "TODO"]) ;block is not a task
[(* 0 1) ?count] ;set count to zero
)
)
]
;Use of :view to display our result in a table
:view (fn [rows] [:table
[:thead [:tr [:th "Project"] [:th "Tasks"] ] ]
[:tbody (for [r rows] [:tr
[:td [:a {:href (str "#/page/" (clojure.string/replace (get-in r [:project]) "/" "%2F"))} (get-in r [:project])] ]
[:td (get-in r [:taken]) ]
])]
])
}
#+END_QUERY
Let me know how it works out. Or if you need any help adjusting the query for your needs.
I’ve got a query for currently “DOING” tasks (which are not “#blocked”) but I’d like to pull ones mentioning “#pinned” to the top – either by sort or by grouping – and leave ones which don’t have that tag to be sorted by date and priority.
As you can see, I started pulling out the “#pinned” block in the :where clause, to do something with it, but I can’t figure out what. Or would I somehow need to pull it out in the :result-transform? Maybe I need a has-ref? function, then I can sort by its boolean result???
{:title [:h3 "Doing"]
:query [:find (pull ?b [*])
:where
[?b :block/marker ?marker]
[(contains? #{"DOING" "NOW"} ?marker)]
[?blocked :block/name "blocked"]
(not [?b :block/refs ?blocked])
[?pinned :block/name "pinned"]
]
:result-transform (fn [result] (sort-by (juxt
(fn [r] (or (get-in r [:block/scheduled]) (get-in r [:block/deadline])))
(fn [r] (get-in r [:block/priority] "Z"))
) result)) ; Sort first by scheduled, then deadline, then priority.
:table-view? false
:group-by-page? false
:breadcrumb-show? false
:collapsed? false
}
For now I’ll try just highlighting the pinned ones with the :view.
One option would be sorting.
See my answer here for the basics that would entail.
Then we would need to somehow tell the database that it needs to sort by a value that is not always present. That’s the tricky part. You need something similar to the count mechanism I proposed in my post above yours.
And so probably your best option for this is two queries.
The first query will pull those tasks that are pinned.
The second query will pull those tasks that are not pinned.
This makes the results also visually distinct and so this would be a “grouping”.
I also ran into the issue of your query not returning anything. This is because your not statement needs to include the [?blocked :block/name "blocked"] to work properly. I fixed that below as well.
This one is great - I’ve swapped out the input from current-page to query-page to make it a little more stable.
I’m also wondering if there’s a way to post this on a parent of a namespace, to pull all the tasks that are tagged with the subpage aliases - for example-
parent
parent/sub - has alias: sub
so want to pull in the TODOs that have #sub, not just #parent/sub like here
PS - thank you for this thread and all your responses on other threads - I’ve been able to go from zero understanding of queries to feeling decent in only a few days going through all your templates and responses!
The use case is getting all new tasks (which created by default with an empty priority) on top of the priority list, for processing (like an inbox).
Empty priority can be also treated as high priority (as default A priority for new tasks is not supported)
Yes! That option didn’t exist back then.
In general :query-page probably what you want unless you have a query on the sidebar and want it to use the page open in the main panel.
Yes. Through getting the namespace and then the alias of it.
So we’re on parent.
We can get [?p :block/name parent]
and then [?c :block/namespace ?p]
Then [?c :block/alias ?a]
And finally [?b :block/refs ?a]
Very off the top of my head quick answer.
Basically combine the info from both places.
Only way is to substitute empty with “A”.
There should be sort examples that do this already.
From the top of my head (get r :block/priority "A")
This would intermingle the priority A tasks with the empty priority tasks though, as A is the first letter of the alphabet
I don’t know if something like “1” would work, but might be worth a shot.
I searched for examples and didn’t find, maybe I missed…
Is it something with assoc function?
Ooof that bit complex for me
If you can link to me relevant code it will be great not urgent
I actually ended up finding a good use for :current-page - I’m using Embed blocks for different sections of my journals, and have those embed blocks in a daily template - so I only edit the Query once and it populates across all my journals, but still gets the Current page content - absolutely brilliant, I’m loving Logseq more every day!