Using Unicode as icons on tiddlers?

As you know the icon field on tiddlers currently needs to contain a tiddler name of a SVG icon.

I wonder if it would be possible to modify or update the core to also permit Unicode characters to be placed in the icon field and use them instead?

One way may be to test if the content of an icon field is an existing tiddler name then transclude it, otherwise use the value in the icon field.

  • What happens to existing transclusions of the icon field?

Why;
A large set of unicode characters are now available in most fonts and use less bytes to represent a wide range of common symbols.

When a tiddler has a non-blank icon field value, the $:/core/ui/TiddlerIcon shadow tiddler does this

<$transclude tiddler=<<tiddlerIcon>>/>

Thus, without changing anything in the TWCore, you can define a tiddler containing an emoji (e.g., :grinning:) or the equivalent unicode HTML character entity (e.g., &#x1F600;), and that symbol (or any other content in the referenced icon tiddler) will be displayed.

Note that in order to properly align the emoji in the tiddler title, you may want to include a little inline CSS:
@@vertical-align:top;&#x1F600;@@

Here’s an excellent reference for emojis:
https://unicode.org/emoji/charts/full-emoji-list.html

-e

4 Likes

Thanks @EricShulman, I have taken your suggestion and worked it a little more to meet my requirements;

The following new version of $:/core/ui/TiddlerIcon will transclude an icon tiddler named in the icon field if it exists, otherwise it will transclude the icon field.

\whitespace trim
<$let tiddlerIcon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}>
<$list filter="[<tiddlerIcon>!is[blank]]" variable="ignore">
<$list filter="[<tiddlerIcon>has[title]]" emptyMessage="""@@vertical-align:top; {{!!icon}}@@"""><$transclude tiddler=<<tiddlerIcon>>/></$list>
</$list>
</$let>
  • Now I just put a unicode character eg; :star:instead of a tiddler title and that is used instead. Looks good thanks to your suggested styling.
  • Because its transcluded it can include other wikitext including macros widgets and html.

Would it be safe to propose a core change?

  • If I was to do this I may design it a little differently to permit other cases such as if icon is empty automatically identify an appropriate icon from the type field, or others etc…

Thanks again. for your help

Edited with update to let tag pills use the unicode
unicode-image-wikitext-icons.json (2.7 KB)

  • If you create a tiddler with the title “:star:” it will be transcluded and if that is not a icon or short word it will mess-up the icon on the current tiddler.
1 Like

I just put the unicode in it’s own tiddler and then use tiddler icon cascade rule.

I also think the OP is reasonable - it is a lot more intuitive to just put an icon in the icon field than a to-be-transcluded-title.

With that said, here’s a hack:

title: any tiddler
icon:  theicon
text: 
<<icon>>
Lorem ipsum

That macro call triggers this:

tags: $:/tags/Macro
text:
\define icon()
<style>
[data-tiddler-title="<<currentTiddler>>"] .tc-title:before {content:"{{!!icon}}"}
</style>
\end

It appears not to work for CamelCased tiddler titles… once again confirming my dislike cc-autolinking… hmm…

Super useful to know! Not least because Unicode is vast and may well address icon issues well much of the time.

Am I allowed to ask a persnickety question?

One of the issues with emojis is that different fonts can show them quite differently.
FYI, I use BabelMap on Windows to explore that issue.

Why bother?: Simply, if on all platforms one’s “Unicode Icons” look the same consistent style if you can apply one font directive to them.

In the the back of my mind is the idea to make a TW Custom Font just for “Unicode Icons” you install in your production wiki so it is always there.

So, what is my question?: How do we apply a specific custom font just to “Unicode Icons” (limited numbers).

I hope this query is clear!
TT

2 Likes

That is a good question however given there are hundreds of thousands if unicode characters it can be expanded to apply a font to render at least the most importiant symbols and character sets including emoticons and mathematical sets.

Right.

The whole issue with a Custom Font installed in TW is it ONLY needs contain the “Unicode Icons” you need for a wiki, no more.

That was my point, I did not make clear enough, a Font can deliver a very lightweight solution (say 50 Unicode characters for icons?).

I hope this is clearer?

TT

@TiddlyTweeter I understand what you are saying and are agreeing however extending it. There are special fonts with the key target symbols to reduce the apperence of undisplayable symbols. Choosing one or more appropriate and idealy websafe fonts that also gives somewhat consistent results is what we need to find. I belive such character sets number in the thousands and offer great value.

I think the exact choice is not as importiant as providing advice and guidence to users and designers on the selection and usage in tiddlywiki.

I will return soon with an example font.

The Google noto fonts (Short for no tofu - the missing symbols) seem to be an answer for multiple language character sets and symbols.

It seems to me however a font that focuses on symbols that are international in nature but not supporting the different languages would be ideal for empowering tiddlywiki to make use of unicode, I say this because if a tiddlywiki needs character’s for different languages then presumably the wiki, browser or device is using these specific language fonts. That is the wiki need not be responsible for the languages, just the extended symbol sets.

  • So far finding a free, good and reliable font to provide symbols but not alternative languages has being difficult.

The alternative code for $:/core/ui/TiddlerIcon as posted by @TW_Tones above works great, but understandably only in tiddler titles, it does not work e.g. in tag pills (and probably many other places e.g. buttons).
I attempted to solve it for tag pills by editing $:/core/macros/tag – similarly to solution above I have added <$list filter="[<tiddlerIcon>has[title]]" emptyMessage="""@@vertical-align:top; {{!!icon}}@@"""></$list> around the code that transcludes the icon tiddler. The edited $:/core/macros/tag looks like follows:

\define tag-pill-styles()
background-color:$(backgroundColor)$;
fill:$(foregroundColor)$;
color:$(foregroundColor)$;
\end

<!-- This has no whitespace trim to avoid modifying $actions$. Closing tags omitted for brevity. -->
\define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions)
<$vars
	foregroundColor=<<contrastcolour target:"""$colour$""" fallbackTarget:"""$fallbackTarget$""" colourA:"""$colourA$""" colourB:"""$colourB$""">>
	backgroundColor="""$colour$"""
><$element-tag$
	$element-attributes$
	class="tc-tag-label tc-btn-invisible"
	style=<<tag-pill-styles>>
>$actions$<$list filter="[<tiddlerIcon>has[title]]" emptyMessage="""@@vertical-align:top; {{!!icon}}@@"""><$transclude tiddler="""$icon$"""/></$list><$view tiddler=<<__tag__>> field="title" format="text" /></$element-tag$>
\end

\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)
<$macrocall $name="tag-pill-inner" tag=<<__tag__>> icon="""$icon$""" colour="""$colour$""" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
\end

\define tag-pill(tag,element-tag:"span",element-attributes:"",actions:"")
\whitespace trim
<span class="tc-tag-list-item" data-tag-title=<<__tag__>>>
<$let currentTiddler=<<__tag__>>>
<$macrocall $name="tag-pill-body" tag=<<__tag__>> icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}} colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}} palette={{$:/palette}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/>
</$let>
</span>
\end

\define tag(tag)
{{$tag$||$:/core/ui/TagTemplate}}
\end

There are two problems with this solution however:

  1. If an icon tiddler is linked in the icon field of a tag, a link to the icon tiddler is rendered instead of the icon.
  2. It is not rendered as pretty as in the title. In the tag pill the unicode character (e.g. emoji) is pressed against the tag title with no space in between.

I will try to solve it, but I hope someone with more experience in TW and CSS can help out, so that I won’t be reinventing the wheel here.

You can directly paste UTF-8 icons, e.g this :grinning: directly into a tag pill, if that is what you’re asking about.

Yes, I see the problem, fix below, it was an oversight when considering this, I wonder where else the icon field is referenced and treated as a tiddler title?

  • The $:/core/macros/tag assumes the icon is a tiddler name to transclude.
    • It’s retrieving the icon using the Tiddler Icon cascade
  • The tiddler manager lets you select an icon using $:/core/ui/TagTemplate and all references seem to go back to the tag-pill-body macro, then tag-pill-inner,
    • Thus modifying tag-pill-inner or providing an override fixes this.
    • All that remains is to add the icon edit to the tag manager?

So here is a fix with the updated tag macro as well and seems to be working;

unicode-image-wikitext-icons.json (2.7 KB) updated

  • Please test and comment
  • Let me know if it needs fixing elsewhere?
    • Existing button transclude Icon tiddlers, to change these to unicode replace the transclusion with unicode, and they are typically not using, if ever, the icon field
1 Like

Thanks a lot @TW_Tones , as far as I have tested it works as expected, that is, the unicode content of icon field is displayed in titles and tag pills. This all I needed.

As far as proposing core change is concerned, it seams reasonable to me, but obviously I have not much expertise in how TW works, and if such a change is a good one. But now it is at least a complete solution, rendering the unicode icons everywhere where expected.

1 Like

Thanks for the review @vilc lets see if some of out developers have a look and comment or propose improvements to the methods used.

The proposed core change alters the existing semantics. Specifically, using the existing core code, if the icon field contains a title that does not exist, then nothing is displayed. In contrast, with your proposed change, if the icon tiddler doesn’t exist, then the text contained in the icon field is shown in place of the icon.

In addition, the desired effect (showing a Unicode character instead of an image) can be currently be accomplished without any core changes, just by entering the Unicode character or character entity (e.g., &#x1F5BC;) in the tiddler referenced in the icon field.

-e

2 Likes

Yes, certainly,

  • However
    • The desired effect is not all the proposed solution offers, it allows any wikitext that is not the same as a tiddler title to be used.
    • this does require the creation of a new tiddler
      • and sometimes more than one for dual or multiple state buttons
      • This interferes with the value of having single tiddler buttons and the reduced bytes required, only one in an icon field, less that currently.
  • On the positive side, with both methods, you can then wrap it in color css etc… because they are transcludes.
    • Although when used in the toolbar this CSS is likely defeated with core toolbar classes
  • Actually the code form &#x1F5BC; is not necessary, you can paste directly the character.

Never the less I agree the package I made is fine as an installable (for now), but installable become a dependency when the feature is used in another package, undermining the single tiddler advantage, we would have if it were in the core.

However its done, the reason we need new icons is because we need more and SVG is often excessive.

I observe now we have a cascade for Tiddler Icon the idea that the “icon field contains a tiddler title” for the icon, is now unfortunately cemented into tiddlywiki core functionality.

  • In some ways this forces the use of a seperate icon tiddler.
  • unfortunately such tiddlers, using unicode must also contain the css @@vertical-align:top; {{!!icon}}@@ Thanks @EricShulman for that tip.

I am now working on a cascade to set the icon conditionally for a given fieldvalue, but I cant introduce the unicode version without a icon tiddler :frowning_face: .

One could just use the unicode character as the first character of the title, like
:wave: HelloThere
It would automatically also show up in tag pills and whatnot and would require no changes in any system tiddler. Also, you could search for it, e.g. find all tiddlers starting with a :skull:, because you use that to identify a certain category (those describing problems) of tiddlers. Changing the icon later is gracefully taken care of by our favorite plugin, Relink.
However, using this probably would mess up alphabetic sorting, if you need that sort of thing.

Have a nice day
Yaisog

2 Likes

That is a useful tip, however its different when creating buttons or using the cascade.

But a good point anyway.