Transclude a tiddler based on the name of the tiddler the transclusion is in

Total beginner, thought this wouldn’t be too hard but I’m totally stumped. All i want to do is transclude a Tiddler whose name contains the name of the current tiddler.
This is for a character profile, So lets say the Tiddler I’m editing is named “Charactername” and the Tiddler i want to transclude is called “Bio - Charactername”. How do i transclude the current tiddler into the title for transclusion? I tried {{Bio - << S t o r y T i d d l e r >>}} and some other variations, but nothing seems to work.

G’day,

That is a good scenario to learn about macros and filters. (Anybody else can give the “procedure” or “function” version of this.)

The idea would be to put that “thisBio” macro in a dedicated “global” tiddler (tagged as $:/tags/Macro), and then the macro is available to all of your tiddlers. (So you don’t have to define that macro in every tiddler in which you want to use the macro.)

1 Like

If I understand your issue correctly, that’s either:

  1. not possible
  2. or dangerous
  3. or both

The title, along with every other field in a tiddler, is stored as JSON in a script element in the HTML file. A title which is only known at render time would likely break you TiddlyWiki – might even make it unusable.

The title field is fundamental to how TiddlyWiki works. For regular tiddlers, it must be unique.

Hey, thanks a ton, that did the trick! I tried reading the Grok Tiddlywiki on Macros and some other stuff and it just wasn’t clicking but I think I’m finally getting my head around it now. Saved me potential hours, thanks again!

Actually, I had a problem crop up, do you have any idea why my formatting would disappear inside the transclusion? My bullet lists have turned back into asterisks.

Ah, give me a couple of minutes and I’ll introduce you to some new concepts.

1 Like

That’s the function of the $text widget: it returns unformatted content. If you want to preserve the formatting used in the original tiddler, you’ll want to use $transclude instead. (The {{TiddlerName}} construction is in fact a shortcut for the construction <$tiddler tiddler="TiddlerName"><$transclude/></$tiddler> – you can read more about that here.)

Here are a couple of options for you, starting from the closest to Charlie’s original suggestion:

<$tiddler tiddler={{{ [<currentTiddler>addprefix[Bio ]] }}}>
<$transclude $mode=block />
</$tiddler>

In this case, we use a filtered attribute value to get the name of the tiddler to be transcluded, just as Charlie did in the $text widget. The difference here is that we don’t need get[text] because the $transclude widget defaults to $field=text if you don’t specify a different field to use. (It’s good to specify $mode=block so all your wikitext formatting is properly preserved.)

As an alternative to $tiddler, you could use a $list to set the name of the tiddler(s) to be transcluded:

<$list filter="[<currentTiddler>addprefix[Bio ]]">
<$transclude $mode=block />
</$list>

By default, $list resets the <<currentTiddler>> value within the widget contents to each output of the list—so this particular list will work just like the previous option.

The advantage of using a $list is that if you have multiple tiddlers with the same name scheme, you could write a filter to transclude each “child” tiddler’s contents. For instance:

<$list filter="[suffix<currentTiddler>]">
<$transclude $mode=block />
</$list>

This will find and transclude the content of each tiddler whose title ends with the parent tiddler’s title. Of course, it’s possible to write more complex filters, too!

You can put either of the above snippets in a macro and call it wherever you want the transclusion(s) to appear, as Charlie did. But if you have a number of “character” tiddlers and you want them all to use the same formatting, it gets a little redundant to have to call the macro in the text field of each character tiddler - not to mention tedious to update! So for a case like this, I’d personally recommend using a ViewTemplate. Here’s how to get started:

  • Make a new tiddler and give it the tag $:/tags/ViewTemplate. This tiddler will hold your template, which will automatically appear as a segment of all the relevant tiddlers. Name it whatever you like.
  • Paste the following code in the template tiddler:
<$list filter="[<currentTiddler>tag[Character]]">
<!-- all your template content goes here! -->
<$list filter="[<currentTiddler>addprefix[Bio ]]">
<$transclude $mode=block />
</$list>
<!-- end of template content -->
</$list>

You probably don’t need this template to appear on any tiddler that doesn’t represent a character—and that’s the function of the outer $list, which will check that the current tiddler has the tag “Character” (for instance) and display its contents only if that first check succeeds.

  • If you’re using TW 5.3.2 or later, you could also replace the outer list with the same filter in conditional shortcut syntax if you prefer it—but $list is the “old-school” way to do this kind of check.

Finally, paste the following code in any tiddler:

<<tag $:/tags/ViewTemplate>>

This will give you a tag pill that you can use to position your new ViewTemplate wherever you want it relative to the other segments of the tiddler. Simply click on the tag pill and drag and drop your new template tiddler’s title wherever you want it to appear in the list. You can delete this tag pill once you’re done with it.

1 Like

Replace the macro with this one:

\define thisBio()

<$tiddler  tiddler={{{ [<currentTiddler>addprefix[Bio ]] }}}>
{{!!text}}
</$tiddler>

\end

I don’t use the transclude widget, but most folk are quite happy with it, so you can use that instead.

Setting the tiddler context with the tiddler widget: this approach makes a larger and more complex snippet of wiki text (within the tiddler widget) immediately possible for that macro.

2 Likes

Hmmm, I’m still having the same problem here with this code, though i prefer your macro method, So i will probably try and adapt Etardiffs approach to a macro. Thanks again!

Assuming that you meant to quote Charlie’s code rather than mine, you’re likely running into an issue with the parser mode. The parser tries to automatically determine whether to apply block or inline parsing (which doesn’t respect block mode elements like bulleted lists) based on the presence or absence of line breaks; you can probably fix the issue by adding an emply line between the $tiddler widget and {{!!text}}.

For cases like this, I tend to prefer the longform $transclude because it lets you specify which parser mode to use, and then you don’t need to worry about where to put your line breaks.

Okay, thanks a bunch! It’ll take me a minute to parse all this, the ViewTemplate approach might be the way to go.

O whoops, you are correct, i edited that out, I’d accidentally hit the quote button XD

Aha! you were correct, that fixed the problem!

Thanks to both of you again! Great community to be a part of here!

1 Like

Apologies, gotta have a blank line between the $tiddler widget and the Transclusion.

This keeps formatting A-1:

\define thisBio()
<$tiddler tiddler={{{ [<currentTiddler>addprefix[Bio ]] }}} >

{{!!text}}
</$tiddler>

EDIT: Oops, just noticed etardiff’s note saying to do that.

1 Like

No worries, learning about this mistake actually helped me understand the code better haha.

Hope you have a nice evening!

A-1, right back at ya.

I’m just hoping my TV rabbit hears can catch a hockey game tonight !