Alternative to conditional viewtemplates?

152 views
Skip to first unread message

Mat

unread,
Apr 7, 2020, 4:19:33 PM4/7/20
to TiddlyWikiDev
tags: $:/tags/ViewTemplate
text
:
<$list filter="[all[current]tag[Foo]]">
...


Such "conditional viewtemplates" are cool but I have a feeling they can be very inefficient in that such custom templates often only get positive hits for very few tiddlers. (Is my reasoning flawed?)

Is there instead a targeted way to control which viewtemplates the current tiddler shows? 

For example, is there some pragma that, for current, can command "show fields a and b but not the text field nor the tags"?

Or could one manipulate the $:/core/ui/ViewTemplate listing for - and from - the current tiddler? 

(CSS is not a good idea for this even if it can hide (but not reveal) fields because the field should not be processed at all which it still does even if "display:none")

<:-)

PMario

unread,
Apr 8, 2020, 9:58:52 AM4/8/20
to tiddly...@googlegroups.com
On Tuesday, April 7, 2020 at 10:19:33 PM UTC+2, Mat wrote:
tags: $:/tags/ViewTemplate
text
:
<$list filter="[all[current]tag[Foo]]">
...


Such "conditional viewtemplates" are cool but I have a feeling they can be very inefficient in that such custom templates often only get positive hits for very few tiddlers. (Is my reasoning flawed?)

I'm not sure, if I understand the question right. .. It will always hit for tiddlers tagged: Foo in your example.

Is there instead a targeted way to control which viewtemplates the current tiddler shows? 

For example, is there some pragma that, for current, can command "show fields a and b but not the text field nor the tags"?

This is a completely different thing. The above code will just add something like a "footer" to the ViewTemplate. All elements taged $:/tags/ViewTemplate are visible _plus_ the new component.

Showing a different ViewTemplate could be done by using a new field. BUT .. It would need new core code to support it.

We can't use the type field, since this is responsible to define the parser, that should be used for the wikitext. ...

At the moment the list-widget is responsible for the view-template that is used. see: https://tiddlywiki.com/#ListWidget

$:/core/ui/PageTemplate/story tiddler contains the list-widget, which uses the content from $:/config/ui/ViewTemplate and $:/config/ui/EditTemplate to define the defaults.

It's possible to "globally" set those templates by the user. ... but there is no "per tiddler" configuration atm. The "story" has no idea about the single tiddler content.

It's $:/core/ui/ViewTemplate that would need to be changed. The list there looks like this:

<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
  <$transclude tiddler=<
<listItem>>/>
</$list>

If we change a part from the filter from tag[$:/tags/ViewTemplate] to eg: tag[$:/tags/myTemplate] based on a tiddler field, it should work "out of the box". ... Maybe ;)

-m


PMario

unread,
Apr 8, 2020, 10:02:34 AM4/8/20
to TiddlyWikiDev
Hi,
A similar thing would be possible for the EditTemplate
-m

Mat

unread,
Apr 8, 2020, 12:43:14 PM4/8/20
to TiddlyWikiDev
Mario, your input is much appreciated!

I'm not sure, if I understand the question right. .. It will always hit for tiddlers tagged: Foo in your example. 

My point is that a conditional viewtemplate for all tiddlers tagged "HelloThere" will only "yield" something for some six tiddlers - but the viewtemplate is checked for every tiddler in the river  to decide if the template contents should show or not. I'm thinking this can be "expensive" if I have several such conditional viewtemplates - ?


Showing a different ViewTemplate could be done by using a new field. BUT .. It would need new core code to support it. 

AFAICT, the bigger problem is to hide a viewtemplate.

 
It's $:/core/ui/ViewTemplate that would need to be changed. The list there looks like this: 

<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
  <$transclude tiddler=<
<listItem>>/>
</$list>

If we change a part from the filter from tag[$:/tags/ViewTemplate] to eg: tag[$:/tags/myTemplate] based on a tiddler field, it should work "out of the box". ... Maybe ;)

Hm, wouldn't this just repeat the same problem? It would still not be on a per-tiddler-basis. For example, say I want to hide the text field but show my custom foo field, in only the current tiddler. (And by "hide" I mean it should not be processed.) 

I think the (main) viewtemplate would need to look in the current tiddler for a field that lists which templates to show and, as a fallback if there is no such field, use the usual "tag[$:/tags/ViewTemplate]".


<:-)

Saq Imtiaz

unread,
Apr 8, 2020, 4:27:08 PM4/8/20
to TiddlyWikiDev
Here is how I do custom view templates. This is from memory, as I cannot refer to my tiddlywiki right now, so allow for the possibilty of syntax errors.

a) create a new viewtemplate as follows:
\define folded-state()
$:/state/folded/$(currentTiddler)$
\end
<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify "$:/state/popup/tiddler-info">>>
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
<$set name="_viewtemplate-tag" filter="[all[current]get[sq-viewtemplate]else[$:/tags/ViewTemplate]]">
<$list filter="[all[shadows+tiddlers]tag<_viewtemplate-tag>!has[draft.of]] [enlist{!sq-viewtemplate-add}] -[enlist{!!sq-viewtemplate-remove}]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>
</$set>
</div>
</$vars>


b) edit $:/config/ui/ViewTemplate to point to the above tiddler you just created.

c) You can specify an entirely different view template tag (instead of $:/tags/ViewTemplate) for a given tiddler by giving it the field sq-viewtemplate

AND/OR you can specify template tiddlers to add or remove in the fields sq-viewtemplate-add and sq-view-template-remove, eg $:/core/ui/ViewTemplate/subtitle

The latter is an quick way to hide a specific template, eg subtitle, on a tiddler. Note also that adding a template like subtitle to the sq-viewtemplate-add field changes the order of the view template tiddlers, moving it to the end.

On my list of future improvements is the ability to just specifiy a filter that modifies the existing viewtemplate list. This was a super quick hack some time back, so there is surely room for further refinement. The same logic can be applied to the EditTemplate. Also note that I did most of this before the $:/config/ui/ViewTemplate tiddler was introduced, so there might be room for using it to streamline the logic for choosing templates.

Hope this helps.

Saq

TonyM

unread,
Apr 8, 2020, 10:28:25 PM4/8/20
to TiddlyWikiDev
Mat

In one published wiki for a client I have a view template whose first test is does the current tiddler have an object-type field. It then uses the value to load the view template for that object type. I see no performance problems.

In each of my object view templates I refer to field values through a macro '<<field fieldname>>' which looks up how to display the fieldname according to a field definition and its field type e.g. date, and In fact displays the fields according to a global or local tiddler mode read-only view update and edit.

This allows the same object template to be used for all modes.

In this case most tiddlers with an object type have all there values in fields other than text which is reserved for simple notes.

In addition I have a global designer mode that if on the view template will show a link to the object template. And a field mode that places a link to the fields definition and field-type just after it is displayed.

There happens to be less field types than field definitions.

This is a potted overview but I hope it shows a little structured design can go a long way and without performance problems.

Perhaps one day I will publish this as a tiddlywiki platform tool.

Regards
Tony

Mat

unread,
Apr 10, 2020, 10:38:27 AM4/10/20
to TiddlyWikiDev
Saq - thanks a lot for that code!

A variant of your code would be to allow for sq-viewtemplate to contain a filter rather than a tag, so the user has the option to directly specify titles and/or [tag[]] including tag[$:/tags/ViewTemplate] if one merely wants to add/remove to the standard set. This would also make it easier to add a template into the correct position.

A UI idea: In tiddler edit view, there could be a dropdown multi select (perhaps next to the type dropdown) where the user picks templates. Picking sets the tiddlers (hidden) sq-viewtemplate field.

<:-)

Mat

unread,
Apr 10, 2020, 11:51:36 AM4/10/20
to TiddlyWikiDev
Tony


it would be easier to understand if you could show it, perhaps a simple tiddlyspot? However, a little litmus test to see if we are at all talking about the same thing is if your approach also enables to not display one of the standard viewtemplates, e.g the tags. (And no cheating with CSS).

A concrete example would be the "text to tabs" thread where you participate, and my tabber thingy. The idea there is to that some tiddler should display their text in a different way. A solution could be to hide the text-viewtemplate and present another template that runs the tabber macro on the text field content. 

<:-)

Saq Imtiaz

unread,
Apr 10, 2020, 12:25:54 PM4/10/20
to TiddlyWikiDev


On Friday, April 10, 2020 at 4:38:27 PM UTC+2, Mat wrote:
Saq - thanks a lot for that code!

A variant of your code would be to allow for sq-viewtemplate to contain a filter rather than a tag, so the user has the option to directly specify titles and/or [tag[]] including tag[$:/tags/ViewTemplate] if one merely wants to add/remove to the standard set. This would also make it easier to add a template into the correct position.

Yep, there are many alternative ways to tweak that code. I actually started by just having a filter in sq-viewtemplate that was used for the list of view template tiddlers. However since this was for a specific use case rather than meant to be general purpose, I found it easier in use in the form I posted. My priorities were:

a) being able to define a completely different UI for some tiddlers, hence a different tag.  
b) being able to easily remove a single tiddler from the default view template list (and not have to worry about specifying a filter for the entire list). The add/remove fields would for example, be an easy way to hide the text field of a tiddler and use a different template for that field instead.

While the filter approach solved both of these, in my usage I found it more heavy handed. .
Hope this helps,

Saq

Matthew Lauber

unread,
Apr 24, 2020, 4:17:31 PM4/24/20
to TiddlyWikiDev
I'm late, but I actually implemented a generic custom edit template tool this for my D&D CreatureManager Plugin here: https://github.com/mklauber/tw-CreatureManager/tree/master
basically, editTemplate chooses a EditTemplate based the "type" field of the tiddler, falling back to a "default" version that handles the current implementation.  Anything that wants it's own edit template, just needs to choose a "Type" value, then create a tiddler named: $:/core/ui/EditTemplate/{Type}

I'd love a way to do that kind of thing without overriding core tiddlers, and also a similar system for ViewTemplates based on "type".

That said, I'm open to the idea that "type" isn't the right field, if other people have different thoughts.  

Matt Lauber

TonyM

unread,
Apr 24, 2020, 6:40:09 PM4/24/20
to TiddlyWikiDev
Matthew

As In my post I just nominate another field object-type.

Regards
Tony
Reply all
Reply to author
Forward
0 new messages