Bases: Nested tags support

Use case or problem

The new bases filter tags.contains("...") doesn’t support nested tags (can’t insert links but its in the docs). For example, if you use tags.contains("recipe") as a filter then files with the tag #recipe/snack or #recipe/cookies won’t show up.

Proposed solution

The filter tags.contains("...") behaves like an array search. Adding support for nested tags can be done by “expanding out” a file’s list of tags. Using the example above, a file with #recipe/snack tag would be treated by the bases plugin as an array with both #recipe and #recipe/snack tags.

Current workaround

While the bases syntax is very powerful and allows for many smartly crafted workarounds, many have their own set of downsides or issues. In my opinion having to figure out any of these workarounds kinda defeats the point of nested tags. Its in the Obsidian docs so it is an official feature all things considered. It only makes sense that all core functionality treat nested tags how the user would expect.

14 Likes

Does file.hasTag("recipe") do what you want? It’s searching the tags: Property as well as inline #tags.

1 Like

The downside to that workaround is it also includes files that contain that tag inside the body of the file. tags.contains("...") only accounts for frontmatter/properties, which is much more desirable for most.

1 Like

Desperately needing this as well!

I can image some potential circumstances in which I wouldn’t want my Bases to reveal all nested tags, but it could still be a pain to exclude each one of them individually - perhaps some syntax like tags.contains(recipe/**) to indicate the tag and all nested tags vs without the asterisks just returning the tag itself, as is current behavior. Although I’d love for nested tags to be included as the default, I’m not sure what the syntax would be to exclude all nested tags if that is the case.

1 Like

Unique syntax is a good potential solution. Maybe a unique function for when you do (or don’t) want to use nested tags? Like tags.containsNested("...") or tags.containsExact("...")?

As a workaround in the meantime, you can do:

or:
  - tags.contains("recipe")
  - tags.toString().startsWith("recipe/")
  - tags.toString().contains(", recipe/")

That gets you the Front Matter tag and its nests without pulling in inline tags.

It rules out all of the false positives that I could think of, making sure that a tag like #great-recipe/squash doesn’t accidentally get included.

5 Likes

I just tried this and might need some experimentation:
this would match “#area/finances” and “#area/journals”

/area\/[^ ]+/.matches(tags.toString()) == true

Nice. Careful though, because that would also net #subarea/fish, and it would omit plain #area.

yeah, I had quickly thrown that together…this seems to be a much better option:

/(?<!\S)area(\/[^ ]+)?/.matches(tags.toString()) == true

Negative lookbehind makes sure there are no non-whitespace preceeding “area” (this allows it to be the in the beginning or middle since multi tags are space delimited). It also eliminates partial matches like “subarea/fish”

The part after area makes it so it matches on just “area” but also matches for anything “area/xxxxxx”.

Use case or problem & proposed solution

When I create a base and add a filter with a tag #lit
Then I expect to see all the pages with child tags in the results, e.g. #lit/podcast, #lit/book

Note: Obsidian’s search engine already works exactly the way I’ve described.

13 Likes

Just encountered the same situation with my nested-tags → I totally agree with you that the expected behaviour would be to see all sub-tags when filtering for the parent-tag!

1 Like

I’m encountering this issue as well. Definitely need that functionality.

2 Likes

Similarly held back by this issue, as most of the notes that I’d like to put in a Base have child tags attached to them!

2 Likes

file.hasTag() is the solution regarding supporting nested tags in bases.

tags.contains only targets the tags property on the frontmatter as a list, which is what it is.
So I don’t think we should We will not make contains have a special behavior just for tags.

You can open I opened a FR asking to extend List.contains() so that it also searches for substrings within an element of the List. This should address the specific use case highlighted in this thread (search only within the tag property in frontmatter).

Alternatively, this FR will also enable the same thing:

2 Likes

The tags property isn’t the same thing as every other list property. All we are asking is that tags gets treated as expected based on its unique status. Nested tags are an officially supported part of tags and its confusing and jarring to new users that bases doesn’t support nested tags properly.

3 Likes

You haven’t added anything new to the conversation and I don’t want to begin a circular argument.
The special treatment of tags is file.hasTags().
What I wrote above stands.

From the second linked feature requests above, filter will be implemented in v1.9.5+

You’ll be able to search for parent tag in frontmatter-only tags with tags.filter(value.startsWith('parent'))

2 Likes

I am gonna add a quick note here.

Besides the addition of file.hasTag(),
From Obsidian v1.9.14, (note.)tags.contains*() and file.tags.contains*() will be aware of nested tags and will also be case-insensitive.

2 Likes