Just like procedures can be given parameters, tiddler fields can be given parameters, giving a transclusion of that field some parts that change. To define the parameters of a field, a \parameters
pragma is placed at the start of the field. This takes a parameter list that looks and works exactly like that of a procedure. The specified parameters are made available as variables when rendering the field.
To specify parameters when transcluding a tiddler, place each parameter after a single |
at the end of the usual transclusion syntax. For instance, suppose we write a snippet tiddler Sn:Hi
:
\parameters(interlocutor, speaker)
Hi <<interlocutor>>, I'm <<speaker>>!
Hi , I'm !
Then we can say:
{{Sn:Hi|Alice|Bob}}
Hi Alice, I'm Bob!
Of course, you can also do parameterized field transclusion with a $transclude
widget. Just use the $tiddler
attribute, and name each of the parameters, just like you would with the parameters of a procedure:
<$transclude $tiddler="Sn:Hi" interlocutor="Alice" speaker="Bob"/>
Hi Alice, I'm Bob!
Unlike procedure calls, the wikitext syntax for {{field transclusions}}
doesn't allow you to use named parameters – you can only use positional parameters. However, this is easily overcome by using the $transclude
widget instead of the wikitext syntax, as shown immediately above.
Less common options
While we typically only have reason to transclude the text
field when working with parameterized transclusions, it's perfectly valid to give a different field parameters and transclude that. For instance, if we set the description
field of Sn:Hi
to \parameters(interlocutor, speaker) <<speaker>> is talking to <<interlocutor>>
:
{{Sn:Hi!!description|Alice|Bob}}
<$transclude $tiddler="Sn:Hi" $field="description" interlocutor="Carol" speaker="Daniel"/>
Bob is talking to Alice
Daniel is talking to Carol
It's also possible to combine template transclusion with parameters, using the syntax {{CurrentTiddler||TemplateTiddler|parameter1|parameter2}}
. You cannot directly combine this with transcluding a different field using !!
, but you can work around that limitation by manually setting the currentTiddler
variable and then performing the field transclusion.
The $parameters
widget
The \parameters
pragma is actually a shortcut for a $parameters
widget. The widget form has two extra features:
- You can compute the default parameters dynamically (so, for instance, if you left off a parameter when calling the transclusion, it could be filled in by a filter expression or a different variable).
- You can retrieve parameters passed to ancestor transclusions (i.e., if you transclude a tiddler with parameters which transcludes another tiddler with different values of the same parameter, in that second tiddler you can retrieve the value which the first transclusion set).
These are rarely necessary, but if they would come in handy for you, check out the documentation.
Slots
Believe it or not, there is actually yet another way to pass content into a transcluded tiddler: slots. Here, you use a $slot
widget with an arbitrary name in the tiddler to be transcluded, instead of referencing a variable. Then, in the body of a $transclude
widget transcluding that tiddler, you place the content for the slot in the body of a $fill
widget referencing the same name.
First we create a tiddler with a slot:
\parameters(interlocutor, speaker)
<<speaker>> says to <<interlocutor>>:
<blockquote>
<$slot $name="quote" />
</blockquote>
says to :
And then we transclude it, filling the slot:
<$transclude
$tiddler="Sn:SaidAThing"
interlocutor="Alice"
speaker="Bob"
>
<$fill $name="quote">
Charlie told me, “[[There's a horse in aisle five|https://what-if.xkcd.com/34/]].”
</$fill>
</$transclude>
Bob says to Alice:
Charlie told me, “There's a horse in aisle five.”
You can include as many slots as you want; each will be filled by a separate $fill
widget when it's transcluded (or remain blank, if no appropriate $fill
widget is provided).
Slots, unlike variables, do not carry over into nested transclusions. That is, if you are in some wikitext that has a particular slot S filled and you transclude another field or variable, S's value will not be directly available inside that transclusion. However, you can use the $depth
parameter to the $slot
widget to access it. This is 1 by default; if you set it to a higher number, it will go up to the parent transclusion that number of times before looking for the slot. In our example, setting $depth
to 2 will retrieve the value of S.
The benefit of using a slot rather than a parameter is that including long content with lots of formatting is much easier, since you don't have to cram it into part of a {{field transclusion}}
or the attribute of a $transclude
widget. The syntax is still a little ugly though – you're forced to use a $transclude
widget rather than {{braces}}
, plus you have to nest an extra $fill
widget inside the $transclude
widget. Custom Widgets wrap a single slot called ts-raw
in more convenient syntax, and are often a better choice in such a situation.
The main drawback of using a slot rather than a parameter is that you cannot access its value inside a filter, which means you're limited to displaying its contents as wikitext, rather than changing it or making decisions based on its value.
Here we saw how you can use slots within field transclusions, because they tend to feel most intuitive this way. But it's actually possible to use a slot inside any type of transclusion – so this would work fine within a procedure as well.
Parameterized transclusions vs. procedures
Why use a transclusion with parameters (or slots) rather than a procedure? Well, there's no technical reason, really; it can accomplish exactly the same things. It's more about semantics. Sometimes it feels more natural to think about reusing wikitext in terms of calling a procedure (for instance, when you want to create a link to something or format a small chunk of text), and sometimes in terms of transcluding a tiddler (for instance, when including an icon in the current tiddler and specifying its color). We'll come back to this question in Choosing a Type of Transclusion, in chapter 6.
Parameterized transclusions are a recent addition to TiddlyWiki; for many years the only way to have parts in a transclusion that changed was to manually set variables to values before performing the transclusion (probably having to go look at the tiddler you were transcluding to remember what variable names to use). This means that most parameterized wikitext out there in the wild uses procedures (or, really, macros – more on that later), less because they're actually better and more because they're the only thing we're used to. As more time goes by, the community will probably get a better idea of which options make the most sense where.
Exercises
Create a WikipediaLink
tiddler equivalent of the procedure. It should take articleName
and text
parameters and generate a Wikipedia link when transcluded.
Clone the ContactInformationTemplate
and create a ContactInformationParameters
version that does not use the current tiddler in any way (and thus does not need to be transcluded as a template).
If you've been messing with your ContactInformationTemplate
, feel free to start with this version:
<h2>Information about {{!!title}}</h2>
<ul>
<li>''Email'': {{!!email}}</li>
<li>''Phone'': {{!!phone}}</li>
<li>
''Family'':
<$transclude $variable="list-links-draggable" tiddler=<<currentTiddler>> field="family" />
</li>
<li>''Manager'': {{!!manager}}</li>
</ul>
go to answer
Suppose you have several co-workers who each have their own opinion about what action to take, and they write a short statement explaining it. Create a Statements
tiddler that accepts the names of up to three people as parameters, along with corresponding slots where you can write what the statements are. For each statement it should give the person's name, then a block quote containing their statement.
Use a procedure inside Statements
to avoid duplicating the wikitext that shows the person's name and their statement.
(You might end up with some text that appears even if you didn't use all of the people/slots. If you want to try hiding it, feel free – we already know some techniques that can do this – but in the next section), we'll learn the easiest way to do this, so it's fine to just wait!)
go to answer