Is there a way to provide the output of a widget as an attribute value?

Hi folks, Just experimenting with custom widgets and there are some cool possibilities.

While experimenting I have discovered the desire to set an attribute value to the output of a widget. I know it can be done in some special cases like the text attribute of the $wikify widget, and the emptyMessage of the list widget, but in this case you provide the TiddlyWiki script and that is “evaluated” in those widgets.

So here is a very simple example;

<$text text="<$my.Widget/>" />

Such that <$my.Widget/> would be “evaluated” and passed to the text widget.

Another example may be inside a custom widget;

<$text text="<$slot $name="ts-raw"/>" />
<$slot $name="ts-raw"/>
  • In this example it would show the content of the calling widget as text,then as rendered.

I understand the above does not work, but is there any way to do this other than the wikify widget? Even if we can set a variable to the widgets output, use transclude somehow?

  • I suspect I am expecting too much, but ask how we may go about capturing the output of a widget?

The output of widgets usually are HTML elements. You should use functions if you want to assign the output to a variable.

  • Thanks for that clarification @pmario
  • If you can comment on my documentation and clarification, it would be appreciated.

In my words;

Widget output is typically rendered into HTML for display, so their output is usually to the “display”, or an interactive component like a button or select. The exception being action widgets, which require a trigger (such as a button) to make changes to a tiddler, tag or field.

  • As a result, widgets cannot be used to set the value of an attribute unlike other methods.

Some core widgets are designed to assign a value to a variable such as set, vars, let and list. But includes other such as wikify.

  • In these cases a number of methods are available to set a variable using tiddler and field references, other variables, macros, functions, procedures, transclusions and filtered transclusions. Since TW 5.3.0 also Substituted Attribute Values.

With the introduction of the genesis widget TW 5.2.4 and custom widgets TW 5.3.0 designers may be tempted to write their own custom widgets, which have some advantages over the alternatives, especially with improved parameter handling.

  • However it is important to remember “Widget output is typically rendered into HTML for display” so keep this in mind when to choosing a widget over the other methods.
  • Specifically don’t use a widget if you wish to assign the output to an attribute or variable.

Not withstanding these caveats for the use of Custom widgets;

  • Widgets can make use of any value passed in a parameter, variable or the content of the widget.
  • Custom widgets can contain other widgets internally.
  • It is possible to use a custom widget from within a custom, tiddler and transclusion, macro or procedure allowing the creation of a hybrid solution.

For me all of that text looks good.

There is only 1 thing which is important. “Child” widgets can see variables that are defined from “parents”. The other way around is not possible.

Parents do not know, what their children do. That’s intentional. So if a child widget creates a variable with the same name, it will only be visible within the child’s scope.

Outside the child scope, the parent variable will take over again.

I agree with that, if you can work it into the text please do so.

The result of a widget and its child widgets, its parent etc… all result in html displayed to the user. If we are think of widgets as ultimately only displaying something then we can say the widget displays everything within it, including its child widgets, even if the parent can’t see inside the children.

Perhaps this is not the best example, but “rendering” is a fundamental feature of tiddlywiki, and it seemed it was explained more in the past, I wonder it we need to find a way to describe it for more recent users, and how do we do that?

I came to the forum today to ask about this very issue mentioned by @TW_Tones. It seems @pmario is pointing to functions to do something like this kind of work. I confess I understand nothing about functions yet, and am not ready for a steep learning curve at the moment.

So maybe someone can give me perspective on this very specific challenge (whether or not that becomes my front door to appreciating functions). I need to take the output of

<$view tiddler="$:/springer/template/alt" format="htmlwikified"/>

(itself evaluated within a <$list> widget, so each tiddler is being transcluded with the template) — and then do stuff with that resulting html sequence (starting by trimming out leading and trailing <p> strings, and eventually making a button to copy that modified html string to the clipboard).

I’ve been struggling with it for a while. It seems only the <$view> widget can help me achieve the htmlwikified format I need, but then I don’t see how to pass this widget-result to the clipboard. (I have no trouble getting simple html-format contents of this or that field to the clipboard, but in this case I’m trying to get the html for a complex template result.)

The workaround so far (in case it helps make the goal vivid) involves making a new tiddler, setting the template-transclusion string into its text field, and using the view-html option in the internals plugin to display the desired full-template html, and then try to select all that html in the right-hand pane. Rinse and repeat for each desired tiddler on the list.

(In case anyone is tempted to give me other html-tiddler-export advice: there are very annoying reasons why I need to get this html directly onto the clipboard for further handling. I’m pasting the results to moodle (university LMS), which strips out all style tags and css declarations tags. So I need to handle and massage the html on the clipboard way more than what any normal workflow would require.)

Many thanks for any insight! And maybe responses to this challenge will help orient people to analogous cases where widget output wants to get taken up for further handling…

You should file a bug at GitHub, that there is a leading and a trailing P-tag. It should not be there in the first place. That’s a known issue of the core atm, but if it’s only me how is annoyed by it, it probably won’t get enough attention.

1 Like

@Springer I have being doing a deep dive into both the use of functions and substitution offline. I am sure I can provide some insight into functions soon.

On your current issue “do know if you install the core Internals plugin there is a html preview?”

Anyway I have being looking into your issue and it is multi-faceted but I have a number of techniques that may help. I will be back.

Here is a working solution in a tiddler tagged $:/tags/ViewTemplate

<$wikify name=html text="{{||plainhtml}}">
<$button tooltip="click to copy" message=tm-copy-to-clipboard param=<<html>> >
HTML {{$:/core/images/copy-clipboard}}
</$button>
</$wikify>

Where plainhtml contains;

<$view field="text" format="htmlwikified"/>

I did not see arbitary <p></p> tags appearing but many thddlers start with a paragraph and end with another (but not all)

  • Remember that the html view is in fact what we see after the content is wikified.

Yes. If you look back at my “workaround” paragraph, I explicitly say that if I make a new tiddler to hold the relevant transclusion, I can indeed use the internals plugin html view to display (in edit view’s right pane) the html that I need to copy.

And your button enables me to copy-as-html from that tiddler without getting into edit mode, which is helpful!

However, for each tiddler of this kind that I’m working with, the html content I need corresponds to a complex templated transclusion — not to the text field. I have a cascade condition that displays according to the template (and there’s actually a specialized edit template as well).

I’ve played with what you compiled, above. Probably the quickest way to explain the remaining challenge is a link to what’s actually going on (recreated on my demo site, since my actual teaching site has read-only stuff that would keep you and others from peeking under the hood):

https://quick-demo.tiddlyhost.com/#Goodness%20vs.%20Lawfulness

I had hoped a button like this could work right from the tiddler I’m looking at. (This tiddler is already displaying with the desired template due to cascade condition.)

Again (still), it’s easy enough to pick up the html-format contents of the text field of any tiddler, and that’s what your button is automating…

It’s frustrating to be generating a separate tiddler (with the template-transclusion) just in order to get at html that in some sense is already “there” and just can’t be reached…

I do appreciate your taking the time to work through this!

I will have a look at your example soon, however you should just be able to use the code to place the “complex templated transclusion” inside the wikify widget.

I think the wikify widget is the best way to achieve this. It is the primitive upon which the format="htmlwikified" option of the <$view> widget is based.

Ah, thanks! Once we’re in a ViewTemplate element (which is a mechanism I’ve been neglecting ever since turning to cascade conditions), I can change what you’re calling the plainhtml tiddler to work this way:

<$view tiddler="$:/springer/template/alt" format="htmlwikified"/>

… and then use your button. (Even better, I should figure out how to reference the cascade conditions for displaying the tiddler, so that the html-copy button uses whatever template-tiddler is required according to the cascade. But that’s tricky since the plainhtml tiddler is not currently interacting with my content tiddler at all… I’ll follow up once I’ve explored possible solutions for that, in case anyone else has such a need.)

The copied html still does have the extra <p> tags… so I’m still wishing that the output of a widget could become something subject to further operations, and there might be other ways in which the html needs massaging… But I no longer feel my html-clipboard workflow is unmanageable.

Although @pmario suggested I submit a bug report about the extra <p> tags, I’m afraid it would take me quite a while to orient to how to do that.

If I have understood your requirements correctly, namely that you want to copy the HTML for the body of a tiddler as displayed in the story river, try the following:

<$wikify name="renderedHtml" output="html" mode="inline" text="""<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} />""">
<$button tooltip="Copy rendered HTML" message="tm-copy-to-clipboard" param=<<renderedHtml>> >
Copy rendered HTML
</$button>
</$wikify>

If you want to do any further processing of the HTML via filters, modify the variable renderedHTML after the $wikify widget and before the $button widget.

3 Likes

Thanks! Can’t try it now, but I look forward…

Wonderful.

If I have installed Highlight.JS, for a tiddler tagged with $:/tags/Stylesheet this solution generates the right HTML.

Thank you!

@Springer when you continue work on this remember that p tags are a common result of wiki text. Perhaps remove unnessasary line breaks, use whitespace trim etc… As they could be creeping in.

  • in my own tests I am not getting unwanted p tags.

Yes!

For some reason your variant (@saqimtiaz) does not put those extra <p> tags (bookending the intended html) onto the clipboard.

So I’m happy as a clam. (Are clams happy? :thinking: … I’m as happy as a clam would be if it were happy.)

Does that suffice or do you need to be able to copy the HTML for multiple tiddlers at once?

It suffices! My need is to be able to copy-paste on a per-tiddler basis anyway.

I’m still curious about whether operations can be performed on the html taken as output of the view widget (getting it not just onto the clipboard but into some further manipulation first, such as replacing certain elements), which is why I posted here. But at this point I am absolutely happy with at least being able to get the needed html — responsive to the cascade’s display of the tiddler body, with no extra <p> tags — onto the clipboard!

-Elise

I did make and share a snapshot tool which took the current tiddler converted it to html and displayed that instead of rendering the tiddlers wikitext.

  • The idea was to take a post render snapshot and display that instead, allowing large complex tiddlers to be viewed staticaly and demand less processing. It also allowed you to capture the state of a tiddler “as at a moment in time”.

Your could take this method which saves a copy of the tiddlers rendering as html in a seperate tiddler. Then you could create some tools that act on the html copy in the way you want, before copying to the clipboard.