How to assign a value to field within a macro?

It is possible, AFAIU, to make e.g field values be set upon page load, i.e without user interaction.

Following on: you can do this with startup actions, assuming that you don’t need the field to reflect changes made since startup. (And if you do, you probably want to tie the $action-setfield to the trigger widget responsible for the change anyway.)

I do have an experimental trigger-widget, which will be activated when a tiddler is rendered. I do not propagate it because it has the potential to brick a wiki if done wrong.

You need a trigger.

What is the event that should cause the value to be assigned to the field?

i.e.: when should the assignment happen?

If it is, I’d be very surprised. Making changes to a tiddler just by opening it seems like tragic design. Wouldn’t it also update the tiddler every time it refreshed? And thus by updating, it would refresh? And thus by refreshing, It would update? etc…

The act of opening and viewing a tiddler seems like a side-effect free action, at least I would think it should be.

To answer your question, I’m not sure what you’re trying to do, but it might work out better for you if you detected changes to $:/HistoryList. It updates with every opened tiddler, and it maintains an order. Or you could take advantage of the tv-story-list variable.

I was referring to what @etardiff followed up with, i.e startup actions. Or can “page load” refer to some other time? Or maybe I’m wrong anyway and you can’t set a field value even at that point? I never used startup actions so I’m not sure.

No no. Not by opening a tiddler. At TiddlyWiki startup.

Well, that’s my understanding of the reply by @twMat .

Oops, did not notice twMat already replied.

1 Like

Ooh, you’re right. I misread.

Nope, you’re spot on.

I use startup actions quite heavily, all kinds of action widgets.

@TechTangle

I understand what your are after and its seems like a barrier to using tiddlywiki, however there are good reasons why you need a trigger.

However there are a lot of ways to solve things in tiddlywiki and tools to help. For example we can piggyback on existing triggers.

However could you explain when and how you want this field to be set at a practical or logical level without code? Think about what it means to the user, what it means to them?

I am sure we can get the result you want if not by others means.

Macros come into being when they are defined and I am sure you dont want it happening then.

  • you can include a trigger such as a button in a macro but the user needs to click it.

The aim is to facilitate diverse modes of presentation of images and their descriptions in TiddlyWiki.

I have a wiki with lots (hundreds) of image tiddlers (Bobwin.exe) each of which is a component of a narrative theme, each theme is represented by a uuid stored in a field. A narrative tiddler uses a macro to filter component tiddlers thus:

<<narrativeMaker "4a45696f-5fbd-4054-996b-523a0293727c">>

the narrativeMaker macro brings together the components of the theme and formats the visual presentation. There is a small-scale demo of the principles here: TiddlyImage — Beautifully compose & curate visual narratives

Because the uuid is passed as a parameter to the macro I wanted to find a technique to extend the narrativeMaker macro to store the uuid into a field, thereby solving the issue that I have hundreds of existing narratives and I would like to get programmatic access to their uuids. Use logic to check if the field exists, if not then create it.

Once programatic access to the uuids is possible the intention is then to extend the demo Tag Filtering tiddler such that the results are presented not just as a link, but enriched with a gallery of thumbnails for each result. Such as described here: Grid CSS in Tiddlywiki Demystified - #4 by Mohammad . Ideally each thumbnail when hovered upon would pop out with its enlarged image and text description.

Any help or guidance in accomplishing this would be much appreciated.

Have you looked at creating a single button to process all tiddlers and assign the UUID (If that what you want) in a batch. Then set up your new tiddler button to also add the UUID to all future tiddlers created that way?

Good idea, thanks, a single button to process all tiddlers! I’ll do that.

I’d like to create a ‘new narrative’ button that auto-generates a uuid, is there a way to do this?

I am sure but you need to concider your algorithium. You can use a counter as a seed, and a bach number eg on a list widget use the counter=item-no paremater then use the batch number and item-no to apply unique UUID’s

Search tiddlywiki resources for discussions on UID and UUID as its being discussed a few times.

You possibly want a macro you can use both in your button and your batch button.

Have a closer look at the ActionCreateTiddlerWidget and play with all the examples until you understand them.

The first example creates a new (non functional) Homemade Button.

If you click the tag: $:/tags/PageControls pill you’ll see all the functional buttons. You can use them eg: New Tiddler or New Journal to create your own button

have fun!
mario

So I’m reworking the narrativeMaker macro to be called with a field name as parameter but have hit on an issue that I can’t get past; The issue is <fieldvalue> does not appear to be passing its value into the filter. I’ve tried <<fieldvalue>> and fieldvalue, dollar signs and curly brackets in varying quantities, but I’m stumped. If, inplace of <fieldvalue>, I paste a known example uuid value into the filter then everything functions and renders as intended. N.B I get the correct output from <<fieldvalue>> on line 3 so I know the value has been assigned. Anyone know what’s wrong here?

\define narrativeMaker(fieldname)

<$set name=fieldvalue value={{{ [all[current]get[$fieldname$]] }}}>

<<fieldvalue>>

<!-- Transclude edit & read-only buttons -->>
<<toggle>>

<!-- Filter by the tiddler's field 'narrative', a uuid, to find the component tiddlers then sort and iterate to display -->

<$list filter="[narrative[<fieldvalue>]!tag[narrative]sort[title]]">
    <!-- Transclude the data via these templates to structure the layout, the absence before '||' in {{ ||Template }} transcludes the current tiddler to the template -->
    {{ ||NarrativeEditTemplate }}
    {{ ||NarrativeImageTemplate }}
</$list>
\end

<<narrativeMaker test>>

You’ve run up against a very common misunderstanding about filter syntax. When using a filter operator, the brackets surrounding the operand value are used to indicate how to handle that operand.

  • single square brackets are used to surround literal text values
    (e.g., narrative[someUUID])
  • single angle brackets are used to surround variable references
    (e.g., narrative<fieldvalue>)
  • single curly braces are used to surround tiddler field references
    (e.g., narrative{!!fieldname} or narrative{TiddlerName})

Note that, unlike wikitext syntax which uses doubled brackets, within filter syntax the brackets are not doubled.

Thus, in your filter, you could write:

<$list filter="[narrative<fieldvalue>!tag[narrative]sort[]]">
...
</$list>

which uses the value of the fieldvalue variable as the operand value.

Alternatively, you could also write it like this:

<$list filter="[narrative{!!$fieldname$}!tag[narrative]sort[]]">
...
</$list>

which constructs a field reference operand for the $fieldname$ of the current tiddler by adding a leading “!!” prefix to the $fieldname$ parameter

Some other notes:

Instead of using a $set widget like this:

<$set name=fieldvalue value={{{ [all[current]get[$fieldname$]] }}}>

you could use the more compact $let widget:

<$let fieldvalue={{{ [all[current]get[$fieldname$]] }}}>

Within the filter syntax you can also use the slightly more performant <currentTiddler> variable instead of the all[current] filter operator, like this:

<$let fieldvalue={{{ [<currentTiddler>get[$fieldname$]] }}}>

You could also simplify it even further by skipping the “filtered transclusion” syntax (tripled curly braces) entirely, and just use doubled-curly braces to make a direct field reference like this:

<$let fieldvalue={{!!$fieldname$}}>

(note that this syntax uses doubled-curly braces, since it is NOT a within a filter!)

I realize that all these variations on syntax can be somewhat confusing, especially if you are new to TiddlyWiki scripting… but I promise you that once you get some familiarity with them, it will become second nature and the “syntax guessing game” will be a thing of the past.

Hope this helps. Let me know how it goes…

enjoy,
-e

2 Likes

What if you wanted to set a field indicating last viewed?, do tiddlers refresh if there is no change to be properagated?

Sure such a trigger may give us “enought rope to hang ourselves” but it may also allow a class of solution that are otherwise imposible.

  • I have actualy used a message catcher to trap the navigate message and perfom actions on open tiddler and did not loose a wiki because of it.

As I wrote it is possible to do it without problems. If trigger actions only open new tiddlers which contain other triggers that’s not a problem. But if those triggers also modify the text area it can cause problems or if triggers are part of view templates. Otherwise it’s pretty robust.