Sorting a List by an interim macro result

Hopefully, I can explain this as it is hard to show a code example at the moment.

Lets say I have tiddlers with names of people in the title
Bob
Sally
Steve

Now, let’s say I have other tiddlers called LifeEvents. Life Events are kind of related to the people tiddlers such that there are fields called:
person
event
date

So, there would be a tiddler called LE-12345 (the title isn’t important, it is basically a GUID)
and the fields of LE-12345 are:
person: Bob
event: Birth
date: 19600715

And we’d have one for each person. This design lets there be any number of LifeEvents related to a person. e.g., Marriage, Lived at 123 Main Street, Joined the Navy, whatever

There might be a performance hit because of this design but anyway, here’s my question:

I have a $List of people. During the run, a macro is called that looks up the CurrentTiddler among the LE tiddlers to pull back the Birth event date.
That I have kind of figured out but what I really want to do is use the result of that macro (in my Bob example, the value of 19600715) as a sort value so that all the people are sorted by their birth date.

Obviously, the easiest is to scrap the idea and simply store the birth date on the Person tiddler but I want to see if it could be done this way.

Can a list sort like this be done?

Thanks for helping with my crazy idea,
Scott

Rather than generate your sort via macro, use a filter that;

This filter can then be used in your $list filter with the :sort[ filter ] run

Since TiddlyWiki 5.2.0 there is a Sort Filter Run Prefix for this exact purpose.

If you need help converting the macro into a filter to retrieve the sort value post it here.

I have a similar setup as @TechLifeWeb. My person tiddlers are tagged person and birth life events are tagged event and birth. In the life event tiddlers I have a people field instead of person. Based on @TW_Tones response I tried the Sort Filter Run feature. This is new to me. And, I did not get working. What I thought would work is:

[tag[person]] :sort:string[tag[event]tag[birth]contains:people{!!title}get[date]else[no-date]]

The first part lists all tiddlers with a person tag, then sorts a date string (my dates are strings, e.g. 1898-09-08) where the date field can be found in a tiddler tagged event and birth, and the people field contains the title of the person tiddler. If no date is found a string of “no-date” is returned.

Well, that was the intent of the filter. However, this is not working. It returns a sorted list of person tiddlers by the title.

Any help with the syntax would be appreciated.

Thank you.

Unfortunately I have not yet done this myself, only read of others doing so or the documentation.

A strategy to debug this is to generate a list of the values you hope to sort on, if they look correct then put this inside a sort filter run. The reason we need the sort filter run is because the output needs to be the tiddler titles (from the subset of titles defined by [tag[person]]) sorted by the evaluated sort key.

For example - I cant test without the test data, perhaps thereis an equivalent query on tiddlywiki.com?

Interim filter check

[tag[person]] +[tag[event]tag[birth]contains:people{!!title}get[date]else[no-date]]

or

[tag[person]tag[event]tag[birth]contains:people{!!title}get[date]else[no-date]]

To be clear all tiddlers need all three tags and the people field with either the date field / or not.

Once the above list returns a valid list of sortable keys we can then move on to use the :sort filter run.

Keep in mind the list from the interim filter may be deduplicated.

[Edited] Given contains:people{!!title} I read this to mean the people field contains self?

Does people contain more than one person? If not then you probably just want:

[tag[person]] :sort:string[tag[event]tag[birth]people{!!title}get[date]else[no-date]]

In any event, the contains filter operator expects a list-type field, so any entries in people would have to be in link quotes (e.g. [[Charles Sturgeon]])

Good luck!

1 Like

Thanks to all for the direction. I think I have this figured out.
Below is my code. It is a little more complicated because I’m using fileds not tags. There are tiddlers that are different ‘doctypes’.

<$list filter="[all[tiddlers]field:doctype[Person]] :sort:date[listed[referenced]doctype[LifeEvent]name[birth]get[date]else[5000]]">

</$list>

Here’s a little demo set of tiddlers to drag onto tiddlywiki.com to help explain things

interim-sort-demo.json (2.3 KB)

Try this:

[tag[person]] :sort:string[all[tiddlers]tag[event]tag[birth]contains:people{!!title}get[date]else[no-date]]

By default the :sort filter run prefix only receives a single input title at a time. Since you need to look up amongst all tiddlers, you need to explicitly start the run with all[tiddlers]

1 Like

@saqimtiaz Thank you again. Works as expected. We need more detailed examples in the documentation. I do realize that also means more text to be written about those examples.

Thanks, Mark. Yes, all my events support a list field named people. In many cases it makes sense that multiple people be associated with an event, but not a birth event.

Craig