Syntax for inline properties::

From the discussion here I think we have a cool proposal.

We want this syntax:

- [[title::The Picture of Dorian Gray]] is a [[type::book]]
  written by [[author::Oscar Wilde]].

as a more compact way to write this block:

- type:: book
  title:: The Picture of Dorian Gray
  author:: Oscar Wilde
  [[The Picture of Dorian Gray]] is a [[book]]
  written by [[Oscar Wilde]].

Rendered, with links, as:

The Picture of Dorian Gray is a book written by Oscar Wilde.

So it’s rendered just like:

- [[The Picture of Dorian Gray]] is a [[book]]
  written by [[Oscar Wilde]].

But it also has these properties:

- type:: book
  title:: The Picture of Dorian Gray
  author:: Oscar Wilde

So with a sentence we could add an entry to our personal database:

Title Author
The Picture of Dorian Gray Oscar Wilde

Imagine if in the future we will have a (Machine Learning?) tool that infer from the sentence which properties could be assigned to certain words and suggest to add the systax above: we could have a personal database automatically populated from sentences in our notes!

I like this idea, with the assumption that it would still be possible to add properties without the need to make it a link. In my example the [[type:: book]] would not be a link as I do not wan’t a page book in my vault.

With that in mind I would suggest a different syntax like {{type:: book}} for a property without the link and {{type::[[book]]}} for a property with the value (book) as a link.

The rendering should be the same as you suggest while taking into account to show the link or to not show a link.

Adding to that I would like to drop the page-property and property difference. No need for that both link to a block with the first linking to the first block on a page. No need to treat that differently I think.

3 Likes

I though about that and ignored it to don’t make things more complicated for now. But also something like this would work:

- This is a type:: "book".

Notice that there are other cases not covered here, for example the , to separate multiple values:

- key:: value 1, value 2

But for the proposed syntax I prefer this:

- [[title:: This is only one value, with a comma]]

is just interpreted as:

- title:: [[This is only one value, with a comma]]

So mine is just a shortcut for the most common use case. I didn’t cover the others (not links, multiple values etc).

1 Like

It would be great! And even better if we could extract graph rentering algorithm from Neo4J and render like them: Relationship types (predicates) - Colored graph - #4 by gww

1 Like

I think you just described Tana, more or less.

Sorry I can’t disagree more, this is what Tana is:

I like your contrast and comparison of the two systems, and can’t speak as much to the underlying programming of the two tools. From my perspective, constructing a “type:: book” property in Logseq is an effort to make it ontological, and adding “key:: value” properties of other types can be tantamount to making attributes for objects.

So in terms of the mental processes I need to execute to design these key-value systems in Logseq, that kind of thinking feels similar to designing supertag systems in Tana. It’s the one area where using Tana feels most like “levelling up” to use properties and queries in Logseq.

I know that’s not “levelling up” Logseq use relative to where you are in your mastery of the tool, but it is for me. If I am going to struggle that much to think in this new way, Tana’s tag UX for thinking about those things helps.

I prefer many things about Logseq. I find the “page” to be a useful construct for my way of thinking, and I love its PDF annotation features. But when you consider the mental activity of constructing queries over personally-defined properties (just that functionality alone), from the perspective of a new user who has never done this before, that cognitive work is not completely different in the two tools.

I still look at my content struggling at how to make it so I can pull it together in a meaningful way, by defining types of things and the properties about them that I care about. Tana basically pushes that style of thinking in your face right from the get-go. Step 1 = define objects and properties, and searches that makes those properties meaningful.

Tana people will say you can “just start typing” like Roam/Logseq people emphasize, but that’s not really true. Their own tutorials almost always begin with “tag your node so it becomes a type of thing, then configure its properties”.

In Logeq, you can carry on for quite some time before you have to do that kind of thinking, but at a certain point, to do some of what you want to do, you end up doing the same kind of thinking about groups of objects, attributes and queries. But where Tana’s worked hard on the UX of that, Logseq gives you much less support.

From a beginner’s experience perspective, the most extreme difference besides Tana forcing structural thinking on you right away is that Logseq has Pages you can go to and edit, which is more familiar as a cognitive construct than Tana’s “everything is a node” nature, where you essentially need queries (“live searches”) to see anything cohesive on any subject.

I really don’t care where my data lives, or if there’s an relational or graph database working under the hood, or any underlying issue like that at all. Also, honestly, if its open source like Logseq, or core-team plus plugin-community like Obsidian, or the more closed-shop models like Roam or Tana, again, those don’t have an impact on my efforts to use the tool.

So the YAML front-matter and data-scoping in Obsidian, Tana supertags & Logseq properties and queries are all functionally similar enough for someone like me to call them the same “feature”, and compare how that function is implemented in each tool. And they are the same not because of any characteristic of the technology, but because of the kind of thinking they force me to do.

If I’m sitting here trying to learn Logseq, and I’ve played with Tana, and I read that I should define “This is a type:: book”, then it definitely feels experientially like Logseq’s asking me to do what Tana asks me to do, which prompts me to compare my experiences using booth tools.

Edited to add: this is why I support your Feature Request on the syntax for inline properties, @alex0 . It makes this whole process of defining objects and properties feel much more natural than in any other tool I know. It also really fits the Logseq “efficiency first” pattern you describe, of “just writing”, and quickly developing structure almost as a side-effect. So I think your improved syntax is a good idea on a few counts.

I don’t know what your day job is but I wish Logseq would make you product manager for the “properties” layer of the tool!

2 Likes

@alex0 I generally like the [[property:reference]] syntax to define link type in context, but I don’t exactly understand why your example is useful.

Shouldn’t [[The Picture of Dorian Gray]] have page properties type:: [[book]] and author: [[Oscar Wilde]], instead of your example block? If your goal is to query the block by author and type, wouldn’t it be more useful to inherit those properties from [[The Picture of Dorian Gray]] than to redefine them in every block?

If you want a page for each “object” you mention, your approach is fine; but for me this means too many pages (and files).

For example, if I don’t write anything in [[The Picture of Dorian Gray]] then it won’t become a file but can still be used to browse references and as a filter in queries.

Maybe the example of a book with title and author didn’t make clear that you can use properties for a lot of things in context, for example adding metadata to longform writings.

Let’s say I have two courses treating the same subject in two different ways, I could have something like this:

- # [[Course title]]
  - ## [[Title:: Noether Theorem]]
    - [[type:: Definition]]: ........
    - [[type:: Proof]]: ........

Currently I have a query that let me look for properties in a block’s parents, so I can easily query for all definitions of a certain theorem or the one used in a specific course.

The syntax [[key:: value]] would just make everything look cleaner and without creating a page for everything I mention, that in my use case would mean thousands of files in /pages.

1 Like

Seeing this makes my fingers cringe thinking about all the prefixes I would have to type in a block. I hope they do not make this a thing in Logseq. This should be pitched as a plugin idea and see if a developer is interested enough to pick it up.

It’s supposed to be an optional syntax, you would be able to achieve the same result adding properties in their own lines as always.

I doubt a plugin can implement this because it is needed to interfere with Logseq attempt to parse [[key:: value]] as a usual page reference and to create the page “key:: value”.

1 Like

I am afriad that support for extra syntax like this, is one of those things that it’s better to do on base layer - or maybe even impossible as plugin.
Therefore , more likely to result in making a fork , rather then plugin, and no one will use fork, so no one will do the work to make something no one will use, amen.

IMHO has to be on base layer, but not somethign required or to use always, but a way to make it opt-in , optional, for those who need it, or in contexts where it’s needed, where it makes sense.

3 Likes

Concerning multiple values, within the spirit of natural writing, shouldn’t the property be repeated, to also maintain natural reading? E.g.:

- [[title::The Gray Picture]] is a [[type::phenomenon]]
  discovered by [[scientist::Person1]], [[scientist::Person2]] and [[scientist::Person3]].
  • Or what should happen:
    • in the particular example anyway?
    • if we edit the block later?
  • Should the respective earlier or pre-existing values be:
    • Overwritten?
    • Merged?

@mentaloid good point and I think you provided the solution too. I think in your example the values should be merged, de facto covering the multiple values case. Do you see any disadvantage? And what’s exactly the issue with editing the block later?

P.S. I know this syntax may look too verbose but Logseq is supposed to get a proper WYSIWYG editor later, so it would be visible only in the Markdown files while in Logseq it would be gracefully rendered. For example, when the text cursor is near the value, the key:: would be visible above or below and being editable by moving the cursor with the mouse or with the up/down keys.

  • The issue is with the expectations:
    • If we remove one scientist from the text, should its value also be removed from the respective property?
    • If we remove from the text the mention to the type, should that property be removed from the block?
  • In other words, should:
    • the properties be in precise sync with those found in the text? (as expected during editing)
    • be possible for the properties to contain extra info than the one found in the text? (like it is now)

Yes and yes, definitely. I expect it to match what we have now:

- key:: [[value]]

the above will not be a proper property declaration if it is edited to:

- [[value]]

or:

- key::

I like this idea of embedding structured Data in Markdown very much.

It allows to put Data into context and makes Text queryable.

But please don’t invent another Syntax. Consider using the Syntax used in Obsidian DataView.

This will make both Tools interoperable so we have more options.

DataView has 3 Syntax Alternatives that are already close to your Proposals and do not conflict with the existing [[…]] Parser:

SingleLineKey :: Single Line Value

… (hiddenInlineKey :: visible inline-Value) …

… [inlineKey :: inlineValue] …

@Spoc_Web I’m surprised to find this reply in this thread, since I made another one that fit it way more, check it:

Meanwhile, check Inline properties and reuse of property values, basic implementation

4 Likes