Using tiddler field values

I am having a real trying time sorting out how to use the values of tiddler fields in various scenarios. The examples in the documentation are very unhelpful.

A simple example

<$set name="objectLink" value= {{$:/TLS/storage_format}} >
<$set name="objectLink" value={<objectLink>addsuffix[.]} >
<$set name="objectLink" value={<objectLink>addsuffix[$/TLS/Prefix/Artwork!!artwork_id]} >
<$set name="objectLink" value={<objectLink>addsuffix[$/TLS/Prefix/Artwork!!artwork_prefix]} >
<$set name="objectLink" value={<objectLink>addsuffix[Web/Images/]} >
 <<objectLink>>
</$set>
</$set>
</$set>
</$set>
</$set>

I am trying to format a value of ‘Web/Images/YB1234.jpg’ by concatenating various fields from different tiddlers.

The end result will be a action-setfield statement in a button action but after many trying hours, I thought a simple set of set statements to get the syntax sorted out would be helpful.

No luck as yet…

The first $set statement works a treat, after that …

All I see displayed is

addsuffix[.]} > addsuffix[$/TLS/Prefix/Artwork!!artwork_id]} > addsuffix[$/TLS/Prefix/Artwork!!artwork_prefix]} > addsuffix[Web/Images/]} > { --—

bobj

Why do you use such number of $set? Why not use $let instead of all those $set?

The example is a trial splitting the whole statement into a number of discrete statements. I did try $let and it also does not work.

Dr. Bob Jansen
122 Cameron St, Rockdale NSW 2216, Australia
Ph: +61 414 297 448
Skype: bobjtls
http://cultconv.com

First off, you’ve got some bad filter syntax…

When using filter syntax to construct a parameter value, it needs to be enclosed in TRIPLED curly braces and an outer set of square brackets (e.g., {{{ [...filter stuff here...] }}}). Then, within the filter syntax, if an operand is a tiddler field reference it needs to be enclosed in single curly braces instead of square brackets. A good rule to remember is that the type of brackets surrounding a filter operand are used to indicate how that operand is to be interpreted:

  • square brackets surround literal text value (e.g., addprefix[sometext])
  • curly braces surround tiddler field references (e.g., addprefix{SomeTiddler!!somefield})
  • angle brackets surround variable references (e.g., addprefix<somevariablename>)

Thus, fixing up the syntax, your code would be:

<$set name="objectLink" value={{$:/TLS/storage_format}} >
<$set name="objectLink" value={{{ [<objectLink>addsuffix[.]] }}} >
<$set name="objectLink" value={{{ [<objectLink>addsuffix{$/TLS/Prefix/Artwork!!artwork_id}] }}} >
<$set name="objectLink" value={{{ [<objectLink>addsuffix{$/TLS/Prefix/Artwork!!artwork_prefix}] }}} >
<$set name="objectLink" value={{{ [<objectLink>addsuffix[Web/Images/]] }}} >
 <<objectLink>>
</$set>
</$set>
</$set>
</$set>
</$set>

However, this still won’t produce the output you want, because addsuffix would seem to be the wrong filter operator. I think you mean to use addprefix

<$set name="objectLink" value={{$:/TLS/storage_format}} >
<$set name="objectLink" value={{{ [<objectLink>addprefix[.]] }}} >
<$set name="objectLink" value={{{ [<objectLink>addprefix{$/TLS/Prefix/Artwork!!artwork_id}] }}} >
<$set name="objectLink" value={{{ [<objectLink>addprefix{$/TLS/Prefix/Artwork!!artwork_prefix}] }}} >
<$set name="objectLink" value={{{ [<objectLink>addprefix[Web/Images/]] }}} >
 <<objectLink>>
</$set>
</$set>
</$set>
</$set>
</$set>

Lastly, you can greatly simplify the construction of the output by listing all the parts as separate filter “runs” (each surrounded by single square brackets) in a single filter and using +[join[]] to glue them together, like this:

<$let objectLink={{{ [[Web/Images/]]
   [{$:/TLS/Prefix/Artwork!!artwork_prefix}] [{$:/TLS/Prefix/Artwork!!artwork_id}]
   [[.]] [{$:/TLS/storage_format}] +[join[]] }}}>
<<objectLink>>
</$let>

Let me know how it goes…

enjoy,
-e

1 Like

Thanks @EricShulman . I typed the example into the Talk window after a very long and frustrating day, so yes, I should be using addprefix. However, forgot all about the join statement.

I tried all sorts of combinations of brackets after reading @TW_Tones ’ page on brackets and the Grok Tiddlywiki section of filtered transclusion and still did not get the correct sequence - bugger.

I wonder though if the documentation could not be improved by the addition of examples for a set of conditions, rather than the very limited set now. For example, for addprefix, how to use it in a variety of situations, such as adding a text literal, the value of a tiddler, the value from a tiddler field, the value from a variable, the value from a macro or procedure, etc. a template for examples could, I assume be implemented to standardise this.

I appreciate this is a huge task if we were to do it now for everything but as a just in time effort, it should be manageable.

Even an entry on how to concatenate strings/field values would be beneficial, pointing out the various ways this could be done.

Just some ideas…

Thanks for your response though, appreciated as always.

Bobj

Heres what I would do to just transclude three tiddler fields and add some additional text among those fields - a procedure will do this ( which is the same mechanism as <$set> in TW )

\procedure objectlink(artwork-settings-tiddler)
<$tiddler tiddler=<<artwork-settings-tiddler>> >
Web/Images/{{!!artwork_prefix}}{{!!artwork_id}}.{{!!format}}
</$tiddler>
\end

<<objectlink "$:/TLS/storage_format" >>

I would not consider an approach using filter operators like addsuffix as the goal isn’t to have a list of tiddlers to iterate through.

I other words - if the goal is just to create a string sequence - then transclusion is all you need. If the goal is to find a specific tiddler or tiddlers - then you need filters

Cheers - CB

The docs could definitely use improvements, in all sorts of ways. If you want to take a stab at improving in this area, you can do it – if you’re comfortable in git – through an issue or, better, a pull request. If you’re not versed in git, then you can use the Docs PR-maker edition.

I assume you mean the examples shown at the SetWidget.

The example for addprefix is at: https://tiddlywiki.com/#addprefix%20Operator%20(Examples).
IMO most of the usecases you request are described with the set-widget, except macro or procedure return values.

Macro and return values should not used that way. Functions are much better suited for that usecase.

I am not sure, what you mean here. Can you be more specific.

While I don’t want to speak for Bob, I would love it if rather than that one example of

{{{ Cat Garden [[Favourite Armchair]] +[addprefix[My ]] }}}

There would also be ones like this:

<$let owner=" Your ">
{{{ Cat Garden [[Favourite Armchair]] +[addprefix<owner>] }}}
</$let>

{{{ Cat Garden [[Favourite Armchair]] +[addprefix{!!field-name}] }}}

(where field-name might, for instance, be "Our "), and perhaps other examples as well.

But it is a very large job to do this sort of editing across the whole of https://tiddlywiki.com.


I’ve thought a number of times about how documentation could be improved, but have never really been able to settle on a reasonable proposal. It’s not a trivial topic.

@pmario

yes, the examples for the setwidget are more comprehensive and understandable for various situations someone finds themselves in. Even @EricShulman’s explanation to my original post,

is more explanatory and provides some sort of template, after all, the only thing that changes in this example is the widget/operator name. Now, I hear the multitude utter, ‘but if you understand filter syntax then this is all obvious’ and that’s the problem. Most people who go to the documentation are like me, casual users who forget stuff between sittings or whose current TW programming uses a situation they have not used before. Most of the people, like yourself and @EricShulman and @TW_Tones, dream filter syntax and so might require a reminder of what a widget/operator might do but do not need the level of assistance I am suggesting is needed.

So the example for addprefix,

Cat Garden [[Favourite Armchair]] +[addprefix[My ]]

is hopelessly inadequate for any other situation other than prefixing literals. I would immediately replace this with @EricShulman’s explanation from above.

@TW_Tones’ missive, https://anthonymuscio.github.io/#Standard%20Nomenclature is great but at the other extreme of usefulness, lots of dense text that requires intense scrutiny (yet better than most other stuff I have come across, even if it might be out of date).

GROK Tiddlywiki’s page, Common Transclusion Syntax, is closer to the mark, I think, but it could use the paragraph from @EricShulman I quoted above to make things clear.

As for concatenation, this is something that is used frequently, I would have thought especially from my long term programming experience. Yet the documentation has almost nothing about the various ways to do this. Even GROK does not have a simply accessible discussion on how to achieve this. Yes, I know, using the operators is one way of doing it but @Christian_Byron showed a different way using procedures. Surely a page for common functionality like concatenation and others would not go astray?

Just more ideas based on feedback to my post. I’m not trying to be critical, I am trying to improve things and, as a result, maybe make casual/early users more confident.

bobj

Worked flawlessly, as usual. Thanks @EricShulman

Also, I think your explanation for the various scenarios was most illuminating.

bobj

@Scott_Sauyet

I will have a look at https://saqimtiaz.github.io/tw5-docs-pr-maker/ and see how I can get involved.

As for the effort, yes it is huge but many hands make lighter work as they say.

Today, I was having some issues with the SetField action and looked up the documentation. It had examples of many situations but not the one I needed, setting the value of an already existing field in a tiddler. Reading the doc more deeply, rather than just going to the examples which I am sure most of us to initially, it stated to use the existing field name as an attribute without the $ sign, so I did that and everything works.

However, adding a simple example would have made life a lot easier, after all it is one of the use cases for this action.

[follow up] have now added an example to the documentation using the GIT facility mentioned previously

bobj

I, for one, am starting to internalize the filter syntax, but still get tripped up semi-regularly. My trouble right now can be best described with a recent anecdote:


Ok, I need to use a button to add a field to all tiddlers contained in a list. I’ve done that before, but what was the exact syntax?


Search documentation for "addfield"

No results


Well, I know I’ve done this before. Isn’t that the name?


Add a hyphen, and search for "add-field"

Two results including WidgetMessage: tm-add-field


All right, why is there a hyphen in “add-field” but not in “addprefix”? Also, I thought this was a direct action widget, not a message one. Well, no matter, let’s visit that tiddler.


The tm-add-field message is handled by the FieldManglerWidget. It adds the specified field with a blank value if the field doesn’t already exist.

Name Description
param Name of field to add

The add field message is usually generated with the ButtonWidget, and is handled by the FieldManglerWidget.


That’s it?

Really?

I recently visited ButtonWidget; I’m quite sure there’s nothing relevant there. And FieldMangerWidget describes something about how these are generated, probably by the system; it doesn’t sound like documentation for how to send a message. Ok, well that Messages tag sounds likely.


Clicks the tag pill

50+ tiddler titles for other messages


None of those look helpful. Let’s look at the Tag Tiddler for Messages.


Widget messages are generated by Widgets in response to user actions. Messages have a name , an optional primary parameter , and one or more optional named parameters. These messages travel up the widget tree where they are handled by ancestor widgets or the core itself.


Really? No information about how to SEND a damned message? Tags of Concepts and Core Messages. Ok, Concepts is definitely not going to help here. What if I open the Core Messages tiddler?


Widget messages are generated by Widgets in response to user actions. Messages have a name, an optional primary parameter, and one or more optional named parameters. These messages travel up the widget tree where they are handled by ancestor widgets or the core itself.

The following widget messages are implemented by the core:

    (followed by what looks like the same list in the Messages tag pill dropdown.)


Arggh!!!

Ok, I know its something like action-send-message. And it’s pretty clear that I only need one argument, named param, since that was one of the few bits of information in the first tiddler. I guess the tiddler to set it on is optional, defaulting, I assume to the current tiddler. But wait, what about the value? Can that be optional?


Search for send-message

No results

Grrrr. Search for sendmessage without the hyphen

Numerous results, starting with ActionSendMessageWidget


Ok, let’s try that one. But why is there no hyphen here?!


Introduction

The action-sendmessage widget is an action widget that sends a message back up the widget tree. ActionWidgets are used within triggering widgets such as the ButtonWidget.

Content and Attributes

The action-sendmessage widget is invisible. Any content within it is ignored.

Attribute Description
$message The message to send (eg, WidgetMessage: tm-new-tiddler)
$param Optional parameter string whose meaning is dependent on the message being sent
$name Optional name of additional parameter
$value Value for optional parameter whose name is specified in $name
$names Introduced in v5.2.1 Optional filter evaluating to a list of additional parameter names
$values Introduced in v5.2.1 Optional filter evaluating to a list of parameter values corresponding to the parameters names specified in $names
{any attributes not starting with $} Multiple additional, optional named parameters that are attached to the message

Examples

Here is an example of button that displays both a notification and a wizard, and creates a new tiddler with tags and text:

<$button>
<$action-sendmessage $message="tm-modal" $param="SampleWizard"/>
<$action-sendmessage $message="tm-notify" $param="SampleNotification"/>
<$action-sendmessage $message="tm-new-tiddler" title="This is newly created tiddler" tags="OneTag [[Another Tag]]" text=<<now "Today is DDth, MMM YYYY">>/>
Click me!
</$button>

That renders as:

+-----------+
| Click me! |
+-----------+

(pardon the ASCII.)


So wait, is it called param or $param? I assume the latter is correct, since there are actual examples, and they use the $. Still have no idea how to supply the value. Is it value, $value, or something else? Or worse, can this only add a field and it takes a second step to set its value? That would be stupid.

It’s late, and maybe being tired is making me stupid. I’ll look again another day.



(a few days later): Sees Bob’s discussion of the SetWidget, which triggers something.

Search for "set widget"

First link: https://tiddlywiki.com/#ActionSetFieldWidget


D’oh!!

Now why was I trying to do that again?



This is far too frequent for me, bouncing around the documentation, hoping to find something relevant.

The only think I’m certain would help would be many more examples, and many more “see also” links. Even that is a big job, and I really feel it’s only a start.

2 Likes

That’s a nice story. – Some time ago I did create a PR, that was rejected. But I think it would have solved all your problems. If you would have searched for add. IMO most of the answers would have been shown.

Changes in the PR:

from

title: $:/core/ui/DefaultSearchResultList
tags: $:/tags/SearchResults
caption: {{$:/language/Search/DefaultResults/Caption}}
first-search-filter: [!is[system]search:title<userInput>sort[title]limit[250]]
second-search-filter: [!is[system]search<userInput>sort[title]limit[250]]

...

to

title: $:/core/ui/DefaultSearchResultList
tags: $:/tags/SearchResults
caption: {{$:/language/Search/DefaultResults/Caption}}
first-search-filter: [!is[system]search:title<userInput>] :sort:integer[levenshtein<userInput>] :and[limit[250]]
second-search-filter: [!is[system]search<userInput>sort[title]limit[250]]

...

I feel for you @Scott_Sauyet , your journey is similar to one I take every time I re-start TW development again. I also seem to be bedding down the basics of syntax but like you can not understand why some things include a hyphen and others do not. Maybe a result of enhancements over time by a team :slight_smile:

I will though, now I have registered on GIT project, will try and add content to the documentation that I think would be helpful. Not sure if it will all be accepted but then we can only try.

I hope familiarity will assist in overcoming these types of issues. Well, anyway, I live in hope.

bobj

1 Like

That would definitely have helped, as would the three-part result in the subsequent discussion.

But I think it’s a far way from a full solution. add field (with or without punctuation) was a reasonable guess, but in fact it wasn’t really what I needed, which was setfield. And my main frustration there was not being able to keep clicking on links to find related information. The docs for tm-add-field did not really explain how to use it, and there were no links to other documentation that did explain. That was the crux of the matter. The bad guess on the search and the difference with and without the hyphen was mostly a minor nuisance.

I have to say that for me, it’s no longer anything like “every time.” It’s becoming less and less frequent. But it’s frustrating every time… and for some reason it seems to have happened a lot more in the past month or two.

I think there’s more consistency than we sometimes realize. The operator names, for instance, simply don’t have punctuation or capital letters, except for two oddballs, standard-deviation and search-replace. The ActionWidgets all have names like $action-createtiddler and $action-deletefield. And the Messages look like tm-add-field and tm-edit-text-operation. My trouble in this area is that I don’t immediately recall what’s a Filter Operator, what’s an ActionWidget, what’s a Message, so that consistency doesn’t help me much.


I created an initial PR to start addressing what I think of as the core problem, one of discoverability of the documentation, adding a “See Also” footer, based on a list field called see-also. It’s perhaps too naive on its own, and might need a bit of polish before it’s acceptable, but I’m hoping that the maintainers would see this as a useful direction.