This is a stripped-down version of a single section of Grok TiddlyWiki, optimized for fast loading and readability by search engines. Some features are missing.

For the full Grok TiddlyWiki experience, please visit the wiki version of this page.

Exercise Browser

 8th April 2021 at 9:25am

0 / 177 exercises completed.

Find in text
Section
Show

The following table shows all exercises in this book. Click the checkbox to the left to mark an exercise as complete.

Exercise Section Length Text
Ex:AddContactTemplates Templates and the Current Tiddler (s)

Place the ContactInformationTemplate on all of the contacts in your wiki.

(You may be wondering if there's a way to avoid even the repetition of adding the reference to the template to all your tiddlers. The answer is yes, and we'll be getting there in a couple chapters.)

Ex:AllFamilyInformation Filters and Transclusions (m)

Edit the ContactInformationTemplate so that a contact's family members each get their own bullet point, nested underneath the Family bullet point, listing their name and phone number, like this:

  • Family:
    • JohnDoe: 888-555-9999
    • EmilyDoe: 888-555-1111

Tip: You'll need to use HTML for the inner bulleted list, as wikitext lists can't be interleaved successfully with $list widgets. While it's possible to make everything show up correctly while still writing the outer bulleted list in wikitext, if you're struggling with the formatting, it may be easier to switch the outer list to an HTML list as well.

As a reminder, to nest lists in HTML, put another <ul> opening tag inside an <li> tag.

Ex:AlphabeticallyLastDescription Common Filter Operators (M)

What is the alphabetically last description that any button on the editor toolbar uses? (The description is what shows up when you hover over the button, minus the indication of the keyboard shortcut. No cheating by hovering over every button!)

You'll need some additional information for this one:

  • Remember that everything's a tiddler? Buttons in TiddlyWiki's interface are tiddlers too!
  • A tiddler is part of the editor toolbar if it is tagged $:/tags/EditorToolbar.
  • You'll need to start your filter with all[shadows] to get any results.
  • Your filter expression will have more steps than any we've seen so far. Add one step to the filter expression at a time, inspecting the result to determine how you need to modify the list (what step you need to add) next. You'll eventually reach a point where you have a bunch of results that are wrapped in curly braces, like {{$:/language/Buttons/Paint/Description}}. When you get here, add the following filter steps to the end of your filter: split[{{]split[}}].

And here are two hints if you need them:

  1. How do you think we would define the description of a button in the TiddlyWiki data model?
  2. The content of a language tiddler, like $:/language/Buttons/Paint/Description, is stored in its text field.

This one is intended to be a little bit above your level at the moment – we won't get to some of the concepts involved until chapter 6, Looking Under the Hood – so you might not be able to figure it out. But spend some time working on it before you look at the answer.

Ex:BacklinksConditionalDisplay Hiding and Showing Things (m)

Using a $list widget, update your template that displays a list of links and backlinks so that the list doesn't appear if there are no links or backlinks.

Ex:BasicBacklinksList Creating a List of Links and Backlinks (m)

Create a tiddler called $:/yourname/TiddlerLinkSummary. Make this tiddler display a simple bulleted list of all backlinks of the current tiddler. (Since we will need to make this more complex momentarily, use a $list widget, not a list-links macro.) Then make this content included at the bottom of every tiddler.

Ex:BasicLinksList Creating a List of Links and Backlinks (m)

Edit $:/yourname/TiddlerLinkSummary to show a list of the forward links as well. We don't want the wikitext to get too repetitive, so create a procedure to hold the bits that are the same in both. You may find the subfilter filter operator helpful.

Ex:BasicWikitext Journal Tiddlers (m)

Edit the journal tiddler again by clicking the pencil icon in its upper-right corner, and add some boilerplate that uses the following types of formatting in the notes editor:

  • Bold, italics, and monospaced text
  • A bulleted list
  • A numbered list
  • A section heading
  • A block quote
  • A code snippet (called a “monospaced block” on the editor toolbar)

For the lists, block quotes, and code snippets, note that you need to have at least one blank line both above and below them to ensure everything displays correctly.

We'll be learning more wikitext syntax as we go through the rest of the book. You can also refer to the Wikitext Reference appendix for a listing of the syntax you're most likely to want. That said, if you don't feel comfortable with what you've seen so far, you might consider doing this exercise a second time; if you feel uncomfortable using wikitext, it will be a major drag on your ability to accomplish more complicated things in TiddlyWiki.

Ex:BulletedMeetingList Your First Dynamic List (m)

Modify the MeetingList so that instead of separating the meetings with a simple line break, they form a bulleted list.

Hint 1: Remember that HTML code for creating a bulleted list?

Hint 2: The contents of the list widget are rendered once for every tiddler output by the filter. Which parts of the HTML code for creating a list need to be used repeatedly, and which need to be used only once?

Ex:ButtonDisplayTweaks Creating Tiddlers With Predefined Fields (M)

Our buttons don't display very nicely:

  • They're absolutely gigantic on the toolbar and have text on them instead of an icon.
  • Their shape doesn't match that of the other tiddlers.
  • They don't have tooltips.
  • They don't have a description in the Tools tab of the sidebar.

Correct these issues. You'll want to refer to an existing tiddler on the toolbar to see how each of these things is done.

Tip: The fastest way to choose an icon from the set that comes with TiddlyWiki is to open the tag manager and pretend to pick an icon from the drop-down. Each icon shows its full tiddler name, so you can then use that name elsewhere.

Ex:ButtonsOnPageToolbar Creating Tiddlers With Predefined Fields (m)

Add these new buttons (created in Ex:NewContactButton and Ex:NewMeetingButton) to the toolbar above the search box in the sidebar. This will require applying a tag to their tiddlers.

Ex:BypassSecurityWithTextSubstitution Macros (m)

Suppose that the following macro is being used to validate whether the user is authorized to access something:

\define checkAuthorization(password)
<% if [[$password$]match{$:/config/SecretPasswordExample}] %>
  The user is authorized.
<% endif %>
\end

<<checkAuthorization "">>

Because of the way text substitution works, it's possible to bypass this authentication check without knowing the password (or looking in that tiddler). Figure out what you can fill in between the quotation marks in the macro call to bypass the password check, and check your answer by editing the live example above.

Ex:CamelCaseKnowledgeTiddlers Reviewing the Basics (m)

Try changing the title of one of your knowledge tiddlers to not be in CamelCase (add some spaces to it, and/or change the capitalization).

  • Notice the drop-down showing you any links that will break when you rename the tiddler.
  • Visit the tiddlers those other links were contained in and update the links to match. You'll have to use the [[square bracket syntax]] now.
  • What are some of the advantages and disadvantages of camel-case linking? If you have a TiddlyWiki use case in mind for yourself, do you think camel-case links will be a good idea there?

Note: If you rename tiddlers often, the Relink plugin can update the links automatically.

Ex:CanonicalUri Images and Attachments (m)

Select a contact you didn't add an image for above. Place an image for this contact in a folder called images next to your example TiddlyWiki, and use the _canonical_uri field on a new tiddler to reference this contact's image. Check to be sure the image is displayed on the contact tiddler as expected.

Ex:CaptionsByTag Buttons and Input Widgets (m)

Create a tiddler called CaptionsByTag. This tiddler should contain an input widget into which the user types the name of a tag. A table underneath the input widget should show all of the tiddlers with this tag along with their captions, if any. That would look something like this:

TiddlerCaption
FudgeAtTheOfficeThe Great Fudge Warning

Note: You'll have to use raw HTML tables to get this to display correctly – wikitext tables don't work if you interrupt them with a list widget. An HTML table has this basic form:

<table>
  <tr>
    <th>Header 1</th>
    <th>Header 2</th>
  </tr>
  <tr>
    <td>Cell 1</td>
    <td>Cell 2</td>
  </tr>
</table>

Header 1 Header 2
Cell 1 Cell 2

The equivalent wikitext table would be:

|!Header 1|!Header 2|
|Cell 1|Cell 2|

Header 1Header 2
Cell 1Cell 2

tr stands for table row, th for table header, and td for table data.

Ex:CarItems Project Tiddlers (M)

Suppose you have a tiddler MyCar, along with a series of tiddlers describing the items you keep in your car. Why should each item state that it belongs in your car, rather than the car listing out all of the items it contains?

Create the car tiddler in your example wiki and relate several items to it, using each of the four methods discussed in this section. What methods do you like best?

Ex:CircleMathRearrangement Functions (s)

In the circle math example, we carefully ordered the functions so that if function B calls function A, function A always comes before function B. What happens if you change the order of the functions so this isn't true? Why do you think this is?

Ex:CircularTransclusion Field Transclusions (s)

What happens if you transclude tiddler A into tiddler B, and tiddler B into tiddler A?

Ex:CloseAndReopen Journal Tiddlers (s)

Close your new journal tiddler and open it again.

Ex:ConditionalProcedure Conditional Inclusion (m)

This code snippet is quite repetitive:

<ul>
  <% if [all[current]has[email]] %>
    <li>''Email'': {{!!email}}</li>
  <% endif %>
  <% if [all[current]has[phone]] %>
    <li>''Phone'': {{!!phone}}</li>
  <% endif %>
  <% if [all[current]has[family]] %>
    <li>''Family'': {{!!family}}</li>
  <% endif %>
  <% if [all[current]has[manager]] %>
    <li>''Manager'': {{!!manager}}</li>
  <% endif %>
</ul>

Write a procedure that wraps the logic that's repeated here, and call it four times to produce the same result.

Hint: To transclude a field of the current tiddler whose name is in a variable, use the $transclude widget with the $field parameter: <$transclude $field=<<myvariable>>/>.

Ex:ConditionalProcedureContinued Conditional Inclusion (m)

The result of Ex:ConditionalProcedure is still repetitive in that it uses the same procedure call four times in a row, with only the field name changing. Can you remove even this repetition, so there is only a single procedure call?

Hint 1: What TiddlyWiki feature have we seen that renders some wikitext multiple times?

Hint 2: A type of filter expression we haven't discussed explicitly yet consists of a tiddler list (sequence of tiddler names).

Ex:ConditionalSetAt Hiding and Showing Things (m)

Repeat the previous exercise, but use a conditional $set widget. It's OK if the behavior when the at field is empty, rather than missing, differs from the previous exercise.

Ex:ConditionalStyle Stylesheets (m)

Modify the tiddler containing my-funny-class so that that class's styles apply only if the config tiddler $:/config/ShowFunnyText is set to yes.

Ex:ConflictingStatements Parameterizing Field Transclusions (m)

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!)

Ex:ConstructorAfterFilterStep Anatomy of Filter Steps (m)

What do you think happens if you run the filter [tag[Contact]title[EmployeeInformationSystem]tag[Application]]? Assume that the EmployeeInformationSystem tiddler is tagged Application but not Contact.

Check your answer by running the filter in TiddlyWiki, after ensuring that EmployeeInformationSystem is tagged appropriately.

Ex:ContactCard Miscellaneous Widgets (m)

Create a tiddler called ContactCard that displays a drop-down menu from which you can select any contact in the wiki. Underneath the drop-down menu, the selected contact is transcluded through the ContactInformationTemplate, showing the contact's details.

Ex:ContactInformationPicture Images and Attachments (M)

Edit the ContactInformationTemplate so that it tries to include a picture for each contact. If the tiddler name is, for example, JaneDoe, and there is a tiddler called JaneDoe/Picture, Jane's picture, at most 300 pixels wide, should appear at the top of the tiddler. No error should be displayed if such a picture doesn't exist (hint: a filter operator called is[tiddler] will come in handy).

Add an image for one of your contacts and confirm that everything displays as expected for contacts that have a picture and for contacts that do not.

Ex:ContactLinks Using Variables as Attributes (m)

Suppose you use a webapp to store your contacts which allows you to access them at https://mycontacts.com/contactname, where contactname is the name of their tiddler in TiddlyWiki (e.g., JaneDoe). Create a tiddler called ContactLinks that contains a bulleted list of all your contacts (sorted in alphabetical order). Each bullet should contain a link to the contact's tiddler in TiddlyWiki, and a link to the contact's page on mycontacts.com.

Use a dynamic list so new contacts are automatically added. Recall that the current item in a dynamic list is available in the currentTiddler variable.

Ex:ContactList Your First Dynamic List (m)

Create a ContactList, similar to our MeetingList, that shows all contacts in alphabetical order by their first name.

Tip: To create a new tiddler and start it with the contents of an existing tiddler, click the "more" drop-down on the existing tiddler's toolbar and choose Clone.

Ex:ContactListNoPhoneExclusion Your First Dynamic List (m)

Modify the ContactList so that contacts with no phone number are excluded.

Ex:ContactQuote Custom Widgets (m)

Write a $contact.quote widget that renders a blockquote for something somebody in your contacts said, given a body containing the quotation and a contact parameter containing the name of the contact's tiddler.

The widget should show a link to the person's tiddler, with text matching their name (taken from the caption field of the tiddler if it exists, or the title if it doesn't), then a colon, then starting on the next line a blockquote.

Tip: Use the <blockquote> HTML element, not one of the wikitext syntaxes – $slot doesn't play nice with wikitext formatting here.

Ex:ContactRadioButtonQualification Qualification (m)

Return to the radio buttons we added to the ContactInformationTemplate in Ex:FamilyRadioButton to display the contact information of a family member of the contact. As written in the answer of that exercise, it is in need of a qualify macro so that if multiple contacts are open, they can have different family members selected at once. Add this macro call. (If you wrote your version in a way that doesn't require qualification to work correctly with multiple contacts open, first modify it to store the selected contact in a temp tiddler like the book's version does.)

Ex:ContactsOnlyOnContacts The View Template (m)

Adjust the $:/yourname/TiddlerTypeTemplates/Contact component of the ViewTemplate so that the contact information template is used only on tiddlers tagged Contact.

Ex:ContactTabs Tabs (s)

Create a set of tabs to show all contacts in the wiki. Take a look through the tabs – what isn't displaying right, and what might that mean?

Ex:ContainingCurrentTiddler Templates and the Current Tiddler (m)

Suppose that in the MeetingList, we want each meeting to display not only its name, but also the name of the tiddler we're using to look at the information (or, more precisely, the current tiddler as defined by TiddlyWiki). That is, since we're viewing the output in the MeetingList tiddler, it should say MeetingList. The list might look something like this:

  • An item on MeetingList: EmployeeProfileSetupMeeting
  • An item on MeetingList: SecondMeeting

Modify your list widget to achieve this output. The output should continue to be correct if you copy and paste (or transclude) the list widget into a different tiddler – i.e., you cannot simply write MeetingList literally but must dynamically retrieve the title of the tiddler the list widget is in.

Ex:CountWidgetReplacement Miscellaneous Widgets (m)

Go to the WikiStatistics tiddler, originally created in the exercise Ex:WikiStatistics, and replace any numbers that you can with an appropriate $count widget.

Ex:CreatedNowButton Working with Dates (m)

Make a button labeled Created Now that resets the created date of the current tiddler to the current time. Place the button on a template, or simply on a test tiddler, and try resetting the created time of the tiddler.

Ex:CreateMeetingTemplate Templates and the Current Tiddler (m)

Our meetings have two fields, at and participants, which don't show up anywhere on the meeting tiddlers. Create a new template tiddler, MeetingInformationTemplate, and add a table something like the following.

| !Time|20200531013141000|
| !Participants|JaneDoe|

Time20200531013141000
ParticipantsJaneDoe

Obviously, your version should include the correct information for whichever tiddler the template is being transcluded into. Don't miss the space before the ! in Time and Participants in the wikitext, which causes the headings to be right-aligned rather than centered.

Transclude this template at the top of all your meeting tiddlers.

Ex:CreateSystemTiddler System Tiddlers (s)

Create a new system tiddler, then close it and go locate it again.

Ex:CreatingBasicFilters Using Filter Expressions (M)

Write and test filter expressions for the following criteria:

  1. All tiddlers tagged with Application.
  2. All tiddlers tagged with both Application and OnboardingProcess.
    • You'll need to add the OnboardingProcess tag to at least one application if you haven't done so already, if you want to see any results.
  3. The tiddler JaneDoe, but only if it is tagged with Application.
    • You won't get any results for this one if you write it correctly, since Jane is not an application, so afterwards you might want to try adding the tag to Jane's tiddler so you can see how it behaves then.
  4. All tiddlers that link to the tiddler EmployeeProfileSetupMeeting.
    • Hint: In addition to links[], there is a backlinks[] operator.
  5. All tiddlers that link to the tiddler EmployeeProfileSetupMeeting and are not daily-journal tiddlers.
Ex:CreatingLinkDivs Creating a List of Links and Backlinks (s)

Let's do a bit of formatting now. It probably will look better if the excerpt starts on a new line after the title, especially once we get this into two columns. An easy way to do that in HTML is to place the excerpt procedure call in a <div> tag (short for division), which is a generic way to group content together, so go ahead and do that and check that it works.

In addition, let's wrap the Links and Backlinks sections, including the titles, each in a div (you can do this within the procedure). We'll need to have them in separate divs to get them to appear in two columns.

Lastly, wrap the whole thing (both the Links and Backlinks sections) in one more div.

Aside from the excerpts appearing on separate lines from the tiddler titles, you should not see any difference in output yet – we've merely made it possible to style with CSS.

Ex:CreatingMoreFilters Common Filter Operators (m)

Compose and run filters to answer the following questions:

  1. How many tiddlers are in the wiki?
  2. How many of those are system tiddlers?
  3. What meetings contain a link to JaneDoe?
    • Hint: Work backwards.
  4. Which contact has the alphabetically earliest phone number?
  5. Which tiddlers have text in a field called at?
  6. Which tiddlers contain the words JaneDoe and help somewhere in their text field? Use only a single filter step.
Ex:CStartTiddlers Functions (m)

This snippet is supposed to show a list of all tiddlers in the wiki whose names start with C. Why do you think it doesn't show all the tiddlers? Fix it so it does.

\function tiddlers-starting-with-C() [all[shadows+tiddlers]prefix[C]]

<$list filter=<<tiddlers-starting-with-C>>>
  <$link /><br>
</$list>

Ex:CurrentTiddlerAndListWidget Templates and the Current Tiddler (m)

In the section on dynamic lists, we used the value of the variable <<currentTiddler>>, without knowing exactly what it was. Review the use of that variable in the dynamic lists section. What does this usage tell you about the interaction of the current tiddler and the $list widget?

Ex:DateFormatter Working with Dates (M)

Create a tiddler called DateFormatter that allows you to choose any non-system tiddler in the wiki and a field on that tiddler from drop-down menus, then displays the date stored in that field in at least five different formats. The formats displayed should be configurable by creating tiddlers in $:/config/DateFormatter/Formats.

If the field chosen can't be interpreted as a date, the text (not a date) should appear where the formatted date otherwise would.

Tip: The fields[] operator gets the names of the fields present on its input tiddlers.

Here's an example of what it might look like:

Ex:DefaultToField Filters and Transclusions (m)

Modify the template you created in Ex:WikipediaLinkTemplate so that if the articleName variable is not defined, the article name will instead be taken from the articlename field of the current tiddler.

Tip: The else filter operator, which adds a constant string to the pipeline if there are no input tiddlers, will be useful here. You will also need to put !is[blank] before the else operator – we'll explain why once you've completed this exercise.

Ex:DontOverrideViewTemplateTag The View Template (m)

In Ex:MoveContactInformation, we edited the list field of $:/tags/ViewTemplate, which means that we now have an overridden shadow tiddler for that tag. (You can confirm this by looking under the tag pill or in the Shadows or Explorer sidebar view – it will no longer be listed in bold.)

In this case, that's not the end of the world, since the tag contains no body text and it's relatively unlikely extra elements will be added to this list in a future version of TiddlyWiki (thus necessitating a manual merge if we want them to show up). However, suppose we want to be purists and avoid overriding a shadow tiddler unless absolutely necessary. How can we achieve the same effect without needing to override $:/tags/ViewTemplate?

Delete the overridden shadow tiddler $:/tags/ViewTemplate prior to attempting this exercise to put your $:/yourname/TiddlerTypeTemplates/ templates back in their default position, so you can tell if you've succeeded.

Ex:EditCurrentTiddler Buttons and Input Widgets (m)

The $edit-text widget can edit any field on any tiddler, so we don't have to use a temporary tiddler if we don't want to. In the example above, we could just update the userwhoclicked field directly as the user types.

Look up the documentation for the $edit-text widget to learn how to select which field the widget should edit, then change the example to behave accordingly.

Ex:EditTemplateInformation The View Template (m)

Add the tiddlers under $:/yourname/TiddlerTypeTemplates/ to the edit template as well. What do you notice about where they appear? Does it make sense to have them here?

Ex:EisLet Variables (s)

Change the EmployeeInformationSystem tiddler from using two $set widgets to using one $let widget. Make sure all references still show up correctly.

Ex:EisVariable Variables (s)

In the EmployeeInformationSystem tiddler, define a second variable called eis with the value Employee Information System, and replace all references to the EIS or Employee Information System with the value of the eis variable. Make sure the disclaimer still shows up correctly.

Ex:EmptyAtField Hiding and Showing Things (m)

Update the MeetingInformationTemplate to use a fallback to display the text (no time specified) if there is no at field on the tiddler.

Ex:EmptyProcedureCall Procedures (s)

Try calling a procedure that doesn't exist (say, one called notaprocedure). What happens?

Ex:EqualsPrefixNeeded Overriding Built-In Widgets (s)

Why did we need to use the = (also called :all) filter prefix in the previous exercise?

Ex:ExcerptConfigurationTiddler Creating a List of Links and Backlinks (m)

Make the size of the excerpt configurable via a configuration tiddler. Call the configuration tiddler $:/config/LinkExcerptLength.

Ex:ExploreSystemTiddlers System Tiddlers (m)

Take a few minutes to poke around in the Explorer section of the More sidebar tab and look into a few system tiddlers to see how they're organized. You can safely edit a system tiddler to look at its wikitext if you like, notwithstanding the scary warning about editing a shadow tiddler; just be sure to click the X button to discard changes when you're done.

Ex:ExtractFunctions Functions (m)

Return to the alphabetically last description exercise:

{{{ [all[shadows]tag[$:/tags/EditorToolbar]get[description]split[{{]split[}}]get[text]!sort[]first[]] }}}

Extract one or more functions from this filter to make it easier to understand. That is, group some of the filter steps by the task they accomplish and create a function with a name that clearly describes what those steps do, and change the filter to call that function instead of using the steps directly.

Ex:FamilyRadioButton Miscellaneous Widgets (m)

Add a series of radio buttons on the ContactInformationTemplate that allow you to view some information about each family member of the current tiddler.

Ex:FilteredTelephoneLink Macros (m)

Repeat the telephone link exercise, but this time use a filter rather than backtick substitution or a macro to combine the tel: part and the phone number. You may need to visit the TiddlyWiki documentation to find an appropriate filter operator.

Ex:FixingContactTabs Tabs (m)

Fix the issue identified in the previous exercise, Ex:ContactTabs, so that all contacts display all information correctly.

Hint 1: You'll need to create a template tiddler. You can specify the name of a template used to render each tab using the template parameter to the tabs procedure.

Hint 2: The currentTab variable contains the name of the tiddler being rendered as the current tab.

If you get really stuck, read the TiddlyWiki documentation on the tabs procedure, which explains how to do this. Try to figure it out yourself for a few minutes first, though!

Ex:FriendlyViewsNames Adding to the Sidebar (m)

By default, all of the tabs will have ugly system-tiddler names on them, like $:/yourname/Views. Fix this so they have friendly names like we defined at the beginning of this section.

Ex:FudgeAdviceReflection Creating Hierarchies with a Table of Contents (m)

Revisit the tiddler you created in the previous exercise.

  • Logically, is it a child of that meeting? Or is it a separate idea that just happened to occur during that meeting?
  • Would it be better to use a different kind of relationship, like a link?
  • Think about the title you chose: does it serve as metacommentary on the idea?
Ex:FudgeAdviceTiddler Creating Hierarchies with a Table of Contents (s)

Suppose that, during our meeting, Jane gave us some advice about the company that probably shouldn't stray. We might want to put that in a separate tiddler to reduce the chance we accidentally copy and paste it over to someone else who asks what happened at the meeting.

Create such a tiddler with the following text, and make it a child of the EmployeeProfileSetupMeeting, so we'll still be able to keep track of it:

JaneDoe told me, while we were together at the EmployeeProfileSetupMeeting, that I should be very careful about saying the word "fudge" in this office, due to an incident involving Robert at the 2018 Christmas party that nobody wants to talk about.

Check the OnboardingProcess table of contents again. Did you get a third level of hierarchy?

Ex:FudgeTiddlerRevisited Creating Evergreen Notes (s)

If you didn't do it while reading, go back to the fudge tiddler and give it appropriate tags and links. You can link to some nonexistent tiddlers if you like.

Ex:FudgeTransclusion Field Transclusions (s)

Our initial motivation for extracting the now-infamous fudge tiddler from the EmployeeProfileSetupMeeting tiddler was so that we wouldn't accidentally share that information with somebody. Suppose that everyone else at the company also uses TiddlyWiki, so we always share our notes as raw wikitext instead of rendered/formatted output so recipients can paste it directly into their own wikis. In this case, we can rely on transclusion to protect us provided that the fudge tiddler's title isn't too revealing: if we copy the whole tiddler without noticing this inclusion, the recipient won't get the transcluded tiddler and thus won't see our embarrassing notes.

All this is to say, transclude the fudge tiddler into the EmployeeProfileSetupMeeting tiddler. What are the advantages and disadvantages of doing it this way as opposed to linking or tagging?

Ex:FudgeWithoutJane Multi-Run Filters (s)

Write a filter to find all tiddlers mentioning fudge that don't list Jane as a participant. Use two filter runs.

Ex:FunnyClass Stylesheets (s)

Add my-funny-class from above (or any styling you like, as long as it is distinctive) to a global stylesheet in your wiki and apply the class to some text.

Ex:FunnyTextCheckbox Stylesheets (m)

Add a checkbox to the control panel on a new subtab within the Settings tab called Styles, allowing this value to be toggled on and off, so the user can make text look funny only if they so desire.

Ex:GoogleLink HTML (m)

In a new tiddler in your wiki, create a link to Google using HTML, with Google as the link text. The element used to create links is <a>; the href attribute contains the URL of the link, and the content is the text of the link.

Ex:HolidayToday Data Tiddlers (m)

Create a tiddler called TodaysHoliday which says It's ''The Day'' today!, where The Day is the name of the holiday that is occurring today, according to the data tiddler. Unless you happen to be doing this exercise on one of the four holidays listed above, you'll need to make up and add your own holiday with today's date so you can check the result.

You may need to look at the documentation for the now procedure to figure out how to get today's date in the month/day format.

Ex:HostingOptions Supplemental Exercises (m)

Try out another option for hosting and saving your TiddlyWiki.

Ex:IdentifyingRecentEvergreenNotes Creating Evergreen Notes (m)

Find some notes you've recently taken, in any format, and review them to see if there are any ideas that would be well served by being developed as evergreen notes. These might be part of a journal, annotations you made in a book, ideas for a project, or scribbles about a lecture you attended. Write down what contexts these ideas would belong in and what other ideas they would be related to.

Ex:ImageHtml HTML (s)

What HTML element is used to insert an image? You may wish to search the web to find the answer.

Ex:ImportScopes Much More Than You Wanted to Know About Scopes (s)

Rather than nesting scopes, why not just place the local procedures in a separate tiddler and use the \import pragma to access them?

Ex:InputExistsText Buttons and Input Widgets (m)

Add a little bit of text to the right of the Go button in Ex:JumpToTiddler that displays "Exists!" in green if the tiddler name currently entered into the input field exists, and "Not found." in red if it doesn't. This text should immediately update as you type.

Hint: To quickly change the color of some text, you can wrap it with a span, like <span style="color:blue;">the text</span>.

Ex:InspectSquare When Things Go Wrong (m)

Using your browser's element inspector, determine:

  1. What the class attribute of the blue square below is.
  2. What the hidden message in this exercise says.

 Help, I'm trapped in an HTML span!

Ex:JaneDataTransclusion Field Transclusions (m)

One of the complaints we had about our Contact Tiddlers when we initially created them was that you couldn't see any of the fields on them without clicking on the info button. Remedy that by adding a section to the JaneDoe tiddler titled Information about Jane, containing a bulleted list or table that shows Jane's email address, phone number, family members, and manager.

Ex:JaneDoeFamily Reviewing the Basics (m)

Visit Jane Doe's tiddler and review the family and manager fields. These fields refer to several people who don't have tiddlers yet. Create those tiddlers, with all the appropriate metadata.

You can assume that John Doe and Emily Doe are also managed by Chris Smith (though managing three family members unrelated to you sounds like a disaster waiting to happen). Your choice of phone numbers and email addresses does not matter, provided they are in the correct formats.

Ex:JaneManagerPhone Field Transclusions (M)

Transclude a line into the text of Jane's tiddler that contains Chris Smith's phone number, in case she messes up so badly that you need to contact her manager immediately.

Can you make it so that it currently refers to Chris's phone number, but if the manager field is updated, the new manager's phone number will appear instead, without having to change the transclusion?

Ex:JaneMeetingList Your First Dynamic List (m)

Modify the MeetingList so that only meetings that Jane attended are shown. Be careful not to exclude meetings that Jane attended along with other people.

Ex:JaneMeetingMultirun Multi-Run Filters (s)

Write a filter to find all meetings that are part of the OnboardingHr project or the TopSecretHr project and were attended by Jane.

Ex:JohnDoeInAnyField Common Filter Operators (m)

In an exercise in the Searching section, we noted that a search for JohnDoe did not find places where John was mentioned somewhere other than the text field. Write and test a filter that finds mentions of John in any field.

Ex:JohnDoeSearch Searching (m)

Search for JohnDoe. Do you notice anything about the results? What's there, and what's missing?

Ex:JsonHoliday Data Tiddlers (s)

Create another data tiddler called UsHolidaysJson using the same data in a JSON format, and change your TodaysHoliday tiddler to look the holiday up in there instead. Everything should continue to work the same way on the transclusion side. The table looks like this in JSON:

{
  "01/01": "New Year's Day",
  "07/04": "Independence Day",
  "10/31": "Halloween",
  "12/25": "Christmas Day"
}
Ex:JumpToTiddler Buttons and Input Widgets (m)

Create a tiddler JumpToTiddler that has an input field and a Go button. When the button is clicked, the tiddler named in the input field should open.

Hint: One of the attributes of the button widget we didn't discuss here will help.

Ex:LinkDivClasses Creating a List of Links and Backlinks (m)

One more step with the divs. In order to get them formatted correctly, we need to be able to identify each of them separately. The way we do this in HTML/CSS is by applying a class (that is, assigning a value to the class attribute of the HTML tag). Adjust the wikitext so that each div has a class. It's a good idea to prefix your class names (in CSS class names, the prefix is normally separated from the rest of the name by a hyphen -), as CSS classes apply globally. I'll prefix these with sib-links-.

Again, you won't see any changes in output yet.

Ex:LinkedTiddlerExcerpt Creating a List of Links and Backlinks (m)

Add an excerpt for each link – in other words, grab the first 200 characters of each tiddler and show it under the title. This will help us remind us what the tiddler is about, if the title wasn't chosen carefully enough.

We can accomplish this by wikifying the tiddler – that is, processing the HTML, transclusions, and wikitext in it as if we were displaying the tiddler – and then taking just the beginning portion of it. Here's a partially completed procedure you can use to get an excerpt from a tiddler. Your task is to figure out what goes in the filtered transclusions (to get the wikitext of the tiddler and convert the rendered wikitext to just its first 200 characters), then call the procedure from an appropriate location.

\procedure excerptify(title)
  <$wikify name="contents" text={{{ ... }}}>
    <$text text={{{ ... }}} />...
  </$wikify>
\end

Hint: The split[] filter operator with nothing in the square brackets can be used to split incoming text into individual characters. You may need to review the filter operators documentation.

Ex:LinkingInTransclusions Field Transclusions (s)

In general, if we reference ChrisSmith in the manager field of the JaneDoe tiddler, Jane does not show up as a backlink in ChrisSmith's Backlinks tab on the info page, because Backlinks shows only links in the text field. However, now we have a link in the text since we have transcluded the value of the manager field into the text. So now that we have a link, we should have a reference back to JaneDoe from ChrisSmith.

Test this hypothesis by looking in the Backlinks tab of ChrisSmith. What did you find? Why might this be?

Ex:LinkPattern Your First Dynamic List (m)

There's a problem with this pattern that we've been using throughout this section to create a list of links to tiddlers:

<$list filter="a filter">
  <<currentTiddler>>
</$list>

The problem is that if the name of the currentTiddler has a space in it, it is not linked. The only reason the results have displayed correctly so far is that they're in CamelCase and as such are linked automatically.

To explicitly create internal links, as we alluded to back in Widgets, we can use the $link widget:

<$link to="Tiddler Name to Link To">Text of the Link</$link>

Add a space to the title of one of your meeting tiddlers, so you can see the problem, then modify the MeetingList you created in Ex:BulletedMeetingList, using the $link widget to fix this problem.

Hint: <<currentTiddler>> will get replaced in more places than you might think.

Ex:LinkTooltipNonReplace Overriding Built-In Widgets (m)

Having overridden the definition of the $link widget above, if we explicitly supply a tooltip attribute on some $link widget, it's now silently replaced with the description one we added. Change the behavior so that the description tooltip is only applied if one isn't already provided for the widget.

Ex:LocalCallFunctions Functions (M)

In the local calls exercise, we created template logic to display whether a contact's phone number was local. Write three functions to determine the type of a number, according to the definitions used in that exercise:

  • phone.toll-free[number]
  • phone.local[number]
  • phone.long-distance[number]

Each function should take a phone number (not just an area code) as its parameter, and return that parameter unmodified as its output if the area code is in that class, and yield no output if it is not.

Modify the template to use these functions.

Tip 1: In the previous answer to the exercise, we did this to check if an area code was in the list of toll-free area codes:

[enlist{TollFreeAreaCodes}match<areaCode>]

That won't work anymore because the area code will need to be coming in the pipeline as an input tiddler, rather than being in a variable. You can't simply invert them, like [<areaCode>enlist{TollFreeAreaCodes}], because enlist is a constructor and will just wipe out the area code. Instead, use a filter run with the :intersection prefix:

[...get-the-area-code-somehow] :intersection[enlist{TollFreeAreaCodes}]

:intersection causes TiddlyWiki to evaluate both filter runs separately, then compare them and keep only the values that are in both.

Tip 2: In order to pass the parameter through unmodified without converting it to just the area code, you'll need to do most of the work in a run with the :filter prefix. When a run has this prefix, TiddlyWiki will evaluate that filter once for each output tiddler of the preceding run, and keep only the tiddlers for which the new run returns any value. The value actually returned by the run is thrown away – it only matters whether there is one or not.

Because the pattern in Hint 1 requires two filter runs, and you can't directly nest multiple filter runs within another filter run, you'll actually need to use a function to combine those two runs, and call that function in the run with the prefixed :filter.

Here's a complete example, for a function phone.outside-line-or-operator, that shows the pattern you'll want to use:

\procedure outside-line-starts() [[9]] [[0]]
\function is-outside-line-or-operator() [split[]first[]] :intersection[enlist<outside-line-starts>]
\function phone.outside-line-or-operator(number) [<number>] :filter[function[is-outside-line-or-operator]]

Will dialing these numbers give you an outside line or an operator (number begins with a 9 or a 0, respectively)?

* Yes: {{{ [phone.outside-line-or-operator[92223334444]] }}}
* No: {{{ [phone.outside-line-or-operator[2223334444]] }}}

Will dialing these numbers give you an outside line or an operator (number begins with a 9 or a 0, respectively)?

Ex:LocalCalls Conditional Inclusion (m)

You can add multiple clauses to a single conditional expression using <% elseif %>. First there must always be an <% if FILTER %>, then there can be zero or more <% elseif FILTER %>s, and finally there can optionally be an <% else %> clause. The first clause whose filter returns a result is used.

Suppose that you're in the 212 area code, and your office still uses landline phones. Within the ContactInformationTemplate, after the contact information list, show whether a call to this person will be local, long-distance, or toll-free, depending on their phone number.

You may assume that the area code is the first three characters of the phone field. Use the filter steps split[]first[3]join[] (turn each character in the input into a single tiddler name, then discard all but the first three, then join all the tiddler names into a single tiddler name) to select the first three characters of a single input tiddler.

Consider a number to be local if it's in the current area code, and to be toll-free if its area code is 800, 888, or 877. All other numbers are long-distance.

Store both the current area code and the list of toll-free area codes in tiddlers, called CurrentAreaCode and TollFreeAreaCodes, respectively, so that you can easily change these values in the future if necessary.

Ex:LogWidget When Things Go Wrong (s)

If you haven't done so yet, try pasting the example $log widget shown above into somewhere in your sample wiki and find the output in the console. You can add multiple attributes to the widget, with any names you want, to log multiple things – try doing this as well.

Ex:LookAtBrowseOptions Browsing Your Tiddlers (m)

If you haven't already done so, take a look at each of the tabs discussed above in your sample wiki.

Ex:MailMerge Supplemental Exercises (h)

Implement a mail merge in TiddlyWiki. Without writing JavaScript, you cannot actually send emails from TiddlyWiki, but you can produce a list of mailto: links that, when clicked, each open a new email in your email program with the email address, subject, and body for that recipient pre-filled. For low-volume tasks, this might be good enough.

On the tiddler that implements the merge, you should be able to fill in fields that provide a filter for contact tiddlers you want to send the message to, and some kind of template tiddler that uses a variable or a setting of the current tiddler to substitute in values that change.

You'll need to URL-encode the subject and body and put it into the link, which TiddlyWiki has a encodeuri[] filter operator to do. See https://en.wikipedia.org/wiki/Mailto for details of the mailto: URI structure; essentially, you want to produce links that look like this:

mailto:whoever@example.com?subject=TheSubject&body=TheBodyOfTheEmail

…where both TheSubject and TheBodyOfTheEmail are URL-encoded.

Hint: You will need the $wikify widget.

Ex:MainSearchBoxBinding Buttons and Input Widgets (m)

Figure out what tiddler and field the main search box in the sidebar is bound to.

Ex:MakeGlobalProcedures Much More Than You Wanted to Know About Scopes (m)

Find the wikipediaLink and ticketLink procedures we created in The Finer Points of Procedures and turn them into global procedures, creating one or more tiddlers to house them.

Remove the original procedure definitions from the individual tiddlers and try calling the procedures from a few different tiddlers to make sure it works.

Ex:ManagerField Reviewing the Basics (s)

We chose to use a field to keep track of employees' managers. List at least two other ways we could have chosen to do this, and some advantages and disadvantages of each.

Ex:MeaninglessSuffix Anatomy of Filter Steps (m)

What happens if you add a suffix that doesn't have any meaning to a filter operator, such as tag or title?

Ex:MeetingInformation The View Template (s)

Put the MeetingInformationTemplate on meetings globally as well.

Ex:MeetingListWithoutCurrentTiddler Templates and the Current Tiddler (s)

Modify the MeetingList so that it does not use the variable reference <<currentTiddler>> but has identical functionality.

Hint: Try transcluding a field.

Ex:MeetingOrdering Ordering Tiddlers (m)

Create several more meeting tiddlers under the OnboardingHr tag, then try dragging and dropping them around using the tag pill list. Have the OnboardingProcess tiddler open as you do so, so you can see the effects on the table of contents.

Ex:MeetingOrderingByProcedure Ordering Tiddlers (m)

Repeat the previous exercise using a list-links-draggable reference of the form described in this section, inserted within the OnboardingHr tiddler.

Ex:MeetingsToday Tabs (M)

Create a tiddler named Today and put a set of vertically arranged tabs on it showing all meetings that are happening on the current day (i.e., whose at field describes any time today) and excluding drafts.

Don't worry if everything doesn't show up right – we'll talk about why that is and how to fix it in the exercises to follow. You're done with this exercise if you can get the correct set of tabs to appear in the list.

  • You can get today's date with the built-in now procedure, like <<now YYYY0MM0DD0hh>>. (If you're wondering why we include the hours, we'll discuss the potential for day rollover when at negative UTC offsets in Working with Dates.)
  • You'll need to look up several new filter operators in the list.
Ex:MethodsOfTransclusion Templates and the Current Tiddler (m)

Create a new tiddler called JaneTransclusion. Transclude the content of the JaneDoe tiddler here – but without writing the text {{JaneDoe}} anywhere in the tiddler. Once you do this successfully, find at least one other way to do it. (The answer will show you seven ways that use only tools we've already seen, so there is no shortage of options.)

Tip: If the information about Jane ends up all in one line, try adding some blank lines to your wikitext.

Ex:MoreSidebarTabs Supplemental Exercises (M)

Come up with some new sections that would be useful to have on the More sidebar tab and add them in.

Ex:MoveContactInformation The View Template (m)

Move the contact information above the rest of the tiddler's body, rather than below it.

Ex:MultipleTransclusion Field Transclusions (s)

What happens if you transclude a tiddler that contains transclusions?

Ex:MultiplyByTwoTwoWays Functions (m)

We saw two different ways to create a function that multiplies its input by two, depending on whether we wanted to take the multiplicand as an input tiddler or as a parameter:

\function multiply-by-two(number) [<number>multiply[2]]
\function multiply-input-by-two [multiply[2]]

<<multiply-by-two 4>>
{{{ [[4]function[multiply-input-by-two]] }}}

Create a multiply-anything-by-two function that works in either of these roles. That is:

\function multiply-anything-by-two(??) ??

* {{{ [[4]function[multiply-anything-by-two]] }}} should equal 8.
* {{{ [function[multiply-anything-by-two],[4]] }}} should equal 8.

  • ?? should equal 8.
  • ?? should equal 8.
Ex:NamingConventionImagination Naming Conventions (m)

Identify a wiki you could imagine yourself creating, then write a set of naming conventions for it. These should include:

  • How exactly titles should be capitalized, including how acronyms and other weirdnesses will be handled.
  • Whether you use CamelCase titles, and if so, what you do if there's only one word or it otherwise doesn't match the capitalization rules required to create a link.
  • Any special rules that seem appropriate (e.g., names of sources end with their publication date or the word Source).

You can refer to the naming conventions for my Mosaic Muse notes system for an example.

Ex:NamingOldNotes Tiddler Titles (m)

Dig up some old notes you've written for yourself, in any format, and identify:

  • How you would divide them into tiddlers (we'll talk more about this later, but you know enough to take a crack at it now).
  • What you would title each of those tiddlers.
Ex:NestedSets Variables (s)

Consider the following code:

<$set name="variable" value="1">
    <<variable>>
    <$set name="variable" value="2">
        <<variable>>
    </$set>
    <<variable>>
</$set>

What do you think happens at each transclusion of <<variable>>? Check your answers by pasting this into a new tiddler.

Ex:NewContactButton Creating Tiddlers With Predefined Fields (s)

Create a button that creates a new contact. The created tiddler should contain the four fields we've been using, email, family, manager, and phone, but empty ready for the user to fill in; it should also have a title of New Contact and be tagged with Contact.

Ex:NewMeetingButton Creating Tiddlers With Predefined Fields (m)

Create a similar button for a new meeting. The at field should be populated with the current time in the standard TiddlyWiki date/time format, down to the minute (i.e., the seconds and milliseconds should be zero).

Ex:NewWiki Supplemental Exercises (h)

Create and customize a new wiki for some purpose, whether it's useful for you or not. Some ideas that might get you thinking about different ways to organize data:

  • A mini-encyclopedia for a topic you know a lot about.
  • A recipe book.
  • A place to plan a book or other large creative project.
  • A catalog for your music or book collection.
Ex:NonexistentTiddlerFilter Anatomy of Filter Steps (m)

What do you think happens if you use the title constructor to add a tiddler that does not exist to the pipeline?

Check your answer by running a filter in TiddlyWiki.

Ex:NowTimestampFunction Working with Dates (m)

Why did I use a function, rather than a procedure or macro, to define now-timestamp here? Feel free to play with this live example if that helps.

\function now-timestamp() [<now [UTC]YYYY0MM0DD0hh0mm0ssXXX>]

<<now-timestamp>>

20241019235626834

Hint: What happens if you try to use the value of the <<variable transclusion>> to set something, as you often will with such a snippet, rather than rendering it within the body of the tiddler?

Ex:OnboardingPeopleFirst Ordering Tiddlers (s)

Use the list-before field to make the OnboardingPeople tiddler appear first in the table of contents you created within the OnboardingProcess tiddler in the previous section.

Ex:PaletteInvestigation Creating a List of Links and Backlinks (m)

In the stylesheet I provided, you may have noticed there is a macro call: <<colour muted-foreground>>. This macro is used to retrieve a color from the palette. The benefit is that if you change the palette of your wiki, the color of the excerpt text will change to something appropriate as well.

Find the definition of the colour macro and figure out how the CSS color value (it'll be a # and six numbers and letters) is retrieved.

Ex:ParameterizedCit Parameterizing Field Transclusions (m)

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>
Ex:PreserveSecurityWithTextSubstitution Macros (s)

Change the filter in Ex:BypassSecurityWithTextSubstitution so that it is not vulnerable to this kind of manipulation. Continue using a macro – don't convert it to a procedure. (Of course, the user could still just edit the tiddler and remove the authentication altogether. TiddlyWiki is not a suitable environment when users need to have limited access.)

Ex:PrettyWikipediaLink Procedures (s)

Update the wikipediaLink procedure to output a link whose text is instead Wikipedia: {Aardvark} (where {Aardvark} is the parameter passed to the procedure).

Ex:ProblematicTiddlerNames Naming Conventions (m)

Explain what is potentially problematic about each of these tiddler names:

  1. Company Entry Doors
  2. Windows
  3. Tiddlywiki
  4. VisitingTheDMV
  5. Onboarding: Office chair selection

None of these are necessarily wrong – although they might be depending on your naming conventions – but they each exhibit a possible danger we discussed above.

Ex:ProcedureAdjacency Using Variables as Attributes (s)

What if we don't want to have any text at all except for the URL itself in our Wikipedia link? Try setting a variable wikipedia to https://en.wikipedia.org/wiki/ and placing a reference to the variable immediately next to the word Aardvark. What happens? Why do you think this happens?

Ex:ProcedurePosition Procedures (m)

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?

Ex:QualifyMultipleCalls Qualification (s)

What happens if you remove the $let widget and the stateTiddlerName variable from the above example and call qualify once every time that the name of the tiddler is needed?

Ex:QuotedProcedureCall The Finer Points of Procedures (m)

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?

Ex:RaffapKnowledgeTiddler Reviewing the Basics (s)

Return to the Employee Information System tiddler and create a new knowledge tiddler for the Really Annoying Five-Factor Authentication Process. Use your imagination on what's involved!

Ex:RaffapReflection Reviewing the Basics (m)

Review what you wrote about the RAFFAP.

  • Did you write about anything or anyone you already have a tiddler for, and thus should link to?
  • Are there any new concepts that should have their own tiddlers (or at least missing links)?
  • Are there other contexts you would expect to want to retrieve the RAFFAP in which would suggest you should add certain tags to it?

Update what you wrote accordingly.

Ex:ReadingDefaultGlobals Much More Than You Wanted to Know About Scopes (m)

Search for all tiddlers that currently contain globals. Remember that most of these will be stored in shadow tiddlers, so you'll need to say you want to filter on shadow tiddlers to get any results. Also remember to search for both the old tag and the new tag (most items will still have the old tag).

Spend a few minutes browsing through some of the tiddlers that come up and looking at some of the system global definitions. You'll recognize some of the procedures/macros from previous chapters, and you should be able to understand a good portion of what's going on. There's no magic – the built-in procedures are simply wrapping up some complicated HTML and widgets for us to use in a convenient way, just like we would do when writing our own procedures.

You'll have to edit each shadow tiddler to look at the definitions. Just click the discard-changes button when you're done so you don't mess anything up!

Ex:RecastProceduresAsMacros Macros (m)

Go back to several of the procedures you have written for previous exercises and create macro versions that use text substitution, similar to how we created wikipediaLinkMacro in this section.

Tip: Try searching for the word procedure to find tiddlers that contain procedure definitions.

Ex:RedATags Multi-Run Filters (m)

Write a filter to find all tiddlers that do not link to a tiddler that has a tag which is both red and begins with the letter C, sorted by title in reverse alphabetical order.

Consider a “red” tag to be one with a color code of #ff0000, as in Classifying Tags.

English is terrible at expressing complicated conditions like this, so to be sure you read it right, here's the sentence decomposed hierarchically and written more precisely:

  • All tiddlers matching these criteria:
    • The tiddler does not link to:
      • Another tiddler:
        • That has a tag:
          • Which is red (#ff0000)
          • The name of which begins with a capital letter C
  • Sorted by title in reverse alphabetical order.

Tip 1: The prefix operator returns items from its input whose title begins with a given string of text.

Tip 2: The is[] filter step will find all (non-shadow) tiddlers in the wiki.

A quick way to test your answer is to add a link from a tiddler that appears in the output to any contact; the tiddler should disappear from the list since it's now linking to a tiddler that has a red tag whose name begins with C.

Ex:RedTagsFilter Classifying Tags (m)

Write a filter to find all tiddlers tagged with red tags. Make sure you figure out Ex:TagMetadataStorage first, or you won't have much luck.

Hint: Review the Tags section of Common Filter Operators.

Ex:ReversedOptionalParameters The Finer Points of Procedures (s)

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.

Ex:RoundtimeMacro JavaScript Macros (M)

Create a JavaScript macro called roundtime that rounds a TiddlyWiki-formatted timestamp to the nearest 15 minutes.

Ex:RubberDucking When Things Go Wrong (m)

Locate a rubber duck or another appropriate object you can explain your TiddlyWiki problems to, and find the problem(s) with the following filter snippet by explaining to your chosen listener what it's doing. Check your answer by fixing the problem.

The goal of this filter is to display, in alphabetical order, the summaries of all tiddlers in this chapter, which are stored in their description fields.

<$list filter="[all[tiddlers+shadows]tag[Section]field;parent[Filtering and Formatting]sort[]get[description]">
  <<currentTiddler>><br>
</$list>

Filter error: Missing [ in filter expression

Ex:SampleExercise How to Use This Book (s)

Search the web to find the name of TiddlyWiki's original developer.

Ex:SaveOptionalParameters Overriding Built-In Widgets (m)

The $link widget has many optional parameters besides to and tooltip: as of the current version, aria-label, tabindex, draggable, tag, class, overrideClass, and any number of CSS data attributes and properties. Right now, we are ignoring these, possibly causing undesired effects. For instance, the following link should be rendered like an external link, but fails to do so:

<$link to="Tiddlers" class="tc-tiddlylink-external">
  Tiddlers (fake external)
</$link>

To prevent such lost parameters, we need to pass all the parameters we aren't explicitly changing through to the original $link widget. We can combine two features to achieve this: (1) the $names and $values parameters of $genesis, which let you set an arbitrary number of parameters by providing two filters that evaluate to a list of parameter names and a list of corresponding values, and (2) the $params parameter to a widget (or function or procedure), which provides a JSON-formatted collection of all the parameters passed to the widget, even those that weren't specified in the parameters list.

You'll need to know several new things to complete this task:

(1) The $parameters widget, which is a more verbose way of specifying the parameters of something to be transcluded (including a widget), is needed to use the $params attribute – we can't specify $params directly in the (parameter list) of the \widget pragma. The value of the $params attribute is the name of a variable into which the parameters are placed. Here's the syntax:

\widget $link(to, tooltip)
  <$parameters $params="params-var">
    ...here <<params-var>> is JSON containing all the params, and <<to>> and <<tooltip>> contain the values of those specific parameters
  </$parameters>
\end

(2) To get the base lists of parameter names and values, use the following functions:

\function .rest-names() [<params-var>jsonindexes[]]
\function .rest-values() [.rest-names[]] :map[<params-var>jsonget<currentTiddler>]

(3) When you call the $genesis widget, you're supposed to be able to override any values in the $names and $values lists by additionally supplying that parameter (so that we could add a new tooltip parameter here, and that one would be used), but due to a bug in TiddlyWiki, this doesn't currently work. Instead, override parameters directly within the $names and $values lists by using new filter runs at the end with the = prefix, something like this:

$names="[[...blablabla]] =[[tooltip]]"
$values="[[...blablabla]] =[[tooltipvalue]]"
Ex:SearchExploration Searching (s)

Try searching for a few more tiddlers you've created, both with keywords found in the title and keywords found in the body text.

Ex:SearchingInTransclusions Field Transclusions (s)

In an exercise in the previous chapter, we observed that tiddlers referenced in fields did not appear in search. Now, however, in Ex:JaneDataTransclusion, we transcluded the manager field directly into the JaneDoe tiddler. Try searching for some of the text in that field again (e.g., ChrisSmith). Has anything changed?

Ex:SelectiveButtonDisplay Creating Tiddlers With Predefined Fields (m)

You may have noticed, as you completed the above exercise, that the list of items that have the page controls tag is quite a lot longer than the buttons that currently appear on the toolbar. Explore your wiki to figure out how the buttons are selectively shown or hidden.

Ex:SelfTransclusion Field Transclusions (s)

What happens if you transclude a tiddler into itself?

Ex:SetLetReplacement Miscellaneous Widgets (m)

Locate several places in your sample wiki where you have used $set widgets and replace them with equivalent $let widgets.

Ex:SidebarCurrentTiddler Adding to the Sidebar (s)

You might be tempted to use [tag<currentTiddler>] within the tabs macro call on the $:/yourname/Views tiddler, so that if you ever change the name of the tiddler you don't have to remember to update the filter. Try this. What happens? Why do you think this happened?

Ex:Slicing Slicing Up Content (M)

Locate some old notes you've taken, or simply consider a topic or problem you've been thinking about recently. What are the important nouns in this topic? How would you divide it into tiddlers, what fields would they have, and how would they relate to each other? You can stub out a few tiddlers in your sample wiki, or simply sketch an outline of the tiddlers on a sheet of paper.

Ex:SlicingInGtw Slicing Up Content (m)

Edit a few sections and tiddlers in the Grok TiddlyWiki wiki to get a feel for how it's divided into tiddlers and what fields are present on these tiddlers. Tiddlers are transcluded into other tiddlers using a syntax involving {{double curly braces}}; don't worry if you see things in the source that don't make sense yet.

Ex:SpacedVariable Variables (s)

What happens if you put a space in a variable name?

Ex:StretchText Supplemental Exercises (h)

StretchText, generally attributed to Ted Nelson, is a form of hypertext in which links, or summary snippets, can be expanded in place: in other words, you can “stretch” parts of the text that you want to see in more detail to zoom in on them. Implement stretch-text in TiddlyWiki using a template or procedure that allows you to expand and contract a tiddler serving as the “next level down”.

You can find an example and a TiddlyWiki implementation as the TiddlyStretch plugin in my list of cynical laws.

Ex:StylesheetExperiments Supplemental Exercises (M)

If you know a little bit of CSS, read about Stylesheets in TiddlyWiki and make some design changes to your wiki, like changing the text color or the shape of some buttons.

Ex:TagColorGrouping Supplemental Exercises (m)

Modify the display of tags in the Tags section of the More sidebar tab so that they are grouped by color.

Ex:TagColoring Classifying Tags (s)

Set the tags corresponding to tiddler types (Contact, Journal, Meeting, and Project) to solid red (#ff0000) and give them a tag icon ($:/core/images/tag-button).

Ex:TagMetadataStorage Classifying Tags (s)

How do you think the color and icon of tags are stored?

Ex:TagStyleRule Stylesheets (m)

Create a rule in a global stylesheet that makes some class of tiddlers (perhaps a couple of specific titles, or tiddlers with a particular tag) display in a smaller font.

Ex:TelephoneLink Macros (m)

Suppose we want to create a link for a contact which, when clicked on a smartphone, calls the contact. This can be accomplished with a link to a URL like tel:888-555-1234. Create such a link and add it to the ContactInformationTemplate.

Use text substitution in a macro to build the link – do not use backticks or filters.

Tip: If you want to use a [[double square brackets]] link rather than an a HTML element, you need to use ext, like this:

[ext[tel:888-555-1234]]

That's because tel:888-555-1234 by itself would be a valid name for a tiddler, too, so if TiddlyWiki isn't told it's an external link, it will assume it's an internal one. See the External Links heading here in the TiddlyWiki documentation for more information.

Ex:TelephoneLinkBrokenSolution Macros (s)

Why doesn't this solution to the previous exercise work, given that macros perform text substitution?

\define phonelink() [ext[Call {{!!title}}|tel:{{!!phone}}]]
<<phonelink>>
Ex:TicketTrackingLink The Finer Points of Procedures (m)

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.

Ex:TicketTrackingTemplate Templates and the Current Tiddler (m)

In the TicketTrackingLink exercise, we created a procedure that outputs a link to a ticket in the company's ticket-tracking system and placed it in the OnboardingProcess tiddler. Create a template based on this procedure, called TicketNumberLink, which displays the link to a project's ticket when it's used as a template for any tiddler that has the ticketnum field populated. Transclude this template in the text of the OnboardingProcess project to show its ticket number.

Tip: It may be helpful to get everything working within the OnboardingProcess tiddler first, then excise the relevant parts into a separate template tiddler – this way, if something doesn't work, you have a better idea of what part isn't right.

Ex:TiddlersContainingWikiTitle Filters and Transclusions (m)

Create a list of all tiddlers that contain the title of the wiki.

  • The current title of the wiki can be found in the tiddler named $:/SiteTitle.
  • The search filter operator is used to find tiddlers that contain some arbitrary text.
Ex:TocAddition Creating Hierarchies with a Table of Contents (s)

Make up and create another meeting under one of the other subcategories, either OnboardingPeople or OnboardingTraining. Be sure to include at least one participant and a time as we did when we set up the initial meeting. Check to make sure that it shows up in the table of contents.

Ex:TocCaptions Creating Hierarchies with a Table of Contents (s)

Having the word Onboarding appear repeatedly in a table of contents within the OnboardingProcess tiddler seems a little silly, especially when those top-level tiddlers don't have any useful content of their own. We'd really like to be able to give them names that make sense in this context, without having to make the title of the tiddler something vague like “HR” that would be ambiguous in the context of the entire wiki.

Fortunately for us, the table-of-contents functionality looks for a field called caption and uses that instead of the title if it exists. Add appropriate caption fields to each of the three top-level items displayed in the table of contents to pretty up the list.

Ex:TocInternalExternalNav Creating Hierarchies with a Table of Contents (m)

There are two more (rarely used) kinds of tables of contents, toc-tabbed-internal-nav and toc-tabbed-external-nav. Try these out. Can you figure out the difference between them?

Ex:TranscludedProcedureScope Templates and the Current Tiddler (m)

In The Finer Points of Procedures, we learned that the scope of a procedure is until the end of the tiddler. But what about when we transclude a tiddler containing a procedure into another tiddler?

Ex:TranscludeWikipediaLink Parameterizing Field Transclusions (m)

Create a WikipediaLink tiddler equivalent of the procedure. It should take articleName and text parameters and generate a Wikipedia link when transcluded.

Ex:UnclosedProcedureCall The Finer Points of Procedures (m)

Take 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?

Ex:UpdatingDisclaimer Variables (s)

Suppose that corporate decides it's time to update the disclaimer, and henceforth all documents need to say “doesn't” instead of “does not.” Update the tiddler to make this change. Notice that, with the use of a variable, you need only make the change in one place, even if you included the disclaimer in hundreds of places.

Ex:VariableAfterSet Variables (s)

What happens if you refer to a variable after the </$set> or </$let>?

Ex:VariableTransclusion Field Transclusions (s)

What happens if you set a variable in one tiddler, and transclude a tiddler that references that variable within the scope of the $set or $let widget? You can start with a Tiddler 1 that looks something like this:

<$let myVariable="test">
    {{Tiddler 2}}
</$let>
Ex:VeryOrdinaryDay Data Tiddlers (m)

The TodaysHoliday tiddler has a problem: if today isn't a holiday, it says “It's today!”. While true, that sounds a little silly, doesn't it? Change the tiddler so that if today is not a holiday, it instead says, “Sadly, it's a very ordinary day today.”

Tip: An attribute to the $list widget called emptyMessage may come in handy.

Ex:ViewsOnSidebar Adding to the Sidebar (m)

Place the new $:/yourname/Views tiddler onto the sidebar between the Recent and Tools tabs.

Hint: You'll have to figure out how TiddlyWiki picks up tabs on the sidebar. A little bit of detective work right within your wiki should be sufficient; we've seen all the relevant mechanisms by now.

Ex:ViewSource HTML (m)

Try right-clicking on the background of this web page and choosing View Page Source. This will show the HTML code behind the page. Scroll through some of it and see if you can find some tags and attributes, like we discussed above.

In addition to HTML, you will find some JavaScript (a programming language for web browsers that uses a lot of {curly braces}), some CSS (a language that defines the colors, spacing, and fonts used on the site), some TiddlyWiki wikitext, and probably a few other mysterious things. When you see something you don't understand, just keep scrolling – you're not meant to understand it all, just to get a feel for how a website's HTML looks.

For fun, go try this on a couple of other websites, too.

Ex:ViewTemplateExplicitHide Hiding and Showing Things (m)

Change the ViewTemplate tiddler that displays the contact information template so that it does not display if the hide-contactinfo field on the contact tiddler has the value yes. Use a $list widget.

Ex:ViewTemplateExplicitHideReveal Hiding and Showing Things (m)

Repeat the previous exercise, but use a $reveal widget instead of a $list widget.

Ex:WikifiedQuotation Wikification (m)

In this snippet, we had to quote the value of text in the $wikify widget (using triple quotes, since the text we were quoting contained single quotes). What goes wrong if we don't quote it? Why do you think this happens?

\procedure myText(text) Text: <<text>>

''OK:'' <<myText "test text">>

<$wikify name="wikitext" text="""<<myText "test text">>""">

''Also OK:'' <$text text=<<wikitext>>/>

</$wikify>

OK: Text: test text

Also OK: Text: test text

Ex:WikifyWikipediaLink Wikification (s)

Add the following snippet to a new tiddler:

\define wikipediaLink(articleName)
https://en.wikipedia.org/wiki/$articleName$
\end

<$transclude $variable="wikipediaLink" articleName={{!!wikipedia-article}}/>

Alter this snippet so the contents of the wikipedia-article field on the current tiddler can be a transclusion of a different tiddler field. (As it stands, the transclusion will render, but not as part of a link, since the transclusion within the wikipedia-article field is only seen after being returned from the wikipediaLink macro.)

Ex:WikipediaLinkSnippet Stamps (m)

Create a snippet Link to Wikipedia article that inserts a call to the wikipediaLink global procedure. Specifically, it should use the prefix/suffix feature mentioned in the previous paragraph so that if you highlight Aardvark, you get <<wikipediaLink "Aardvark" linktext>>.

Ex:WikipediaLinkTemplate Filters and Transclusions (m)

Make the solution of the previous exercise into a separate WikipediaLinkTemplate tiddler that can be transcluded, so that it can be used for creating links to more things than just aardvarks. As we learned in Ex:VariableTransclusion, variable values will carry across transclusion boundaries, so refer to the value of a variable called articleName to decide what article to link to.

While you're at it, make this template more robust by getting the value https://en.wikipedia.org/wiki/ from another tiddler; this way, we can reference the base URL of Wikipedia from other places, and only have to update it in one place if it changes.

Ex:WikipediaLinkWithoutProcedure Filters and Transclusions (s)

In Ex:ProcedureAdjacency back in Using Variables as Attributes, we found that this attempt to use a simple variable to compose a Wikipedia link didn't work:

<$let wikipedia="https://en.wikipedia.org/wiki/">
  <<wikipedia>>Aardvark
</$let>

Fix this example by replacing the <<wikipedia>>Aardvark line with an a element using a {{{ filtered transclusion }}}.

Tip: The filter operator addsuffix will come in handy.

Ex:WikiStatistics Filters and Transclusions (M)

Create a tiddler called WikiStatistics that shows the following pieces of information in a bulleted list:

  • How many contacts are in the wiki.
  • How many unique tiddlers are linked from meetings. (It will be unique without having to do anything special, so don't panic if you think you don't know how to make it unique.)
  • What percentage of non-system tiddlers in the wiki are contacts, to three digits of precision (e.g., 10.2%, or 1.55%).

To complete the last one, you'll need to review the list of Mathematics Operators on the filter operators manual page.