A nice-looking query with clickable links

Did you know you can add click handlers into the queries? It’s actually pretty easy and it allows you to make something like this

Without any need for custom plugins or js. Here’s how:

In your config.edn add the following to the :default-queries:

{:view (fn
         ; the query will return an array with one item, so [[count]] will destructure the number
         [[count]]
         [:div
          {:style {:color "#b1b1b1"}}
          "There are "
          [:span count]
          " notes in the "
          [:a {:data-ref "pile"
               :style {:color "#797979"}
               :on-click
               ; call-api is a magical call that allows you to call any API available
               ; in this case, it navigates to the "pile" page if you click the link
               (fn [] (call-api "push_state" "page" {:name "pile"}))} "pile"]
          "."])
 :query
 [:find (count ?b)         ; return a single item - the total count of blocks
  :where
  [?pb :block/name "pile"] ; where pb is the block for a page named "pile"
  [?b :block/refs ?pb]]}   ; and blocks reference it

That seems unnecessarily complex? And a lot of duplicate hard-coded information.
Here’s a query I use (outside config.edn) for the same idea.

#+BEGIN_QUERY
{:title [:h4 "📥 Inbox"]
 :query [:find ?name ?link (count ?b)
  :keys page link count
  :where
   [?i :block/name "inbox"]
   [?i :block/original-name ?link]
   [(str "Aantal") ?name]
   [?b :block/page ?i]
   (not (has-property ?b :icon))
 ]
 :view (fn [rows] (for [r rows] [:div [:a {:href (str "#/page/" (get r :link) )} (str (get r :page) " : " (get r :count) )] ] ))
}
#+END_QUERY

What I wish to point out is the find. We can give multiple values here back to the result. And then use that in the view to construct a sentence.

The way I constructed my query is a bit clunky too, I admit. But I only need to specify inbox once.

1 Like

The point here is when you don’t want to see the actual items in the query, but just their amount. I use #pile as a tag to quickly tag blocks to declutter later and a single line provides both the info on how many things are pending and how to get there without too much of visual noise.

Yeah my query does the same. Here’s my query output:

We can remove the title if we want.
Or we can have multiple lines even:

Though the query for that is a bit more involved as I use a manual sort. But the view remains the same line.

#+BEGIN_QUERY
{:title [:h4 "🚧 In uitvoering"]
 :query [:find ?name (count ?b)
  :keys page count
  :where
   [?t :block/name ?name]
   [(contains? #{"🧭verkenning" "🔍uitzoeken"} ?name)]
   (property ?b :status ?name)
   [?b :block/page ?p]
   (not [?p :block/name "templates"])
 ]
 :result-transform (fn [result] 
  (sort-by
    (fn [x] (
      (into {}
        (map-indexed
          (fn [i e] [e i]) ["🧭verkenning" "🔍uitzoeken"]
        ) ;;=> ([d 0] [i 1] [u 2])
      ) ;;=> {d 0, i 1, u 2}
      ((fn [r] (get r :page)) x)
    )
  ) ;;=> Get value of :page from result (through x and r). 
      ;;=> Lookup that value in the map created through map-indexed and into. 
      ;;=> Sort result based on that value index number pair.
  result)
 )
 :view (fn [rows] (for [r rows] [:div [:a {:href (str "#/page/" (get r :page) )} (str (get r :page) ": " (get r :count) )] ] ))
}
#+END_QUERY
2 Likes