Sometimes we want to use exactly the same text multiple times, and variables let us eliminate that repetition. But perhaps more often, we want to repeat some text which is mostly the same, but which varies in a small part or two.
In Using Variables as Attributes, we learned that you can combine a variable with other text using a substituted attribute value:
<a href=`$(wpBase)$/Aardvark`>Aardvarks</a>
Technically, one could argue that this allows us to repeat text which is mostly the same. But this is a mighty awkward way to write a link to a Wikipedia article! If we want our fancy wikitext to be easier than simply copying and pasting a new link from our web browser each time, we need a much more convenient way to write it.
Procedures provide this mechanism. A procedure is a special kind of variable with some bits that change depending on how you refer to it; the bits that change are called the procedure's parameters. (As we'll learn later, anything we transclude can have parameters – for instance, a tiddler can have parameters.)
To transclude the value of a procedure (this is more commonly referred to as calling the procedure), we use the same double angle brackets that we would to transclude an ordinary variable, but we include the values of the parameters as well (this is called passing the parameters to the procedure). Specifically, we place them inside the double angle brackets after the procedure name, separated from the procedure name and from each other by a space.
If we write a wikipediaLink
procedure, we can call it like this:
The <<wikipediaLink Aardvark>> is a pig-like African mammal that eats ants and termites.
Defining a procedure
Of course, before that wikitext will work, we have to tell TiddlyWiki what a wikipediaLink
actually is. The syntax looks like this:
\procedure wikipediaLink(articleName)
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<articleName>>
</a>
\end
Put all together, in action:
\procedure wikipediaLink(articleName)
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<articleName>></a>
\end
The <<wikipediaLink Aardvark>> is a pig-like African mammal that eats ants and termites.
The Aardvark is a pig-like African mammal that eats ants and termites.
Let's get this example in your wiki so you can play with it: create a new tiddler called WikipediaLinks
and type this snippet in. (Careful: the HTML closing tag </a>
uses a forward slash, while \procedure
and \end
use a backslash. Review the HTML section if you can't remember which is which.) You should see the link appear, as it does in the preview above, and if you click on it, you'll land on the Wikipedia page about aardvarks.
Anatomy of a procedure
There's a lot of new syntax here, so let's take a closer look at what's going on. Our procedure started with this line:
\procedure wikipediaLink(articleName)
A word starting with a backslash at the beginning of a tiddler introduces a pragma, which is a really fancy name for an instruction that comes at the top of a tiddler and changes the way TiddlyWiki reads the rest of the tiddler. Specifically, the \procedure
pragma tells TiddlyWiki that every time it sees a transclusion of wikipediaLink
, it should follow the instructions in this procedure.
wikipediaLink
, of course, is the name of the procedure.
The part in parentheses, called the parameter list, describes the parameters of the procedure. There can be any number of parameters. Here there is one parameter, articleName
; in the next section, we'll see an example with more than one parameter.
Everything between the line beginning with \procedure
and the line beginning with \end
is called the body of the procedure:
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<articleName>>
</a>
The body of a procedure is like the value of a variable, with an additional feature: each parameter to the procedure becomes a variable within the body. This variable's name is the same as the parameter name, and its value is whatever was passed to the parameter. In this example, we're referring to the value of the parameter/variable articleName
twice, once inside the substituted attribute value for the href
attribute of the a
tag, and once directly in the wikitext.
Lastly, there's the line:
\end
Unsurprisingly, this indicates that we've come to the end of the procedure. A procedure can go on for as many lines as we want it to, until we come to the \end
.
The whole hunk of wikitext we just discussed, from the beginning of the \procedure
to the end of the \end
, is called the definition of the wikipediaLink
procedure.
How TiddlyWiki processes procedure calls
When something doesn't work the way you expect, it's helpful to be able to “think like the computer” as you try to understand what you did wrong, so let's talk about what TiddlyWiki does when it encounters a <<procedure call>>
.
First, TiddlyWiki stops rendering the tiddler for a moment, looks at each of the parameters passed in the procedure call, and matches them up to the parameters in the parameter list, based on what order they come in. Then it sets a variable for each parameter, scoped to the procedure. In our example, it sets a variable articleName
to the value Aardvark
.
With the values of the variables set appropriately, TiddlyWiki will read the body of the procedure and see, in our example:
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<articleName>>
</a>
It will render this wikitext, using the value of the articleName
variable (namely, Aardvark
) as required to do so.
Once the body of the procedure has been rendered, the articleName
variable will go out of scope, TiddlyWiki will return to the rest of the tiddler after the procedure call, and rendering will continue.
Exercises
Update the wikipediaLink
procedure to output a link whose text is instead Wikipedia: {Aardvark}
(where {Aardvark}
is the parameter passed to the procedure).
Try calling a procedure that doesn't exist (say, one called notaprocedure
). What happens?
Try calling the wikipediaLink
procedure before defining it. What happens? What about if you put some arbitrary text before the procedure definition that doesn't include a call to wikipediaLink
?