I’m further developing my mnemonic medium platform (that Grok TiddlyWiki is built on) and wanted to make an option where the person configuring the plugin could provide an arbitrary macro containing action widgets, to be triggered from somewhere within the plugin at an appropriate time. To edit settings like this, I have a custom control panel that provides text entry fields and documentation for a variety of settings:
The way this control panel works is there are a bunch of config tiddlers that have fields describing how they should show up in the control panel, and the text field of each is bound to the text entry field. Pretty standard. But the macro thing didn’t work the way I expected:
First I tried tagging the tiddler being edited with $:/tags/Macro. This caused the entire page to re-render and scroll up to the top every time the text was edited. This understandable, I guess, though I’m spoiled by the recent version that prevented loss of focus when editing fields of the current tiddler!
Then I tried removing the tag and \importing the tiddler into a different tiddler containing the sendFeedbackLink macro (where the user-defined macro is called). This caused all of the macros in that tiddler to fail to be defined.
In this case I was able to use an $importvariables widget within the calling macro instead:
\define sendFeedbackLink(tooltip:"Suggest an improvement to this question.", icon:"" text:"send feedback")
<$importvariables filter="[[$:/config/sobjornstad/TakeAway/AuthorProvided/FeedbackActions]]">
<$button class="tc-btn-invisible tc-tiddlylink" tooltip=<<__tooltip__>>>
<<sendFeedbackAction>>
$icon$ $text$
</$button>
</$importvariables>
\end
Is it intended that \import doesn’t work properly within a tiddler containing macros after the directive? If so, we should probably add this to the documentation and suggest a workaround.
(Also, I’m not sure \import would have worked anyway – anything imported by \import presumably goes out of scope at the end of the tiddler, so it probably wouldn’t be accessible at the time the macro is called by somebody outside of that tiddler. I don’t think TiddlyWiki macros offer “closures” like this, do they? Maybe this should be mentioned too.)
Sorry, I left out an important part. Calling <<macro1>> does work within test1, as you say, but it doesn’t do anything in any other tiddler, even though test1 is tagged $:/tags/Macro.
I never expected this to occur because import is typically used to import macros without making them global.
I tested the approach for you to take is to transclude rather than import. It does not work.
test3
# <<macro1>>
# <<macro2>>
only macro 1 works
Test4 tagged $:/tags/Macro
\define macro1() Test
{{test2}}
Perhaps the way I would say this is;
Import pragma or macro definitions by transclusion can not be nested
I also looked at the ImportVariablesWidget but it needs to wrap the area where it is valid and its existence in a tiddler tagged $:/tags/Macro is not globalised.
Some alternatives
You could edit the $:/core/ui/ViewTemplate/body/default tiddler to wrap the import variables around the text field.
Since macros are in effect variables perhaps you could make use of the new ## SetMultipleVariablesWidget in some way (un tested)
Your simple solution is to tag [[test2]] with $:/tags/Macro
In a way I think it reasonable to expect the import pragma to only operate in the scope of the current tiddler, given the global method is to tag the tiddler containing the macro definitions with $:/tags/Macro
Perhaps you could use import variables widget inside the view template but the macros will only be valid within the widget and thus only part of the view template.
alternatively using cascades make your own "conditional "ViewTemplate Body that wraps it with the import variables widget
[Edited] to state $:/core/ui/ViewTemplate/body/default not the edit one
But neither macro1 nor macro2 works for me when called in a different tiddler. I’m not particularly surprised that macro2 doesn’t work (I wasn’t expecting it not to at first, but that’s a perfectly logical design decision, and like I said in my original post, I found a way around it in my case, the <$importvariables> just needs to go inside the outer macro).
The problem is that the \import directive is preventing any macros in that tiddler from being available globally, even ones which have nothing whatsoever to do with the import and are fully defined without any of its contents. It seems like that isn’t happening for you though?
Interesting. Why do you say \import [[test2]] is “invalid” though? It works within this tiddler. Seems more like a bug (or an undocumented requirement).
I am pretty sure this is the case. Globally $:/tags/Macro tiddlers work because they are imported in to the page template using \import which creates an $importvariables widget.
The way that the $importvariables widget works is that it looks at the widget tree for the target tiddler and imports the first $set widget and any immediate children that are $set widgets. Macros are internally represented as set widgets so this works for importing macros.
However, when the macro tiddler starts with \import, the first thing that the importing $importvariables widget sees in the widget tree of the target tiddler,is an $importvariables widget (rather than a $set widget), and it therefore does not import anything from that tiddler.