Is there a way to query empty pages?

Hey everyone,

is there a way to query all empty pages? And is there a way to query based on a missing property? E.g. if I have a property “note-type”, can I query all pages where this property is either empty or not even there yet (i.e. the “note-type::” is not written on the page)

One of the main reasons for this is that I don’t create everything from the Journal pages – for certain notes, I like to elaborate inside the pages themselves. And when I do and create links from there, it would feel clunky to always indent those new pages under something like #inbox or #fleeting. So being able to query empty pages in either one of those two ways would help a lot, but I wasn’t able to find a way

Its an interesting problem because as I understand it if you create a link eg. [[page1]] but never go to page1 and add any blocks then page1.md will not physically exist until such time as you add content to page1. However in this situation page1 will be included in the ‘All Pages’ list of pages (with back links shown as 1).

So the query would need to know that although there is no physical page1 that it is an empty page as far as Logseq’s database is concerned.

Its actually good that Logseq does not create a physical file as it saves on having lots of unnecessary files.

I see, thank you!

I think the best solution for me is using block properties to mark blocks including links to any new pages for further processing, inspired by @thatgothlibrarian’s workflow

I see that you already have your solution, but I would like to leave this here for future people coming across this page:

#+BEGIN_QUERY
{:title "Pages"
 :query [:find ?tag
         :where
         [?p :block/name ?tag]
         [?p :block/journal? false]
         [?p :block/file ?f]
 ]
  :result-transform (fn [result] (sort result))
 :view (fn [tags]
           [:div
           (for [tag (flatten tags)]
                [:a.tag.mr-1 {:href (str "#/page/" tag)}
                (str "#" tag)]
     )]
    )
}
#+END_QUERY

This finds all pages that have a file. (Displays as a hashtag list)
You can change that to: [(missing? $ ?p :block/file)] to find all pages without a file, which are by definition empty pages.

Still trying to figure out how to query for page-properties that are empty or missing myself. :slight_smile:

6 Likes

Is there any way to add a number of back-links to this list, and ideally sort by it?

And, how does the :find ?tag part work? Where does the ?tag variable come from? I haven’t seen that in many other query examples…

Ok, this query kind of works - it returns the numbers, but it appears to insert them into results as a single flattened list, instead of a list of tuples (sorry, very new to clojure)

 :query [:find ?tag (count ?b)
         :where
         [?p :block/name ?tag]
         [?b :block/refs ?p]
         [?p :block/journal? false]
         [(missing? $ ?p :block/file)]
         [(missing? $ ?p :block/alias)]
 ]

Which means that I can’t sort the names by the numbers

1 Like

OK, I spent way too long on this today, but it’s working:

#+BEGIN_QUERY
{:title [ :b "Missing Pages" ]
    :query [:find ?tag (count ?tagcount)
        :keys name count
        :where
        [?p :block/name ?tag]
        [?p :block/journal? false]
        [(missing? $ ?p :block/file)]
        [(missing? $ ?p :block/alias)]
        [?b :block/refs ?p ?tagcount]
    ]

 :result-transform (fn [result] (sort-by (fn [r] (get-in r [:count])) > result))

;:view pprint

 :view (fn [rows] [:table [:thead [:tr [:th "Page"] [:th "Count"] ] ]
    [:tbody (for [r rows] [:tr
       [:td [:a {:href (str "#/page/" (clojure.string/replace (get-in r [:name]) "/" "%2F"))} (get-in r [:name])] ]
       [:td [:a {:href (str "#/page/" (get-in r [:name]))} (get-in r [:count])] ]
    ])]
   ])

}
#+END_QUERY

Also, this is relevant. I wrote a PR to allow different styling for empty pages and aliases, but it’s yet to be reviewed:

1 Like