Making the list item template more hackable

Folks,

I thought I would raise this for discussion before I consider asking for a core change to add hackability to the list item template;

Background
Various core lists in the sidebar and search ultimately list each item found using the tiddler $:/core/ui/ListItemTemplate which contains;

<div class="tc-menu-list-item">
<$link />
</div>
  • using <$transclude tiddler="$:/core/ui/ListItemTemplate"/>
  • This has the advantage you can change how these items are listed editing only $:/core/ui/ListItemTemplate
  • This has the disadvantage that editing effects all lists using $:/core/ui/ListItemTemplate which includes the following;
    • $:/core/ui/AdvancedSearch/Filter
    • $:/core/ui/AdvancedSearch/Shadows
    • $:/core/ui/AdvancedSearch/System
    • $:/core/ui/DefaultSearchResultList
    • $:/core/ui/MissingTemplate
    • $:/core/ui/MoreSideBar/All
    • $:/core/ui/MoreSideBar/Drafts
    • $:/core/ui/MoreSideBar/Orphans
    • $:/core/ui/MoreSideBar/Shadows
    • $:/core/ui/MoreSideBar/System
    • $:/core/ui/TagTemplate
    • $:/core/ui/TiddlerInfo/List
    • $:/core/ui/TiddlerInfo/Listed
    • $:/core/ui/TiddlerInfo/References
    • $:/core/ui/TiddlerInfo/Tagging
    • $:/core/ui/UntaggedTemplate

A number of useful customisations can be done to the list item tiddler to include buttons such as edit, copy to clipboard, checkboxes to list or tag, show tag pills on the listed tiddler even and popup tooltips or previews etc…

  • However since the core tiddlers using this include ones in advanced search, default search and sidebar tabs extending the features for all of these is not practical.

I want to propose we allow the default $:/core/ui/ListItemTemplate be overridden without needing to edit these core tiddlers.

  • Although we may need to update the core tiddlers, so as to enable this hackability

So I have some ideas but thought I would seek your views and ideas how we may achieve this?

1 Like

Post Script

I observe the $:/core/ui/ListItemTemplate is referenced both using the transclude widget and the template parameter on the list widget but this has no effective difference.

As discussed here Modified version to $:/core/ui/ListItemTemplate to show pop up for the list links

I had tried to hack the listitemtemplate to show pop up preview on hover over links. What i did was clone the core listitemtemplate and used the modified version where I needed.

<div class="tooltip">{{!!title}}<div class="tooltiptext"><$transclude tiddler="$:/core/ui/ViewTemplate/body" mode="block"/></div></div>

I haven’t used it much on daily basis since its not yet in a usable state (have to do some CSS magic there).

@arunnbabu81 thanks for sharing but here I am looking to redevelop the listitem method to allow customisation and hacking without editing, or cloning the existing list items.

  • Your example is a good one, for how someone may customise a link.

For example we could change all the core lists to transclude a config setting, that contains by default the “$:/core/ui/ListItemTemplate” however this config entry can be modified to point to another such as the example you gave.

I for one developed a sophisticated enhancement of the list item template I call “linker” that allows one to add buttons, modifier keys, display info in the tiddler etc… on any list. I can use this as needed for my own lists but it is only relevant to some core lists, like lists in the sidebar are not tolerant of too much information but the advanced search lists are.

Here in this thread I am trying to solicit a developer focused approach to adding this hackability. How should we make this hackable?

Thanks @TW_Tones this is a good idea.

As you note, at the moment, tiddlers like $:/core/ui/AdvancedSearch/Filter transclude the list item template like this:

<$transclude tiddler="$:/core/ui/ListItemTemplate"/>

Instead, they could try to transclude a more specific template, only falling back to the generic template if the specific one is missing:

<$transclude tiddler="$:/core/ui/ListItemTemplate/AdvancedSearch/Filter">
<$transclude tiddler="$:/core/ui/ListItemTemplate"/>
</$transclude>

I think that would make a worthwhile improvement.

3 Likes

@jeremyruston sounds Good,

Perhaps I will try and refresh my fork and submit the PR’s?

  • Will we leave them missing so one adds them to override the default?
    • In this way there is no need to overwrite a core tiddler.

The final question maybe where do we document this?

Wouldn’t it be easier to leave the $:/core/ui/ListItemTemplate as it is, and create separate list item templates that you use where you need them? That’s what I do, for example, in my list-searches and in list widgets.

@DaveGifford I think that is what is being suggested;

  • We will “leave the $:/core/ui/ListItemTemplate as it is”
  • This remains a way to modify every list that makes use of it, which some may already do.

To clarify;

  • Each of the current references to the list item template is changed from;

<$transclude tiddler="$:/core/ui/ListItemTemplate"/>
to

<$transclude tiddler="$:/core/ui/ListItemTemplate/customnamehere">
<$transclude tiddler="$:/core/ui/ListItemTemplate"/>
</$transclude>

With there own “customnamehere”.

Thus they all will by default continue as before and use $:/core/ui/ListItemTemplate

Then in the documentation on tiddlywiki is says for each of the core lists you can replace the list item $:/core/ui/ListItemTemplate buy creating the corresponding $:/core/ui/ListItemTemplate/customnamehere containing the alternative code.

  • Perhaps since this is user optional code it may be best not to use the $:/core/ui/ prefix but $:/config/ such as $:/config/ListItemTemplate/customnamehere

So adding this prefix change, the new code in each will use;

<$transclude tiddler="$:/config/ListItemTemplate/customnamehere">
   <$transclude tiddler="$:/core/ui/ListItemTemplate"/>
</$transclude>

And the custom names will be;

  • $:/config/ListItemTemplate/AdvancedSearch/Filter
  • $:/config/ListItemTemplate/AdvancedSearch/Shadows
  • $:/config/ListItemTemplate/AdvancedSearch/System
  • $:/config/ListItemTemplate/DefaultSearchResultList
  • $:/config/ListItemTemplate/MissingTemplate
  • $:/config/ListItemTemplate/MoreSideBar/All
  • $:/config/ListItemTemplate/MoreSideBar/Drafts
  • $:/config/ListItemTemplate/MoreSideBar/Orphans
  • $:/config/ListItemTemplate/MoreSideBar/Shadows
  • $:/config/ListItemTemplate/MoreSideBar/System
  • $:/config/ListItemTemplate/TagTemplate
  • $:/config/ListItemTemplate/TiddlerInfo/List
  • $:/config/ListItemTemplate/TiddlerInfo/Listed
  • $:/config/ListItemTemplate/TiddlerInfo/References
  • $:/config/ListItemTemplate/TiddlerInfo/Tagging
  • $:/config/ListItemTemplate/UntaggedTemplate

Keep in mind none of these will exist in the empty.html however if created they are used instead.

I will create a package as a demo.

2 Likes

I have observed 11 of the aformentioned tiddlers with references to $:/core/ui/ListItemTemplate also use template="$:/core/ui/ListItemTemplate" on the list widget.

  • This needs different treatment to that suggested by @jeremyruston with the nested transcludes.

Thus I propose I also change all occurances of;
template="$:/core/ui/ListItemTemplate"
with
template={{{ [[$:/config/ListItemTemplate/MissingTemplate]has[text]else[$:/core/ui/ListItemTemplate]] }}}

  • Where the 1st title is the custom template

I have modified the required tiddlers and implemented on this Proof of Concept tiddlyhost; listitemtemplates.tiddlyhost.com

  • I have two alternate listItem template examples (so far) installed
    • Advanced Search > Filters tab (Edit button, Description tooltip and tag pills)
    • Advanced Search > Shadows tab (Mouse over for shadow source)

I have done this based on the tiddlers containing the use of $:/core/ui/ListItemTemplate and not sure yet how to make use of all the cases.

What I have done is sufficient to meet the OT;

  • However since it involves editing 17 core tiddlers it may be the right occasion to add a little extended functionality.
  • I have included a tool to assist creating Using custom ListItem templates
  • This could remain an optional core plugin to enable the additional functionality.

Extended functionality

  • Allow the listitem template to be selected from a set of preconfigured ones
    • This would involve a set of tiddlers containing alternative list item templates similar to how one can create filter tiddlers - tagged $:/tags/Filter
    • Perhaps gathered using a tag eg $:/tags/list-item-template or just as current, a prefix of $:/config/ListItemTemplate/
  • Display before such lists the description used on the custom list item

Bump, Seeking feedback

I love the list item template you’re illustrating here for the Advanced Search results!

Certainly, some lists want to be compact (say, sidebar lists, and most title lists in multi-column view as they appear at my fonts site), and others may want to be much more informative. Being able to tailor list presentation to one’s common use cases, and then re-use those “recipes” without re-generating the details, would be helpful.

-Springer

I agree, I have come to realise a list item template is only a line based tiddler template. The list items we use could be a whole form, and in other cases we just use the form. A third is when the list items all appear on the one line.

I need to find a way to collapse these tthee concepts into one, perhaps “item view template”, perhaps with three common variations - inline, line or block ?

My feeling is list items default to the current one, or if a named config tiddler exists it will contain the title of one of a number list items templates, which is used instead.

  • However now the list items templates can be “inline, line or block” templates.

I am tempted to now call for variations on the standard list item template and create a “list item template tiddler standard”, to start with variations on $:/core/ui/ListItemTemplate

Eg default

<div class="tc-menu-list-item"><$link /></div>

With caption

<$link> <$text text={{{ [{!!caption}else{!!title}] }}}/> </$link>
  • This one untested, I just came up with it.

Beyond the list items - line templates

  • So too we can look at using a similar method to the custom list item templates in other places and our own code.

Thanks for the inspiration @Springer

1 Like

I believe the following is a better solution than to add multiple new templates and having to modify all the various lists that originally called for ListItemTemplate:

Remake only ListItemTemplate like so:

\define current-template() $:/config/ListItemTemplate/<<currentTiddler>>

<$list filter='[<current-template>is[tiddler]]' 
   emptyMessage='<div class="tc-menu-list-item"><$link /></div>'>
<$transclude/>
</$list>

Thus, ListItemTemplate checks if there exist other (custom or generated) templates for the current tiddler, otherwise fall back on the display that is used today. (The concatenation can really be done directly in the filter without a macro. The is[tiddler] really should somehow be is[tiddler+shadow] though, as there may be plugins with templates.)

Great idea, just a custom one for the use of list items for the current one.

  • I am not sure however if it works for all cases
  • my own solution is designed all cases where a particular list item is used.

I will give it more thought, thanks for the inspiration.

[EDIT] Woops ! Wrong thread, and already made proposal… :sweat_smile:

Hi,

Silently reading this thread since the beginning, I can’t help thinking that it’s a perfect use-case for a new cascade…

Fred

1 Like

New discovery,

In as discussion with @twMat we discovered something of use and a simpler way of creating alternative list item templates buy only changing the following tiddler, which is available for this type of hacking anyway.

Wailt: If you only want custom list items, perhaps don’t read this any further, Soon a set and forget solution will be made available.

For the tiddlywiki enthusiast’s and geeks continue reading to extract some interesting code pattern(s).

The Discovery is that currently, most uses of $:/core/ui/ListItemTemplate is coded within a tab, for example the four tabs in $:/AdvancedSearch, the unintended side effect being that when $:/core/ui/ListItemTemplate is used the <<currentTab>> variable is ofthen available and gives us the name of the tab.

  • Thus it will be possible to replace $:/core/ui/ListItemTemplate with one that looks to see if a custom list item template exists, for that tab and use it if so, if not use the default behaviour.

I will share a working example shortly.

But before I do so, another realisation is that in the <<storyTiddler>> variable is also available, this is the tiddler through which you are looking through, and in which the list is presented. As a result $:/core/ui/ListItemTemplate can now work as follows;

  • If the current tab variable is set, add the prefix $:/config/ListItemTemplates/ and if a tiddler exists of that name transclude that (for each list item).
  • If there is no currentTab variable use the <<storyTiddler>> variable, add the prefix $:/config/ListItemTemplates/ and if a tiddler exists of that name transclude that (for each list item).
  • If none of the above, through the emptyMessage use the default list item format, emptyMessage="""<div class="tc-menu-list-item"><$link /></div>"""

So as a result of the above the standard list item format is used unless an alternative is found in a template of the form $:/config/ListItemTemplates/tiddlername where the tiddlername is the tab or story tiddler in which you are viewing the list.

But wait, there is more, No, not the steak knives!.
The only issue arising from the above is what if you have more than one list in a single tab or tiddler? They would have to use the same list item template unless you explicitly set it. So to address this you can do one of the following;

  • Transclude the required list item template tiddler in the body of the list as the listItem eg {{$:/config/ListItemTemplates/tiddlername}}
  • use the template="$:/config/ListItemTemplates/tiddlername"
  • Or set the variable ListItemTemplate to the templates name see next

ListItemTemplate variable
I propose testing for a value in this variable “ListItemTemplate” before the currentTab and storyTiddler as above and use this as the tiddler name to test if a template exists.

  • This will allow us to override the currentTiddler or storyTiddler list item templates allowing;
    • More than one list in the same tab or tiddler to use a different custom list item template (in addition to regular methods)
    • make it possible to set the list item template programmatically such as using a dropdown selector, and/or getting it from a field value.
    • The ListItemTemplate variable needs to include the full name, including the $:/config/ListItemTemplates/ prefix if needed, this allows a list item template of any name to be used.
    • You could set ListItemTemplate variable globally for a new default result. At least for lists using the default.

Working solution along soon,

  • now we can start designing, collecting and sharing alternative [prefix[$:/config/ListItemTemplates/]] tiddlers. There is a topic on this already.
1 Like

Today I wanted to show a field other than title in the tag pill drop-down. I traced it back to $:/core/ui/ListItemTemplate.

So I agree with @tw-FRed - it seems like a cascade would be ideal here. A cascade would let me pick a template conditionally based on another field, and also have a fall-back to the default template for backwards compatibility.

A solution would be in place if my last post was read and responded to earlier. Multiple places in the core point to $:/core/ui/ListItemTemplate and should continue to do so by default. But the ability to override such links provided. Perhaps a cascade could be introduced however I am not sure it is the most valid approach in this case as the customisability needs to be added then it can be used, by simply adding an appropriately named list item alternative, no need to nessasarily build the cascade facility.

  • I think we can go with this idea but a different approach, covered in this thread.

The design question

  • I suppose do we modify all the core tiddlers that reference the $:/core/ui/ListItemTemplate to look if they have a custom list item template
    or
  • Provide an alternate $:/core/ui/ListItemTemplate (for all that currently use it) that can detect and lookup custom list items templates using the variables currentTab, currentTiddler and storyTiddler
    or
  • Both of the above?
    • documenting changing core list items but the ability to go a lot further.

Personal view, take the second option because it is easier to insert custom lists into the view template and other places.