Can the substitute filter operator only return one tiddler?

If I put the following code on a tiddler at tiddlywiki dot com …

\procedure ckbox() - [ ] 

\function check.list() [tag[HelloThere]limit[5]]+[addprefix<ckbox>]

List: 

{{{ [function[check.list]] }}}

Other list:

<$vars subme="${[function[check.list]]}$">
{{{ [<subme>substitute[]] }}}
</$vars>

{{{ [<check.list>] }}}

I get the following output

As you can see, the check.list on it’s own, or with substitute, only has the first entry. Is there a way to make substitute output all the lines of the corresponding filter?

The shortcut var={{{ [tag[HelloThere]] }}} will always only return the first element in the list if assigned to a variable.

So does the output of a filter-function if you call it as a macro.

So you need to format the list as a titlelist and join it into a string.
Then “disassemble” the string into a titlelist with enlist-input[]

Try this:

\procedure ckbox() - [ ] 
\function check.list() [tag[HelloThere]limit[5]] +[addprefix<ckbox>format:titlelist[]] +[join[ ]]

<<check.list>>

{{{ [<check.list>enlist-input[]] }}}

For better readability functions can also be formatted like so:

\procedure ckbox() - [ ] 

\function check.list()
  [tag[HelloThere]limit[5]]
  +[addprefix<ckbox>format:titlelist[]]
  +[join[ ]]
\end

<<check.list>>

{{{ [<check.list>enlist-input[]] }}}

Hi Mario,

This information was helpful, but the problem is that when used with the substitute operator, only the first title is shown. That is, if you do

${ [<check.list>enlist-input[]] }$

As a substitution, you still end up seeing only the first item. It would be handy if there was some way to pump out all the titles, but I think I can least see a workaround for my use case.

Thanks!

Have you tried omitting the enlist-input operator to leave it as one string?

${ [<check.list>] }$ instead of ${ [<check.list>enlist-input[]] }$ with pmario’s code.

It does work, but the output is like:

### Check List
[[- [ ]Finish this hack]]
[[- [ ]Start another hack]]

When you apply the enlist-input operator, you only get the first line.

So, my point is mostly that the substituted text can only put out one title list. I just have to think in terms of creating and displaying one output string in a manner that it appears to be multiple items. Sometimes when we get a new tool there’s some backdoor that makes it operate in some alternate mode … so I was hoping/wondering if such a thing existed for substitute.

The additional complication in my example is that I’m using square brackets, the two characters that can break TW. I’ve found a workaround, but I might post a question about some method to escape characters.

Thanks everyone!

If you have a look at the docs: https://tiddlywiki.com/#substitute%20Operator it says that only the first element will be returned if you substitute ${ filter expression }$

So why do you want to use the substitute operator when it’s documented, that it does not work that way?

I started by using varname, and that didn’t work at all. I didn’t actually understand what “first result” meant. Now it makes sense.

Thanks!

Ahh, OK … So we should probably use a different wording there. eg:

Text substitution with the first result of evaluating the filter expression. So if the expression returns multiple titles, only the first one can be used.

Would that have made it clearer?

Yes. That would be very clear.

Thanks!

I did create a PR: Update substitute Operator.tid by pmario · Pull Request #7609 · Jermolene/TiddlyWiki5 · GitHub

FYI: If you use a function or filter to generate the value you can use join to create a Parmeter containing a list, that is it bypasses the first parameter rule, but of course you need to use it as a list you need split it again eg;

\function mylist() filter +[format:titlelist[]join[ ]]

To expand on @TW_Tones note about constructing lists…

Using this example function definition:

\function mylist() [tag[HelloThere]] +[format:titlelist[]join[ ]]

You can display the list as a single text string
(with double square brackets around titles that contain spaces):

<<mylist>>

or pass the entire list as a single macro parameter:

<$macrocall $name="someMacro" list=<<mylist>> />

or process the individual list items
(e.g., use a $list widget to render a link for each item):

<$list filter=<<mylist>>> <$link/><br> </$list>

or “split it again” for additional processing using the enlist filter operator
(e.g., show links to tiddlers that have non-blank caption fields)

<$list filter="[enlist<mylist>has[caption]]">
   <$link to={{!!title}}><$text text={{!!caption}}/></$link><br>
</$list>
1 Like

@Mark_S Give the conversation that followed have you found a good solution for this?

Can the substitute filter operator only return one tiddler?

or at lease understand a good work around?

This was for the dynamic rubber stamp. In the end, since only one item can be output, I built that one item as the concatenation of all the desired items separated by carriage returns.