3 level filter problem

Okay, the snippet below did not do what I thought it would:

<$list filter="[search:book:literal<currentTiddler>] +[sort[tags]]">

<$list filter="[all[current]tags[]limit[1]]"><b><$view field="title"/></b><br>

<span class="indent1"><$list filter="[all[current]tagging[]sort[title]]"><details><summary><b><$view field="title"/></b>&nbsp;<$link>*</$link></summary><span class="ltgray2"><$transclude field="text" mode="block"/></span></details></$list></span>

</$list>

</$list>

I thought each list would narrow the lists inside of it, doing the following:

a. Grab all the tiddlers whose book fields contain the title of the current tiddler,
b. Then grab the tags from that list of tiddlers, and display the tags as a list (shown as text, not as tag pills),
c. Then create lists under each tag of the tiddlers from the list in a, that have that particular tag.

It does a and b just fine, but c is not confined to the list from a. The results show ALL tiddlers that have that particular tag.

Use case: I create note tiddlers where I have the book ([[Feel Good Productivity, Abdaal]]) in a book field and the topics as tags. There are also topic tiddlers that have a viewtemplate tiddler with a list search of all notes tagged as that topic. That part was easy to figure out.

There will also be book tiddlers, that will have a view template tiddler that has the above snippet. Listing the topics from note tiddlers with this book in their book field, and under each topic, a list of the note tiddlers themselves.

I thought the “all current” bits in each list would successively filter/limit the list of tiddlers in c to the list in a, but to no avail. What am I doing wrong?

I can give a fuller analysis and answer tomorrow.

Each list changes the current tiddler. Although you may nest these you only have access to the current tiddler value resulting from each item generated from the list filter at anyone time.

You can use the variable parameter on each list widget but then inner filters need to refer to the correct variable not current tiddler.

  • even this will not work if your filters are not constructed correctly.
  • by naming the variables it can be easier to follow and debug.

Perhaps also simplify with a filter in a set variables name.

2 Likes

Each list looks up tiddlers independently. To build nested lists, you need to keep incorporating the previous levels. Here’s an example:

\define getTids() [search:book:literal<currentTiddler>]

<$list variable="getTags" filter="[subfilter<getTids>tags[]]">

<b><$text text=<<getTags>> /></b>
<$list filter="[subfilter<getTids>tag<getTags>]">
<details style="margin-left: 1em;">
<summary><b><$view field="title"/>&nbsp;<$link>*</$link></b></summary>
<i><$transclude field="text" mode="block"/></i>
</details>
</$list>
</$list>

I defined an initial filter that gets all the tiddlers with the book field that matches the current tiddler

The first list uses subfilter to match all tiddlers to the defined filter, then gets those tiddlers’ tags. Those results are put into the “getTags” variable, rather than “currentTiddler”

The second list again matches all tiddlers to the defined filter, then also matches to the current tag, using the “getTags” variable.

1 Like

Thanks @Brian_Radspinner! I am going to study variables and this example to see what else I can cook up. More solutions, that is, not more questions! Thanks again.

Yeah, always a good idea to use the variable attribute with list widgets, especially when nested.

Especially when using nested list widgets, a very good idea to banish “currentTiddler” from the relevant code and use very explicit references.

<$list variable="Context1Tid" filter="[[whatever filter]]">
  <$list variable="Context2Tid" filter="[<Context1Tid>etc]">
    <$list variable="Context3Tid" filter="[<Context2Tid>etc]">
      <<Context1Tid>> <<Context2Tid>>  <<Context3Tid>>
    </$list>
  </$list>
</$list>
3 Likes

Good point @Charlie_Veniot because having the current Tiddler title available can be helpful and for completeness the storyTiddler is also available.

  • when writting macros its a good idea to have them opperate on the current Tiddler and retaining its value.

This gets verbose, but I’m a big fan of clarity. Taking my previous pseudocode sample:

<$list variable="Context1Tid" filter="[[whatever filter]]">
  <$list variable="Context2Tid" filter="[<Context1Tid>etc]">
    <$list variable="Context3Tid" filter="[<Context2Tid>etc]">
      <<Context1Tid>> <<Context2Tid>>  <<Context3Tid>>
      <$tiddler tiddler={{{ [<Context1Tid>] }}}>
        <<SomeMacro>>
      </$tiddler>
    </$list>
  </$list>
</$list>

Off topic:
Hi Brian,
How your TW puts tiddlers in such nice arrangement? It seems you have flying tiddlers?
Am I right?

1 Like

Hi Brian (or anyone so inclined),

Is there a way to also do this the other way around? That is, while keeping the tiddlers’ tags as happy and sad, and their book field A Book Title, have a list in happy and sad that looks like this:

A Book Title

  • Tiddler 1
  • Tiddler 2

Another book title

  • Tiddler 2
  • Tiddler 3

That way I can set up two viewtemplate tiddlers, one specifically for tiddlers that are tags (happy, sad), and one for tiddlers that are books (A Book Title). I know how to do this viewtemplate part. I just would need how to refactor the macros and list so that things are reversed from the example you gave me.

[Edit: I should add that I tried this for hours but couldn’t figure it out.]

Thanks in advance for any help.

Also, how could I make the list of notes under each book order by ‘sortan’? Tried different ways to do this with no success.

@DaveGifford

As long as all of the multi-word book titles are surrounded by square brackets, you can try this code for the tag tiddlers’ viewTemplate:

<$list variable="getBookTitles" filter="[all[tiddlers]tag<currentTiddler>get[book]enlist-input[]unique[]sortan[]]">

<<getBookTitles>>

<ul>
<$list filter="[all[tiddlers]tag[happy]sort[title]] :filter[search:book:literal<getBookTitles>]">

<li>{{!!title}}</li>
</$list>
</ul>
</$list>

For using sortan[] in the original code, you can try this:

\define getTids() [search:book:literal<currentTiddler>]

<$list variable="getTags" filter="[subfilter<getTids>tags[]]">

<b><$text text=<<getTags>> /></b>
<$list filter="[subfilter<getTids>tag<getTags>sortan[]]">
<details style="margin-left: 1em;">
<summary><b><$view field="title"/>&nbsp;<$link>*</$link></b></summary>
<i><$transclude field="text" mode="block"/></i>
</details>
</$list>
</$list>

@Mohammad

The previous screenshot was thanks to the power of Photoshop just for presentation. But, I do want to make a useful horizontal layout for a secondary Story River in a few layouts. For that I will probably start with something like:

.tc-story-river {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    column-gap: 1em;
}

.tc-story-river .tc-tiddler-frame {
    flex: 1 0 min(20em, 50%);
}

Won’t this part limit its usefulness to just the happy tiddler?

@Brian_Radspinner Neither of your solutions worked, and I tried tweaking them, too. I am going to re-do my question as a new post. This is getting way too confusing and would be even more confusing to you if I were to show you the file I uploaded.