Build Tiddler from a $list Search of Field

Hello, folks :slight_smile:

More or less a follow up on my previous post: How to list number of occurrences of a particular field/value?

This is a two-part request:

Part 1: I’ll create a Tiddler for each Creator ($:/Creator Name). I need a $list filter that will produce a list of links to each Tiddler with their name in the author Field, sorted by title. What would that look like?

Part 2: I would like to be able to click on the Creator’s name in the above, to open the Tiddler from Part 1, the link ideally created in the template tiddler that produces the GUI above.
Something like <$link to tiddler=<CurrentTiddler[Field{author}]></$link>
(see, I told you I can’t write filters to save my life! :grimacing:)

All help greatly appreciated :slight_smile:

I’m assuming all your Creator tiddlers have a common tag, like “Creator”—this will make it much easier to filter them out from all the other system tiddlers. :slight_smile: I’m not entirely sure I followed your requirements, but I think this may address both parts: I’m leaving this in case it’s helpful for some other purpose, but see the edit below!

<$list filter="[tag[Creator]]">
''<$link />''

<$list filter="[author<currentTiddler>]">

* <$link />
</$list>
</$list>

If you want to include a list of links to tiddlers by a certain author on that creator’s page, you can use just the inner list:

<$list filter="[author<currentTiddler>]">

* <$link />
</$list>

The key here is that when you use a list widget, you’re automatically defining a variable which will hold each title produced by the filter. You can give this variable a custom name, like <$list filter="[tag[Creator]]"> variable="author">, but if you don’t, it will default to reusing the “currentTiddler” variable. This means that inside the outer $list, <<currentTiddler>>/{{!!title}} will refer to each tiddler in the [tag[Creator]] list, not the title of the tiddler where you use the code.

The following code will thus produce the same results as the first snippet (and it would be a good alternative if you need to reuse the original <<currentTiddler>> value somewhere inside one of the $list widgets):

<$list filter="[tag[Creator]]" variable="author">
''<$link />''

<$list filter="[author<author>]">

* <$link />
</$list>
</$list>

EDIT: Oops, I missed the annotation in your image on first reading! So in your example, you want to click on “baufive” and be taken to the “baufive” tiddler, which contains a list of all the tiddlers with author: baufive—is that right?

In that case, is there a reason not to call the “baufive” tiddler “baufive” rather than making it a system tiddler (with the $:/ prefix)? That would let you use <$link to={{!!author}} /> on a “content” tiddler (assuming it has author: baufive), and the simple second $list I posted above on a “creator” tiddler.

Heh heh, it would be a lot easier in several areas if I had used Tags instead of Fields, but, no I had to be DiFfErEnT… :stuck_out_tongue:

I hadn’t planned on it, but, yes, the Creator Tiddlers could have a “Creator” Tag.

The Creator’s name is in a Field named author in each item’s Tiddler, that is what I need to have referenced from the list filter to build the tiddler title to link to: $:/ + <CurrentTiddler>{{!!author}}

Hmm… I’m not getting this to work - When placed in a tiddler, there is no output from it :thinking:

The reason I’m using the “$:/” is to keep these Creator Tiddlers from cluttering up in the sidebar - I try to keep it just for the titles of the items only…

Tags are generally a bit more performant, but fields work too! The idea is just to have some common property that is shared by all tiddlers of a certain type, and not by tiddlers of other types. I really would recommend tagging your Creator tiddlers, though, especially if they’re system tiddlers; it will make it much easier for you if you ever need to round them up for export or for batch editing in the future.

Right—this was assuming a Creator tiddler titled e.g. ‘baufive’. If you’re going with $:/baufive instead, you’ll need to get slightly more complicated. Again, this is for use on a Creator tiddler (or template, if you have one):

<$list filter="[<currentTiddler>trim:prefix[$:/]] :map:flat[all[tiddlers]author<currentTiddler>]">

* <$link />
</$list>

For the link on your content page, try this:

<$link to={{{ [{!!author}addprefix[$:/]] }}}>{{!!author}}</$link>

Or if you’re using 5.3.0+:

<$link to=`$:/${ [{!!author}] }$`>{{!!author}}</$link>

Personally, though, I’d really recommend making a new sidebar tab that only shows “Content” tiddlers and leaving the system prefix off your Creators, or you’ll have to use these kinds of work-arounds any time you need to refer to them.

1 Like

By the way, in field transclusions like {{!!author}}

  • You can specify a particular tiddler before the !! (like {{Grant Park Build Set!!author}}, which will retrieve the author field from the Grand Park Build Set no matter where you use that transclusion).
  • But if you don’t, it will default to looking at the <<currentTiddler>>'s field’s—so {{!!author}} will retrieve baufive on the Grant Park Build Set tiddler, unless you use it inside a $list widget that redefines <<currentTiddler>>. This means you don’t need to worry about how to get <currentTiddler> into the field transclusion; it’s already there. :slight_smile:

Remember tiddlers already have a created, creator, modified and modifier field that are set to the current “Username for signing edits

Here is a TW with the relevant Tiddlers added and (hopefully) a better explanation so you can see what I’m after.

SimsWiki @ TiddlyHost

If I extract from the bigger picture your desire to do this " $:/ + {{!!author}}" there are a number of ways to do this. I love functions so this is what I would do.

\function author.tiddler() [{!!author}addprefix[$:/]]

The use <<author.tiddler>> where needed with the current tiddler set correctly.

You could also uses this in a filter [author.tiddler[]]

Oh, wonderful - You’re going to introduce a whole NEW ‘thing’ I’ve never experienced before! :stuck_out_tongue:

So, where do I place the function? It doesn’t work inline in my $list filter (of course), I tried putting it under a <style> tag and that didn’t work, either…

You’re going to have to treat me like a three-year-old :rofl:

Did you try this? It ought to do what you’re looking for, and may be less intimidating than functions.

To use Tony’s function, paste the definition

\function author.tiddler() [{!!author}addprefix[$:/]]

at the top of your template, and then use <$link to=<<author.tiddler>>>{{!!author}}</$link> where you want the link to appear—probably just replacing {{!!author}} in your current template.

You don’t seem to have a template for author tiddlers yet, but pasting this in a new tiddler named $:/baufive

… gave me the list you wanted. To achieve the same thing with a function:

\function author.name() [<currentTiddler>trim:prefix[$:/]]

<$list filter="[author<author.name>]">

* <$link />
</$list>
1 Like

I swear, I tried this last night and got absolutely nothing from it, but tried it now, and it works just fine! :thinking:

That’s why I went to the trouble of assembling an entire TW to demonstrate…

*sigh* oh, well we’ll live through it.

Thank You so much, @etardiff - This indeed does what I need :slight_smile:

I’ll also play around with @TW_Tonesfunction (and your explanation) to see how it works and maybe use it later.

Now I need to go format the Creator Tiddler to output an all prettified list with images and such :star_struck:

Thank You again!

1 Like
  • We are happy to treat you how you want, just let us know you are a new user and we can adjust for all levels of experience.

I suggest putting the function (and other macros and procedures) in a system tiddler like $:/my-global tagged $:/tags/Global

\function author.tiddler() [{!!author}addprefix[$:/]]
<!-- retrieves the author from the current tiddlers author field and prefixes is with $:/ to use as an author tiddler. -->

And this will work any where you use it that the current tiddler is what you want

Slowly you will collect useful definitions you can use in any wiki.

Heh heh, I’m by no means a new user - I started my TiddlyWiki journey waaaay back in 2016, with TW Classic version 2.5.0. Took me a while to come (kicking and screaming) to start using the new-fangled TW5, but I finally saw the light of how much more feature-rich it was and made the conversion.

The reason that I keep coming back here with questions is, sadly, my brain is not what it was back in 2016, and I really struggle with understanding (and remembering!) many concepts of using TW; even things which were ‘simple’ to me a year or so ago, now prove to be a challenge…
Even solutions that I have come up with myself, unless I interact with them every day, are soon lost from memory and more or less have to be learned all over again.

I try to maintain a few Tiddlers which contain snippets of code, and documented and explained concepts that I have gleaned from here, the old GG, or have come up with myself, so that I have a reference to look at once I (inevitably) forget them.

Your name pops up frequently in these lists, as I’ve gotten much great info from your discussions and answers to other folks’ problems - I really appreciate you taking the time to help others like you do :slight_smile:

I will take your advice from above and include that function in a Global Tiddler - I haven’t used it yet, but will experiment with it soon.

1 Like

@etardiff Continuing on from the above…

No, I didn’t have a template tiddler for the Creator at the time, as I figured it would be simple to create one. (Zaphod frequently thinks these strange things…), however, after a couple of days of frustrated attempts, I cannot seem to make my vision a reality.

In another wiki I have a series of old photos from the web. In the main Tiddler, I’ve created a div layout with three cells across, and a very simple line of WikiText in each:

{{$:/SomeImageTiddlerName||$:/Shorpy}}

which, as you can see, references a Tiddler that has a link to a local image $:/SomeImageTiddlerName, and all the data about it (Name, Location, Date, Description) and uses the tiddler $:/Shorpy as the template to format the data in the cell.

The $:/Shorpy Tiddler has some CSS classes (which I didn’t include here for brevity), and the complete layout for the cell:

<div style="display: flex; align-self: center;">
<div class="bt">
<$link to={{!!title}} tooltip="Open Tiddler"><img class="ptp" src={{!!pic}}></$link>
<span class="ct">{{!!piccaption}}</span>
<br><br>
<span id="Shorpy1">Date: <$list filter="[<currentTiddler>has[month]]">{{!!month}} </$list><$list filter="[<currentTiddler>has[day]]">{{!!day}}, </$list><$list filter="[<currentTiddler>has[year]]">{{!!year}}</$list></span>
<$list filter="[<currentTiddler>has[location]]"><br><span id="Shorpy2">Location: {{!!location}}, {{!!state}}</span></$list>
<br><br>
<span id="Blurb">{{!!blurb}}</span>
</div>

What I thought I could do is to format the link that you so graciously provided (to the Creator, using the {{author}} field) so that it would pass it to a temporary Tiddler (say $:/TempTiddler), which would have the $list filter that you provided, but referencing the Creator name from the currentTiddler which called it.
Is that making sense?

I want to have this tiddler ‘dynamically’ pick up the Creator’s name and display all the Tiddlers associated with it, so I don’t have to create a separate Tiddler for each Creator.

I’ve wracked my so-called brain and tried out (seemingly) every combination of prefixes and suffixes, but cannot get a working version.

Halp! :stuck_out_tongue:

I understand this, however there is a way to help yourself, but it’s not easy.

When writing your solution, do your best to write it so a stranger, including your future self, can read it, even to the extent of writing a manual elsewhere. Note tricks you used, quirks you found and mistakes you made, add self documentation.
Modularise pieces so each module does something specific, and its name reflects that. Bite sized pieces, for a future visitor to ignore or understand as their need demands.

To help us help you

Perhaps dry and build a separate simple example, without the complexity and see if that works, this is one way I often discover what I did wrong. If that does not work you can share a simpler example we can help you with.

Some quick tips that may be relevant, use author instead of creator.

Finds each different author in the wiki and gets their name

<$list filter="[each[creator]get[creator]]" variable=creator>

</$list>

List all tiddler where “research” is the creator, listed by title

<$list filter="[creator[research]sort[]]">

</$list>
  • Note [creator[research] is field creator with value of research.
  • Because I don’t use variable= the default is currentTiddler for each item.
  • Alternatively, get[creator]match[research] but the output will be the creator name

Lets create the creator tiddler name
if the creator variable is available as in my first example

<$let creator-tiddler={{{ [<creator>addprefix[$:/]] }}}>

in here use <<creator-tiddler>>

</$let>

I hope this helps.

Yes, I see what you’re going for: you want a link that will dynamically generate a template that displays the appropriate content.

  • This isn’t possible with a normal link, or at least it’s not trivial; the $link widget doesn’t execute actions (other than navigating to the specified tiddler), so you’d need to trap the click event with something like the $eventcatcher widget, and have that handle the appropriate actions.
  • Instead, I would take a look at the $button widget, which is intended to use actions—and can be styled to look just like a normal link with class="tc-btn-invisible tc-tiddlylink" and/or other custom classes of your choice. You’d want to use the $action-createtiddler widget to generate your temporary tiddler, with the template of your choice, and you could set its fields based on those of the tiddler where it was clicked.

However! Personally, I don’t think I’d use a button either, because it’s actually possible to use a view template to display content on a tiddler even if the tiddler itself doesn’t exist. In this case, your view template would contain a list widget that checked all your extant “author” fields, and then display your content if the title of the currentTiddler appeared in an author field. This is very similar to the way the MissingTiddler template works in the TW core, and it would mean…

  • You wouldn’t have to generate any extra tiddlers, even temporary ones—and you’d see the same content on an author “tiddler” whether you clicked a link or typed the name into your search bar.
  • You could use a normal $link widget to navigate to missing author tiddler; just style it to remove the italics if you don’t want it to look “missing”.
  • You could use whatever naming convention was most convenient; these tiddlers won’t show up in searches or in recently-edited lists since, again, they don’t actually exist. You could stick with the $:/author naming scheme, but you could also just use author—that would be my personal recommendation, as it’d be quickest and easiest to access from the search tab.
  • If you ever decide in the future that you do want to have real, permanent tiddlers for your creators, you won’t have to change your current system: the view template will display the same content whether the tiddler itself exists or not.

I’m not at my computer at the moment so it’s tricky to give you some sample code, but if you’re interested in any of the above options, let me know! I use buttons and “missing tiddler” view templates all the time in my own wikis, and I’d be happy to walk you through setting them up.

Here’s a very quick, minimal sample of the view template approach I was suggesting:

$ _AuthorViewTemplate.json (236 Bytes)

Here, I made a tiddler with the $:/tags/ViewTemplate tag and the text

<$list filter="[author<currentTiddler>]">

</$list>

If you add the tiddler to your demo wiki and navigate to the missing tiddler “baufive”, you’ll see a list of links to tiddlers with that value in the author field. On tiddlers that don’t match the contents of an author field, you won’t see any evidence of this view template at all. This means you can use it to display a simple list of links to content tiddlers (as my demo tiddler will display by default), or to conditionally display a more complicated template, e.g.

<$let by.this.author={{{ [author<currentTiddler>] +[format:titlelist[]join[ ]] }}}>
<$list filter="[enlist<by.this.author>] +[limit[1]]" variable="display">

There are <$count filter="[enlist<by.this.author>]" /> set(s) by {{!!title}} in this wiki:

<$list filter="[enlist<by.this.author>]">

* <$link/>
</$list>

</$list>
</$let>
  • If I were building this for myself, I might use a \function to define by.this.author rather than a $let widget: \function by.this.author() [author<currentTiddler>] +[format:titlelist[]join[ ]]. (Like variables set with a filtered transclusion, functions only return their first result by default, so we need the format+join step to preserve the full list.) But a $let or $set (or even $vars) widget will work just as well, so you can use whatever is most familiar.

You can see I used the list-before field in my example tiddler to force this template to display above the normal contents of the $:/core/ui/ViewTemplate/body template. You could alternatively rearrange your view templates by dragging their titles in the dropdown of the $:/tags/ViewTemplate tag. In either case, any text you add to “baufive” will display below/above the custom template.

Now that we have a view template in place, we can replace any instances of {{!!author}} in your $:/_CatLayout_PostBuilderVertical01 template with <$link to={{!!author}} />, and link to a nicely formatted author tiddler—even though it doesn’t technically exist. These tiddlers will appear in your Open tab when you follow the link, but otherwise they’ll disappear completely when you close them, so they won’t add any clutter to your wiki.

1 Like

Hi @Chan_Droid! Just wanting to second etardiff’s suggestion here about enabling links to an author’s name, even though there’s no tiddler “there”. Instead, a viewtemplate (which etardiff set up for you) builds an automatic “virtual tiddler” that serves as a home/index for that author.

Anticipating where you’ll be a couple steps down the line: If you follow etardiff’s advice above, you may soon find the standard "Missing Tiddler " alert annoying, since it appears together with the actual navigation content you intend to display… You can customize what shows up in the default body area for a missing tiddler by altering this shadow tiddler:

$:/language/MissingTiddler/Hint

And to be clear: After you set up these templates (so that you’ll get a “virtual tiddler” for any author’s name), nothing prevents you from editing that tiddler to add other info about that author, such as an image, a bio blurb, whatever. In which case you then have a real tiddler there, which would (by default) also appear in your Recent sidebar…

If you want the Recent sidebar to contain only a certain kind of tiddler (specifically leaving out author tiddlers, for example), there are two solutions:

  1. Modify the Recent sidebar filter conditions, so that they include only certain tiddlers, (and/or specifically exclude tiddlers) according to whatever criteria you like.
  2. — probably better in the long term — Make your own sidebar navigation resource that presents exactly what you want to display. Maybe make that the default sidebar tab.

If you’re developing a TiddlyWiki that wants to have two “faces” — one for you as author, and another cleaner or more tightly controlled face for visitors — there are good plugins for that. :slight_smile: Which one to use may depend a bit on how you’re serving up the project for others to access, and what kind of setup you’re using for editing and saving.

Feel free to come back with more questions!

2 Likes