Tagging operator is not working inside $:/config/FileSystemPaths

To customize where tiddlers are stored, I used following rules in $:/config/FileSystemPaths

[is[system]!has[draft.of]removeprefix[$:/]addprefix[_system/]]
[tag[Journal]addprefix[journals/]]
[tag[TiddlyWiki Doc]tagging[]addprefix[tiddlywiki-notes/]]
[tag[TiddlyWiki Doc]addprefix[tiddlywiki-notes/]]
[has[bibtex-title]addprefix[bibtex/]]

Every rule works fine, except the tagging operator.

[tag[TiddlyWiki Doc]tagging[]addprefix[tiddlywiki-notes/]]

This rule should move all the tiddlers tagged with child tags of TiddlyWiki Doc. But it has no effect.

I have tested [tag[TiddlyWiki Doc]tagging[]] in advanced search and Commander plugin. It works as expected. But when used inside $:/config/FileSystemPaths it becomes ineffective.

Am I making some mistake here? Or is it a bug in TW?

From the documentation at https://tiddlywiki.com/#Customising%20Tiddler%20File%20Naming:

Every time a tiddler is saved to disk it is tested against each filter in turn, and the first output of the first filter to produce any output is taken as a logical path to be used for the tiddler file. If the logical path has changed a new file is created and the old file is deleted.

That is, the input to the filters in $:/config/FileSystemPaths is a single tiddler title, as opposed to using the same filter elsewhere where the implicit input unless specified otherwise is all[tiddlers]

Therefore the filter [tag[TiddlyWiki Doc]tagging[]addprefix[tiddlywiki-notes/]] only matches tiddlers with the tag TiddlyWIki Doc and not tiddlers returned by the tagging operator later in the run.

2 Likes

To test whether a filter in $:/config/FileSystemPaths matches a given tiddler and what path will be used for it, you can use the following in the Filter tab in Advanced Search:

[[tiddler title]] :cascade[{$:/config/FileSystemPaths}split[\n]]

1 Like

Awesome trick! This confirms that my tagging rule is not working inside $:/config/FileSystemPaths.

Not entirely sure about your tag hierarchy or how well multiple filter runs might work in this context, but try this untested filter as an alternative:

[has[title]] :filter[tags[]tag[TiddlyWiki Doc]] :and[addprefix[tiddlywiki-notes/]]

1 Like

What does [has[title]] do here? The only guaranteed field is “title”.
Thanks!

1 Like

Thanks @saqimtiaz. This filter works.

If I understand correctly, then this [tags[]tag[TiddlyWiki Doc]] is different from [tag[TiddlyWiki Doc]tagging[]].

[tag[TiddlyWiki Doc]tagging[]] recursively finds all tiddlers that have TiddlyWiki Doc tag directly or in the ancestor of their tags.

[tags[]tag[TiddlyWiki Doc]] does a union operation on the tags of [tag[TiddlyWiki Doc]] results.

But [tags[]tag[TiddlyWiki Doc]] work, even though it too will need all[tiddlers] to evaluate the result.

I vaguely remember that a workaround is needed in path filters if the filter starts with some of the newer filter run prefixes, due to the way the filters are invoked from JavaScript. Otherwise the filter runs see no input and are never processed.

The :cascade filter run prefix implements the same logic but I believe does not have the same issue when invoked from wikitext.

When used for instance in Advanced Search, this is true and the full filter that is evaluated is:
[all[tiddlers]tag[TiddlyWiki Doc]tagging[]]
That is, you start with all the tiddlers and select the ones with a given tag.

However, in path filters your starting point is a single tiddler title and you want to test if it matches a given filter and if so, specify its path. So your filter logic needs to take into account that is starting with the tiddler title of the tiddler to be tested.

Used in path filters, [tags[]tag[TiddlyWiki Doc]] corresponds to
[[tiddler title]] :and[tags[]tag[TiddlyWiki Doc]]

That is, for a given tiddler title get its tags and make sure at least one of them is tagged with TiddlyWiki Doc.

In comparison, in the context of path filters [tag[TiddlyWiki Doc]tagging[]] is equivalent to: [[tiddler title]] :and[tag[TiddlyWiki Doc]tagging[]]

That is, for a given tiddler title check if it has the tag TiddlyWiki Doc and then if it does, check what it is tagging. If the input tiddler does not have the tag TiddlyWiki doc, the tagging[] operator receives no input and therefore your filter fails.

3 Likes

Great explanation! Thanks a lot @saqimtiaz. Much appreciated.