Expanding MVV compatibility

In a similar vein to V5.4.0 prerelease - Clearifications about MVVs using with various operators… I thought I’d start a new conversation for post-5.4.0 possibilities.

As an avid user of +[format:titlelist[]join[ ]] + enlist<var> constructions, I’ve been excited about the potential of multi-valued variables since they were first teased, and this week I’ve finally found some time to start converting a lot of my old functions, filters, and $let assignments to use the new syntax. This has enabled me to convert a lot of code like this…

\function concepts() [tag[Concepts]] +[format:titlelist[]join[ ]]

<$let variables={{{ [tag[Variables]] +[format:titlelist[]join[ ]] }}}>

{{{ [enlist<concepts>] [enlist<variables>] }}}

into the following simpler alternatives:

\function concepts() [tag[Concepts]]

<$let variables={{{ [tag[Variables]] }}}>

{{{ [(concepts)] [(variables)] }}}

Which is great! Except that I keep running into instances like this…

<$let variables={{{ [tag[Variables]] +[format:titlelist[]join[ ]] }}}>

{{{ [[A]match[A]then<variables>enlist-input[]] }}}

At present, the only filter operators that accept MVVs as parameters (as per the documentation) are title and function. This means that in a scenario like the one above, I can’t actually redefine <<variables>> as an MVV, because I can’t replace <variables>enlist-input[] with (variables). then doesn’t support MVVs, so then(variables) will return only the first title in the list, not the entire list I need.

In this very simplified example, I can replace then with :then as a workaround:

<$let variables={{{ [tag[Variables]] }}}>

{{{ [[A]match[A]] :then[(variables)] }}}

But this isn’t always a viable solution, especially in more complex multi-run filters.

This leads me to a question for our devs: Is it possible to extend additional filter operators to accommodate MVV parameters?

And a discussion question for other users: Which other filter operators would you like to use with MVVs?

My personal wishlist:

  • then, as discussed above
  • other operators that can take space-separated lists, like fields:exclude/fields:include or search::words (where each value in the MVV would constitute a “word” — I expanded on this in a later post)
  • perhaps contains could be similarly extended so that contains:tags(var) would return tiddlers containing all the MVV values in their tag field?
1 Like

I am just wondering if MVV’s different values are better described as “titles” rather than “words” however I have not being able to explore the true nature of MVV’s yet to properly understand them deeply. How are they internally delimited?

Yes, probably! And generally speaking I’d tend to opt for “strings” rather than “titles”, which might imply that values correspond to extant tiddlers — though obviously this isn’t really true in filter logic, and doesn’t completely describe the way we use constructions like {{!!title}}.

In this case, I used “words” in scare quotes because I was thinking about search::words (i.e. the default form of search) in particular. With the current filter syntax, we can do something like this:

{{{ [search:title[filter operator]] }}}

or

<$let terms="filter operator">

{{{ [search:title<terms>] }}}

The default words mode treats its parameter as a space-separated list of tokens which must all be present in each result, so both of these examples will find tiddlers whose titles contain both “filter” and “operator” — but not necessarily in that order.

I’m imagining an expanded version of search which could accept a MVV in place of a standard variable, something like this:

<$let terms={{{ [[filter operator]] variable }}}>

((terms))

{{{ [search:text(terms)] }}} = {{{ [search:text:literal[filter operator]search:text[variable]] }}}

I’d expect this to return all tiddlers that contained the strings “filter operator” and “variable”. This would allow us to search for multiple tokens which could themselves include whitespace.