How to pass a variable to a HTML-tag inside a procedure?

I am at the very beginning of understanding TiddlyWiki and now there are these new procedures. So I decided to re-write very easy macros to procedures for the learning-process. Some went well. This one didn’t.

This macro creates vertical whitespace. You choose how high it should be.

\define vspace(height:"42px")
<p style="margin-bottom: $height$;"></p>
\end

This procedure creates only the fixed whitespace. It does not use the entered height. I tried many versions of { " $ ( < in different numbers nd combinations.

\procedure vspace(height:"42px")
<p style="margin-bottom: <<height>>;"></p>
\end

Your inspiration taught me that looking into TiddlyWiki should include looking into CSS.
I got a working procedure but it feels like a little detour…

\procedure vspace(height:"42px")
<style>
    .vspace {margin-bottom: <<height>>;}
</style>

<p class="vspace"></p>
\end

Can the variable be passed diretly to the html-tag/element like to the CSS?

The problem is caused by the fact that the value of a widget parameter is not “wikified”.

In the older macro \define syntax, references to macro parameters are automatically substituted with the corresponding passed-in value BEFORE the macro content is returned. Thus, style="margin-bottom: $height$;" works because it appears as style="margin-bottom: 42px;" in the returned content.

For comparison, still using the old macro \define syntax, if you had written style="margin-bottom: <<__height__>>;", – which is a way to reference a macro parameter’s value as a “pseudo-variable” – it won’t work because the widget’s style parameter value is still not being wikified, so the reference to <<__height__>> doesn’t get replaced by the corresponding value.

This latter example is the same as the result you are now getting using the new \procedure syntax – which allows you to reference a macro parameter value as a “true” variable – and also doesn’t work because the widget’s style parameter value is not being wikified, so the reference to <<height>> doesn’t get replaced by the corresponding value.

One work-around is to use a “filtered transclusion” to specify the value of the widget’s style parameter, like this:

<p style={{{ [[margin-bottom:]] [<height>] [[;]] +[join[]] }}}></p>

This WILL work, because the entire style parameter value is dynamically constructed on-the-fly when the filtered transclusion is processed. However, the code is still kind of “lumpy”.

Fortunately, there is yet another, lesser-known alternative syntax that is definitely cleaner. The TWCore processing adds a special-case widget parameter syntax that allows you to set the values of individual style attributes, by using style.attribute-name="attribute-value". Thus, something like this will work to achieve your goal:

<p style.margin-bottom=<<height>> ></p>

enjoy,
-e

4 Likes

Thank you! @EricShulman

You worte not only two solutions but a beautifull and teaching explanation!
Together with me staring at this short code and the documentation for way too long, I feel like I got a really deeper understanding from this.

I tried to use the $transclude Widget but hose brackets broke it.

This is the first “filtered transclusion” (plus join Operator / a second subject for newbies) that I cearly understand now. This was helpfull for learning.

The special-case widget looks cleaner.

I thought this macro might be one of those cases:

It is now recommended to only use macros when textual substitution is specifically required.

but there are solutions.

Hi @Hanlon

Here is another solution available since v5.3.0:

\procedure vspace(height:"42px")
<p style=`margin-bottom: $(height)$;`></p>
\end

The “single backtick” syntax for attributes is documented here.

Have fun,

Fred

1 Like

OH! So I was close.

I read

attr=`value`

but did not look at the examples close enough.

I tried

<p style=margin-bottom: `$(height)$`;></p>

with the backtids too close at the variable, because that was the “value” I wanted to pass because I hard-code the margin-bottom:.

Actually to be exact it is either of the following;

\define height() 5em
a
<p style.margin-bottom=`$(height)$`>aa</p>
b
<p style=`margin-bottom:$(height)$;`>aa</p>
c

[Edited] Post script

  • The advantage of the first method is you can introduce multiple separate style parameters each with thier own computed value.

With the “separate style parameters” syntax, you can also use a <<height>> reference, like this:

<p style.margin-bottom=<<height>>>aa</p>

which accomplishes the same result, but is also backward-compatible for use in TiddlyWikis that are older than TWCore5.3.0.

1 Like