The qualify macro use the transclusion variable and returns a unique string that encodes its position within the widget tree, as identified by the stack of transcluded tiddlers that lead to that position. I’m not sure but given that description I’m guessing that the number you get from the qualify macro can be used to detect a transclusion depth.
@telumire It doesn’t seem to offer a way to “decode” the string to get the “stack of transcluded tiddlers”, and the transclusion variable referenced before doesn’t include the whole stack. I don’t think these will help me here.
I’m confused. If one refactors one’s code in a way where the <$slot>
widget gets moved to a macro, is that an extreme edge case? Because, as you say:
And this is true even if you weren’t originally using the $depth
attribute - simply moving it to a macro, which is a variable that gets transcluded, changes the needed depth from 1 to 2.
In my mind, it’s inflexible and brittle as it is.
The whole point of my desire for a <<transclusionDepth>>
variable was to be able to use the slot at any depth without messing with the $depth
attribute. All I’d need to do is:
<$let slotDepth=<<transclusionDepth>>>
<$transclude ...>
<$fill name="cheese">
...
</$fill>
</$transclude>
</$let>
Then when I use the slot, I can use it like this:
<$slot $name="cheese" depth={{{ [<transclusionDepth>subtract<slotDepth>] }}} >...</$slot>
By thus computing the $depth
value, I could flexibly refactor my code all I want (or upgrade the wiki) and let the transclusion depth change however it will, without breaking my slot.
I was intending to make a plugin or “edition” that would fill slots, and custom widgets designed to be used that would do things with those slots. I didn’t want the users to have to only use the custom widget at a specific depth, or to have to know the depth at which they’re using it, so it would be nice to let the widget compute the $depth
attribute so that the user doesn’t have to worry about it.
I am now considering alternatives in order to avoid using slots at all, since they don’t seem to afford this flexibility.
Something like this, but aggregating count instead of aggregating tiddler titles, right?
TiddlerTransclusionLevels.json (877 Bytes)
@Charlie_Veniot Yeah, that’s the basic idea, but also without having to specify a special template to keep track of the count (besides, I could need to transclude a widget or macro).
Yes, even if you change your own code, if there is any need to use the depth of something, it is most likely to be to the parent or grandparent process, that is the relative depth, -1 or -2 conceptually. Very unlikely an absolute depth.
I think your issue stems from the same issue I raised, because the slot contents are only returned using a widget (read as a final output mechanism) there is little we can do to make use of the contents. And this includes the contents of the calling widget/procedure which is what slots are all about. Accessing ts-raw without the slot widget?
- Since we can’t use those contents much at any level we can’t set variables etc… that will be available in a child widget or process either.
- So we then look to the depth parameter and it all gets really confusing.
- What do you mean with these words? surely there is no need to use the word transclude here? Just
-
I could need to include a widget or macro
- Or do you mean something different?
-
At least in a way, yes. I wanted to access slots at an unknown relative depth. My thought was that if the absolute transclusion depth were available as a variable, then the relative depth would be easily computable, but if slots were available as variables as in the idea in your post, that would also make it a lot easier.
@pmario provided a good answer:
Almost every widget or procedure that we call in v5.3.x will end up to create 1 or more transclusions.
As the $transclude widget documentation says:
The
$transclude
widget dynamically includes the content from another tiddler or variable
(emphasis added)
And as we know macros are also a kind of variable. Even custom widgets are implemented as a kind of variable:
Custom widgets are implemented as a special kind of variable. The only thing that distinguishes them from ordinary variables is the way that they can be called as a custom widget with attributes mapped to parameters.
surely there is no need to use the word transclude here?
Normally I wouldn’t use that word for widgets, procedures, or variables because that’s just the implementation under the hood. But in this case, it’s relevant that the underlying mechanism is a transclusion, because this changes the transclusion depth, and thus, changes the $depth
value needed to use slots. For example, if you copy the following code into a new tiddler and open the preview:
\define myMacro() <$slot $name="ts-raw"/>
\widget $my.widget() <<myMacro>>
<$my.widget> slot content </$my.widget>
You’ll find that the slot content isn’t displayed. (As per the custom widgets documentation linked above, ts-slot
is the slot that TW automatically fills in a custom widget to provide access to the the children of that widget, slot content
in this case.) But if you change the first line to:
\define myMacro() <$slot $name="ts-raw" $depth=2/>
Then it displays. This is because the macro call is technically a variable transclusion, so to use the slot widget’s slot within the macro, we have to specify that it is not a slot filled in the macro call but filled in the widget call, its parent in the tree.
(If you change the preview type to widget tree, you can see that the widget and macro are both rendered via transclusions. However, despite the simplicity of the code example, the widget tree is too unwieldy to share here.)
That’s why I chose to use that word - not just because it’s a transclusion under the hood, but because the fact that it’s a transclusion is relevant to this particular issue of wanting to use $slots without having to know the transclusion depth.
\define myMacro() <$slot $name="ts-raw"/>
To my understanding this is an incorrect use of the slot widget. The slot widget is designed to be used inside a widget definition, be it a custom widget, or one that overrides a core widget.
- It is interesting that you point out it works when placed inside a macro definition but this is just a side effect. Macros are deprecated and procedures recommended).
- Interesting but non-standard
That’s why I chose to use that word - not just because it’s a transclusion under the hood, but because the fact that it’s a transclusion is relevant to this particular issue
Actually I think this view point is confusing the issue, seriously.
Lets go back to the slot widget, what do you want to use it for?, I have learned how to use them and never needed to consider depth.
- As I understand it the depth already is a relative term, and no need to work it out, there is arguably no useful absolute depth.
- If one was to use depth, most likely it would ONLY be for access to the grandparent or higher within a specific set of code, such as a reiterative or recursive code set. The default depth is the one before.
- And the ways variables flow down to its children, even this is unlikely to be needed.
- Perhaps except in the event of meta things, like writing code that writes code, or generates templates and objects like buttons.
- And the ways variables flow down to its children, even this is unlikely to be needed.
- I think there is value in building a code structure that uses the slot widget in standard ways, and only then asking how you can make use of the depth.
Being a bit of a hacker myself, I did guess that using depth may give us some interesting hacks into the tiddlywiki core processes and provide some creative design opportunities. But I have not yet found a compelling reason to do so.
To my understanding this is an incorrect use of the slot widget. The slot widget is designed to be used inside a widget definition, be it a custom widget, or one that overrides a core widget.
It is interesting that you point out it works when placed inside a macro definition but this is just a side effect.
It’s not a side effect. It works because the macro is called by a widget. It’s only incorrect if I call the macro outside the widget.
Perhaps I should amend the example:
\widget $my.widget()
\define myMacro() <$slot $name="ts-raw"/> <!-- add $depth=2 to make it work -->
<<myMacro>>
\end $my.widget
<$my.widget> slot content </$my.widget>
This would make it a little more clear that the macro can only be called inside the widget, I think.
Macros are deprecated and procedures recommended
From what I understand, this is only relevant when using parameters; for reusable code snippets with no parameters, \define and \procedure work exactly the same, do they not?
I have learned how to use them and never needed to consider depth.
This means you are only using them directly in the widget definition or transcluded tiddler. In a way, this is where I was going wrong - assuming that you ought to be able to easily use them that widget or tiddler’s children. (Keyword “easily”) I am looking to things other than slots now (although there’s no alternative to the ts-raw
slot).
Edit: as for the relative vs absolute depth: $depth
is a relative depth, yes. I wanted absolute depth available (as a variable) in order to be able to easily compute the needed relative depth (as in the examples above).
It’s not a side effect.
- To me it (needing the depth) is a side effect of
This would make it a little more clear that the macro can only be called inside the widget, I think.
putting the slot widget inside a macro.
But why not just;
\widget $my.widget()
<$slot $name="ts-raw"/>
\end $my. Widget
<$my.widget> slot content </$my.widget>
This would make it a little more clear that the macro can only be called inside the widget, I think.
It does make it clearer.
From what I understand, this is only relevant when using parameters; for reusable code snippets with no parameters, \define and \procedure work exactly the same, do they not?
- There is a little more to it than that but the part you say is not wrong.
- It is a problem using both macros and procedures when some sort of evaluation needs to take place, because some uses will need you to wikify it first.
- But this is also true when your macro includes the slot statement, however your invocation of that macro
<<myMacro>>
is just that it gets wikifeld in the final render.
- But this is also true when your macro includes the slot statement, however your invocation of that macro
I do think I know where your queries were generated. There is some incompletness in the code for manapulating slots and I have reased this in the past
- Accessing ts-raw without the slot widget?
- Custom widgets and making use of slots this is unanswered
- How to make $slot and $fill palatable which leads to a change I was involved in;
in order to be able to easily compute the needed relative depth (as in the examples above).
I would argue I see no case where you need to do this. As the coder you can see what the depth is and encode that.
- In the example above, inside the macro you need depth 2, in the body depth 1 the default.
As the coder you can see what the depth is and encode that.
I was intending to make a plugin or “edition” that would fill slots, and custom widgets designed to be used that would do things with those slots. I didn’t want the users to have to only use the custom widget at a specific depth, or to have to know the depth at which they’re using it, so it would be nice to let the widget compute the
$depth
attribute so that the user doesn’t have to worry about it.
(Discourse won’t let me post without at least 20 characters, and apparently quotes don’t count, so I’m writing this junk sentence.)
I think there would be value pursuing as simple an example as you can of what you are trying to do. Ideally a package we can drop on tiddlywiki.com and experiment with. Looking at tiddlywiki at this level of sophistication gets complex perhaps as a result of its flexibility. I expect it is quite easy to get the same results by more than one path.
- The standard way to fill a slot is using the fill widget?
- I think they were designed for a much simpler use case, but I applauded your objectives. Initially only the ts-raw was in effect valid.
- Traditionally the approach is to transclude the content of a macro, procedure or tiddler. The slot is the first time we gained access to the content of the calling widget to support custom widgets and is still incomplete.
Can you be more specific about a “real usecase” other than “I just want to test it”.
I think there would be value pursuing as simple an example as you can of what you are trying to do. Ideally a package we can drop on tiddlywiki.com and experiment with.
@pmario @TW_Tones Here is an oversimplified example of why I want to be able to use slots at arbitrary depths without having to worry about the $depth
attribute. I don’t yet know how to format the json so that it can be dragged onto a TiddlyWiki to be imported, but this should at least be able to be downloaded and the contents copied and pasted into the $:/Import tiddler. Thanks @Scott_Sauyet
Oversimplified version (1).json (1.6 KB)
I have created an <$error.context>
custom widget that does nothing but display its ts-raw
slot. I have also created a <$safe.button>
widget that is a wrapper for the <$button>
widget, except that it wikifies the slot of the error context widget into a widget tree and detects the presence of any <$error>
widgets within the <$error.context>
widget, and disables the button if there are any errors present.
As a demonstration of how this could be used, I have created a couple of input fields, and some logic to produce <$error>
widgets if there are any incorrect inputs. This acts as “validations” that also result in the button being disabled.
The limitation I want to overcome is that the <$safe.button>
widget needs to know the relative depth it’s being used inside the <$error.context>
widget in order to get the correct slot and check for the <$error>
widgets. I have simply hardcoded it as 2, but because of this, I have to use the <$safe.button>
as a direct child of the <$error.context>
and can’t make tiddlers containing the buttons etc. (or else would have to use $fillignore everywhere along the chain to the <$safe.button>
widget).
Even if I don’t make the tool public, I myself don’t want to have to deal with the $depth attribute. That’s why I wanted to be able to simply compute it.
I originally tried doing the wikification of the slot in the <$error.context>
widget itself, thus creating a variable that the <$safe.button>
widget can access. The issue with that is that any time the widget tree for the slot changes (such as if an error message appears or disappears), any contained <$edit-text>
widget will lose focus.
I am currently looking at making the <$safe.button>
widget send a custom message that contains enough information to simulate what would happen if all the same attributes were given to a <$button>
widget, and adding a <$messagecatcher>
to the <$error.context>
widget that catches the custom message. When it catches the actions, it would wikify the ts-raw
slot (into the widget tree) in order to check for <$error>
widgets, and if there aren’t any errors, it would run the actions that simulate what would’ve happened with a normal <$button>
widget (using the information in the custom message to do so).
I’m also considering avoiding slots altogether and using some kind of template in place of a custom <$error.context>
widget. That doesn’t seem as nice to use, though.
I don’t yet know how to format the json so that it can be dragged onto a TiddlyWiki to be imported
In the tiddler’s More Actions dropdown is an “export tiddler” option. You can choose “JSON file” from there:
For more than one, you can write a filter that includes exactly the tiddlers you want to export and put it in the Advanced Search
> Filter
box, and there will be an export button that will allow you to choose JSON.
(Note that when you do this, although the pre-import screen puts them in alphabetic order, the one that says “The following tiddlers were imported:” restores the order from the filter. This lets you put the most important ones [e.g. “My Overview”] first in the list…)
Thanks, @Scott_Sauyet
Oversimplified version (1).json (1.6 KB)
Fixed (also fixed the bug caused by changing temp tiddler titles in one place but not another)
Should probably also change to display: table-cell but that’s not too important here.
Is there a way to detect the transclusion depth within a tiddler?
It will likely require a real expert to answer for certain, but my guess is that this is not available in wikitext. You might look to the rendering code or, as mentioned earlier, to the qualify
widget to see if this could be added to the core. You could fiddle with updating it for your needs with an eye towards both solving it for your own use and creating code that could be contributed back to the core.
You could fiddle with updating it for your needs with an eye towards both solving it for your own use and creating code that could be contributed back to the core.
Maybe one day! (I would imagine that it could be kept track of in the widget tree)
I will look at your example tomorrow. best of luck