Question about [ext[..]] with value from a field

Hi. I’d like to create a link to a local file (say files/book.pdf) where I put book.pdf in the field file of a tiddler.

I tried:

[ext[files/{{!!file}}]]

or

<$set name="ff" value="{{!!file}}">
[ext[files/<<ff>>]]
[ext[files/$(ff)$]]
[ext[files/$ff$]]
</$set>

but none of them works. The variable <<ff>> gives book.pdf correctly, but how do I use it inside [ext[...]?

Hi! When using the SetWidget, we use <<ff>> to get variables. So the first [ext[files]] is the correct one. I’m not sure why you’re sample code isn’t working. Does anyone know why?

I tried to solve your problem without using the [ext[link]] syntax.

\define fileLink(name:"link",path:"files/",field:"file")
<a href={{{[is[current]get<__field__>addprefix<__path__>]}}} class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer">$name$</a>
\end

<<fileLink>>

EDIT: Never mind! Here’s a much simpler way to do it with the [ext[]] syntax.

\define extFileLink() [ext[files/$(file)$]]

<$vars file={{!!file}} >
<<extFileLink>>
</$vars>

The extFileLink macro makes the [ext[]] link. The $()$ means it will get the value of a variable that is defined outside the macro and substitute it. The vars widget (which is just the set widget but simpler) defines the variable “file” and gives it the value of whatever is stored in the field file, which is book.pdf. By the time extFileLink is called, the file variable has already been defined.

Have a great day!


PS: Have you seen this: How to embed PDF and other documents from the TW docs? I think you can use canonical uris to link to files too, but I haven’t tried it.

Ahh this works:

\define extFileLink() [ext[files/$(file)$]]

<$vars file={{!!file}} >
<<extFileLink>>
</$vars>

Thank you!

So we need to create a macro to be able to use the variable file inside [ext...] command. I wonder why can’t we not have to use macro and simply do [ext[files/$(file)$]] or [ext[files/<<file>>]] (or something similar) in normal wikitext. Oh well.

PS: Have you seen this: How to embed PDF and other documents from the TW docs? I think you can use canonical uris to link to files too, but I haven’t tried it.

Yes I read it. The reason I dont use canonical uris is because I want to write more details about the pdf in the tiddler body.

You can do it with just one macro.

\define links(name) [ext[files/$name$]]

Then you call it with <<links "book.pdf">>.

But a shorthand macro (alone) can’t get the value of a field.

Why? When you call <<links "book.pdf">>

  1. Get the string inside links macro and replace $name$ with book.pdf.
  2. Put this: [ext[files/book.pdf]] into the tiddler
  3. Parse that wikitext and render it into html

Macros and $var$ are text substitutions. You can’t say <<links {{!!field}}>> because this is what would happen:

  1. Get the string inside links macro and replace $name$ with the text “{{!!field}}”.
  2. Put this: [ext[files/{{!!field}}]] into the tiddler
  3. Parse that wikitext and render it into html. This would either render as a link to “files/{{!!field}}” or give an error, because this way of writing [[links]] and {{transclusions}} can’t have {{ or [[ inside them, or else they won’t work.

Edit: You can use the longer way of calling macros:

\define extLink(file) [ext[files/$file$]]

<$macrocall $name="extLink" file={{!!file}} />

And this would work because when Tiddlywiki parses the macrocall widget, it already gets the value of field “file”. Make sure not to put " " around the transclusion, or else it will take it literally.

But why can’t we do that with a setwidget? Because variables are parsed in time with the wikitext. So it would be like:

  1. Parse the wikitext
  2. Set the value of variable ff to the value of field “file”, which is book.pdf
  3. Then parse the [ext[…] into a link–hold up! I can’t parse the <<file>> part, I don’t know what << means!

I’m on mobile and the caps are for emphasis, not aggression :laughing: please correct me if I’m wrong abt my understanding of macros.

1 Like

Forgive me for forgetting about the macrocall widget :man_facepalming: , I’m not a long-time TW user yet. You can feed a field value into a macro using the macrocall widget. The code would be something like this:

\define extLink(file) [ext[files/$file$]]

<$macrocall $name="extLink" file={{!!file}} />

This is not equivalent to <<extLink "{{!!file}}">> or <<extLink {{!!file}}>>. The shorthand way of calling macros <<macro>> doesn’t parse the “{{!!file}}” as wikitext.

1 Like

Just a quick FYI Now in Tiddlywiki 5.2.0 there are other cases where we can avoid the macrocall widget because of More Flexible Parsing of Macros

Eg: <<macro "{{!!file}}">> but this does not answer the original question just points to new alternatives.

1 Like

Thank you for a detailed explanation.

Thank you. The link you gave talked about using the output of macro as an input of another macro. The documentation says this would work:

<<mymacro arg:"""nested <<macro>> call""">>

So I experimented with this:

\define extLink(file) [ext[files/$file$]]
\define filepath() books.pdf
<<extLink file:"""<<filepath>>""" >>

But it does not work :frowning: It rendered files/<<filepath>>. (I’m on 5.2.0)