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">>…
- Get the string inside links macro and replace $name$ with book.pdf.
- Put this: [ext[files/book.pdf]] into the tiddler
- 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:
- Get the string inside links macro and replace $name$ with the text “{{!!field}}”.
- Put this: [ext[files/{{!!field}}]] into the tiddler
- 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:
- Parse the wikitext
- Set the value of variable ff to the value of field “file”, which is book.pdf
- 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  please correct me if I’m wrong abt my understanding of macros.
 please correct me if I’m wrong abt my understanding of macros.