Create a style to show icon next to link title?

89 views
Skip to first unread message

Evan Sherwood

unread,
Dec 11, 2021, 12:31:03 AM12/11/21
to TiddlyWiki
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=<<tid>> field="icon">
    <$set name="iconsrc" tiddler=<<icon>> >
      <$list variable="urititle" filter="""[<uri>removeprefix[data:text/plain,]]""">
        <style>
          a[href="#<<urititle>>"] { display: inline-flex; align-items: baseline; gap: .15em; }
          a[href="#<<urititle>>"]:before { content: <<makedatauri """$(iconsrc)$""" "image/svg+xml">>; width: 1em; height: 1em; margin-top: 2px; align-self: center; fill: <<colour tiddler-link-foreground>>; }
        </style>
      </$list>
    </$set>
  </$set>
</$set>
\end

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

When I inspect the DOM and look at the <style> tag created, the value of my `content` CSS rule shows as an <a>... 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. :)

Anyone see what I'm doing wrong here?

---

Also, what is the $()$ syntax? I couldn't find documentation on it... I'm guessing because I don't know what it's called and thus don't know the right term to search for.

Télumire

unread,
Dec 11, 2021, 12:38:24 PM12/11/21
to TiddlyWiki
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 <style> 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 :

https://talk.tiddlywiki.org/t/trick-to-convert-the-core-images-to-svg-image-for-css-background/802

Online demo : https://telumire.be/TiddlyTweaks/index.html#:%5B%5B%24:/ThemeTweaks/svg/style/external_link%5D%5D

Télumire

unread,
Dec 11, 2021, 12:44:38 PM12/11/21
to TiddlyWiki
Check also this thread : How to set the favicon of website?

Mat

unread,
Dec 11, 2021, 2:49:10 PM12/11/21
to TiddlyWiki
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.)

<:-)

Evan Sherwood

unread,
Dec 11, 2021, 8:55:01 PM12/11/21
to TiddlyWiki
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="""[<uri>removeprefix[data:text/plain,]]""">

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

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

      <$vars fill="external-link-foreground-hover">
        a[href="#<<urititle>>"]: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... 

Evan Sherwood

unread,
Dec 12, 2021, 12:30:30 AM12/12/21
to TiddlyWiki
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="""[<uri>removeprefix[data:text/plain,]]""">
    a[href="#<<urititle>>"]:before{ content: " "; margin-right:.5ch; display: inline-block; height:1em; width:1em; background: center / contain no-repeat var(`--`url); }

    <$vars fill="primary">

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

    <$vars fill="primary">

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

    <$vars fill="primary">

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

<$list filter="""[has[icon]]""">
  <$vars tid={{!!title}}>
    <<linkstyle>>
  </$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:

Govos Cloud Search — notes and thoughts from an architect.png

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 https://morosanuae.github.io/tw-icons/ 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!
Reply all
Reply to author
Forward
0 new messages