How do I get the simplified block content as in regular logseq.table.version 1 of Advanced Queries in custom :view

When I create an Advanced Query to list all tasks on the current page and sort them by priority and date, I cannot get the bare tasks marker and the bare priority to show up.

However it works if I create a handcrafted table using a custom :view and render the table with hiccup syntax. In this case I have only access to the raw :block/content. I failed to get a grip at the transformation used for the logseq.table.version 1.

The output is like the new logseq.table.version 2 decribed here and contains the marker prefix and the priority and possible properties, the logbook etc. bloating the table output.

Viewing the source block data in debug mode (right click on bullet and select (Dev) Show Block Data did not help. Only the raw content is displayed.

Question: Ist there a standard form to get these filtered block lines?

I already tried :block/name and :block/original-name

Here is my current code:

#+BEGIN_QUERY
{:title [:h4 "List Tasks with Marker and Priority"]
    :query [:find (pull ?h [*])
            :in $ ?page
            :where
            (task ?h #{"TODO" "DOING"})
            [?p :block/name ?page]
            [?h :block/page ?p]
            ]
    :inputs ["acsr|evenios"]
    :result-transform (fn [result]
                        (sort-by (fn [h]
                                   (get h :block/created-at)  
                                   (get h :block/priority "Z")
                        ) result)
   )
  :view (fn [rows] [:table 
   [:thead 
    [:tr 
     [:th "content"] 
     [:th "page"]
     [:th "marker"]
     [:th "priority"] 
    ]
   ] 
   [:tbody 
   (for [r rows] [:tr 
     [:td (get-in r [:block/content])] 
     [:td (get-in r [:block/page :block/original-name])]  ; does only fetch the name of the page
     [:td (get-in r [:block/marker])]
     [:td (get-in r [:block/priority])] 
     ])
     ]]
     )
}
#+END_QUERY

Example of the full :block/content with a property

TODO [#B] Mailrelay check on friday!
collapsed:: true

expected content to be shown in table

Block Page TASK Status Priority
Mailrelay check on friday! MyPage TODO A

To filter out properties, try replacing this line:

[:td (get-in r [:block/content])]

…with this:

[:td (clojure.string/replace (get-in r [:block/content]) (re-pattern "\n?.*[:][:].*\n?") "")]
1 Like

@mentaloid Thanks for the regex example

Not the final solution, but I am very happy with the regex boilerplate code fixing the properties.
I can confirm that this works for the part to filter out the properties.

Remaining Challenge: Get rid of the marker and priority and the logbook stuff.

Therefore I cannot mark this as final solution for now.

I am familiar with regex but was not for the clojurescript flavor.

Now I have to do my homework on this…

Properly getting rid of all those cases (and only them) is indeed a challenge. If you get stuck, feel free to provide specific examples of content that gets over- or under- filtered, and we’ll look for working regexes.

1 Like

Might want to check out this thread where I did something similar for someone else:

Hopefully this can help you along. Let me know for any customization you may require / issues you run into.

Another option could be to add the additional things as properties with a result-transform and use the default table output.
If you’re interested in that I’ll see if I can dig up an example.

Edit: would be customizing something like this example:
https://siferiax.github.io/#/page/logseq%2Fquery%20tests/block/âś…%20table%20with%20block%2C%20scheduled%20and%20deadline%20(updated!%203%2Foct%2F23)

1 Like

@Siferiax @mentaloid thx for your generous offers.

At first my expectation was that there is an easy grip in a special method already used by Logseq like they did the jobs for Queries and the view logseq.table.version 1.

@Siferiax I already used the dedicated properties to work around this, but it builds up an overhead often not suitable for existing stuff.

A better solution than hiccup would be the support for a more easy to write template format, that you can link as a renderer. E.g. Jinja2 from my point of view even with the hickup converters hiccup adds an additional level of complexity.

I recently worked with eta-templates and it was a whitespace nightmare. But you can learn a lot, how to develop this. There is an eta-playground online to live test templates. Maybe I should start to edit the query code in VSCode while watching Logseq updating the rendering. The UI shifts after editing the query are sometimes annoying. OKand I should test with simpler examples.

I am writing from my phone. I remember there was also a hiccup live editor. Need to loouip that.

I don’t mean dedicated properties actually. Neither example I use actually use dedicated properties to show the information.

  • Either
    • it uses clojure to manipulate the information to show it a certain way
    • it uses clojure to add information to the block’s properties post query so they can be used in the query table output

ah, I get your point.
Sure its like distilling the nuggets out of the block and put them on a stage for solitaire presentation.

Again regex can be a solution to drill down the facts.

When you isolated your result, you can also fiinally filter out everything you extracted from the block first to reach my goal, before you transform the match to a different format as property for isolated display. In python we would add methods to the object for display to keep the source format. I am still not mentally in sync with the object model in clojurescript.

Depends all on what you need of course!

So I think the important distinction to make here is that we are using clojurescript functions on top of datascript / datalog tuples.
Which is your query result really.

So to get back to this, you are looking for a query like this:

Query:

#+BEGIN_QUERY
{:title [:h4 "🎯 Tasks"]
 :query [:find (pull ?b [*])
  :where
   ; Add the criteria for which ?b you want to find here. I've added all tasks as an example.
   [?b :block/marker ?m]
   (not [(contains? #{"DONE" "CANCELED"} ?m)] )
 ]
 :result-transform (fn [result] 
   (sort-by ; Any sort field here.
     (juxt ; sort by multiple fields
       (fn [r] (get r :block/scheduled 99999999)) ; sort field 1, if no value use 99999999
       (fn [r] (get r :block/priority "X")) ; sort field 2, if no value use X
       (fn [r] (get r :block/deadline 99999999)) ; sort field 3, if no value use 99999999
       (fn [r] (get r :block/content)) ; sort field 4
     )
     (map (fn [m] ; make a new map based on the query result
       (update m :block/properties ; update the block properties
         (fn [u] (assoc u :status (get-in m [:block/marker] "-") :priority (get-in m [:block/priority] "-") ) ) ; associate the marker and priority attribute values, use - when no value is present
       )
     ) result)
   )
 )
 :breadcrumb-show? false
}
#+END_QUERY

If you want to be able to add this to different queries. You can add the result-transform in the config.edn.

Here’s what my config looks like as an example.

Which we can use as :result-transform :sort-by-list for example.

1 Like

Dear @Siferiax , this works great and is a great starting point for further enhancements.
In general the example works as described. I did no test the config.edn based reusable DRY version yet, but this will be a great deal.
I am currently fiddling around with some table layout CSS enhancements.

I changed the value for empty priorities to “Z” to allow sorting by Alphabet “-” comes before “A”. Another solution would be to map empty values to an ASCII whitespace char after Z or something else.

To replace properties by key,value pairs in the result could also help.

I marked this as solved in general related to the question, but may return to share my results here.
We guess this is useful for others as well.

1 Like