Using text references in TiddlyWiki script - support in tiddlywiki

Folks,

I am writing a macro and/or custom widget that allows the user to provide a text reference in the following forms tiddlername, tiddlername!!fieldname or !!fieldname. See https://tiddlywiki.com/#TextReference

  • I want this parameter to be converted to target-tiddler and target-field and when one or the other is not provided use a default eg target-tiddler=<<currentTiddler>> and target-field=text

This seems to me a valid way to reference resources in tiddlywiki for which we do not have any helper macros.

  • My attempts have being failing

eg

\procedure update.reference(text-reference target-tiddler target-field)
   \function delimiter() !!
<$parameters target-tiddler={{{ [<text-reference>split<delimiter>first[]] :else[<currentTiddler>] }}} field={{{ [<text-reference>split<delimiter>last[]] :else[<target-field>] }}}>
text-reference: <<text-reference>>, target-tiddler: <<target-tiddler>>, field: <<field>>.
</$parameters>
\end 

# <<update. Reference "tiddlername!!fieldname">>
# <<update. Reference "!!fieldname">>

Background;
I am trying to create a procedure or custom widget that allows you to provide a text references or tiddlername and fieldname, that transudes the value, however allows you to click it or an icon next to it to edit it in-line and/or allows you to select from a list (generated by a filter).

Why a text reference and not separate parameters?;

  • Using a text reference implies a fixed reference that you do not change, it is a reference to a specific location tiddler and/or fieldname to store a global value.
  • But you could use target-tiddler and/or target-field if you generate them programmatically.

You have a couple of typos (spaces/inconsistent capitalization in your macrocalls). But if I’m understanding your goal, I’m also not sure you need $parameters to do this. It seems to me that you don’t really need the target-tiddler/target-field parameters, either, since they can be derived from text-reference.

\procedure update.reference(text-reference delimiter:"!!")
<$let
	target-tiddler={{{ [<text-reference>split<delimiter>first[]!match[]] ~[<currentTiddler>] }}}
	field={{{ [<text-reference>search<delimiter>split<delimiter>last[]] ~[[text]] }}}
>
	''text-reference:'' <<text-reference>>,
	''target-tiddler:'' <<target-tiddler>>,
	''field:'' <<field>>.
</$let>
\end 

# <<update.reference "tiddlername!!fieldname">>
# <<update.reference "!!fieldname">>
# <<update.reference "tiddlername">>

Edit: Made some changes so it will fall back to “text” as standard when no field is specified.

Thanks for your response @etardiff

  • I can’t see them, but discourse has a habit of changing them.

Of course if the text reference is given, but I want to allow in the same procedure/custom widget to also allow the separate values.

  • I am using the parameters widget for “attribute processing”, think of also immediately using a $let widget, but I am using the $parameters widget to do two jobs.

I have now moved these into two functions, thinking they could be global

\function reference.tiddler(reference default:"currentTiddler") [<reference>split[!!]first[]else<reference>] :else[<currentTiddler>]
\function reference.field(reference default:"default") [<reference>split[!!]last[]else<reference>]

# <<reference.tiddler>>
# <<reference.field>>
# <<reference.tiddler "tiddlername!!fieldname">>
# <<reference.field "tiddlername!!fieldname">>
# <<reference.tiddler "!!fieldname">>
# <<reference.field "!!fieldname">>
# <<reference.tiddler "tiddlername">>
# <<reference.field "tiddlernamef">>
  • Defaults are not yet working, The first two should use the default, as should any without a tiddlername or fieldname.

You need to exclude the blank results of the split, as I did with <<target-tiddler>> in my code above.

\function reference.tiddler(reference default) [<reference>split[!!]first[]!match[]] ~[<default>!match[]] ~[<currentTiddler>]
\function reference.field(reference default:"default") [<reference>split[!!]last[]!match[]] ~[<default>]

I’d also leave the reference.tiddler default blank, or it will give you the title “currentTiddler” rather than the actual contents of <<currentTiddler>>.

I solved the default issue too;

  • But thanks a lot.
\function reference.tiddler(reference default:currentTiddler) [<reference>split[!!]first[]else<reference>!is[blank]else<default>]
\function reference.field(reference default:fieldname) [<reference>split[!!]last[]else<reference>!is[blank]else<default>]
  • note how the defaults can be given as parameters.

However this is via functions, I wonder if there are other ways to simplify the retrieval of the value at the reference?

  • I imagin these can be referenced from within a procedure

Working on that now.

[Edit]

  • Dealing also with ## indexes would be good

Just in case you haven’t encountered this potential issue yet…

If you use default:currentTiddler, <<reference.tiddler>> will yield “currentTiddler”, not the actual value of <<currentTiddler>>. That’s why I omitted the default value from the default parameter in my version, and used ~[<default>!match[]] ~[<currentTiddler>] instead.

Thanks for pointing that out, I was planning to do this and forgot

 :else[<default>getvariable[]]

In fact I have dropped the parameter reference and set it once outside the functions so I can do this;

\function reference.tiddler(default:currentTiddler) [<reference>split[!!]first[]else<reference>!is[blank]] :else[<default>getvariable[]]
\function reference.field(default:fieldname) [<reference>split[!!]last[]else<reference>!is[blank]else<default>]

<$let reference="$:/HistoryList!!current-tiddler">
<<reference.tiddler>> = <<reference.field>>

<$transclude $tiddler=<<reference.tiddler>> $field=<<reference.field>>/>
</$let>
<hr>
<$let reference="!!description">
<<reference.tiddler>> = <<reference.field>>

''returns:'' "<$transclude $tiddler=<<reference.tiddler>> $field=<<reference. Field>>/>"

</$let>
<$let reference="!!">
<<reference.tiddler>> = <<reference.field>>

''returns:'' "<$transclude $tiddler=<<reference.tiddler>> $field=<<reference.field>>/>"

</$let>
  • Until I work out how to use preset variable OR parameter.