I’d like to remove the list widget with a single set widget with mylist containing the complete list of tiddlers.
I have tried various filter operators without success. If you need more details: This would be used on person tiddler. The list widget returns events for this person that are “parent” events (ie. these events have children events). The set filter returns all child events… so I’m my objective is to set mylist to a complete list of event tiddlers that are children events of the person tiddler. I need to use this variable in a call to a macro, so I need the list widget removed. Hope this makes sense.
The filter in the list uses {!!title} or the effectively current tiddler when the list is displayed, is this correct? I understand it is on person tiddlers.
Perhaps the output of your first list could use format:titlelist[]? not enlist-input[]] +[unique[]]
has:field[event]get[event] can be simplified to get[event]
Your set filter starts with all tiddlers again with the event tag, when inside the list is iterated once for each event found by the list filter. Perhaps use variable=event-tiddler (on the list) and in the set use <event-tiddler>.
Once you have it working then share back and we can suggest how to eliminate the list f necessary (but why?)
The first filter run is unchanged and returns a list of the events for the person that are parent events.
The second filter run uses a :map prefix and thus transforms each input title from the previous run.
the flat suffix for :map means we replace each input title with all the results of the map filter run and not only the first result which is the default behaviour of :map.
the :map filter run is evaluated once for each input title and sets the value of the currentTiddler to the title being evaluated, making it easy to check all events to see if they contain the event indicated in currentTiddler in the event field.
Hi Mohammad, in order to keep the changes in the filter easier to understand, I tried to change only what was strictly necessary and tried to emulate the precise logic of the combination of the $list and $set widget to illustrate how they could be mapped on to a single filter run.
Good spot! This is because the input to :map is a single tiddler so we need to specify all[tiddlers] if we want to select from all the tiddlers. Updating the answer above.
Thank you Saq!
I like your clever solutions! Specially when you propose a single filter expression while I have to do it in several steps including many $list
When you simply need to print out the results on screen, combining several widgets is usually quite OK. However, when you need to use the output as input to another widget or filter, then it is recommended and helpful to use a single filter expression where possible. Otherwise you fall into the trap of needing $wikify which is an antipattern for such use cases and leads to poorer performance.
Also just for clarity please note that the proposed answer above is a single filter expression but consists of two filter runs.
@saqimtiaz@Mohammad Thank you for walking through this to find the solution. I discovered that each filter’s syntax was not exactly what I wanted. However, this answers my question. The power of this map operator is brilliant. This opens up opportunities for numerous situations. Thank you again.
…which I removed in this example, is me thinking (likely incorrectly) that removing all tiddlers without the event field would be faster than it performing get[event]enlist-input[] when there is no event field.
You can use! Normally it is recommended to use a template here. Look at the last paragraph in official doc tiddler: https://tiddlywiki.com/#tabs%20Macro
I believe [get[event]] is enough. If a tiddler has not an event field or its event field is empty will be ignored. The performance is Saq expertise. Hopefully he gives his advises.
I stand corrected. Thanks. I’m not sure what occurred when I first implemented this filter. But when I changed it to {!!title} it worked. I shall put <currentTiddler> back in place.
This gets complex real quick… and it makes my head spin.
There are event tiddlers tagged with event.
There are person tiddlers tagged with person.
All event tiddlers (parent and child) support an event field (title list of parent events) and a people field (a list of person tiddlers associated with the event).
Any event can reference another event as it’s parent with the event field. i.e. parent and child events use the same “event” tiddler definition.
Example:
World War I – this is an event. It would be a parent event for numerous child events. On the event tiddler I want to show a timeline of events that occurred during the war. In this example, I would not likely reference all people in my TW that took part in this parent event (but I could). This event has an empty event field.
The first child event could be “Archduke Francis Ferdinand is assassinated”. Its event field references the World War I event. This event can reference 1 or more parent events. It can also be a parent event to other events.
In this query, I want a list of all children event tiddlers for a person where they are referenced in both the child and parent event.
The reason for the request is for a more complex implementation. The event tab (shown on person tiddler) displays a timeline ($:/plugins/kookma/timelines) of events for that event. This plugin does not support, natively, nested timelines. But, that does not mean it cannot do it with the appropriate timeline templates. When the parent event appears on the timeline I do not want the children events tiddlers from that parent to appear in the outer timeline, because they appear nested in a sub-timeline under the parent. So, I’m using the filter provided here in a much bigger filter. In my example, I simplified the filter to obtain tiddlers, but in fact, what I am doing is removing tiddlers from my grand filter so these child events do not appear in a given level of the timeline. Now that I have my list of event tiddlers I use mylist variable like this:
[remove<mylist>]
…embedded in my grand filter. I have not tried, but instead of using a set variable could I embed the filter like this, I am guessing this would not work:
Aside, but you asked, I also have an “event-role” tiddler. These are tagged “event-role” and are used as an intersection (an old DB design term–I’m old) between person and event tiddlers. These tiddlers define a person’s role in an event. So, instead of a person being referenced in the people field on an event tiddler, they are referenced in the people field of an event-role. Therefore, event role tiddlers have an event field, a people field, and a role field. In this way, I can assign an individual a role in the event.
Using the example above (which is not a great example), I would assign the person tiddler, “Francis Ferdinand” tiddler, to the “Archduke Francis Ferdinand is assassinated” event. But, I could create an event-role tiddler defining the role of “assassin” and associate that with the event and the people who were assassins (such as Gavrilo Princip). I still need this to work when viewing the event timeline of Gavrilo Princip.
Just to make this more complex, my “event” tab tiddler can be used on various types of tiddlers. I used the person tiddler only as an example. For example, this tab tiddler is also used on place tiddlers, to show a timeline for a given place.
This is the correct syntax here! You cannot directly pass another filter operator as input to remove, but you can pass a title list (here you have created it using $set widget).