Problem with variable substitution to create a class

Hello everyone.

I’m trying to use a single macro to create all the Admonitions variants that require six macros in the add-on I created.
To do this, I created two additional parameters: styles (whose values ​​would be lateral or lateralb) and dropdown (with the value details).
Following @Scott_sauyet’s advice, I transformed the macro into a procedure, and everything seems to work except I can’t get the class to have the value I want. This also happens with the normal macro.
This is the code I’m using:

\procedure callout2(type:"note", src, title, width:"100%", class)
<$let theme-class   = {{{ [[$:/palette]get[text]get[color-scheme]else[light]addprefix[theme-]] }}} 
      callout-title = {{{ [<title>!is[blank]] :else[<type>titlecase[]]  }}}
      callout-style = {{{ [<style>!is[blank]then[<style>]] }}}
      icon-tiddler  = {{{ [all[tiddlers+shadows]tag[$:/tags/TimitAdmonitions/Image]contains:callout-type<type>]
                          :else[[$:/plugins/timit/admonitions/images/note]] }}}
      source        = {{{ [<src>get[text]else<src>] }}} >
<div class=<<theme-class>> style=`width:$(width)$`>
<div data-callout=<<type>> class=`callout <<callout-style>>`>
<div class="callout-title">
<div class="callout-icon"><$transclude tiddler=<<icon-tiddler>> field=text/></div>
<div class="callout-title-inner"><<callout-title>></div>
</div>
<$list filter="[<src>!is[blank]]" variable=ignore>
<div class="callout-content">
<$transclude tiddler=<<source>> field=title mode=block />
</div>
</$list>
</div>
</div>
</$let>
\end callout2

In this example, I’m just using one new parameter, callout-styles.

For some reason, it doesn’t create the class correctly. I’ve tried everything: ``, " ", {{{ }}}, using +[join[]], etc…, but it always ends up wrong.

class=`callout <<callout-style>>`>

If I separate callout from callout-style in this code: class="callout <> ", the admonition appears, but with the callout class, if I put it all together, the admonition doesn’t get any style.

I’m sure it’s something obvious, but I can’t figure it out. I’ve been reviewing the documentation, but I’m getting really confused and can’t figure anything out. The AI ​​tells me everything’s fine, but I know it’s failing a lot…
Does anyone know what I’m doing wrong?

Best regards, and thanks.

The backtick syntax used for substituted attribute values uses a special format for variables. You’d need to use this instead:

class=`callout $(callout-style)$`

This is a crucial difference because “normal” variables like <<callout-style>> don’t get replaced with their values in this context, so <<callout-style>> would be treated as a literal value referring to a (non-existent) class .<<callout-style>>.

But you also have some issues with your <<callout-style>> definition:

  • Syntax: {{{ [<style>!is[blank]then[<style>]] }}} has extra brackets: then[<style>] means “then use the literal value<style>” (rather than the value of the <<style>> variable)”. then<style> would be correct, but you don’t actually need it here at all: {{{ [<style>!is[blank]] }}} will produce the same result.
    • … and in fact, since the filter is so simple, you don’t really need callout-style = {{{ [<style>!is[blank]then[<style>]] }}} at all: you could get the same results and save a line of code by using the following instead:
class=`callout $(style)$`
  • Variable names: You’re using the variable <<style>> (or $(style)$) in your code, but you haven’t actually defined it anywhere in your procedure. On the other hand, you do have a procedure parameter class which you don’t seem be using anywhere, so I’d recommend replacing <<style>> and $(style)$ with <<class>> and $(class)$ respectively.
    • In theory, you could alternatively keep the <<style>> variable and change class to style in your procedure parameters. But to me, style implies an inline CSS rule like border: 3px solid red;, and that won’t work in this context.
class=`callout $(style)$`
   would be transformed to
class="callout border: 3px solid red;" --> doesn't work

So IMO, it’s better to use class as it clarifies the sort of values you should be giving the parameter.

4 Likes

Just for the record, I don’t believe I actually suggested the transformation, although I did offer advice on how to do it. I see a good reason to use procedures and other modern tools for new work (although see @EricShulman’s good arguments for the opposite point of view) so I would support doing this, especially as this is fresh development. But the differences are small and the advantage fairly minor. I wouldn’t do this change except when I was in the process of making other changes.

And all the advice from @etardiff is excellent, even if I might choose differently between “style” and “class”. (I might even pull out a thesaurus to find an alternative free of other implications, but that’s just me.)

1 Like