Advance query: Exclude template pages from a particular query

Hi, i am a novice on advance queries, I am struggling here.
i am trying to exclude in the below query, my pages that starts with TEMPLATE/.

I tried closure but it gives me a error mesage so not sure.

(not [(clojure.string/starts-with? ?p "TEMPLATE/")])
#+BEGIN_QUERY
{:title [:h1 "Tasks" ]
 :inputs [:query-page]
 :query [:find (pull ?b [*])
  :in $ ?inputpage %
  :where
   [?b :block/marker ?m]
   [(contains? #{"TODO" "DOING" "NOW" "LATER" "WAITING" "WAIT"} ?m)]
   (or-join [?p ?inputpage]
     [?p :block/name ?inputpage] 
     (and
       [?a :block/name ?inputpage]
       [?a :block/alias ?p] 
     )
     (and
       [?ns :block/name ?inputpage]
       (check-ns ?ns ?p)
     )
     (and
       [?ns :block/name ?inputpage]
       (check-ns ?ns ?a)
       [?a :block/alias ?p]
     )
   )
   (or-join [?b ?p ?inputpage]
     (and 
       [?x :block/refs ?p]
       [?x :block/pre-block? true]
       [?x :block/page ?y]
       [?b :block/page ?y]
     )
     (and
       [?b :block/page ?p]
       (not [?p :block/name ?inputpage]) 
     )
     [?b :block/path-refs ?p]
   )
 ]
 :group-by-page? true
 :breadcrumb-show? false
 :result-transform (fn [result]
   (let [sorted-result (sort-by (fn [h] (get h :block/marker)) > result)]
   (map (fn [m] (assoc m :block/collapsed? true)) sorted-result))
 )
 :rules [
   [(check-ns ?ns ?p)
     [?p :block/namespace ?ns]
   ]
   [(check-ns ?ns ?p)
     [?p :block/namespace ?t]
     (check-ns ?ns ?t)
   ]
 ]
}
#+END_QUERY
  • starts-with? operates on strings, but the passed ?p:
    • is not a string
    • is an id
  • The string that corresponds to ?p is ?inputpage
    • This is the :block/name of ?p
      • But :block/name is always lowercase.
  • Therefore, in your attempt should either:
    • replace ?p with ?inputpage and turn "TEMPLATE/" to "template/"
    • replace ?p with e.g. ?name and add a line [?p :block/original-name ?name]
1 Like

Thanks,

I tried either the 2 below but none worked

[?p :block/original-name ?name]
(not [(clojure.string/starts-with? ?name "temp/")])

and

(not [(clojure.string/starts-with? ?inputpage "template/")])
  • Datalog doesn’t forgive any mistakes. The first one should be:
    [?p :block/original-name ?name]
    (not [(clojure.string/starts-with? ?name "TEMPLATE/")])
    
  • The second one looks correct.
    • If it doesn’t work, should share the exact names of the pages, for us to see if something is wrong.
      • For example, name temp is different than name template

So the name of the page where I get the tasks I want to not show is:
TEMPLATE/New User

So ideally, I avoid any page under this TEMPLATE/ structure.
I tried again both code and none are working. I have no error message, it just doesn’t exclude the tasks from the Template page

Apparently in some of your cases ?p is not the page of ?b, but a page referenced by ?b. To exclude tasks from pages named TEMPLATE/..., add also this:

[?b :block/page ?bp]
[?bp :block/original-name ?name]
(not [(clojure.string/starts-with? ?name "TEMPLATE/")])
1 Like

OMG I think you nailed it.
Here is the complete working query

#+BEGIN_QUERY
{:title [:h1 "Tasks"]
 :inputs [:query-page]
 :query [:find (pull ?b [*])
  :in $ ?inputpage %
  :where
   [?b :block/marker ?m]
   [(contains? #{"TODO" "DOING" "NOW" "LATER" "WAITING" "WAIT"} ?m)]
   (or-join [?p ?inputpage]
     [?p :block/name ?inputpage]
     (and
       [?a :block/name ?inputpage]
       [?a :block/alias ?p]
     )
     (and
       [?ns :block/name ?inputpage]
       (check-ns ?ns ?p)
     )
     (and
       [?ns :block/name ?inputpage]
       (check-ns ?ns ?a)
       [?a :block/alias ?p]
     )
   )
   (or-join [?b ?p ?inputpage]
     (and
       [?x :block/refs ?p]
       [?x :block/pre-block? true]
       [?x :block/page ?y]
       [?b :block/page ?y]
     )
     (and
       [?b :block/page ?p]
       (not [?p :block/name ?inputpage])
     )
     [?b :block/path-refs ?p]
   )

[?b :block/page ?bp]
[?bp :block/original-name ?name]
(not [(clojure.string/starts-with? ?name "TEMPLATE/")])

 ]
 :group-by-page? true
 :breadcrumb-show? false
 :result-transform (fn [result]
   (let [sorted-result (sort-by (fn [h] (get h :block/marker)) > result)]
   (map (fn [m] (assoc m :block/collapsed? true)) sorted-result))
 )
 :rules [
   [(check-ns ?ns ?p)
     [?p :block/namespace ?ns]
   ]
   [(check-ns ?ns ?p)
     [?p :block/namespace ?t]
     (check-ns ?ns ?t)
   ]
 ]
}
#+END_QUERY