Discussion: Unify pages and blocks

Block aliases or not, the fundamental issue is:

  • Pages have unique names
  • Blocks have UUIDs
  • We need a way to reference blocks in queries and properties that work as good as [[page]] references
  • And eventually display certain blocks in the Graph View
1 Like

The first point is a constraint of the file system (unique names). The second is a constraint for the domain logic (unique block IDs). This might be done by assigning an UUID to every block, incl. root block (=page), so there is a mapping of page name to page UUID.
What about an id:: property at the top of every page, akin to tags::, same as current block ids?

Alternatively we could use string ID and keep uniqueness of pages via filename, but that probably has performance issues.

Yes. + Showing block references in the “Linked References” widget at each page bottom would be quite useful.

No, this is the key, you think we have pages because of files on the file system, while we have pages because we want [[wikilinks]] i.e. we want to turn words in our paragraphs into references by simply adding [[ ]]. Storing pages as files is a consequence, not a cause.

Now I understand while you brought the file system in this discussion…

Logseq is not constrained by the file system at all and it already abstracts it away with its DB.

I hope now you understand why I proposed block aliases, because we would be able to define a new node from context instead of creating a new page.

Think more about it, block aliases are all we need: if you want a block to be treated like a page, assign an alias and use that as [[handle]] in properties and queries.

Good hint, seeing your point with “just quickly typing it”, for example as well with an external editor. But I am asking myself if this a contradiction at all. [[ ]] could be the syntax for uniquely named blocks, (( )) for blocks with possible duplicate titles and needed technical ID - no change again.

What has become more clear and important to me - and I think we both agree on this - , is that Query, Linked references + filter and all these great UI features in Logseq need to work on block-scope. And they should behave consistently (take page-tags/tags: for example), no matter if we keep pages or not.

Yes and they choose to call those named blocks “pages”… but the issue is that pages can only be root blocks (and this is what block aliases are meant to fix) and that they enable different features in the UI (just because devs decided to do so).

Yes and I have an idea on how block references (with ((UUID)) and [[aliases]] ) could be presented:

  • At the moment a block with references has a count on the right that you can click to list references. I think it could instead show two (virtual) additional children blocks: Linked References and Unlinked References that when expanded show references that can be edited just like we do at the bottom of pages.
  • When focusing the view to a particular block by clicking the bullet point, the same Linked and Unlinked References appears at the bottom, just like in a page.
  • In both cases there would be a way to filter references as we do now at the bottom of pages.

Additionally, I hope that devs will hear the suggestion I made to the designer about replacing Linked and Unlinked References sections with fixed queries where you can add additional filters with the future query builder.

So basically reuse UI components as much as possible.

As said, I am not a fan of this idea:

  • A page is a block with additional unique title constraint (*), but in the end still a block (superset or extends relations if you will with object oriented programming). There should be no need to artificially promote a block to page, if most of the logic operates on block as common type.
  • If I understood this, we need to manually prepare this block and looks to be repetitive work

Interesting idea, I like it.

If everything internally uses queries, that would reduce our block-scope issue to … queries, hence more easy to fix :slight_smile: I’d like to have some customizable footer for pages as well, where you can place more queries - similar to :default-queries in the journal.

And we haven’t spoken of transitive queries yet. John Doe -> Author -> Person. Then on page Person query everything which is transitively linked, like page John Doe. That as custom query at page bottom would be cool.

I am out for today. Cheers!


(*) thanks again for your point, this indeed is important for easy typing links in the editor. Even if Logseq provides auto-complete for page IDs like [%title%](<page-id), creating links in an external editor would be more difficult. Btw: Haven’t we already spoken of this with regards to blocks and their titles?

Personally I would only show those (un)linked references when you zoom into a block (as it is only referenced to that specific block) and not the larger set of blocks (aka page). A small indicator to indicate that there are references to this block in the first place is fine.

UPDATE : I wrote to soon :slight_smile: … seeing you next bullet. But I do not like the expanded show when not being zoomed in into the block.

To be clear, when not “zoomed” it would look just as it is now, but:

  • when clicking on the number of references they are not displayed in a popup as it is now but as “virtual” children blocks. EDIT: I was wrong, there is no popup anymore, it is already as I desired!
  • when clicking on the bullet point the view “zooms” on it as it is now but additionally at the bottom there are the references like on pages

The difference is due to the nature of file storage (& performance limitation)
Hopefully the database-based storage can remove the barrier. It’s under development.

2 Likes

I think the concept of “pages” comes from the need to have references using [[words]] and saving them as files is a consequence (but not strictly needed).

Even with a different storage method, I don’t think the concept of pages (and [[wikilinks]]) will cease to exist but correct me if I am wrong.


On the other hand what started this discussion is more about differences in UI/UX for pages and blocks that appear arbitrary, than a need to remove the distinction between pages and blocks.

(Edit: for example the issue reported by OP is about Simple Queries looking for references in block content and path, but not considering page-tags:: values too, that is something that would definitely makes sense from the user point of view).

@venture-comp let me stress again that the term “unify” in the title is misleading, what you are looking for is more consistency.

“Makes pages and blocks more consistent” looks like a better title to me, that reflects what’s discussed here.

1 Like

Thanks for the info!
I have noticed the post has been marked with “estimate-very-large”, which is fair enough. Do you think the main described issues #7592 and #7978 can be fixed sooner - or are they are out of scope and we need to wait for database design first?

@alex0 it makes more sense then to mark OP as solved with this post I guess.

The two issues seem to be more complex to change than I hoped :frowning: . Developers’ statement:

It requires large effort due to the inner implementation of query

Feeling inclined to say: Only use block properties for now.
Omit any page-properties including tags::, if you need to search for multiple page references in a consistent manner with queries and filter widget.

I am currently testing a smallish Python script, which auto-converts all page-properties to block-properties. Disadvantage: There is an additional indention inside the page (for block inheritance). Advantage: searching and filtering works. Let me know, if there is any interest for discussions.

I have not this issue because I use page properties only to find pages.

Instead in pages I use [[references]] in section headers and below I place the content.

If you are looking for a workaround try to ask for an Advanced Query in #queries on Discord.

Recently I got a query that looks for properties in parents (basically how [[references]] appear to be “inherited” by children, but for properties).

This is basically the behavior you are looking for but for pages (because with pages you are forced to use properties).

Interesting. Guess that is the beauty of Logseq - everyone has own, unique workflows.

I heavily rely on combining pages for quick searching, like [[logseq]] and [[feature]]. That might be a simple query (and [[logseq]] [[feature]] ). But you’ve got a problem, if any of these links are declared as page tags:

  • Was it (and [[logseq]] [[feature]] ) ?
  • Or (and (page-tags [[logseq]]) [[feature]] ) ?
  • Oh fu**, it was (and (page-tags [[feature]]) [[logseq]] ) .

Same with the filter - not predictable at all. You can’t be sure to not have missed a result.

I know, advanced queries take it to another level. But that all is too cumbersome. I yet have to find an app that can create links and pages easiert than Logseq - [[foo]] is all it takes. If something is intuitive, quick and simple to do, you enjoy doing it more often. Same would be nice for searches and filter.

Your proposed query wizard certainly seems to be a good compromise. In the end, there is still a flaw in the current query implementation we should fix, so everything works consistently. E.g. a query builder doesn’t help for the UI filter, or if you are already used to do your stuff with simple queries etc.

1 Like

I understand your need, but on the other hand it is very natural to do so:

Logseq.md
type:: [[Application]]
tags:: [[PKM]]

- [[Features]]
  - ...
- [[Plugins]]
  - ...
{{query (page-tags [[PKM]])}}
{{query (and [[Logseq]] [[Features]])}}
1 Like

This may feel natural to you, but is not my exact workflow.
Natural is to have freedom of choice how to organize things, without surprises.

Assuming we would organize notes like in your example with a template, even then it would be hard to keep notes consistent.

(Edit) Regarding example: At one point in the future, you’d like to find out content about PKM features and search for {{query (and [[PKM]] [[Features]])}}. Nothing found, if you can’t remember, that PKM is a page tag - ouch.

1 Like

I recognized your usecase as legitimate since my first reply in this thread.

I tried to help you in multiple ways and I just shared my workflow where this issue is not prominent.

Logseq doesn’t support your use case with Simple Queries but it would be nice if it did. This has been my position for the whole thread.

Logseq supports your use case with Advanced Queries. I can’t find your request for help on Discord#queries as I just suggested to do.

I understood your point from the beginning and we discussed it for a while, no need to reply in a prickly way like I didn’t understand the issue at all.

You hit the second strike of being mannerless (first one here).

You even refused to rename this thread despite I said many times “unify” is the wrong term in a polite way.

I won’t waste another minute with you. Bye!

Again: Not any intention to be rude from my side. I am sorry, if you perceived the discussion in a different way.

Sorry, but simply no. Read again before and after the post, as well the comments from others users.

By chance: Have you overread that I intent to close this post? After discussion, my expression was this post is either
a) too broad for a specific feature request
b) rather a bug report.
(still not sure about this)

The whole post has been about making page and block behave like one common unit, so just renaming the title would confuse future readers more than help.

Thanks for your time anyway.

Hi. In the upcoming db version, blocks and pages are being unified. Blocks can have linked references. See docs/db-version.md at feat/db · logseq/docs · GitHub for more details

But the main issue discussed here as not been addressed yet i.e. now in DB version we have a menu entry named “Node reference” that let the user pick a page or a block and it appears as a [[wikilink]] using the title of a page or the content of a block. But when you manually type the same wikilink somewhere else it creates the classic page.

So we have wikilinks that looks exactly the same but point to different things:

There is this fundamental issue of how to reference a block with [[unique name]] and on Discord I have suggested the following:

  1. The blocks could have an optional name: property set manually by the user or automatically (more later)

  2. [[name]] could display the unique name given to the block

  3. ![[name]] could display the content of the block when used inline with other text…

  4. …and embed the whole block with children when used on its own line

For example:

- content of the block
  Name: short unique name
  - child block
- This is a reference to [[short unique name]]
- This is an inline embed of ![[short unique name]]
- ![[short unique name]]

Rendered as:

- This is a reference to short unique name
- This is an inline embed of content of the block
- content of the block
  - child block

The same would happen with pages and their titles.

“Short unique name” could be set manually by the user or by a ML algorithm (for faster workflows when using the current Node reference menu selecting blocks with no name) and it doesn’t matter the format as long as it’s unique. For example the algorithm could use parent and children blocks to infer that a proper name could be The Title (book) and assign it if there isn’t another block with that name. The user could change that later.

What do you think?