Automatic Links in ViewTemplate for Core Tiddlers?

Hello there,
does anyone know if there already exists a ViewTemplate for core tiddlers somewhere, in which any references to other core tiddlers are automatically linked?

The core sensibly makes extensive use of such transclusions in the various templates, and I find it tedious having to use the More → Explorer to follow the trail to the piece of code where the things happen that I’m interested in. I’d be faster if anything between {{ and }} and any literal attribute values of tiddler ($transclude) and template ($list) were links so that I could click straight through.

I’d be hoping that a couple of well-placed search-replace[] would do, but then again links within a pre might not be possible. Alternatively, I’d like to show an auto-generated list of any referenced tiddlers somewhere in the UI for core tiddlers.

Have a nice day
Yaisog

Yaisog,

It would be a good idea and I have done part of this in the past, perhaps a Tab behind the info button that could optionally display in the viewTemplate would be best.

  • My prior work was to find all macros with lines beginning “\define” and also showing the parameters in the ().

You can make your own parser that lists the text field and searches for your key strings, then presents these as links using the result, perhaps just finding titles beginning “$:/” would go 90% of the way. This should capture tags as well and turn them into tag pills.

Perhaps an adaption of the free links plugin could highlight titles just when viewing the code.

I will give it some more thought.

Most UI template connections are defined using list-widgets and filter definitions. So most of the time you’ll need to search for a $:/tags/xxxx tag, which will list all elements that are involved.

So some <<list-links ..>> macros in a tiddler will go a long way. Or you have a closer look at: https://tiddlywiki.com/#SystemTags … The tag-pills are clickable and show the “linked” tiddlers.

Many UI elements are defined with the new “cascade” mechanism, which can be found at the
$:/ControlPanel : Info : Advanced : Cascades tab.

The mechanism is very abstract but extremely powerful, because it allows users to add or modify the core UI without the need to change any core tiddlers.

I think, this info should go a long way already

@TW_Tones, @pmario: Thanks for the helpful input that put me on a good track.

In the space of an evening I whipped up a template that pretty much does what I need:


Any (and only) system tiddlers become linked, and tag references are replaced by proper tag pills. Note that links are only created for existing tiddlers or shadows, but not e.g. the parameter in the addprefix filter.

The template code is not very complicated or long:

\rules except dash
\whitespace trim

\define category() [is[tiddler]] ~[is[shadow]]

\define cleanup() [encodehtml[]search-replace:g[{],[&#123;]search-replace:g[}],[&#125;]search-replace:g[--],[&#8208;&#8208;]]

\define format-tag() <$list filter="[<__text__>subfilter<category>prefix[$:/tags/]]" emptyMessage="<$text text=<<__text__>> />" ><span class="mwi-code-tag"><<tag>></span></$list>

\define format-link(text) <$list filter="[<__text__>subfilter<category>!prefix[$:/tags/]]" emptyMessage=<<format-tag>> ><$link/></$list>

<style>
.mwi-code-tag .tc-tag-list-item {
	display: inline-flex;
}
</style>

<pre>
<$let coreTiddlerRE="(\$:\/[\w\/-]+)"
	  replacementRE="""</code><<format-link "$1">><code>"""
	  text={{{ [all[current]get[text]] }}} >
  <$list filter="[<text>splitregexp[\n]]" variable="line">
    <$let parsedLine={{{ [<line>subfilter<cleanup>addprefix[<code>]addsuffix[</code>]search-replace:gi:regexp<coreTiddlerRE>,<replacementRE>] }}}>
      <<parsedLine>><br>
    </$let>
  </$list>
</$let>
</pre>

I tried to deactivate the dash rule by pragma, but was unsuccessful and thus had to add a search-replace for double-hyphens as they do appear in HTML comments. I had to escape a few other characters as well, in order not to cause unwanted changes in the output. Might’ve been done with rules, if they worked.
The style would normally go into the StyleSheet and is here just for completeness. Without the CSS rule, the tag pill has a height that is too large and moves when clicked. Didn’t care to find the cause and just quick’n’dirty jury-rigged it.

To use the template, just copy the code into a tiddler and set it in $:/config/ViewTemplateBodyFilters/system.
This is the way of the Cascade.

Have a nice day
Yaisog

2 Likes

Thanks for sharing back. I have put it on tiddlywiki.com but not so sure what you mean;

Did you mean add it into the list?

$:/config/ViewTemplateBodyFilters/system

[[MyTiddler]] [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/macros]] [prefix[$:/core/save/]] [prefix[$:/core/templates/]] [prefix[$:/core/ui/]split[/]count[]compare:number:eq[4]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[limit[1]then[$:/core/ui/ViewTemplate/body/code]]

Actually the cascade mechanism helps you introduce code without editing but rather than reverse engineer this could you clarify your install instructions please.

Sorry if I was unclear, it was getting late…
You just have to replace $:/core/ui/ViewTemplate/body/code in $:/config/ViewTemplateBodyFilters/system with the name of the tiddler that you have saved it as, so that it gets used instead of the core template to show system tiddler bodies.
This way the original core tiddler needs not be overwritten, as you wrote.

Have a nice day
Yaisog

I updated the code to make it more robust:

\whitespace trim

\define category() [is[tiddler]] ~[is[shadow]]

\define format-tag() <$list filter="[<__text__>subfilter<category>prefix[$:/tags/]]" emptyMessage="<$text text=<<__text__>> />" ><span class="mwi-code-tag"><<tag>></span></$list>

\define format-link(text) <$list filter="[<__text__>subfilter<category>!prefix[$:/tags/]]" emptyMessage=<<format-tag>> ><$link/></$list>

<style>
.mwi-code-tag .tc-tag-list-item {
	display: inline-flex;
}
</style>

<pre>
	<code>
		<$let delimiter={{{ [charcode[27]] }}}
					wrapper="""<<format-link "$1">>"""
					coreTiddlerRE="(\$:\/[\w\/-]+)"
					replacementRE={{{ [<delimiter>] [<wrapper>] =[<delimiter>] +[join[]] }}}
					text={{{ [all[current]get[text]search-replace:gi:regexp<coreTiddlerRE>,<replacementRE>] }}} >
			<$list filter="[<text>split<delimiter>]" variable="segment">
				<$list filter="[<segment>!prefix[<<format-link]]" emptyMessage=<<segment>> >
					<$text text=<<segment>> />
				</$list>
			</$list>
		</$let>
	</code>
</pre>

The lines are no longer split and individually wrapped in <code> tags. Instead, delimiters are inserted before and after each found link / tag. Everything that is not a link / tag is then wrapped in a $text widget to prevent any unwanted formatting / wikifikation.
I used the ESC charcode as delimiter, as this is unlikely to ever be used anywhere and works (for me on a Windows system).
The definition of e.g. replacementRE is a bit indirect, mainly so that tiddler containing the above code is also shown correctly.
The result is still the same as in the screenshot above.

Have a nice day
Yaisog

1 Like

pragma rules are activated when a new parser is started. Evaluating a new macro starts a new parser. That’s why the first rule only “rules” for the code in the tiddler, starting with <style> … every \define has it’s own parser. …

Your <<parseLine>> … looks like a macro call, but is a variable. No pragmas are applied here. … I don’t know, if it is possible to rewrite the code, that rules would be valid.

Extremely Impressive Code. Thx for sharing. – I think that’s definitely worth to be packed into a dev-plugin.

Excellent idea, and a very cunning implementation.

I tried a different approach: to overwrite $:/core/ui/ViewTemplate/body/code with:

<$let
	newline={{{ [charcode[10]] }}}
	text={{{ [<currentTiddler>get[text]addprefix<newline>addprefix[\rules only syslink]] }}}>
<pre><code><$macrocall $name="text"/></code></pre>
</$let>

The trouble with my approach is that it loses the highlighting supplied by the highlight plugin.

Both approaches show that it’s a useful feature, and would be worth exploring more.

1 Like