The contextual sidebar: query current page and organize pages in indexes

This method may help you if:

  • You use Linked References to “query” the current page but you would like more powerful filters.
  • You want to organize pages hierarchically and you found that namespaces are not meant for that.
    • Specifically you want a page to be in multiple hierarchies.

The idea is to place some useful queries in a page in the right sidebar. These queries will use the variable <%current page%> to refer to the page you have actually open in the main view.

For example here there’s a query extracts the TODOs for the current page:

Of course it works also for blocks stored elsewhere, for example in the Journal:

The query results are not updated when switching pages (and this is useful as shown later): to update a query just collapse and re-expand the block containing it.

All the queries mentioned in the screenshots are available at the end of this guide.

Indexes

This contextual sidebar works particularly well with the method of indexes to organize pages hierarchically. Here there is an example of index, an indented list of pages (but it can really contains everything):

The important thing is tagging the top block of an index with something like #index (hidden in the screenshot) to make it easy to retrieve it with queries.

With the right query it is possible to see the indexes where the current page is mentioned:

To see siblings click on one of the levels of the breadcrumb:

image

and expand the desired elements:

image

Since the query results don’t update while you switch pages, you can actually use this as an index and jump from one page to another:

When you are done and you want to update the query to refer to the actual current page, collapse and re-expand its block:

image

image

Useful queries

  • Current page in indexes
    {{query (and [[index]] <%current page%> (not (page <%current page%>)))}}
  • Indexes in current page
    {{query (and [[index]] (page <%current page%>))}}
  • Notes about the current page
    {{query (and [[note]] <%current page%>)}}
  • Current page as author
    {{query (property author <%current page%>)}}
  • Active tasks for the current page
    {{query (and <%current page%> (todo todo doing))}}
  • Completed tasks for the current page
    {{query (and <%current page%> (todo done))}}
  • Blocked tasks for the current page
    {{query (and <%current page%> (todo waiting))}}

Notes

  • I have placed these queries in a page called [[Current page]] and placed it in the right sidebar by default using the plugin Sidebar Preset.
    • If you prefer, you can place them directly in [[Contents]].
    • You can also just store a single big index in [[Contents]], not using the #index tag and replace [[index]] with (page [[contents]]) in the queries.
  • The tabs in the sidebar are the result of the plugin Tabbed Sidebar.
  • The theme is Awesome Styler and the rest is custom CSS, including the custom icons as bullet points.
17 Likes

Hi @alex0, thanks for a thought-provoking article, it gave me a good idea!
I have a couple of questions regarding indexes.

Many of my notes can be linked to a geographic area. So, if I want to have an Index page for Africa and one for North America, should one of them have #index/africa and the other #index/north-america at the top? Presumably I cannot have 2 or more pages called Index even if the have different contents.

An alternative would be to have it all on 1 page:

Africa
  [[Algeria]]
  [[Morocco]]
  [[South Africa]]

North America
  [[U.S.]]
  [[Canada]]

etc.

This could be placed directly in [[Contents]] page, as you indicate in the Notes section above.

  1. If I create a new page for e.g. Togo it would have to be added manually to the Index for Africa - if there is such an index.
    Manual work is time-consuming AND I have to remember to do it.
    A way around that would be to add a property to Togo’s page, e.g. area:: Africa, and to make the Index Africa page just consist a query to list all pages with the property value Africa. What do you think?

Hi @Ngungu,

  1. I would just tag each index with #index, unless I really need to split the results of the queries…

    I mean, the point of using #index is that a query will find all the mentions of the current page in multiple indexes, no matter where they are.

    Why would you want a query for #index/Africa, one for #index/NorthAmerica and so on? If it has a practical reason for you go on.

  2. Yes, having to list everything manually in Contents or somewhere else is a pain. In SiYuan at least there is an indented list of pages that populates when you add a new page. And the new one appears under the page where you referenced it. Basically a Contents page is bootstraped automatically but that it is freely editable later.

    If for you it is easier to derive some indexes using properties go on, it is basically my example with “author” but with a different property. What’s the disadvantage though? It works well when the elements are an unordered list with no indentation: if for you it’s OK to have a query that just lists all the pages that match area:: <%current page%> nice, but my manually compiled indexes have the advantage that I can control the order and the hierarchy by indenting.

1 Like

Thanks a lot for replying. i have enough info, for now anyway, to get cracking with this.

BTW, do you use SiYuan?

I have imported my main Logseq graph in SiYuan and I am taking advantage of its better UI to navigate notes. I still edit them in Logseq only, but having tabs, split views and floating windows to browse long evergreen notes is very convenient.

Logseq is better to take notes and retrieve back single blocks with queries but it is bad when it comes to consuming notes. I mean when you need many long pages opened at the same time.

1 Like

So, you mean re-import your notes into SiYuan each time you edit a note in Logseq? That seems like a very laborious process I would not expect from you :grinning:

Lol, I did it only once but I am consulting only old notes that I have not edited for months and probably won’t edit anyway. For the fresh notes I just keep using Logseq.

1 Like

This is great. A tip for anyone using the vanilla version of Logseq without related plugins:

(1) You can pin/anchor Current page item at the top of right sidebar by adding to custom.css:

#right-sidebar-container .sidebar-item-list > .sidebar-item:has(a[href$='current%20page']) {
  order: -1;
}
  • Replace current%20page by the actual name of your Sidebar queries page.
  • This page name is lower case and needs to be URL-encoded. E.g. spaces get replaced by %20.
  • Latest Logseq version is required due to :has selector.

(2) Open sidebar queries as default on each startup by putting into config.edn:

:default-home {:sidebar ["Current page"]}
  • Replace Current page by the actual name of your Sidebar queries page.
4 Likes

Hello! I saw your idea in another thread about structuring notes, and took some time to implement it to my own logseq. My problem with using simple queries was that there was some friction for me to see the whole index block, so I used advanced queries. Disclaimer though, I only knew a bit of python programming, and read only the first two chapters of a book on lisp, so I probably don’t know what I’m doing. Here’s the code! Hope it helps!


#+BEGIN_QUERY
{
:title [:b "index"]
:query [
            :find (pull ?iblock [*])
            :in $ ?pname %
            :where
            [?current-page :page/name ?pname]
            [?itag :page/name ".index"]
            [?iblock :block/refs ?itag]
            (get-children ?iblock ?pblock)
            [?pblock :block/refs ?current-page]
            ]
:inputs [:current-page
            [
                [(get-children ?parent ?child) [?child :block/parent ?parent]]
                [(get-children ?parent ?child) [?t :block/parent ?parent] 
                      (get-children ?t ?child)]
            ]
]
:breadcrumb-show? false
:table-view? false
:group-by-page? false
} 
#+END_QUERY

Edit: I use #.index instead of #index

4 Likes

@noterist it looks much more like an actual index, very cool!

1 Like

Looks like an interesting proposition. I am not query savvy at all, simple queries is about what I can handle.

I have added this query to a page with a property children:: [[child 1]], [[child 2]], [[child 3]] but there is no property parent:: because it is the parent page.

The query returns “No matched result”: could that be because it does not find the parent property? If so, how should I approach this.

@Ngungu that query is a replacement for the index one I showcased, so just tag the top of a list with #.index to use it (I guess you interpreted “parent” and “child” as properties but they refer to the indentation structure).

1 Like

@alex0 , thank you so much for the ideas. A simple question that I can’t seem to find an answer to: is it possible to make the query auto-run when changing pages, or do we need to keep collapsing and expanding the query for it to update? It seems like a cumbersome process. Is there another solution?
.

@turkito sorry, I see why one would want that, but I can’t think of any way other than modifying Logseq source code.

Could be possible with custom code. What would be convenient ways to mark some queries for auto-running?

Can you share a screenshot of how you structure your notes for this to work and how the output looks like?

@Gangula structure the index like in my guide. In the screenshot below the “Breadcrumbs” part is the default, the “Indented lists” is the query by @noterist:

Thank you for this post @alex0, really useful!

I can contribute as well:

  • if you have (and you probably have) multiple queries in the right sidebar, you can refresh all of them by hiding and expanding the right sidebar (instead of individually collapsing / expanding them)

    • clicking into query (to start edit) and pressing Esc (to exit edit mode) is another way to refresh an individual query
  • {{query (namespace <%current page%>)}} - view the namespace structure (which effectively returns the children pages) for the current page (useful so that you don’t need to scroll to the bottom of the page)

  • {{query (and <%current page%> (not (page <%current page%>)))}} returns all page / block references to the page. To be useful, I think this needs to be displayed in a Table view and have block property hidden. After that it’ll display all Page references in a table. If the page is referenced multiple times, it’ll also appear multiple times in the table. I’m still undecided sure if that’s a bug or a feature…

Now I’m just trying to figure out if the other halves of the above queries exist:

  • Is there a way to see what pages does the <%current page%> reference?
  • Is there a way to see the current pages parents?
2 Likes

Thanks useful tips.
What do you mean by page parents? Like namespaces?

Yes, exactly. So, given 3 pages

  • my
  • my/home
  • my/home/kitchen

And when I’m on the my/home page, the {{query (namespace <%current page%>)}} will return my/home/kitchen but not my (I’m not sure which query does that).