Let's discuss attributes (and tags) vs page structure

First, I apologize for this TLDR; and that it’s so messy text. It’s also not real proposal or anything like that. I would just like to discuss this because it’s of great interest of mine…

I wanted to utilize [attr: ibutes] for some specific cases extensively, especially when the Lua support is on it’s way to us. :innocent: So I dug into the documentation and found out that:

Attribute syntax can contribute additional Metadata to various Objects, including:

  • Pages
  • Items
  • Tasks

I have some questions…

What does “items” in fact mean here? The list items? I assigned some attributes to a paragraph and failed to iterate them in template/query (if you know how to, show me, please). But it worked for list items. So, this is quite confusing. I would assume that attributes would belong to the document node they are within. If somewhere inside a paragraph, then it should belong to the paragraph. If inside an emphasized text inside some paragraph, then it should belong there. So, I think the “items” means “list items” exclusively, or something similar. This should be clarified in the documentation, because it is not clear what “items” mean there.

Second question is somewhat related. Attributes can contain arrays, like [foo: [1, 2, 3]]. But if I do: [foo: 1] [foo: 2] and [foo: 3] there is just the last value 3 of the foo attribute present (perhaps I did wrong, again, please tell me how to iterate correctly). I guess it’s because it just got overwritten, right? Will [foo: [1]] [foo: [2]] and [foo: [3]] work? Will that result in the [foo: [1,2,3]]? (This came to my mind right now when writing this, I had no chance to test that, sorry.).

All this seems to me very counter-intuitive and non-ergonomical. I do not want to remember where some rule applies and there should also be no need to (although I certainly can, it’s not a good UX). Once given attributes (and tags), I would like to assign attributes (or tags) to anything I like to. It feels very natural to me to collect some values in an attribute while, for example, writing some long text with many many paragraphs etc. Therefor this second question is somewhat connected with the first one.

From my point of view, I would like SB let us assign attributes anywhere, or at least also to paragraphs, quotes and other “container”/block objects (header, paragraph, quotation, table row/cell, list, list item) where it can be clearly “contained”. Attributes (as well as tags, of course) should have also parent field to get content of object they reside in. The queried parents should expose children fields accessible to the scripts as well. It would be nice to have the possibility to list attributes (or tags) filtered with specific criterior and then to construct, e.g., a page with all close surroundings up/down to any level rendered using some live scripting on the data (template, query, LUA, plug, …).

There are some edge cases too, the objects like images (etc.), horizontal line, and fenced code blocks… There is no issue with embedding attribute inside **bold [a: 1] text** but it is unclear which of the two whitespaces is actually the attribute separator and which is not, i.e. how to do indexing here, but it is certainly undoable for code inline blocks, for obvious reason. There is also no problem in placing an attribute inside a paragraph but it’s bad idea to try to place it inside fenced code block. In all the described edge cases the solution may be to let attach the attributes (and tags) in some special way.

For vertical containers, such as the fenced code block, if the attribute (or tag) would be right before or after the object, it would belong to it, e.g.,

[a: 1]
```sh
for i in 1 2 3; do echo $i; done
```
[b: foo] [c: bar]

The same rules would apply to any inlined object:

Some paragraph with **bold text**[a:foo] and [a: 123]`code`[b: bar][c: quux]

Notice, that there is no white space between the attribute and the object as well as between the attributes (and the same would apply to tags as well). Much nicer would be if we could group them in single one like [b: bar, c: quux] (much clearer and feel quite intuitively… at least to me. :wink:

There is one last edge case I can imagine. If an attribute (or a tag) is placed in separated paragraph consisting of only the attributes (and tags) it would belong to the page section (divided by h1-6). (Not really sure here.)

Single document can be generalized as a tree-ish structure and no matter what are the leafs kind of similar rules should apply to all of them, without any exception. Then, in the hypothetical documentation, you could say something like “Hey, here you are some attributes and tags, place them anywhere you like. Oh, and there are only two rules to follow and are indeed intuitive”. : That would be the best UX I can imagine (of course, SB is for hackers, and this approach may perhaps feel far too holistic in some way).

This was no way critique of SB in neither way. I use it on daily basis and I love it. I just wanted to share my ideas on some details and perhaps inspire some further discussion. Thanks for you patience. :+1:

Yes items are indeed list items (bulleted and numbered).

While not in the docs, I see in the code that attributes should also be indexed for paragraphs, which would mean that if you put [hello: something] in a paragraph, it should become part of that paragraph object. It doesn’t go deeper than that, like italicized text, that would get… problematic, not sure even how that would be indexed.

This is what works now:


Hello there [test: attribute]!

```query
paragraph where page = @page.name and text =~ /there/
```

This indeed gives me back the paragraph with a test attribute, so this seems to work correctly.

Indeed I think it will just take the last value, there’s no way to concatenate or append to these attributes, because I never saw a need for that and nobody ever requested it. I think this could be implemented in principle.

At this point I’d start to ask for concrete use cases. Academically, sure, you could do lots of things, but in practice: would you really? In what scenario would you do what you’re describing?

This is what it’s doing (or at least attempts) to do right now: if you put an attribute in a (list) item, it’s attached to that, in a paragraph, it’s attached to that, if you put it in a header it’s attached to that. We can argue about granularity. Should it be per character, per sentence, per paragraph, per section? Not really sure if that’s easy to decide.


So far, honestly, in my date to use I never use this attribute syntax. I use frontmatter based attributes for pages, but that’s it. I added it because it seemed cool and powerful, but found no practical use cases in the end. That’s also why this feature was never super deeply developed.

If you have use cases, let’s talk, then we can see if it makes sense to support them.

If you have use cases, let’s talk, then we can see if it makes sense to support them.

Coming from Logseq, I love writing my notes in the journal pages and then viewing summaries on (meta) pages. Currently, I do this by tagging headings and then transcluding them, because there is no way to transclude just a (list) item and it’s children, I believe.

It’s a pretty simple use case that’s a) already supported and b) does not require appending attributes, but I wanted to contribute it nevertheless. :slight_smile:

1 Like

Yes items are indeed list items (bulleted and numbered).

Clarified, thanks. I would like to see the docs reworded, including other information mentioned here in your replies in this thread (paragraphs, headers, etc.). I may be also worth describing how the document is splitted into indexable parts, how it is in fact indexed, how to access the indexed things, in other words, a description of the granularity level to which the document is parsed and indexed and whether/how are tags and attributes assigned to the pieces. :slight_smile:

Indeed I think it will just take the last value, there’s no way to concatenate or append to these attributes, because I never saw a need for that and nobody ever requested it. I think this could be implemented in principle.

The bad thing is that it would probably lead to breaking backward compatibility unless special rule is applied. I think this can work: make attribute value always be array and if accessed as a scalar, then return last value from the array, if accessed as array, do what it does for array now… If implemented this way it would not break backward compatibility (IMHO).

At this point I’d start to ask for concrete use cases. Academically, sure, you could do lots of things, but in practice: would you really? In what scenario would you do what you’re describing?

Yeah, you can collect anything while typing, e.g., bibiliographical references. Whatever… If the former was implemented, it’s not academical question anymore and people could use it, if they needed it.

This is what it’s doing (or at least attempts) to do right now: if you put an attribute in a (list) item, it’s attached to that, in a paragraph, it’s attached to that, if you put it in a header it’s attached to that. We can argue about granularity.

Should it be per character

Definitely not. :smiley:

per sentence

No, if not made/marked an “inline block” somehow. I think we have no support to further segment vertical blocks in SB now.

per paragraph

For sure yes.

per section

For sure yes.

Not really sure if that’s easy to decide.

I understand that clearly. Therefor I suggest to apply attributes and tags primarily for all vertical objects (pages, headers, sections, paragraphs, quotes, lists, list items, tables, table rows, table row cells). Then there are the inline blocks (italics, bold, inline code blocks). For both vertical and inline blocks, there are the edge cases I described that would require special treatments (i.e., both the code blocks; therefor I would avoid those for now, perhaps even avoid all the inline blocks for now). I realize there are issues with semantics of some of the objects (e.g., what’s a “paragraph”). This can be resolved just that somebody tells how it is. But within laid rules, the semantic would be clear-enough, I think.