This is working code, but it seems far too redundant. In JS, I would probably do something like
const results = (c, {won = ''} = c ) =>
won == 'yes' ? '✅' : won == 'no' ? '❌' : won == 'pending' ? '◎' : ' '
but it could easily be done with a switch statement or a sequence of if-else statements.
Are there cleaner TW techniques for this?
I’m assuming this could be done with a data-tiddler equivalent of the following code, but that also feels more heavy than I would like for this simple function:
(I do recognize that these are not precise equivalents to the first version above, with very slightly different behaviors if there is a won property that differs from the three values I define. These JS ones are actually the preferred behavior, but the difference won’t matter in my wiki.)
It is somewhat cleaner, though, as it doesn’t involve multiple text widgets.
I like avoiding the multiple <$text...> widgets, but there is still a great deal of duplication… which of course would get worse with more cases.
And we have a winner! This is very nice. I know I’ve seen getvariable, and maybe used it once, but it doesn’t leap to mind for me yet. It’s perfect here.
Hmm, I assumed it would be possible to nest a single-line pragma within a function definition (as you can do with procedures and traditional macros), but apparently it’s not. Moving the variable definitions outside the function should fix it, though. Sorry about that!
It using preview you need to refresh the preview after changing the field.
Unlike the first this does not result in a link, but only text
This allows any field to have the same rules applied
Notes
You can see here we can use functions, filters and there results can be displayed, or used in filters of subsequent conditional sections.
I am confident we can build switch (we have above), case, if then else etc…, in functions.
If you see recent examples of recursion using two functions, we may even be able to nest these.
I was working on reducing the length of the filter in field.status by using one or more “filter run prefix”, but I am not yet that well versed in their use.
It is not that importiant
Perhaps someone else can suggest how?
However
We can abstract our functions more to both simplify the way they are used, read and make them much more reusable. See my next post.
To support this we defined a number of sub functions, however you will notice they initialy look more complex but each individual one is simple, and they become available to use and reuse just by calling them.
\function current.field(fieldname) [all[current]get<fieldname>] <!-- not in use -->
\function status.field(fieldname:"status-field") [all[current]get<fieldname>]
\function if.yes.then(symbol:"✅") [match[yes]then<symbol>]
\function if.no.then(symbol:"❌") [match[no]then<symbol>]
\function if.pending.then(symbol:"◎") [match[pending]then<symbol>]
\function short.status() [status.field[]if.yes.then[]] :else[status.field[]if.no.then[]] :else[status.field[]if.pending.then[]] :else[[ ]]
Note:
Since if.yes and if.no are too generic, you can rename these to if.won and if.lost
I try and always write my functions, macros etc.. to act on the current tiddler, so all I need to do is choose which tiddler to apply it to.
Yes, I could implement the same reduction @etardiff did into my solution as well. By using a getvariable as a result if the goal is to reduce as much as possible, but my approach is to abstract, generalise and self document, especialy the second (short.status) example.
Just for fun, here’s a genericized approach that lets you specify a field to check, a list of possible options and the desired output for each, and a fall-back option to use if the field is blank:
In this case, since we’re constructing variables on the fly and using using $transclude rather than $text to display them, you can use wikitext in a “definition” and it will be properly wikified for display. So, for instance, this would also work:
I chose to use : to separate each value and its output, as a dictionary tiddler does, and ; to separate each value pair in the list—but you could change them to the delimiters of your choice. If we wanted to put each pair on its own line, for example:
\procedure conditional-display(field, options, blank)
<$setmultiplevariables
$names="[<options>splitregexp[\n]] :map[split[: ]nth[1]]"
$values="[<options>splitregexp[\n]] :map[split[: ]nth[2]]">
<$transclude $variable={{{ [<currentTiddler>get<field>] ~blank }}} />
</$setmultiplevariables>
\end
<<conditional-display
field:"won"
options:"yes: ✅
no: {{{ [tag[HelloThere]] }}}
pending: here's some longer text that could benefit from its own line"
blank:"[[HelloThere]]">>
This is a good point! In this case, I used \define rather than one of the more “modern” alternatives because 1) it’s slightly shorter, and 2) it highlights the fact that we’re defining variables to be used by the function.
@etardiff some interesting ideas in your conditional-display, it expands in my mind what can be passed into a macro. I too have exploered this further but its better I stop exploring this path for now. I wont start another topic. So here is my somewhat final example;
Replace the tiddler names and fields with ones relavant to your own test data
Using the get variable we can actualy pass in a tiddlervar to use, otherise it uses currentTiddler or tiddlername (this is a great feature to use elsewhere)
We can use simple names for the value icons because they are only known within this widget, Keep It Simple Sweetheart (principal)
Widgets are good if the only thing you need from them is to display the result, as is the case, with displaying icons.
For any value you use you can come to the widget and give that value an icon and just use the same widget.
There is a tooltip for each icon, you could add the tiddlername as well.
If there is no matching icon the value will be displayed, so you can find an icon later if desired.
You could also use cascade prefix. Only you need have stored your filters to call it. I read in documentatio the use with append, it is not simpler. I found a more simple version of cascade with append filter, but you have to store al filter together.
Yes, I mentioned that in the OP, and was trying that right now, getting stuck. I’ll post another version in a few minutes asking how to fix my approach.
I’ve been playing around with these. I think I agree with @stobot simply because it’s all too “wordy”. I did, however, have a brain-fart for a new operator…
I’m curious as to why the following alternative does not work. I’m almost certain it’s a simple syntax error, but I can’t find it. You can test it with this: