Use system variable inside template scope

I’ve defined the following ViewTemplate which is applied on all tiddlers acting as tags:


\define sv-exclude-tags() {{!!title}}

<$list filter="[tag<currentTiddler>limit[1]]" variable="">

<h2>Bookmarks tagged <b>{{!!title}}</b></h2>

<<table-dynamic
filter:[tag{!!title}]
fields:"tbl-expand title href tags"
pagination: yes
>>

</$list>

The above displays a Dynamic Table via @Mohammad’s excellent Shiraz plugin.

It works just fine, except the sv-exclude-tags() at the top is not taken into account. All other title references are displayed and used properly and if I hardcode the exact same code in a tag tiddler by hand it also works properly.

It looks like I’m missing something when trying to apply it via a template. Any ideas what that might be?

I don’t have experience with Shiraz plugin, after looking it up quickly I’d guess the problem is that the sv-exclude-tags variable is interpreted as literal title list, so e.g.

\define sv-exclude-tags() Literal_title_to_exclude [[Another title to exclude, this one has spaces so it has to be inside double braces]]

will work, but

\define sv-exclude-tags() {{!!title}}

will not, because the wikitext {{!!title}} will not be interpreted as wikitext, but as a literal title of a tag to exclude. In this case the value of the variable is {{!!title}}.

Try surrounding the table macro call in a let widget like this:

<$let sv-exclude-tags=<<currentTiddler>> >
<<table-dynamic
filter:[tag{!!title}]
fields:"tbl-expand title href tags"
pagination: yes
>>
</$let>

In this case, the let widget sets the value of the variable to the title of the current tiddler.

It worked! Thank you :slight_smile:

Any reason why the first line is treated differently? My guess is that \define declarations must be at the very top, but when they are inserted by a ViewTemplate they end up somewhere in the middle of the wiki text and that messes them up?

To figure out WHY your initial usage didn’t work, we need to look at HOW the Shiraz plugin uses the sv-exclude-tags variable.

One tiddler is listed: $:/plugins/kookma/shiraz/templates/body/tags

In that code, we can see the reference to tv-exclude-tags here:

<$list filter="[<currentRecord>tags[]sort[title]]  :except[subfilter<sv-exclude-tags>]">

Note that the variable is used as the parameter value for a subfilter operator. As such, the variable MUST contain valid filter syntax, and {{!!title}} (with doubled curly braces) is only for use within wikitext. For filter syntax, you would need to use single curly braces, and enclose that within square brackets, like this: [{!!title}].

However, that likely also won’t work, because it depends upon the value of the currentTiddler variable, which might be different from the tiddler from which you invoked the <<table-dynamic>> macro in the first place because the Shiraz macro undoubtedly uses many $list widgets, any one of which could have changed the value of currentTiddler.

The reason @vilc’s answer works, is that using <$let sv-exclude-tags=<<currentTiddler>>> (or alternatively, <$let sv-exclude-tags={{!!title}}> before invoking <<table-dynamic>> ensures that the variable is set to the literal text value of the current tiddler’s title at that point in time, and is thus not subject to any further evaluation later on, when it is used deep within the Shiraz code.

However, also note that this assumes that the title of the invoking tiddler does not contain any spaces. Otherwise, each word in the title would wind up being treated as separate values when the subfilter<sv-exclude-tags> is used in the Shiraz code. To avoid this possibility, you could write:

<$let sv-exclude-tags={{{ [{!!title}format:titlelist[]] }}}>

which ensures that a multi-word tiddler title will be automatically enclosed within doubled square brackets, so that it will be handled later on as a single value, rather than a list of multiple word values.

-e

2 Likes

I’m in awe with the clarity and depth of the answer. I’m now using your final <$let> suggestion and it looks to be working as it should.

Again thank you for the solution and the explanation.

What is the correct syntax of your command for defining multiple tags?

The plain \define syntax just lists them with spaces and double brackets for tags with spaces:

\define sv-exclude-tags() tagA [[Tag B With Spaces]]

The “plain define” syntax (with double brackets for tags with spaces) is sufficient if you are only specifying literal tag values (as shown in your example).

If you want to use a combination of field references and literal tag values, you can write something like this:

<$let sv-exclude-tags={{{ [{!!title}] [[Tag B With Spaces]] +[format:titlelist[]join[ ]] }}}>

Notes:

  • The +[format:titlelist[]] syntax adds double square brackets as needed, and the join[ ] then assembles the tags into a single space-separate value that is assigned to sv-exclude-tags

-e

1 Like