Generate explicit hierarchy out of properties

Sadly, I do not know enough javascript and datalog to get this working quick. I might have to go look into this again over the weekend. Thank you.

Here is a quick workaround:

  • Find this line in the code:
        const roots = pgRoots.get(nodeconfig);
    
  • Replace it with these lines:
        const curpage = (div.dataset.page === "current") && logseq.api.get_current_page();
        if (curpage) curpage["original-name"] = curpage.originalName;
        const roots = (curpage) ? [curpage] : pgRoots.get(nodeconfig);
    
  • Add this macro inside file config.edn, inside macros{}:
    :curpagetree "<div class='kit pagetree' data-kit='pagetree' data-node-prep='$1' data-node-prop='$2' data-leaf-prep='$3' data-leaf-prop='$4' data-page='current'>pagetree</div>"
    
  • Visit the desired page
    • e.g. man1
  • Use the macro, either in the page or on the right sidebar
    • e.g. {{curpagetree from, parent}}
      • the result of the example:
        image
1 Like

bro do you know any tutorial for this? looks like is what i was seeking in a note app, but im not tech savy
Is there a page/github that we can track that code ?

  • Everything is available in the first post and the links there:
    • examples
    • code
      • The whole code is public within posts in this forum.
        • It has not changed for many months now.
        • Nobody has reported any problem so far.
    • instructions
      • Read the posts
      • Follow the steps
        • If you get stuck at any step, let me know.

bro im testing here and looks very promissing, may i ask you some questions that i have ?
so just a example i have a note called “Despesa Publica”
Despesa Publica.md
broader:: [[finPublica]]
Divida Publica.md
broader:: [[Despesa Publica]]
narrower:: [[Divida Flutuante]], [[Divida Fundada]]
Divida Flutuante.md
broader:: [[Despesa Publica]]
Divida Fundada.md
broader:: [[Divida Publica]]

Output on Despesa Publica.md

  • {{pagetree(from,broader)}}
    image

Divida Flutuante.md stays sibling of Divida Publica.md, altough should be child
Is there a way to make narrower and broader work together ?
I saw that the code works as expected just looking to “broader” attribute, but if it could take in consideration the “narrower” this code would be the god of hierarchies PKMs.

another possibility, if not using “narrower” property, would be in broader property, you could set more than one links, and the code would handle like this:

Despesa Publica.md
broader:: [[finPublica]]
Divida Publica.md
broader:: [[Despesa Publica]]
narrower:: [[Divida Flutuante]], [[Divida Fundada]]
Divida Flutuante.md
broader:: [[Despesa Publica]], [[Divida Publica]]
Divida Fundada.md
broader:: [[Divida Publica]]

Output on Despesa Publica.md
image
Now it duplicates

instead it could understand the tree hierarchy taking the nearest one as broader and then just:
image

just an parenthesis here, ofc these suggestions/feature request(if i may) that i made look dumb with few notes, but bro when you hit a lot of notes (i have more than 2k), that sense of direct hierarchies kinda lost, and that code would help a lot

And congrats for that fantastic work you made, i really appreciated was the far most well done implementation of hierarchies in any pkm that i know. And i searched a lot for this, glad that i landed here

  • Despite its complexity, this implementation is dumb, it doesn’t understand anything at all.
    • That includes complimentary properties and redundant relationships.
    • It doesn’t even understand circular relationships.
      • It simply stops repeating after reaching the provided limit.
  • The code could be modified to support the requested features.
    • The needed effort seems disproportional to the gains.
    • I’m currently looking to improve the underlying engine, so as to enable the user to direct the whole process.
      • That could result in something much better than your “god of hierarchies PKMs”.

Regard the add of another property i agree that the effort could be disproportional to its gains and could turn code way more complex.
But why (honest question) do you think the second idea is bad as a feature request ofc ?
because not always we know the exactly parent of the note in a big graph, so we put more than one on the child property note, and code could take the short path without duplicate as it is doing, but again just giving ideas to improve, not trying to say the approach now is bad or wrong.
By the tone of the last phrase of your answer i feel that you may felt insulted somehow or didnt like what i said, but was not my intention.
I really appreciated what you did, congrats again

Plenty of misunderstandings in that one.

Without being tech savvy, can only guess.

The current approach is merely the technically easy one, far from the desired one.

Never assume any tone for things written in a forum, rather stick to the content itself. It is the responsibility of the poster to communicate what they think through prose, rather than through literature. In that instance, no tone was meant.

Nobody can feel what someone else feels. In that instance, I actually felt nothing.

I never said that is bad. I just happen to aim at a higher level, therefore I cannot adopt your description without quotes.

I am the one who asked for feedback and I appreciate all of it (as long as it remains on topic).

1 Like

btw, i will adjust my notes to use that code, do you think is possible logseq in the future updates break something/or turn unusable ? or since is relying on java script is kinda of independent stuff ?

This code uses Logseq’s API to query the database for the needed data. In the rare case that a future version changes these conventions in an incompatible way, someone should adapt the respective API call and queries to the new conventions. Meanwhile, the previous versions will continue working normally. Therefore, there is a theoretical chance for troubles, but too small to worry.

thanks and last question, i will not bother you anymore rsrsrs

is possible to use that command {{pagetree from, broader}} with any “AND” clause , that will only show the pagetree of notes with giving tag/s ?

  • Any extra clause should be provided by editing the queries directly.
    • i.e. the datalog code found under the various PageTree.roots.queries and PageTree.children.queries
    • One could also define their own keywords and respective queries.
  • In other words, if you can use a normal query to filter the desired pages (whether through tags or any other condition), the same clauses can be applied to this implementation’s queries, so as to limit its processing to the desired pages only.
  • Examples:
    • only pages that contain a specific tag:
      [?some-tag :block/name "mytag"]
      [?child :block/tags ?some-tag]
      
    • only pages that contain all of specific tags:
      [?child :block/tags ?some-tag]
      [?child :block/tags ?some-other-tag]
      
    • only pages that contain any of specific tags:
      (or
        [?child :block/tags ?some-tag]
        [?child :block/tags ?some-other-tag]
      )
      

tried here with car tag example but probably im doing something wrong:
in the excample below i added [?some-tag :block/name “car”] and
[?child :block/tags ?“some-tag”]
, but result is the same


PageTree.roots.queries.from = `[
    :find (pull ?Root [*])
    :in $ ?prop
    :where
    	[?some-tag :block/name "car"]	-add
    	[?child :block/tags ?"some-tag"]      -add
        [?child :block/properties ?child-props]
        [(get ?child-props ?prop) ?child-from]
        [?Root :block/original-name ?Root-original-name]
        [(contains? ?child-from ?Root-original-name)]
        (not
            [?root :block/page ?Root]
            [?root :block/properties ?root-props]
            [(get ?root-props ?prop) ?root-from]
        )
]`;

the approach im looking is to when i type the {{pagetree from, broader}} it gives me the tree but filtering(AND clause) with the tag of the note (like dynamic variables for it to get the tag of the note)

Sure, that would be nice. But it needs parsing and this implementation doesn’t do any.

?"some-tag" should be without quotes, i.e. ?some-tag . Although it would make more sense to rename both to either ?car-tag or simply ?car .

Mind that PageTree.roots.queries is only for the top-level pages in the hierarchy. Should make the same change to PageTree.children.queries. Likewise, you may want to add similar conditions for ?Root, ?Parent and ?Child. Each one of these entities is considered separately. After you start making some progress with the limiting, you may have to try various combinations until you achieve the exact form of limitation that you need. Not being familiar with the domain of your application, I cannot make good guesses. But all kinds of query-based limitations remain possible.

Also, after changing the code, should either:

  • rerun the code (with a kits button)
  • restart Logseq

thanks bro, i though i could somehow adapt a dynamic variable to the code in the query, to it only render the pagetree related to the tag of the note.

How would identical page names be handled in this approach?

E.g., imagine I would have “OPNsense”

  1. as a general topic page to describe the software, take notes on features etc (“resource” in PARA)
  2. as page with maintenance notes etc. (“area” in PARA) and
  3. documentation page on how it is configured in my infrastructure (also kind of “resource”).

In current “default” Logseq hierarchy paradigm, I would have e.g. (1) “Tech/Topics/OPNsense”, (2) “Tech/Homelab/OPNsense” and (3) “Tech/Docs/OPNsense”.

But with property-based hierarchies, I only see the solution in altering titles, like “OPNsense (Topic)” and “OPNsense (Doc)”. Am I missing something?

The problem of name conflicts is addressed with namespaces. I am not aware of any problem with using namespaces that way (i.e. as surnames). Just avoid using them to model hierarchies.

My problem with namespaces are long, not-nice names. They are long, contain slashes, are hard to read / grasp what they are referring to. Esp. in queries and alike. (Off-topic here, but if there are any suggestions on these issues I would be glad to be pointed to them; have not found any so far…).

That’s why I was wondering if I could use the property-based hierarchy approach discussed in this post. But then the problem of identical names arises…

  • I don’t see any obstacle in using properties with a few namespaces when they are actually needed.
  • Namespaces:
    • are not a paradigm in Logseq
      • they are merely a convenience (an abused one)
      • their implementation is relatively basic
      • Logseq’s default hierarchy paradigm is the outliner (i.e. nested blocks)
    • need a slash
      • If that is an issue, should make your own convention on how to separate the parts.
    • should not be long
      • Long namespaces are madness.
    • don’t have to be long
      • 80% of names in a graph don’t need a namespace.
      • 96% of names in a graph don’t need more than one surname.
      • If your own percentages differ a lot, it most probably means that you are mixing irrelevant info in a single graph.
        • If this is your case (it doesn’t seem so), separate the graphs.
  • PARA method:
    • can be implemented in Logseq in more than one ways
    • is not the best method to begin with
      • For sure was not made with Logseq (or graphs) in mind.
  • In my opinion, your examples of namespaces are bad.
    • “Topics” and “Docs” are not namespaces (they are classes).
      • It would make more sense to either:
        • simply tag a block (or an ancestor block) as #topic or #doc
        • make “Topics” and “Docs” children of “OPNsense”
          • Could even keep them inside the same page (default paradigm).
            • Then just collapse their blocks as needed.
  • Follow the links in the opening post, as well as my previous post, to read the discussions on the matter.
    • They contain plenty of material to make your own decision.
    • Please don’t continue here, unless you have technical questions.
    • For non-technical questions, open a new thread under category General.
2 Likes