Can I use transclusion in hyperlinks?

162 views
Skip to first unread message

Jake

unread,
Jun 7, 2020, 6:20:27 AM6/7/20
to TiddlyWiki
The question is can I use a transclusion in hyperlinks?

For example if I have links to local files, folders located in C:\MyFolder01\MySubfolder\myfile.txt, and it currently works just file [[myfile|file:///C:\MyFolder01\MySubfolder\myfile.txt]], but if I rename MyFolder01 to MyFolder02 I don't want to rename EVERY link that I made to that folder, making it [[myfile|file:///C:\MyFolder02\MySubfolder\myfile.txt]] for every single one of them.

Can I make a tidller like [[MyFolder Path]] and then use [[myfile|file:///{{MyFolder Path}}\MySubfolder\myfile.txt]]? And if I rename/move my folder - I just adjust the single tiddler [[MyFolder Path]] and that's it, no need to rename ALL the links.

Spoiler: Well, obviously the mentioned thing didn't work. I tried. :)  So the question is there is another way to do that? Maybe some macro or something? Because I don't think I'm the first one with this problem (though I searched the forum, didn't find the answer).

Eric Shulman

unread,
Jun 7, 2020, 7:35:13 AM6/7/20
to TiddlyWiki
On Sunday, June 7, 2020 at 3:20:27 AM UTC-7, Jake wrote:
The question is can I use a transclusion in hyperlinks?
Can I make a tiddler like [[MyFolder Path]] and then use [[myfile|file:///{{MyFolder Path}}\MySubfolder\myfile.txt]]? And if I rename/move my folder - I just adjust the single tiddler [[MyFolder Path]] and that's it, no need to rename ALL the links.
...Maybe some macro or something?...

Yes... a macro (actually 2 macros)

First, enter this into a tiddler (e.g., MyLink) tagged with $:/tags/Macro:
\define link(text,file) <$vars folder={{MyFolderPath}}><<link2file "$text$" "$file$">></$vars>
\define link2file(text,file) [ext[$text$|file:///$(folder)$/$file$]]

Next, create a tiddler named "MyFolderPath", containing something like:
C:/MyFolder02

Then, to use it, write:
<<link "text to show" "MySubfolder/myfile.txt">>

What it does:
The <<link>> macro gets the contents of MyFolderPath and puts it in a variable and then calls on <<link2file>>.
The <<link2file>> macro substitutes the macro parameters, $text$ and $file$ along with the variable $(folder)$ to construct and return an external link for rendering.

Note:
* even though Windows uses backslash in path names, we can use *forward slash* within the browser.  This makes it cross-platform compatible, since other platforms (e.g., Linux) use forward slash exclusively.

enjoy,
-e

Jake

unread,
Jun 7, 2020, 8:48:31 AM6/7/20
to TiddlyWiki
Wow! Looks like it worked! Thanks a lot, Eric!

"BUT..." :)  what if I want to make it a bit more complex? What if I want to make "MyFolder" also a variable?

e.g. if I have folders like "MyDocs", "MyImages", "MyData", "Downloads", etc. with this method, as I understood, I would have to make a separate variable for each, like:

MyGoto Macro:
\define godocs(text,file) <$vars folder={{MyDocs Path}}><<link2file "$text$" "$file$">></$vars>
\define goimg(text,file) <$vars folder={{MyImages Path}}><<link2file "$text$" "$file$">></$vars>
\define godata(text,file) <$vars folder={{MyData Path}}><<link2file "$text$" "$file$">></$vars>
\define godownloads(text,file) <$vars folder={{Downloads Path}}><<link2file "$text$" "$file$">></$vars>
\define link2file(text,file) [ext[$text$|file:///$(folder)$/$file$]]

with tiddlers [[MyDocs Path]], [[MyImages Path]], [[MyData Path]], [[Downloads Path]] defining path to the folders.

and the usage

<<godocs "My awesome document" "Agreement/doc1.doc">>
<<goimg "My Fabulous picture" "Scenery/lake.img">> etc.

but what if I want a "universal" macro with usage like:

<<gofolder "text to show" "Folder" "MySubfolder/myfile.txt">>

How can I do that? Or will it become too complex? Actually I can do with the separate ones, but was just curious if it is possible to make it into one?

Eric Shulman

unread,
Jun 7, 2020, 12:25:21 PM6/7/20
to TiddlyWiki
On Sunday, June 7, 2020 at 5:48:31 AM UTC-7, Jake wrote:
Wow! Looks like it worked! Thanks a lot, Eric!
"BUT..." :)  what if I want to make it a bit more complex? What if I want to make "MyFolder" also a variable?
e.g. if I have folders like "MyDocs", "MyImages", "MyData", "Downloads", etc. with this method, as I understood, I would have to make a separate variable for each, like:

MyGoto Macro:
\define godocs(text,file) <$vars folder={{MyDocs Path}}><<link2file "$text$" "$file$">></$vars>
\define goimg(text,file) <$vars folder={{MyImages Path}}><<link2file "$text$" "$file$">></$vars>
\define godata(text,file) <$vars folder={{MyData Path}}><<link2file "$text$" "$file$">></$vars>
\define godownloads(text,file) <$vars folder={{Downloads Path}}><<link2file "$text$" "$file$">></$vars>
\define link2file(text,file) [ext[$text$|file:///$(folder)$/$file$]]
with tiddlers [[MyDocs Path]], [[MyImages Path]], [[MyData Path]], [[Downloads Path]] defining path to the folders.
and the usage
<<godocs "My awesome document" "Agreement/doc1.doc">>
<
<goimg "My Fabulous picture" "Scenery/lake.img">> etc.

Yes.  That would work just like you have written.  The name of the macro implies the name of the tiddler containing the path text.
 
but what if I want a "universal" macro with usage like:
<<gofolder "text to show" "Folder" "MySubfolder/myfile.txt">>

That's even easier.  You can just add a third param to the outer <<link>> macro, and combine it with the inner <<link2file>> macro, like this:
\define gofolder(text,folder,file) [ext[$text$|file:///$folder$/$file$]]
and then use it as you have indicated:
<<gofolder "text to show" "Folder" "MySubfolder/myfile.txt">>

Notice how, since you are no longer getting the folder from the contents of a tiddler, there's no need for an
outer macro to use transclusion (the {{...}}) to get the variable value for use with an inner macro, and
$(folder)$ (a *variable* substitution) has been replaced by $folder$ (a *macro param* substitution).

However, since you would then be providing all the needed values as parameters to the macro call,
there's really no reason for the folder and file values to be passed as separate params, and you could just write:
\define gofolder(text,file) [ext[$text$|file:///$file$]]
which you would call like this:
<<gofolder "text to show" "Folder/MySubfolder/myfile.txt">>

See.  Nice and simple!

enjoy,
-e 

Eric Shulman

unread,
Jun 7, 2020, 12:42:25 PM6/7/20
to TiddlyWiki
On Sunday, June 7, 2020 at 5:48:31 AM UTC-7, Jake wrote:
but what if I want a "universal" macro with usage like:
<<gofolder "text to show" "Folder" "MySubfolder/myfile.txt">>

On Sunday, June 7, 2020 at 9:25:21 AM UTC-7, Eric Shulman wrote:
...you could just write:
\define gofolder(text,file) [ext[$text$|file:///$file$]]
which you would call like this:
<<gofolder "text to show" "Folder/MySubfolder/myfile.txt">>
See.  Nice and simple!

Addendum:

There *is* a drawback to the "universal" macro, in that every usage would then contain a literal instance of the folder name.
If you wanted to move that folder later on, you would have to change each place you called the macro!

With the "folder name stored in a separate tiddler" method, you only have to change the folder value once, in the separate tiddler,
and all instances of the macro usage would stay the same, but use the newly changed folder value.

To keep "the best of both worlds", you could do something like this:
\define gofolder(text,foldertid,file) <$vars folder={{$foldertid$}}><<link2file "$text$" "$file$">></$vars>

\define link2file(text,file) [ext[$text$|file:///$(folder)$/$file$]]
with tiddlers [[MyDocs Path]], [[MyImages Path]], [[MyData Path]], [[Downloads Path]] defining path to the folders.

and then call it like this:
<<gofolder "text to show" "MyDocs Path" "agreement/doc1.doc">>
<
<gofolder "text to show" "MyImages Path" "Scenery/lake.img">>
<
<gofolder "text to show" "MyData Path" "Data/something.dat">>
<
<gofolder "text to show" "Downloads Path" "Downloads/somefile.ext">>

enjoy,
-e

Jake

unread,
Jun 7, 2020, 5:46:23 PM6/7/20
to tiddl...@googlegroups.com

To keep "the best of both worlds", you could do something like this:
\define gofolder(text,foldertid,file) <$vars folder={{$foldertid$}}><<link2file "$text$" "$file$">></$vars>
\define link2file(text,file) [ext[$text$|file:///$(folder)$/$file$]]
with tiddlers [[MyDocs Path]], [[MyImages Path]], [[MyData Path]], [[Downloads Path]] defining path to the folders.

and then call it like this:
<<gofolder "text to show" "MyDocs Path" "agreement/doc1.doc">>
<
<gofolder "text to show" "MyImages Path" "Scenery/lake.img">>
<
<gofolder "text to show" "MyData Path" "Data/something.dat">>
<
<gofolder "text to show" "Downloads Path" "Downloads/somefile.ext">>


 Yes! That's it! That's exactly what I wanted - a way to transclude (well, "kind of") a "path tiddler" into a local hyperlink, so that in case one of the "core folders" is renamed or moved I wouldn't have to search all the relative hyperlinks throughout the whole wiki and correct it one by one. I just edit one tiddler with the proper path.

So now with this macro 

\define gofolder(text,folderpath,file) <$vars folder={{$folderpath$}}><<link2file "$text$" "$file$">></$vars>
\define link2file(text,file) [ext[$text$|file:///$(folder)$/$file$]]

and tiddlers [[#MyDocs]], [[#MyImages]], [[#MyData]], [[#Downloads]] (listed them all in [[#MyPaths]] tiddler for easier reference)

i can use

<<gofolder "text to show" "#Downloads" "Downloads/somefile.ext">>
<<gofolder "text to show" "#MyDocs" "agreement/doc1.doc">> etc.

and it works! If I change the location of Downloads, I just change 1 Tiddler [[#Downloads]] and all the apropriate links works just fine without any corrections!

Thanks again, Eric!

Jake

unread,
Jun 29, 2020, 9:17:51 AM6/29/20
to TiddlyWiki
Another little dumb question. How to transclude field value into a hyperlink? I tried to tailor info from this topic, but wasn't successful. 

1. So, question is very easy: If I have a "mylink" field in a tiddler. How do I transclude it so that it continued to operate as a hyperlink?
I tried smth like <a href="{{!!mylink}}">MyText</a>  or  [ext[MyText|{{!!mylink}}]], but obviously that didn't work. Is there a proper syntax somewhere? or should it be done via some variables?

2. Plus I need to have it working to local folders as well. So if I have "mylocallink" field, how to do that?
<a href="file:///{{!!mylocallink}}">MyText</a> - obviously didn't work either.

3. And in general: what to do if I want to make values in "mylink" or "mylocallink" fields to be PART of the final hyperlink?

Jake

unread,
Jun 29, 2020, 9:21:15 AM6/29/20
to tiddl...@googlegroups.com
Oooops... looks like there is an answer in the neighbour topic. I swear to God it wasn't there when I started typing this one. I gonna check that "addprefix" or "addsuffix" thing...

PS. Checked this <a href={{{[[file:///]addsuffix{!!mylocallink}]}}}>{{!!mytext}}</a> and looks like it worked!.. though there are definitely A LOT of brackets for a commoner... i'm a bit scary with this "{{{[[" or this "}]}}}" :))

понедельник, 29 июня 2020 г., 16:17:51 UTC+3 пользователь Jake написал:
Reply all
Reply to author
Forward
0 new messages