Custom data styles: targeting fields

237 views
Skip to first unread message

Hubert

unread,
Dec 7, 2019, 4:51:27 PM12/7/19
to TiddlyWiki
Hello,

We're able to style individual tiddlers by targeting their titles and tiddlers en masse by targeting their tags, as explained here.

In a similar fashion, is it possible to style a subset of tiddlers by targeting their fields? Like, for instance, a subset of tiddlers whose field "example" has a value "value"? Or even more broadly, by targeting by condition of whether a subset of tiddlers has a specific field, no matter its value?

Thank you in advance for hints.

Regards,
Hubert

TonyM

unread,
Dec 7, 2019, 8:23:17 PM12/7/19
to TiddlyWiki
Hubert

I believe filters can be used in css data-tags. Not done it myself. There is the class field and you can conditionaly display css between <style> html tags in the view template using filter which can depend on field values or existence.

Short answer because I am mobile.

Tony

Hubert

unread,
Dec 11, 2019, 9:19:11 AM12/11/19
to TiddlyWiki
Thanks for responding Tony.

I believe filters can be used in css data-tags. Not done it myself

I would like to avoid tags as reference points for styling. I'm doing that currently and, if possible, I would like to "deprecate" this. Same for filters. Whenever possible, I've replaced them with the <reveal> widget.

There is the class field and you can conditionaly display css between <style> html tags in the view template using filter which can depend on field values or existence.

Yes, I'm aware of the class field and I'm using that extensively. As for in-tiddler <style> tags, I've done that previously but, again, will not want to re-introduce this approach into my wiki, even if "sandboxed" using the <reveal> widget, because there's always the risk of "style spill" onto other tiddlers.

Just to add, I've had a look at $:/core/ui/ViewTemplate and can see that data-tiddler-title, data-tags and class are the only "modifiers" available. I know I might try adding other field references and overwrite this shadow tiddlrt but I'm generally against modifying core functionality.

Thanks again,
Hubert

TonyM

unread,
Dec 11, 2019, 8:02:33 PM12/11/19
to TiddlyWiki
Hubert,

I am no expert in this but see https://tiddlywiki.com/#Custom%20data-styles this defines the attribute tags that comes with TiddlyWiki, it includes the ability to apply it to tiddler titles as well as using tags. I believe another approach is for you to use the attribute definitions below 

More Possibilities in https://tiddlywiki.com/#Custom%20styles%20by%20data-tags


That is you can use this css method to address elements with your custom attributes and apply css to those elements. This can stop the css bleeding because it only applies to elements with those attributes.

With an unbleading set of css you can then use a list widget/reveal with a filter in the view template that contains a
<style>css</style>
Section, if and only if any desired field condition exists.

I hope this leads you to an answer. Hopefully a CSS expert will see this.

tony

Hubert

unread,
Dec 12, 2019, 4:26:21 AM12/12/19
to TiddlyWiki
Tony,

I appreciate your efforts to assist me. But what you've described or referenced is exactly what I've been doing and what I've already had implemented in my own wiki for a long time.

As you can see in my original post and also in its title, I'm trying to go beyond all of that. I'm trying to apply custom data styles by specifically targeting fields -- also fields other than the designated "class" field alone.

Anyway, thanks again for your time and efforts to provide assistance.

Regards,
Hubert

PMario

unread,
Dec 12, 2019, 6:18:50 AM12/12/19
to TiddlyWiki
Hi Hubert,

Starting with 5.1.16 we have the possibility to use a "class" field to define special behaviour.

Other possibilities can be found in the Style FAQ. Especially "dynamically create a CSS". ... But this method can have a negative performance impact, if done wrong. ... It should be "a last resort" if other possibilities don't work, because it can lead to 1 CSS rule per tiddler if done wrong.

have fun!
mario

PMario

unread,
Dec 12, 2019, 6:21:20 AM12/12/19
to TiddlyWiki
On Thursday, December 12, 2019 at 12:18:50 PM UTC+1, PMario wrote:
...
Other possibilities can be found in the Style FAQ. Especially "dynamically create a CSS". ... But this method can have a negative performance impact, if done wrong. ... It should be "a last resort" if other possibilities don't work, because it can lead to 1 CSS rule per tiddler if done wrong.

Don't understand me wrong. You can do really crazy stuff with this mechanism. So it's definitely worth some experiments.

-mario

TonyM

unread,
Dec 13, 2019, 12:17:45 AM12/13/19
to TiddlyWiki
Hubert,

Perhaps, I expected you to read between the lines a little more. As in marios pointer to "dynamically create a CSS" see how the filter is used?, it is possible to have the filter use fields to decide when to make some css active.

For example in a tiddler tagged $:/tags/ViewTemplate
<$list filter=[all[current]has[fieldname]]">
<style>
css here
</style>
</$list>
The CSS Will be silently "displayed" on any tiddler with a field "filename" that has a value.

Be careful because this css will be valid on the whole page, that is where ensuring the CSS selectors target only elements in the current tiddler, you can use classes and styles in your css and in the tiddler ensure that you label things with the specific class.

Also in a tiddler tagged $:/tags/ViewTemplate
<$list filter=[all[current]has:field[fieldname]]">
<style>
css here
</style>
</$list>
Will be silently "displayed" on any tiddler with a field "filename" that exists with a value or not.

Or other filters like
[all[current]!has:field[fieldname]]
On tiddler that do not have the field "fieldname"

I am no expert in CSS but I think you may be able to see what I am saying. Please ask more Questions.

Regards
Tony

TonyM

unread,
Dec 13, 2019, 12:30:35 AM12/13/19
to TiddlyWiki
Post Script

Using selectors and Understanding specificity is quite involved. One thing I know is you can wrap something in a div with a specific ID and include that ID in your CSS so it only applies to something inside that ID.

In a recent post I shared a solution for creating anchors inside a Tiddler, copy below. The trick was we used the qualify macro to make the ID unique to that tiddler, and in that case within the tiddler, you could do something similar. But I now have an idea how to make this automatic.

Eg in TOC
<a href=<<qualify ##h1>> >Link to My Heading</a>

In Text
<h1 id=<<qualify #h1>> > My Heading</h1>

Also the following works to help users nest headings

<a href=<<qualify ##h1.1>> >Link to My Heading 1.1</a>

Later in tiddler
<h1 id=<
<qualify #h1.1>> > My Heading h1.1</h1>

Notes:
  • There is not current tiddler in the sidebar so this may not work there, but a hardcoded number could be used
  • As ID's can be defined in CSS perhaps we can use the new wikitext in CSS features to automatically generate ID's that qualify them automatically.
  • I am confident there is more to be discovered.

Regards
Tony

Hubert

unread,
Dec 13, 2019, 5:59:06 AM12/13/19
to TiddlyWiki
Tony & Mario, thank you very much for taking the time to help.

I've just realised that I've omitted one important piece of info in my original post which would probably save you time trying to assist me. I'm sorry for that. What I forgot to say is that the functionality I'm looking for is one that would match the power of the "class" field, in that it would be able to style the entire tiddler, not just its body. Like using the class field, we could, say, remove a tiddler's title by using .tc-titlebar h2 { display: none; } etc.

Just an example. My actionable tiddlers (tasks and such) are tagged "item". I use the below custom view template (tagged $:/tags/ViewTemplate) to display them. This view template is itself conditional: the contents of a tiddler tagged "item" will be displayed if the tiddler is not "locked" (having a class "locked" will conditionally remove tiddler body and buttons such as "More", "Edit this tiddler" etc. from view). The locked tiddler view template is itself also conditional (based on other logic that enables me to mass lock locked tiddlers using a toggle that modifies a global variable, something not really relevant to this topic), which means that even if an "item" tiddler also has the class "locked" it will not necessarily be hidden from view as locked, because this depends on the current status of the global locking mechanism (toggle position).

My view template for tiddlers tagged "item", at its most basic level, looks like this:

<$list filter="[is[current]tag[item]]">
<$list filter="[is[current]class[locked]]">

{{_template_tiddler-locked}}

</$list>
<$list filter="[is[current]!class[locked]]">

-- all the styling/macros for the not locked tiddler tagged "item" go here

</$list>
</$list>

So, list filters determine what view template is applied to this tiddler. In short, it's a view template transcluded in another view template.

In addition to that, I target all tiddlers tagged "item" through CSS defined in my own $:/tags/Stylesheet tiddler to remove their titles like here:

[data-tags*="item"] .tc-titlebar h2 { display: none; })

...because I've redesigned the way everything, titles included, look like in "items" by using the above view template.

Everything works perfectly and I've had all of this working well for months. I'm very happy with this design. BUT, as I've said above, I want to get rid of tags altogether (for performance reasons). So, it would seem trivial to simply replace the tag "item" and replace it with a field, say a field called "data_type" with the value "item". Once this is done, this would be my new view template:

<$list filter="[is[current]has[data_type]data_type[item]]">
<$list filter="[is[current]class[locked]]">

{{_template_tiddler-locked}}

</$list>
<$list filter="[is[current]!class[locked]]">

-- all the styling/macros for the not locked tiddler go here

</$list>

</$list>

But now I'm losing all the styling (specifically, the removal of tiddler buttons) because this:
[data-tags*="item"] no longer works, understandably, because the tiddler is no longer tagged, I've replaced the tag with a field!

This is the very root of what I'm trying to accomplish -- to give this "data_type" field the same powers as the "class" field was given, so as to be able to manipulate styling of the entire tiddler, not just its body.

This will be only relevant in the edge cases where a tiddler is "double styled", in addition to this styling being conditional. This is why I had to rely on [data-tags*="item"] and on the "class" field as both of these target the whole tiddler (including system buttons, the title etc.) Styling from within a view template only targets tiddler body and this is not enough for my use case.

I need to apologise for the sprawl, I'm aware it may all seem convoluted. English is not my first language and I occasionally struggle to concisely express what I'm trying to do. I'm also aware that there might be a quick fix to this problem, though I haven't found it yet. I think it can be accomplished by creating some clever CSS cascading or by modifying the core view template (something I'm reluctant to do).

Thank you again for your time and all the help so far, it's very much appreciated. It's amazing that TW has such a thriving community.

Best regards,
Hubert

PMario

unread,
Dec 13, 2019, 7:34:20 AM12/13/19
to tiddl...@googlegroups.com
On Friday, December 13, 2019 at 11:59:06 AM UTC+1, Hubert wrote:

What I forgot to say is that the functionality I'm looking for is one that would match the power of the "class" field, in that it would be able to style the entire tiddler, not just its body.

If you add a class field eg: class: test you can do it:
 
Like using the class field, we could, say, remove a tiddler's title by using .tc-titlebar h2 { display: none; } etc.

like this:  .test .tc-titlebar h2 {display: none}

class is applied at the same level as the data-tags elements

-m

Hubert

unread,
Dec 13, 2019, 8:05:23 AM12/13/19
to TiddlyWiki
Hi Mario,

Exactly. What you've described is my current implementation.

But the class field (being a field) can only have one value. Since I need two values, what I'm missing is another (custom) field that will match the power of class. Or, ideally, the ability to add more custom fields at system level that will match the functionality of a class field.

I know I could probably use a custom filter or some regex to match a list of classes within the class field but it's probably overkill.

More details in my convoluted post above :)

Many thanks,
Hubert

PMario

unread,
Dec 13, 2019, 8:14:43 AM12/13/19
to TiddlyWiki
On Friday, December 13, 2019 at 2:05:23 PM UTC+1, Hubert wrote:

But the class field (being a field) can only have one value. Since I need two values, what I'm missing is another (custom) field that will match the power of class. Or, ideally, the ability to add more custom fields at system level that will match the functionality of a class field.

you can have class like:

class: aaa bbb ccc

The div will look like this:

<div data-tiddler-title="New Tiddler" data-tags="" class="tc-tiddler-frame tc-tiddler-view-frame
tc-tiddler-exists aaa bbb ccc " style="transition: none 0s ease 0s; opacity: 1;"><div class="tc-tiddler-title">
                  ^^^^^^^^^^^
 
I'm not sure if that helps.

-m

PMario

unread,
Dec 13, 2019, 8:29:00 AM12/13/19
to TiddlyWiki

On Friday, December 13, 2019 at 11:59:06 AM UTC+1, Hubert wrote:
..
Everything works perfectly and I've had all of this working well for months. I'm very happy with this design. BUT, as I've said above, I want to get rid of tags altogether (for performance reasons).

hmmm,

That shouldn't happen anymore. See: https://tiddlywiki.com/#Release%205.1.20  Performance Improvements 1st paragraph.

 - Added pluggable index modules to accelerate the field Operator and the tag Operator (in tests on a wiki with 60K tiddlers, startup time is reduced by 25% with these optimisations, and refresh time is reduced by a factor of three.)

 - Enable $:/ControlPanel : Settings : Performance Instrumentation
 - Save and Reload your TW
 - F12 : Console tab shows: performance: Execute $tw.perf.log(); to see filter execution timings
 - enter the text: $tw.perf.log();
 - hit enter button

TW should show a table with all filters and there execution time now. So you can see, if there are are really slow filters.

Jeremy uses TWs with 60k Tiddlers

-mario

PMario

unread,
Dec 13, 2019, 8:29:44 AM12/13/19
to TiddlyWiki
Hi,

If the description doesn't work for you, I can record a short video. Just let my know!

-m

PMario

unread,
Dec 13, 2019, 8:31:41 AM12/13/19
to TiddlyWiki
Hi,

If your filters are not there, you need to open the tiddlers that contain them.
And run the $tw.perf.log(); again

-m

TiddlyTweeter

unread,
Dec 13, 2019, 8:39:56 AM12/13/19
to TiddlyWiki
PMario wrote:
If the description doesn't work for you, I can record a short video. Just let my know!

Would YOU be in it? :-)

Your voice is nice. You might look as good?  

Hubert

unread,
Dec 13, 2019, 8:41:28 AM12/13/19
to tiddl...@googlegroups.com
Thank you Mario, you've been very helpful. I've never used performance instrumentation before but I'll give it a go. Thanks for the instructions.

I'm aware of the improvements in 5.1.20. Also, it's not like the performance I have is poor, not at all. It's just that I want to optimise it as well as I can so as to be aware that any remaining bottlenecks are not design/syntax/filter related but hardware related. I've read that several posters on this forum were experiencing delays if using tags in their filters which were removed once tags were removed from the filters. This is primarily what triggered my interest in removing tags altogether.

I will do these tests first.

Also, following your suggestion to use multiple values in the class field (i.e. treating it as a list field) I was able to match both classes (values) with my CSS, which is promising. I'll give it a go and see what happens.

Thanks again, I consider this resolved. I'll just have to fiddle a bit more haha :)

-Hubert

Hubert

unread,
Dec 13, 2019, 8:44:03 AM12/13/19
to TiddlyWiki
Would YOU be in it? :-)

Your voice is nice. You might look as good?

Thanks TT but I'll give it a pass ;)

-Hubert

PMario

unread,
Dec 13, 2019, 8:55:27 AM12/13/19
to TiddlyWiki
On Friday, December 13, 2019 at 2:41:28 PM UTC+1, Hubert wrote:
...

Thanks again, I consider this resolved. I'll just have to fiddle a bit more haha :)

Cool!

-m

TonyM

unread,
Dec 13, 2019, 6:27:25 PM12/13/19
to TiddlyWiki
Great,


Thanks again, I consider this resolved. I'll just have to fiddle a bit more haha :)

I  knew the answer was there and grateful for Mario to point out the more versatile use of the class field. 

I am still searching for a method to use css specificity to help target single tiddlers elements.

Regards
Tony
Reply all
Reply to author
Forward
0 new messages