modifying shadow tiddlers post-startup (ToolbarCommands)

18 views
Skip to first unread message

FND

unread,
May 31, 2010, 2:28:20 AM5/31/10
to TiddlyWikiDev
It appears that modifications of config.shadowTiddlers.ToolbarCommands
during runtime (after startup) are ignored by the toolbar macro or
template processing.

Example (execute from Firebug):
config.shadowTiddlers.ToolbarCommands.replace("editTiddler", "");
config.shadowTiddlers.ToolbarCommands.replace("saveTiddler", "");
Even after (re)opening tiddlers in view or edit mode, the edit/save
commands are still present in the toolbar.

I've spent some time tracing this, but couldn't quite figure out what's
going on. The toolbar macro is passed a slice reference from the
respective template ("[[ToolbarCommands::{View,Edit}Toolbar]]") - but
rather than doing its own getTiddlerText call for this parameter, its
handler is somehow invoked directly with the respective list of
commands, which appears to be cached on startup.

It seems like I'm missing something obvious, so a sanity check would be
appreciated.

background:
When I'm not utilizing TiddlyWeb for plugin development, I sometimes use
dynamic script loading to simplify the dev cycle:
http://fnd.lewcid.org/misc/PluginLoader.html
(uses http://github.com/FND/jsutil/blob/master/loadScript.js)
While this allows me to edit plugins' .js file and test changes with a
simple page reload (much like when using TiddlyWeb's devstore), scripts
are loaded asynchronously - which led to the observed effect.


-- F.

Eric Shulman

unread,
May 31, 2010, 4:46:06 AM5/31/10
to TiddlyWikiDev
> The toolbar macro is passed a slice reference from the
> respective template ("[[ToolbarCommands::{View,Edit}Toolbar]]") - but
> rather than doing its own getTiddlerText call for this parameter, its
> handler is somehow invoked directly with the respective list of
> commands, which appears to be cached on startup.
> It seems like I'm missing something obvious, so a sanity check would be
> appreciated.

The <<toolbar>> macro takes a list of toolbar handler names (e.g.,
"editTiddler", "saveTiddler"), *not* a slice reference. The reason
the [[ToolbarCommands::...]] slice reference works at all is because
it occurs within a *template*, and template content is retrieved
using:

Story.prototype.getTemplateForTiddler =
function(title,template,tiddler)
{
return store.getRecursiveTiddlerText(template,null,10);
};

which recursively fetches and *inserts* any content from embedded
"[[TiddlerName]]" references before passing the fully-expanded
template definition to the browser for initial rendering, followed by
a call to applyHTMLMacros() to process any TW macros that are stored
as attributes of the resulting DOM elements.

Thus, by the time the macro="toolbar ..." attribute is actually
handled, the slice reference has already been replaced by it's
respective value, and the macro only sees a list of toolbar commands,
not the original slice reference that defined the list.

HTH,
-e

FND

unread,
May 31, 2010, 12:45:10 PM5/31/10
to tiddly...@googlegroups.com
Thanks Eric!

> The <<toolbar>> macro takes a list of toolbar handler names (e.g.,
> "editTiddler", "saveTiddler"), *not* a slice reference. The reason
> the [[ToolbarCommands::...]] slice reference works at all is because
> it occurs within a *template*

I had arrived at the same conclusion - yet I haven't been able to figure
out why my shadow tiddler modifications* are not taken into account (I'd
tried all sorts of refresh calls and whatever else I could think of).

I'll let this settle for a bit and revisit it at a later time, hopefully
with a fresh mind.


-- F.


* I've just noticed my previous Firebug example was missing the actual
assignment - that's just an omission in the post; I correctly assigned
the new values in my test case.

Tobias Beer

unread,
Jun 1, 2010, 7:13:08 AM6/1/10
to TiddlyWikiDev
Hi FND,

A) Though it doesn't look like that in your provided
PluginLoader.html, could it be that whatever theme you use provides
for its own toolbar-sections, thus circumventing the general shadow
tiddler called ToolbarCommands?

B) On the other hand doesn't the core provide some theme-switiching
capability via story.switchTheme() so you could call a refresh on the
current theme? Or would that require a page reload everytime the theme
is being refreshed?

C) What's the purpose of loadShadowTiddlers and would that somehow
play a role in your refresh problems?

D) Finally, I hope I am not getting off-topic here, but how would...

jQuery().trigger("loadShadows");

...in function main() do anything? I can't find "loadShadows" being
attached anywhere.


Tobias.

Tobias Beer

unread,
Jun 1, 2010, 7:32:23 AM6/1/10
to TiddlyWikiDev
I just watched...

http://www.youtube.com/watch?v=WzHRHLd7tyk

...and something rather curious happens from 6:30 up until 7:10. Of
course that version of ToolbarCommands would no longer be a shadow
tiddler then. On the other hand, why would you want it to remain a
shadow tiddler if in fact you modified its source?

FND

unread,
Jun 1, 2010, 10:06:45 AM6/1/10
to tiddly...@googlegroups.com
> could it be that whatever theme you use provides
> for its own toolbar-sections, thus circumventing the general shadow
> tiddler called ToolbarCommands?

I'm afraid not - there's no theme involved.
The issue be reproduced in a vanilla TiddlyWiki by executing the
following lines after startup (e.g. from Firebug):
config.shadowTiddlers.ToolbarCommands =
config.shadowTiddlers.ToolbarCommands.
replace("+editTiddler", "").
replace("+saveTiddler", "");

When (re)opening a tiddler afterwards, I would expect the save/edit
commands to have disappeared - but that's not the case.

> B) On the other hand doesn't the core provide some theme-switiching
> capability via story.switchTheme() so you could call a refresh on the
> current theme?

I've tried that (along with various other refresh functions) - no joy.

> C) What's the purpose of loadShadowTiddlers and would that somehow
> play a role in your refresh problems?

loadShadowTiddlers only populates config.shadowTiddlers, doesn't it?

> D) Finally, I hope I am not getting off-topic here, but how would...
> jQuery().trigger("loadShadows");
> ...in function main() do anything? I can't find "loadShadows" being
> attached anywhere.

http://trac.tiddlywiki.org/ticket/1228

> I just watched...
> http://www.youtube.com/watch?v=WzHRHLd7tyk
> ...and something rather curious happens from 6:30 up until 7:10.

I'm not quite following - but I reckon the issue there is related to
TiddlyWeb permissions.

Eric Shulman

unread,
Jun 1, 2010, 2:12:05 PM6/1/10
to TiddlyWikiDev
> I had arrived at the same conclusion - yet I haven't been able to figure
> out why my shadow tiddler modifications* are not taken into account (I'd
> tried all sorts of refresh calls and whatever else I could think of).

I GOT IT!!!!

** slice values are cached **

When a *real* tiddler is modified, store.saveTiddler() actually
deletes/recreates the tiddler in the store, which performs:
delete this.slices[title];
so that subsequent attempts to retrieve a slice from that tiddler will
re-calculate the cached slice values.

Of course, modification of a shadow definition does not invoke
store.saveTiddler(), since the shadow is not saved in the store.

Thus, while the underlying shadow tiddler content has changed, any
cached slice values are not automatically updated.

Fortunately, you can force the slice values to be updated by invoking
the following line of code after modifying the shadow content:

store.slices["ToolbarCommands"]=
store.calcAllSlices("ToolbarCommands");

I tried this in a vanilla TW... and it works.

enjoy,
-e

FND

unread,
Jun 1, 2010, 2:42:09 PM6/1/10
to tiddly...@googlegroups.com
> I GOT IT!!!!
> ** slice values are cached **

That's excellent, Eric - thanks a lot!
This makes perfect sense now, of course, and I'm a bit annoyed with
myself for not having thought of it. Luckily, the TiddlyWiki community
can always count on Eric to go the extra mile...


-- F.

Eric Shulman

unread,
Jun 1, 2010, 7:29:31 PM6/1/10
to TiddlyWikiDev
addendum:

rather than re-calculating the slices, you could simply flush the
cached values by writing:
delete this.slices["ToolbarCommands"];

Then, the next call time the [[ToolbarCommands::ViewTemplate]]
reference is processed, store.getTiddlerText() will trigger a re-calc
of the slices from the shadow tiddler.

-e

Eric Shulman

unread,
Jun 1, 2010, 8:32:25 PM6/1/10
to TiddlyWikiDev

correction:
>    delete this.slices["ToolbarCommands"];
should be:
delete store.slices["ToolbarCommands"];

-e

Reply all
Reply to author
Forward
0 new messages