We just skimmed the surface of procedures in the previous section, and you may be left with quite a few questions. Let's try to tackle some of the most important ones.
Procedures have scope
In the Variables section, we learned that after the closing </$set>
or </$let>
tag, a variable goes out of scope and is no longer available for use. So you might wonder, what's the scope of a procedure?
The answer is, generally, the procedure is available until the end of the tiddler. It's also possible to define global procedures – ones that you can use across any tiddler in your wiki. We'll discuss how to do that in Much More Than You Wanted to Know About Scopes, next chapter.
Procedures can have zero parameters
It's possible, and even common, to have a procedure with no parameters, which is just a different way of writing a variable scoped to the entire tiddler. For instance, this is equivalent to the example of the corporate disclaimer previously discussed in the Variables section:
\procedure disclaimer()
(This paragraph does not represent the formal opinion of my company.)
\end
You need to use the Really Annoying Five-Factor Authentication Process to get into the Employee Information System if it is a Tuesday, unless you have also purchased coffee (tea or pastries do not count) in the company cafeteria earlier in the day. <<disclaimer>>
You need to use the Really Annoying Five-Factor Authentication Process to get into the Employee Information System if it is a Tuesday, unless you have also purchased coffee (tea or pastries do not count) in the company cafeteria earlier in the day. (This paragraph does not represent the formal opinion of my company.)
Procedures can have multiple parameters
Let's come back to our good old wikipediaLink
procedure again. Let's say we want the user to be able to specify the text as well as the article we're linking to. Here's how we can do that:
\procedure wikipediaLink(articleName, linkText)
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<<wikipediaLink Aardvark "Wikipedia on Aardvarks">>
Note that parameters are separated by a space in the procedure call but by a comma in the procedure definition. No, this doesn't really make any sense, but a lot of programming languages do it this way too.
Also notice the use of "double quotation marks" when a parameter contains spaces.
Procedures can be called with parameters containing double quotes
A moment ago, we saw that you can include spaces in a parameter by surrounding it with double quotes. But what happens when the parameter itself contains double quotes? Uh-oh:
\procedure wikipediaLink(articleName, linkText)
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<<wikipediaLink Aardvark "What is an "aardvark"?">>
In this case, we can use tripled double quotes (colloquially called triple quotes) to mark the start and end of the parameter:
\procedure wikipediaLink(articleName, linkText)
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<<wikipediaLink Aardvark """What is an "aardvark"?""">>
This trick works elsewhere in TiddlyWiki as well, if you ever find yourself needing to quote something that contains quotes.
It's also possible to use 'single quotes' / apostrophes in place of double quotes, if you don't use any inside the parameter text. But since it's common to have apostrophes in text, while triple quotes are virtually never found inside text, triple quotes are a more generally useful tactic.
Procedures can be called with parameter names
If we don't like the order that the procedure parameters are specified in, or there are a lot of parameters and it's hard to remember what order they come in, we can list the parameters by name. If we do this, the order becomes unimportant.
\procedure wikipediaLink(articleName, linkText)
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<<wikipediaLink linkText:"Wikipedia on Aardvarks" articleName:Aardvark>>
Sometimes this is called using named parameters, in contrast to using positional parameters.
A space may optionally be added after the colon :
, but most people find it easier to read without a space.
Procedures can have optional parameters
When defining a procedure, we can specify a default value for a parameter by writing it after the parameter name and a colon. Then we only need to provide a value in the procedure call if we don't want to use the default.
\procedure wikipediaLink(articleName, linkText:"Wikipedia Link")
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<<wikipediaLink Aardvark>>
<<wikipediaLink Aardvark "Wikipedia on aardvarks">>
Again, a space may optionally be added after the colon.
Procedures can be defined on a single line
You can place short procedures whose bodies need only one line on the same line as the \procedure
pragma and omit the \end
:
\procedure disclaimer() (This paragraph does not represent the formal opinion of my company.)
<<disclaimer>>
(This paragraph does not represent the formal opinion of my company.)
Procedures can be called using a $transclude widget
In addition to the handy <<double angle bracket>>
syntax, it's possible to call a procedure using the $transclude
widget. As we discussed in the widgets section, this is a common pattern in TiddlyWiki: anything you can do with convenient wikitext syntax can also be done with HTML tags or widgets, and those forms may offer some additional options for advanced use.
Here's how we could create our aardvark link with a widget:
\procedure wikipediaLink(articleName, linkText)
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<$transclude $variable="wikipediaLink" linkText="Wikipedia on Aardvarks" articleName=Aardvark />
Notice the dollar sign in front of $variable
, which is easily missed. (It's there so that your procedure can have parameters with any names, including variable
, without conflicting.)
The $transclude widget can take variables as parameters
From the above, it was probably not immediately obvious why you would ever want to write out a procedure call the long way with a widget. Here's the main reason why: you can transclude other things into the parameters of the procedure. For instance, maybe we want to link to a few different Wikipedia pages, but use the same link name:
\procedure wikipediaLink(articleName, linkText:"Wikipedia Link")
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<$let linktext="An animal">
* <$transclude $variable="wikipediaLink" linkText=<<linktext>> articleName="Aardvark" />
* <$transclude $variable="wikipediaLink" linkText=<<linktext>> articleName="Bee" />
* <$transclude $variable="wikipediaLink" linkText=<<linktext>> articleName="Cow" />
</$let>
Exercises
Write a procedure called ticketLink
that takes one parameter, called ticketId
, and creates a link whose text is Ticket #{ID}
, where {ID}
represents the ID of the ticket, and which links to the ticket. Assume that the URL of a ticket in the company's ticket-tracking system is https://tix.example.com/ticket/{ID}
.
Test this procedure by putting it at the top of the OnboardingProcess
tiddler and calling it at the bottom of the tiddler with the ticket number 245188
.
What do you think will happen if you reverse the order of the parameters in the version of wikipediaLink
with an optional parameter, so that linkText:"Wikipedia Link"
comes before articleName
in the parameter list? Try it and see.
Try calling wikipediaLink
using the $transclude
widget with variables as parameters, but surround the variable references / procedure calls in the $transclude
widget with "quotation marks", like this:
\procedure wikipediaLink(articleName, linkText:"Wikipedia Link")
<a href=`https://en.wikipedia.org/wiki/$(articleName)$`>
<<linkText>></a>
\end
<$let
article="Aardvark"
description="An animal"
>
* <$transclude $variable="wikipediaLink" articleName="<<article>>" linkText="<<description>>" />
</$let>
What's wrong with the output now? Why do you think this happened? And is there something that's unexpectedly right?
go to answerTake the example The $transclude widget can take variables as parameters and modify it so that the $transclude
tags are unclosed (no /
before the >
). What happens? Why do you think this happened?