Exploring default tiddler links hackability in V5.3.0

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.

Interestingly, while I was troubleshooting (before I discovered it was a css issue), I tried reverting to the “no-op” link widget override from earlier in the thread and I still saw the codemirror issue. I added “\whitespace trim” and that solved the issue:

\widget $link()
\whitespace trim
<!-- 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

Thanks @btheado for trouble shooting this;

  • This was speculation but if we are to provide “default tiddler links hackability” would it make more sense to place it in the core?

I am revisiting this today to try and crystallise the result of this thread into a solution, with tags driving before and after default link hackability.

I think the $remappable attribute of the GenesisWidget is as of yet undocumented. What does it do?

Thank you @TW_Tones and thank you @btheado for this nice example.

Yes please! This example shows an applied and useful scenario of custom widget, genesis widget and parameters widget.

It also shows how wonderful can be the new features of TW 5.3.0.

Thanks @Yaisog that’s an oversight. I’ll push a docs update when I am back at my desk.

The $remappable attribute controls whether the genesis widget honours custom overrides. It defaults to yes which means that any custom redefinition of the target widget will be honoured as usual. Set it to no to ignore any custom redefinitions, and instead create an instance of the base widget as though it had not been redefined.

The latest prerelease now has this fix.

It was great to rediscover the examples in this thread now that I’m digging into the new 5.3.0 features. Many thanks to @btheado in particular for the tip about @params!

A question I haven’t yet managed to answer through trial and error:

I understand the use of <$slot $name=ts-raw><$text text=<<to>>/></$slot> to provide text content for constructions like <$link/>, but is it possible to redefine the text displayed when the children array is not empty?

  • As a hypothetical example: Could I redefine the widget so that [[A-Link-With-Hyphens]] displays as A Link With Hyphens?

Edit: In the interim, since I use uni-link anyway, I hacked the linkText macro (as defined in $:/plugins/wikilabs/uni-link/uni-link-macro) to conditionally display alternate text, and that works just fine for my purposes. If there’s a way to do this with “vanilla” 5.3.0, I’d still like to hear it, though!

Yes. It isn’t as easy but it can be done. The $parseTreeNodes attribute on the parameters widget gives access to the children array and the jsonindexes and jsonget operators can be used to get the content:

\widget $link()
\whitespace trim
<!-- 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" $parseTreeNodes=@ptn>
<$genesis
  $type="$link"
  $remappable="no"
  $names="[<@params>jsonindexes[]]"
  $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]">
<$list
  emptyMessage="<$slot $name=ts-raw><$text text=<<to>>/></$slot>"
  filter="[<@ptn>jsonindexes[]] :map[<@ptn>jsonget<currentTiddler>,[text]] :and[regexp[-]split[-]join[ ]]">
<$text text=<<currentTiddler>>/>
</$list>
</$genesis>
</$parameters>
\end

In the above, I use the variable names @ptn to access the children. If there is a text field containing a dash, then the dashes are replaced with spaces. Otherwise it will fallback to the $slot content.

#[[A-Link-With-Hyphens]]
#<$link to="A-Link-With-Hyphens"/>
#<$link to="A-Link-With-Hyphens"></$link>
#[[some missing tiddler]]
#HelloThere
#[[link text|HelloThere]]
#<$link to="HelloThere">Some different text</$link>
#<$link/>
#<$link to="HelloThere"/>
#<$link to="HelloThere"></$link>

With the changes, the above (placed in a tiddler named “modified link widget test”) renders like this:

  1. A Link With Hyphens
  2. A-Link-With-Hyphens
  3. A-Link-With-Hyphens
  4. some missing tiddler
  5. HelloThere
  6. link text
  7. Some different text
  8. modified link widget test
  9. HelloThere
  10. HelloThere

As you can see the dashes in test case 2 and 3 are not handled. More changes would be required.

You can see the above in action using this share site link.

1 Like

I think the regexp[-] in the above :and filter run is not needed.

`:and[split[-]join[ ]]`

should work also. Is there a reason for the regexp?

Yes. The reason is that <$text text=<<currentTiddler>>/> is not perfectly backwards compatible like <$slot $name=ts-raw><$text text=<<to>>/></$slot>. Therefore I used the regexp to minimize the number of cases in which the emptyMessage is not used.

This case would be broken without the regexp, for example:

#<$link to="HelloThere"><b>Some different text</b></$link>

Since the parse tree doesn’t have a text attribute for :map[<@ptn>jsonget<currentTiddler>,[text]] to pluck out.

@TW_Tones I modified the custom link widget code shared by you in one of the earlier post to add a button next to the link to get popup preview of the tiddler - share demo

Any suggestions to modify it so that it visible only in certain places like tiddler body, recents and in advanced search results ?

1 Like

Nice application @arunnbabu81

The way it works is to redefine the link widget, and currently your wiki has this definition with the $:/tags/Macro/View/Body tag. Which should only replace its use in the tiddler body.

You could instead use $:/tags/Global for it to replace even more cases of its use.
Snag_605a5116

Or you could import it into tiddlers where you want it to apply

\import [[$:/arsheth/widget/link]]

Or since you used the $:/tags/link-suffix you could wrap the contents of that tiddler with a list that determins if it should be displayed or not

<$list filter="[all[current]is[tiddler]]" variable=~>
...
</$list>
2 Likes