Macros in filters

Hey there,
I’m a beginner and i’m trying the following since days without a solution:

\define Suche()
T:{{!!Jahr}}{{!!Monat}}
\end

Suche: <<Suche>>


<$list filter="[search:title:literal<Suche>]">

</$list>

As long as I just write <<Suche>> the output is something like “T:2412”. That’s what I want. But the filter brings no output.

If I define Suche like this:

\define Suche()
T:2412
\end

the filter is working fine.

How can I fix the code above to make it work?

Thanks in advance,
Ben

Hi @Ben and welcome to TW community!

You can replace your Suche macro with a function like this:

\function Suche()
[[T:]] [{!!Jahr}] [{!!Monat}] +[join[]]
\end

The rest of your code will work as expected.

Fred

Hi @tw-FRed,

thanks for your help. Now it is working!

I’m still trying to understand, why my code is not working. Is it because behind the screen T:{{!!Jahr}}{{!!Monat}} is not tied together?

I’ll try to explain crudely what I understand of wikitext rendering, but there will be approximations and imprecision, please bear with me :slightly_smiling_face:

As far as I can tell, your initial code isn’t working because macros are just “text snippets” with a name, they are not “computed” ( = rendered) until after they are used.

When a tiddler is displayed, during the first pass of the rendering process, macro calls are replaced with their definition (ie. the <<macro name>> is replaced by the macro’s content), and in a later pass the widgets (like <$list>) are rendered (ie. replaced by html + css).

In your code, when the macro is called in the filter, during the first pass the content of the macro definition is inserted into the filter, just like if you’d written this:

<$list filter="[search:title:literal[T:{{!!Jahr}}{{!!Monat}}]]">

which doesn’t work because it’s not a valid filter syntax.

In order to solve this problem, you can use a function instead of a macro, because a function is a “custom filter”, which TW’s rendering process recognizes and treats as such.
There are other options, like using a variable initialized with the result of a “filtered transclusion” like this:

<$let Suche={{{ [[T:]] [{!!Jahr}] [{!!Monat}] +[join[]] }}}

Suche: <<Suche>>

<$list filter="[search:title:literal<Suche>]">

</$list>
</$let>

(untested code)

Fred

2 Likes

Thanks for your explaination, I learned a lot today. Your last code is working as well, by the way.

I’ve tried something like

<$let Suche={{{ [[T:]addsuffix{!!Jahr}addsuffix{!!Monat}] }}}>

before, but I guess I was wrong with the brackets…

Thank you very much!

Ben

2 Likes

Small nudge:

To avoid future trouble, it’s probably good to make a habit like this:

\function Suche()
[[T:]] =[{!!Jahr}] =[{!!Monat}] +[join[]]
\end

It’ll be another 75 years before the code offered by @tw-FRed actually creates trouble :wink: (unless you’re working already with historical dates!), but suppose you were to add a Tag (Day) field… Month and Day values may often be the same, and the function expression, if lacking the = prefixes, will remove duplicate values, so February 2 would give you just 02, not 0202.

(Technically, you just need the = before values after the first one. But whenever I want to preserve values despite duplication, I add the = to each, so that it’s easy to move things around, and there’s a clear visual indicator that this value should not be subject to de-duplication.)

1 Like

Thanks a lot for the hint @Springer . Even if it’s no problem in this case, I will change it and try to make it a habit…

1 Like

Thanks @Springer for the advice!

I often forget this tip and get bitten later on…

Fred

1 Like