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]]

...
1 Like

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

2 Likes

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.


@saqimtiaz: This was my first use of the PR-maker. I had recommended it here to someone else without ever trying it, and figured I should give it a go. I had a problem first with an expired token then (I think) because the replacement token didn’t have the correct permissions.1 I’m bothered now that I am using what may be a too-permissive token. I would appreciate if the process told me what permissions the PR-maker required. Because I was having problems, I exported the changed tiddlers to JSON so that I could do this from the command line if necessary. Then, to test fresh, I switched browsers, created still another GH token, with nearly every permission, dragged my JSON export into the PR maker, and was able to accomplish this. I’ve updated the token in my main (Brave) browser’s local storage, and expect next time to be smoother.

The PR that was generated has more changes than I would like, as it doesn’t just add my new field, but rearranges the others, alphabetizing them. Is this simply because of my JSON export/import? Or is PR Maker doing this? Also, I thought I read somewhere that we shouldn’t update modified date in docs PRs. Is that true? And if so, again, was this due to my JSON detour, or is PR Maker not skipping them appropriately? Or do I simply misremember a modified rule whose origin I can’t even recall?

Update: There was one more bit of friction. My PR added one system tiddler and modified another. I would have been nice to have these show in the initial list. It was not hard to add them, but the more that’s automated, the better.

And I should have said above that I think this is a wonderful tool! I’m sure future uses will be smoother. I’m pretty used to working in git, so I don’t know if it will become a regular tool for me, but it’s nice to know that it’s there.


1 This was the on-screen error. I didn’t dig in any further:

If I understand correctly, your comment here really captures my most frequent frustration at tw-com.

That is: I often look at an example and think, “Yeah, I totally see how that thing works for literal strings, but I still don’t get how to make it play nice with connected stuff from variables / transclusions / fields…”

Of course, all the info on how variables and translusions (simpliciter, and transclusions of fields) is “in there”, but sprinkling them into examples would help folks integrate those lessons.

For example, the addsuffix operator has the example: [[London]addsuffix[ Underground]] which could be rounded out with:

{{{ [[London]addsuffix[ — ]addsuffix{$:/SiteSubtitle}] }}}
{{{ [[TiddlyWiki]addsuffix[ —  now at version ]addsuffix<version>] }}}

[EDIT to add: I’m not actually confused about this kind of simple example anymore, but I remember when I was. For my current threshold of learning, though, there are other analogous head-scratchers, but spelling them out as documentation suggestions is… exactly where it takes me more time than I want to toss in at the moment. :sweat_smile: ]

3 posts were split to a new topic: Prblem Signing TiddlyWiki CLA

That’s what I was describing, yes, although it wasn’t particularly for myself. Like you, I’ve mostly moved past that confusion, and can usually see how to use text references, variable references, etc., in place of a literal. But having such in the documentation would help reduce that.

In a subsequent post, I tried to describe with an anecdote my current bugaboo: finding documentation that I know exists, but have not yet internalized. I’m feeling that many links are missing that would help me traverse the docs. For instance, what’s the path from tm-cancel-tiddler to a tiddler that actually demonstrates how to use it? Or to one that explains why I shouldn’t use it?

1 Like

I have been thinking a lot since the start of this discussion regarding TW documentation.

Part of the problem outlined by @Scott_Sauyet and addressed in parts by later comments is that we all have different names for the same thing.

For example, today I wanted to create a dropdown selection in a create action so the user can select from a pre-prepared list. I remember doing that before but can’t exactly rememberwhat widgets, etc, I used. (I’m an old man and just need more stronger drugs :slight_smile: )

Searching in TW was a waste of time, it returned too many results of which I could not easily decide which to read, including a whole set of TW version notes (why are they included at all unless I am asking for details of versions?)

In the end I went back to my previous TW where I did that and copied the code. After some surface editing, all great.

Yet in my coding circle, the function is called a drop down and I’m sure you all agree, it is a widely used facility. Why not have an entry in the TW documentation for that? I know I can propose such an entry but the thing here is that there are many such functions.

Maybe a better solution is to provide a ‘wraping’ of the TW documentation in a mapping layer, map an external term to the correct TW internal term(s) (like a thesaurus)? This layer could also provide sample code.

The entries in this layer can have many tags, each representing that term in alternate names.

Just another thought.

Stop thinking now, drug time…

bobj

1 Like