Simple way to Set style from Variables

I have a div and its style is set based on different criteria. As a simple example consider below code

\define divStyle() color:<<colour foreground>>; background-color:<<colour table-header-background>>;

<$wikify name="myStyle" text="""<<divStyle>>""" mode="inline"> <div style=<< myStyle >> >
some text ....

</div>
<$wikify>

What is a better solution using new features in TW 5.3.x specially substitution operator and backtickets like: “attribute=text+vars+filter”?

I would recommend a solution that only requires 5.2.2+ features, detailed at the end of the documentation for HTML in WikiText:

In an extension to HTML, TiddlyWiki also supports accessing individual CSS styles as independent attributes. For example:

<div style.color="red">Hello</div>

The advantage of this syntax is that it simplifies assigning computed values to CSS styles. For example:

<div style.color={{!!color}}>Hello</div>

Edit: I now notice the reason for the wikify and will edit this answer accordingly.

I wrote custom filter functions to replace the color macro, but which will retrieve the actual value from the pallet (recursively) without needing to use <$wikify>:

\define colorRegexp() <<colou?r .*>>

\define removeRegex() <<colou?r |"|'|>>

\function getColor(c) [{$:/palette}getindex<c>!is[blank]] ~[[$:/palettes/Vanilla]getindex<c>!is[blank]] ~[[$:/config/DefaultColourMappings/]addsuffix<c>get[text]] :map[function[recolor],<currentTiddler>]

\function recolor(c) [<c>regexp<colorRegexp>] :then[<c>search-replace:g:regexp<removeRegex>,[]split[ ]!is[blank]first[]] :map[function[getColor],<currentTiddler>] :else[<c>]

This allows you to do things like this:

<div style.color=<<getColor foreground>> style.background-color=<<getColor table-header-background>> >
(contents)
</div>

I’m American, so I spell it “color,” but you can name the functions whatever you like.

As @pmario points out, if you need styles that can’t be hardcoded, then using classes and adding stylesheets is a good idea. I would add:

1 Like

I would suggest to avoid the STYLE attribute if possible and use functions to define classes. Using the STYLE element will make it close to impossible for users to style the elements properly. Especially if you want to switch palettes.

That’s why the core uses tc-classes if possible to give the users as much freedom as possible.

eg:

\procedure classB() classSomething
\function f.classA() [<condition>match[test]then[ABC]else[XYZ]]
\function f.getClasses() [<f.classA>] [<classB>] +[join[ ]]

<$let condition="test">
  <div class=<<f.getClasses>> >
    some content
  </div>
</$let>

If you want to use the substitute-operator it could look like this:


\procedure classB() classSomething
\function f.classA() [<condition>match[test]then[ABC]else[XYZ]]
\function f.getClasses() [[$(f.classA)$ $(classB)$]substitute[]]

<$let condition="test">
  <div class=<<f.getClasses>> >
    some content
  </div>
</$let>

There are several other possibilities, but that should do for the start.

I personally prefer the first option.

2 Likes

Thank you! All replies are intresting! I use both of them.

@atronoush I found a slight error in my regular expressions in my answer and have corrected (and simplified) them. (Realistically, I don’t think it would actually make a difference, because the issue was that things like <<color or color ...>> alone would be matched as a call to the colour macro even if the syntax wasn’t complete. But, letting you know so you can correct it in your code if you like.)

Many thanks @bluepenguindeveloper.