[tw5] Create a style to show icon next to link title?

I’m trying to get a stylesheet working that will automatically insert the SVG icon before the link text. Here’s what I have so far:

\define link-icon-style()
<$set name=“uri” value=<<makedatauri “”"$(tid)$""" “text/plain”>> >
<$set name=“icon” tiddler=<> field=“icon”>
<$set name=“iconsrc” tiddler=<> >
<$list variable=“urititle” filter="""[removeprefix[data:text/plain,]]""">

a[href="#<>"] { display: inline-flex; align-items: baseline; gap: .15em; } a[href="#<>"]:before { content: <>; width: 1em; height: 1em; margin-top: 2px; align-self: center; fill: <>; }

</$list>
</$set>
</$set>
</$set>
\end

<$list filter="""[has[icon]]""">
<$vars tid={{!!title}}>
<>
</$vars>
</$list>

When I inspect the DOM and look at the tag created, the value of my content CSS rule shows as an … specifically a TiddlyWiki external link. I think some value is being interpreted as WikiText instead of plain text somewhere, but I’m several hours deep into head-banging on the issue so I’m reaching out for help.

I’m a veteran JS programmer but a TiddlyWiki n00b. :slight_smile:

Anyone see what I’m doing wrong here?

To prevent tiddlywiki from wikifying the content of your tiddler, you can use a pragma rule at the beginning of the tiddler :

\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline html

You can also use wikitext to “escape” css. For example, if you try to set a CSS variable inside a tag, tiddlywiki will parse – and make it into a -.
To prevent this you can turn it into a code snippet : --
This way you keep your formatting.

$(…)$ is for text substitution of a variable defined outside of a macro, see https://tiddlywiki.com/#Macro%20Definitions%20in%20WikiText

I have made a post on tiddlytalk that explain how to display svg icon next to links inside tiddlers, check it out :

Online demo : TiddlyTweaks — Small tweaks for TiddlyWiki

Check also this thread : How to set the favicon of website?

I don’t know if it is relevant but by mere coincidence I was fiddling around with images in TW and stumbled across this. Check it out.

The $(…)$ syntax is… let’s back up:
$$ is used to apply the argument value of a macro parameter. But the $()$ syntax allows you to use a variable value from outside of the macro, and that was not included as an argument in the macro. (I’m probably not using the terminology correct.)

<:-)

Thanks for the info and references everyone.

I feel like I’m so close to getting this working… here’s my revised code, based off of code examples from Télumire:

\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline html

<$list filter="""[has[icon]]""">
<$set name=“uri” value=<<makedatauri text:{{!!title}} type:“text/plain”>> >
<$list variable=“urititle” filter="""[removeprefix[data:text/plain,]]""">

<$vars fill=“external-link-foreground”>
a[href="#<>"]:before{<$vars svg={{!!icon}}>{{||$:/ThemeTweaks/svg/url}}</$vars>}
</$vars>

<$vars fill=“external-link-foreground-visited”>
a[href="#<>"]:visited:before{<$vars svg={{!!icon}}>{{||$:/ThemeTweaks/svg/url}}</$vars>}
</$vars>

<$vars fill=“external-link-foreground-hover”>
a[href="#<>"]:hover:before{<$vars svg={{!!icon}}>{{||$:/ThemeTweaks/svg/url}}</$vars>}
</$vars>
</$list>
</$set>
</$list>

My issue now is the “text” argument to the makedatauri macro; it needs to be dynamic, but everything I’ve tried interprets the value literally—so I get an encoded {{!!title}} instead of the encoded actual title of the tiddler. I also tried assigning it as a variable using another $set widget but no luck. I feel like I’m missing some syntax…

Ok, I got it working. I forgot my original source was based off of the LinkStyle (http://linkstyle.tiddlyspot.com), which I had seen in one of Matt’s previous email threads. Once I restored the original wrapping widgets, Télumire’s SVG-handling code provided the missing piece. After a bit of style tweaking, I got what I was after with this:

\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline html

\define linkstyle()
<$set name=“uri” value=<<makedatauri “”"$(tid)$""" “text/plain”>> >
<$list variable=“urititle” filter="""[removeprefix[data:text/plain,]]""">
a[href="#<>"]:before{ content: " "; margin-right:.5ch; display: inline-block; height:1em; width:1em; background: center / contain no-repeat var(--url); }

<$vars fill=“primary”>
a[href="#<>"]:before{<$vars svg={{!!icon}}>{{||$:/ThemeTweaks/svg/url}}</$vars>}
</$vars>

<$vars fill=“primary”>
a[href="#<>"]:visited:before{<$vars svg={{!!icon}}>{{||$:/ThemeTweaks/svg/url}}</$vars>}
</$vars>

<$vars fill=“primary”>
a[href="#<>"]:hover:before{<$vars svg={{!!icon}}>{{||$:/ThemeTweaks/svg/url}}</$vars>}
</$vars>
</$list>
</$set>
\end

<$list filter="""[has[icon]]""">
<$vars tid={{!!title}}>
<>
</$vars>
</$list>

I see now that I can use $vars and “”"$()"""" to pass dynamic arguments to a macro, so that answers my earlier question. I’m still curious if there’s a terser way to accomplish this, though.

Here’s what it looks like:

Now I can set an “icon” field for a tiddler that points to a SVG, and any link to that tiddler will show that icon in the link. Combined with SVGs I’m pulling in from TW Icons v1.10 — A large collection of icons for TiddlyWiki along with a few of my own for smaller libraries that still have logos but aren’t published, and I’m where I want to be… for now, at least!

Thanks again for all the help!

3 Likes