Exploring default tiddler links hackability in V5.3.0

I now have a working example by redefinition of the link widget which does affect the standard links however before I can generalise it I notice a quirk, perhaps specific to this application;

  • Standard links of the forms CAmelCase [[two words]] and [[cute|not so cute]] can now be prefixed or suffixed.

However

  • the actual link widget <$link/> and <$link to=HelloThere/> have no link text appear.
  • Although <$link to=HelloThere>Hi</$link> does show Hi

So I think the example @btheado gave me needs a little finessing to produce a link title when the content of the link widget is empty.

Right, change the parameters line to have to and tiddler if you want to access them directly:

<$parameters to="" tiddler="" $params="@params">

Add a body to the slot widget to give the slot a default value:

<$slot $name=ts-raw><$text text=<<currentTiddler>>/></$slot>

Looks like that is only part of the solution. It works for the first example below, but not the 2nd and 3rd:

<$link/>

<$link to="HelloThere"/>

<$link to="HelloThere"></$link>

I made another change which helps with the 2nd to last test case, but the last case is still rendering different from the default $link widget. I’m a little stumped on that one.

\widget $link()
<!-- Use a parameters widget so we can use `$params` to define a variable
 containing all the passed-in parameters -->
<$parameters to=<<currentTiddler>> tiddler="" $params="@params">
<$genesis
  $type="$link"
  $remappable="no"
  $names="[<@params>jsonindexes[]]"
  $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]">
<$slot $name=ts-raw><$text text=<<to>>/></$slot>
</$genesis>
</$parameters>
\end

#[[some missing tiddler]]
#HelloThere
#[[link text|HelloThere]]
#<$link to="HelloThere">Some different text</$link>
#<$link/>
#<$link to="HelloThere"/>
#<$link to="HelloThere"></$link>

The last case is rendering as

<a class="tc-tiddlylink tc-tiddlylink-resolves" href="#HelloThere">

</a>

instead of like this with the default $link widget

<a class="tc-tiddlylink tc-tiddlylink-resolves" href="#HelloThere">HelloThere</a>
2 Likes

Brilliant stuff @btheado. I think you’re running into a special case of the link widget: if it is empty (ie contains no link text widgets) then the title of the target tiddler is used as the text of the link. I think your override may need to explicitly handle that case.

2 Likes

This is proving to be a very educational problem to explore, learning from your examples @btheado things that are too hard at present to understand for me in GitHub and the Doco’. I will change the title to Exploring default tiddler links hackability in V5.3.0 and repost once the issues are resolved, so people are not confused by the complexity.

  • Interesting, I applied the change to slot and the 1st example fails not the 2nd and 3rd see below via link widget.

Code in use above;

\widget $link()
<!-- Use a parameters widget so we can use `$params` to define a variable
 containing all the passed-in parameters -->
<$parameters to="" tiddler="" $params="@params">
<$let currentTiddler=<<to>> >
<$list filter="[tag[$:/tags/before-links]]" variable=tiddlername>
<$transclude tiddler=<<tiddlername>>/>
</$list>
<$genesis
  $type="$link"
  $remappable="no"
  $names="[<@params>jsonindexes[]]"
  $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]">
<$slot $name=ts-raw><$text text=<<currentTiddler>>/></$slot>
</$genesis>
<$list filter="[tag[$:/tags/after-links]]" variable=tiddlername>
<$transclude tiddler=<<tiddlername>>/>
</$list>
</$let>
</$parameters>
\end $link
  • I saw a hint of this earlier. Perhaps the slot can contain a conditional? if empty then display link title? I am still experimenting. but we have 99%

I’m still stuck. I don’t see how I can have widget code to distinguish between #1 and #2 below. It seems like the slot widget should behave the same for both. I guess I could use the wikify widget to see if <$slot $name=ts-raw/> renders as empty, but that seems kind of ugly.

\widget $$mywidget()
<$slot $name=ts-raw>the body is empty</$slot>
\end

#<$$mywidget/>
#<$$mywidget></$$mywidget>
#<$$mywidget>the body is not empty</$$mywidget>

renders as

  1. the body is empty
  2. the body is not empty

Is it a bug in the slot widget or am I misunderstanding?

Until we can resolve the empty link widget case it would be dangerous to set this as a global replacement for the linkWidget in a wiki.

However I found it is simple to \import tiddlername or perhaps the ImportVariablesWidget could be used in a conditional viewtemplate?

Another desired outcome, where we want access within the new widget is when using the pretty link [[short name|this is the long name]] it would be good if we had access to the pretty name because it could be used to populate the caption field of the target tiddler if one is not available.

Thank you @btheado, It is indeed a bug in slot widget.

For the background, look at the parse trees generated by the three cases:

#<$$mywidget/>
#<$$mywidget></$$mywidget>
#<$$mywidget>the body is not empty</$$mywidget>

The parse trees are similar in each case, with these differences:

  1. The isSelfClosing attribute is true, and there is no children array
  2. The children array is present but empty
  3. The children array is present, containing the text node of the text the body is not empty

The slot widget was only checking for an entirely missing children array. It’s fixed on GitHub by also checking the children array being present but having a zero length.

The prerelease at https://tiddlywiki.com/prerelease/parameterised-transclusions/ should be updated in a few minutes if you can give it a try.

Using the previously developed override of the link widget the last test case still has a problem.

custom-link-widget-test.json (1.9 KB)

Use on latest 5.3.0

  • “Some test cases” is default behaviour
  • “Using custom widget” imports $:/PSaT/linkWidget and fails only in the last item.

Correction Fails on 2 cases

  • <$link/>
  • <$link to="HelloThere"></$link>

The update went through and the only case failing is;

  • <$link/>

Thanks for the explanation and the fix works for me!

The last code for $link I posted works for all 7 test cases included there. Is that the version you are using?

I am now, I added my own mods and must of Broken something, also the revised 5.3.0 pre-release is necessary to avoid he 7th failing - Jeremys fix.

Thanks heaps, I can now explore the possibilities to their fullest extent.

Thanks you @btheado and @jeremyruston we are almost there.

Given the discussion here in I created a small test package for the pre-release. It works well in principal by using a tag driven way to prefix or suffix any link generated by the link widget with an edit button.
link-widger-reimagined.json (1.4 KB) test on prerelease

  • This works against all our versions of link definition
  • It even goes a little too far when applied globally, including appearing in the title, subtitle and site title.
  • However it is a great proof of concept.

However

When you do edit a tiddler the editor is broken, remove the $:/tags/Macro from Link widget reimagined to stop it.

Questions

  • Is the editor somehow using the link widget?
  • Can we fix this?
  • Does this indicate how problems can arise using the widget pragma?
  • Do we need a fix for the Prerelease?

Hi @TW_Tones it sounds like the problem is that your redefinition of the link widget is still in force within the custom link widget. To prevent that, set the variable $link to the empty string before trying to use the link widget.

It would be very helpful if you could use the tiddlywiki.com/share.html feature for these kind of things, it makes it much easier for others to see what you’re talking about.

1 Like

Is there a prerelease wiki to use the share on top of this?

  • I will look into it later, but I found it difficult configuring the share wiki to my needs.
  • Share link here
  • Also I like to share tiddlers that work on tiddlywiki.com

Hi @TW_Tones the prerelease includes a share.html at https://tiddlywiki.com/prerelease/share.html

2 Likes

@jeremyruston I really like the share site and I wrote the following bookmarklet to make it easy to convert tiddler.json links. I’m glad you are promoting it, maybe the bookmarklet will become less necessary:

For @TW_Tones issue, I don’t think the issue duplicates at the prerelease share site. The issue does happen at the main prerelease site. Looking at the DOM of the misbehaving edit widget content, the codemirror plugin is my first suspicion. @TW_Tones I suggest downloading the prelease and disabling the codemirror plugin. If that makes the issue go away, then it will help narrow down the issue.

I am working on an html/javascript page which fetches a remote TW, prepends extra tiddlers, and loads the result in an iframe. The idea is to have the functionality of the share site available to any TW edition rather than just the (effectively) empty edition of the share site.

I’ll share more once I have a working prototype.

2 Likes

As @btheado says it is not failing on the prerelease share wiki and most likely because of code mirror somehow also using the link widget we redefined Share demo as requested @jeremyruston . I imagin we are going to see this in future when overriding core widgets because other core plugins would have been written with the core behaviour in mind.

  • Hacking the default links is an example where we are more likely to run into issues because its a fundamental core behaviour.
  • In most other cases I am tempted to define a new widget or macro rather than redefine an existing, but not in this case.
  • Now I need to look at the opportunities to somewhat localise where this links hackability is active, for example there is no need in edit mode, code mirror or otherwise (except edit preview).

I think this example is an example of where we need to ask do we just use the new hackability or investigate a real core hackability enhancement?

  • To me its fundamental to allow the default tiddler links to be customised because this is an opportunity to introduce usability features on wiki links.
  • Maybe a local parameter, that if set can trigger the behaviour otherwise the default link widget behavior occurs?

I figured out what the issue is. The $:/plugins/tiddlywiki/codemirror/lib/codemirror.css tiddler is marked with type=text/vnd.tiddlywiki so wikitext parsing is performed on it. The style selectors are things like .CodeMirror and .CodeMirror-gutters. To the parser, “CodeMirror” looks like a link so it generates a link widget for it. You have overridden the link widget and are adding extra stuff before the link. This extra stuff makes the CSS invalid.

Without the valid CSS which codemirror relies on, the editor is not displayed properly. If I change the CSS tiddler to type=text/css, then the editor works fine again. IMO, it would be best make this change permanent to the codemirror plugin. I don’t see a reason wikitext processing is requires for that css tiddler.

I don’t see how changing the core can help with this issue.