Core request: customizable DefaultTiddlers tiddler

7 views
Skip to first unread message

Saq Imtiaz

unread,
Jul 12, 2007, 10:06:06 AM7/12/07
to TiddlyWikiDev
Currently the name of the tiddler used to get the list of start up tiddlers is hardcoded into the restart() function. It is suggested to use a variable for this instead to allow plugins to easily change this for different configurations.

Ticket: http://trac.tiddlywiki.org/ticket/362
Patch: http://trac.tiddlywiki.org/attachment/ticket/362/Patch362.patch

Just one extra line of code. This would be very useful for my PresentationPlugin, amongst other things. Any chance we can get this into 2.2.5?

Many thanks,
Saq

--
TiddlyThemes.com ( http://tiddlythemes.com ) : a gallery of TiddlyWiki themes.
TiddlySnip ( http://tiddlysnip.com ) : a firefox extension that turns TiddlyWiki into a scrapbook!
LewcidTW ( http://tw.lewcid.org ) : a repository of extensions for TiddlyWiki

Martin Budden

unread,
Jul 13, 2007, 6:09:01 AM7/13/07
to Tiddly...@googlegroups.com
Saq,

I don't really understand the need for this. The name "DefaultTiddlers" is not obviously visible to the user, so why is there a need to customise it? I can see at least three problems in allowing the customisation:

1) a user who learns how to change the default tiddlers on one TiddlyWiki may find that it doesn't work on another TiddlyWiki

2) Extra questions from users along the lines of "I changed my DefaultTiddlers and nothing happened..."

3) One extra thing to check when debugging a TiddlyWiki.

Martin

Saq Imtiaz

unread,
Jul 13, 2007, 6:22:24 AM7/13/07
to Tiddly...@googlegroups.com
Martin,

Perhaps I did not explain the usage carefully enough. The idea is not to tweak the name DefaultTiddlers just for fun and call it MyStartupTiddlers, or to allow user customization. Rather the idea is to allow plugins to customize which tiddler is used to get the list of start up tiddlers.

So for example, you can have a plugin with different start modes based on paramifiers. Each mode has a different set of "start up tiddlers". Different starting states for instance. This change would allow such a feature to be offered in a clean and efficient manner.

On 7/13/07, Martin Budden <mjbu...@gmail.com> wrote:
Saq,

I don't really understand the need for this. The name "DefaultTiddlers" is not obviously visible to the user, so why is there a need to customise it? I can see at least three problems in allowing the customisation:

1) a user who learns how to change the default tiddlers on one TiddlyWiki may find that it doesn't work on another TiddlyWiki

Since the only time a user would experience this is when using a plugin that offers this feature, it wont exactly come as a surprise. It will be expected.

2) Extra questions from users along the lines of "I changed my DefaultTiddlers and nothing happened..."

See above. This is not an option meant for users to tweak. For example, look at config.tiddlerTemplates. Users could use that to customize the names of the ViewTemplate and EditTemplate but no one ever has. It has never been a problem.

3) One extra thing to check when debugging a TiddlyWiki.

Again,  it would be as simple as seeing if the CustomDefaultTiddlers  plugin is installed  for instance.

I appreciate your concerns  but I do believe  the benefits far outweight them. :)
Cheers,
Saq

Martin


On 7/12/07, Saq Imtiaz <lew...@gmail.com > wrote:
Currently the name of the tiddler used to get the list of start up tiddlers is hardcoded into the restart() function. It is suggested to use a variable for this instead to allow plugins to easily change this for different configurations.

Ticket: http://trac.tiddlywiki.org/ticket/362
Patch: http://trac.tiddlywiki.org/attachment/ticket/362/Patch362.patch

Just one extra line of code. This would be very useful for my PresentationPlugin, amongst other things. Any chance we can get this into 2.2.5?

Many thanks,
Saq

--
TiddlyThemes.com ( http://tiddlythemes.com ) : a gallery of TiddlyWiki themes.
TiddlySnip ( http://tiddlysnip.com ) : a firefox extension that turns TiddlyWiki into a scrapbook!
LewcidTW ( http://tw.lewcid.org ) : a repository of extensions for TiddlyWiki




FND

unread,
Jul 13, 2007, 6:28:25 AM7/13/07
to Tiddly...@googlegroups.com
> I appreciate your concerns but I do believe the benefits far
> outweight them. :)

Not that I should have a vote in this, but I'm with Saq on this one.
(I'm generally against hardcoding these kinda things anyway... )


-- F.

Saq Imtiaz

unread,
Jul 13, 2007, 6:35:15 AM7/13/07
to Tiddly...@googlegroups.com
It's worth noting that all of the following are customizable to a similar degree and could potentially be more problematic if one worried about end user customization:

config.notifyTiddlers = [

{name: "StyleSheetLayout", notify: refreshStyles},
{name: "StyleSheetColors", notify: refreshStyles},
{name: "StyleSheet", notify: refreshStyles},
{name: "StyleSheetPrint", notify: refreshStyles},
{name: "PageTemplate", notify: refreshPageTemplate},
{name: "SiteTitle", notify: refreshPageTitle},
{name: "SiteSubtitle", notify: refreshPageTitle},
{name: "ColorPalette", notify: refreshColorPalette},
{name: null, notify: refreshDisplay}
];

// Default tiddler templates
var DEFAULT_VIEW_TEMPLATE = 1;
var DEFAULT_EDIT_TEMPLATE = 2;
config.tiddlerTemplates = {
1: "ViewTemplate",
2: "EditTemplate"
};
Uninformed changes to the above could lead to a TiddlyWiki not even starting up as opposed to just starting up with the wrong set of tiddlers but it has never been a problem. :)

DefaultTiddlers seems to be the only one that is hardcoded into a function call.

Cheers,
Saq

Martin Budden

unread,
Jul 13, 2007, 7:14:18 AM7/13/07
to Tiddly...@googlegroups.com
Ah, I understand what you are trying to do now. I was worried by the confusion that could be caused, as you said, by users changing to, say, "MyStartupTiddlers". But what you want is, for example, the ability to have:

DefaultTiddlers1
DefaultTiddlers2
DefaultTiddlers3
DefaultTiddlers4

and having the ability to change which is called at startup. This makes sense.

Martin

Saq Imtiaz

unread,
Jul 13, 2007, 7:38:30 AM7/13/07
to Tiddly...@googlegroups.com
On 7/13/07, Martin Budden <mjbu...@gmail.com > wrote:
Ah, I understand what you are trying to do now. I was worried by the confusion that could be caused, as you said, by users changing to, say, "MyStartupTiddlers". But what you want is, for example, the ability to have:

DefaultTiddlers1
DefaultTiddlers2
DefaultTiddlers3
DefaultTiddlers4

and having the ability to change which is called at startup. This makes sense.

Yup, thats it.  My apologies for not explaining better the first time around!
Cheers,
Saq

Udo Borkowski

unread,
Jul 14, 2007, 5:05:17 AM7/14/07
to Tiddly...@googlegroups.com
Rather the idea is to allow plugins to customize which tiddler is used to get the list of start up tiddlers.

So for example, you can have a plugin with different start modes based on paramifiers. Each mode has a different set of "start up tiddlers". Different starting states for instance. This change would allow such a feature to be offered in a clean and efficient manner.


Just two ideas:

Instead of extending the core, what about using the shadow tiddlers mechanism? I.e. don't define an "DefaultTiddlers" tiddler in your TiddlyWiki but a shadowTiddler like this:

config.shadowTiddlers["DefaultTiddlers"] = "MyFavoriteTiddler1 MyFavoriteTiddler2 MyFavoriteTiddler3".

Plugins could then easily modify the list of default tiddlers, like appending things to the list, replacing it etc.

Of cause this only works when there is no "real" DefaultTiddlers tiddler.



Alternatively a plugin that wants to change the set of tiddlers to be opened initially may hijack TiddlyWiki.prototype.getTiddlerText and return the modified list for the DefaultTiddlers tiddler:

(function(){
var old_func = TiddlyWiki.prototype.getTiddlerText;

TiddlyWiki.prototype.getTiddlerText = function(title,defaultText) {
    if (title == "DefaultTiddlers")
        return "PluginStartupTiddler1 PluginStartupTiddler2";
    return old_func.apply(this,arguments);

})();

// not tested


These are two possible approaches if one does not want to change the core.


If we want to change the core I rather prefer to introduce a new function "getDefaultTiddlers()" but not make the tiddler name changable. I.e.

function getDefaultTiddlers()
{
    return store ? store.getTiddlerText("DefaultTiddlers") : "";
}

// Restarting
function restart()
{
    invokeParamifier(params,"onstart");
    if(story.isEmpty()) {
        var defaultParams = getDefaultTiddlers().parseParams("open",null,false);
        invokeParamifier(defaultParams,"onstart");
    }
    window.scrollTo(0,0);
}

This gives us more options to defined the initial set of tiddlers to display. E.g. a plugin does not need to introduce a special tiddler for each "configuration" but could make "getDefaultTiddlers" just return the approriate list of tiddler titles.


Udo

----------
Udo Borkowski
http://www.abego-software.de



On 7/13/07, Saq Imtiaz < lew...@gmail.com> wrote:

Saq Imtiaz

unread,
Jul 14, 2007, 5:19:05 AM7/14/07
to Tiddly...@googlegroups.com
Hi Udo

On 7/14/07, Udo Borkowski <udo.bo...@googlemail.com> wrote:
Rather the idea is to allow plugins to customize which tiddler is used to get the list of start up tiddlers.

So for example, you can have a plugin with different start modes based on paramifiers. Each mode has a different set of "start up tiddlers". Different starting states for instance. This change would allow such a feature to be offered in a clean and efficient manner.


Just two ideas:

Instead of extending the core, what about using the shadow tiddlers mechanism? I.e. don't define an "DefaultTiddlers" tiddler in your TiddlyWiki but a shadowTiddler like this:

config.shadowTiddlers["DefaultTiddlers"] = "MyFavoriteTiddler1 MyFavoriteTiddler2 MyFavoriteTiddler3".

Plugins could then easily modify the list of default tiddlers, like appending things to the list, replacing it etc.

Of cause this only works when there is no "real" DefaultTiddlers tiddler.

The problem with this approach is that its not as easy for the end plugin user to then create a set of DefaultTiddler tiddlers to choose between. Not to mention that this solution probably would lead to end user confusion when a DefaultTiddlers tiddler did exist.
 

Alternatively a plugin that wants to change the set of tiddlers to be opened initially may hijack TiddlyWiki.prototype.getTiddlerText and return the modified list for the DefaultTiddlers tiddler:

(function(){
var old_func = TiddlyWiki.prototype.getTiddlerText;

TiddlyWiki.prototype.getTiddlerText = function(title,defaultText) {
    if (title == "DefaultTiddlers")
        return "PluginStartupTiddler1 PluginStartupTiddler2";
    return old_func.apply(this,arguments);

})();

// not tested

This is what  I am doing right now with a slight tweak so that this only works in startup:

TiddlyWiki.prototype.publisherGetTiddlerText = TiddlyWiki.prototype.getTiddlerText;
TiddlyWiki.prototype.getTiddlerText = function(title,defaultText){
    if (title == 'DefaultTiddlers' && startingUp){
        title = store.isTiddler(config.macros.publisher.startMode + title) ? config.macros.publisher.startMode + title: title;
    }
    return store.publisherGetTiddlerText(title,defaultText);
};

It does work but the desire was to avoid the need for such a hijack. Every other 'special tiddler' in TiddlyWiki is so easily customizable so it makes sense that this should be too.


These are two possible approaches if one does not want to change the core.

Is there any reason we should  not change the core? It seems like this is more of an oversight than intentional. Making this customizable would make it consistent with how other special tiddlers are treated.

If we want to change the core I rather prefer to introduce a new function "getDefaultTiddlers()" but not make the tiddler name changable. I.e.

function getDefaultTiddlers()
{
    return store ? store.getTiddlerText("DefaultTiddlers") : "";
}

// Restarting
function restart()
{
    invokeParamifier(params,"onstart");
    if(story.isEmpty()) {
        var defaultParams = getDefaultTiddlers().parseParams("open",null,false);
        invokeParamifier(defaultParams,"onstart");
    }
    window.scrollTo(0,0);
}

This gives us more options to defined the initial set of tiddlers to display. E.g. a plugin does not need to introduce a special tiddler for each "configuration" but could make "getDefaultTiddlers" just return the approriate list of tiddler titles.

I have nothing against this approach. My suggested patch was aimed at achieving the desired functionality with minimal changes to the core. I  can definitely already think of current plugins that would benefit from this.

Jeremy, what do you think?

Cheers,
Saq

Udo Borkowski

unread,
Jul 14, 2007, 5:36:17 AM7/14/07
to Tiddly...@googlegroups.com
I don't want to argue on whether we should extend the core or not but leave this decision to Jeremy.


I just got one question:


Every other 'special tiddler' in TiddlyWiki is so easily customizable so it makes sense that this should be too.

Can you explain a little bit what you mean by this? I think the other "special tiddlers" (like "PageTemplate", "StyleSheetLayout" etc.) are hardcoded the same way as "DefaultTiddlers" and not really much easier to customize than the DefaultTiddlers. Actually I think it is even  harder to customize these other "special tiddlers". E.g. if you look at Eric's SelectStylesheetPlugin that is intended to "customize" some special tiddlers: it takes quite some code to achieve this.

Of cause a user may change the content of the "StyleSheet" tiddler but this is not the kind of "customization" you are thinking of, I guess, because this is also the case for the "DefaultTiddlers".



Udo

----------
Udo Borkowski
http://www.abego-software.de








Saq Imtiaz

unread,
Jul 14, 2007, 5:46:56 AM7/14/07
to Tiddly...@googlegroups.com
On 7/14/07, Udo Borkowski <udo.bo...@googlemail.com> wrote:
I don't want to argue on whether we should extend the core or not but leave this decision to Jeremy.

Agreed, that was always the intent :)

I just got one question:

Every other 'special tiddler' in TiddlyWiki is so easily customizable so it makes sense that this should be too.

Can you explain a little bit what you mean by this? I think the other "special tiddlers" (like "PageTemplate", "StyleSheetLayout" etc.) are hardcoded the same way as "DefaultTiddlers" and not really much easier to customize than the DefaultTiddlers. Actually I think it is even  harder to customize these other "special tiddlers". E.g. if you look at Eric's SelectStylesheetPlugin that is intended to "customize" some special tiddlers: it takes quite some code to achieve this.

Yes you are correct that it takes some code to change say PageTemplate to AdminPageTemplate. But it can be done without hijacking or replacing any core functions. All you need to do is remove the old notification and a new one.

The removeNotificaton function in SelectThemePlugin shows how easy this can be.

Even easier and what I was really thinking of is the tiddlerTemplates:

config.tiddlerTemplates = {
1: "ViewTemplate",
2: "EditTemplate"
};

Changing ViewTemplate to AdminViewTemplate is as easy as:

config.tiddlerTemplates["1"] = "AdminViewTemplate";

What I am really driving at is that all such settings and special tiddlers should at least provide 'hooks' for plugins to allow easy customization. It does not necessarily have to be as easy as the above example. TiddlyWiki is so extremely versatile and easy to modify.... I guess I am just a at a loss as to why this is the one exception to the rule. Is it just plai n and simple inertia? Anyway...... I'm sure Jeremy will have a good reason if he decides not to make this change.

Cheers,
Saq

Udo Borkowski

unread,
Jul 14, 2007, 6:19:25 AM7/14/07
to Tiddly...@googlegroups.com
I guess we are getting a little bit OT, but ... ;-)


Yes you are correct that it takes some code to change say PageTemplate to AdminPageTemplate. But it can be done without hijacking or replacing any core functions. All you need to do is remove the old notification and a new one.

Is it really sufficient to remove the old notification and add a new one? What about the hard coded reference to "PartTemplate" in refreshPageTemplate(title)?


Udo

----------
Udo Borkowski
http://www.abego-software.de



On 7/14/07, Saq Imtiaz <lew...@gmail.com> wrote:

Saq Imtiaz

unread,
Jul 14, 2007, 6:27:09 AM7/14/07
to Tiddly...@googlegroups.com
On 7/14/07, Udo Borkowski <udo.bo...@googlemail.com> wrote:
I guess we are getting a little bit OT, but ... ;-)

Yes you are correct that it takes some code to change say PageTemplate to AdminPageTemplate. But it can be done without hijacking or replacing any core functions. All you need to do is remove the old notification and a new one.

Is it really sufficient to remove the old notification and add a new one? What about the hard coded reference to "PartTemplate" in refreshPageTemplate(title)?

It is actually. That is a fallback.....

if(!title)
title = "PageTemplate";
 
:)
Cheers,
Saq

Udo

----------
Udo Borkowski
http://www.abego-software.de



On 7/14/07, Saq Imtiaz < lew...@gmail.com> wrote:


On 7/14/07, Udo Borkowski < udo.bo...@googlemail.com> wrote:
I don't want to argue on whether we should extend the core or not but leave this decision to Jeremy.

Agreed, that was always the intent :)

I just got one question:

Every other 'special tiddler' in TiddlyWiki is so easily customizable so it makes sense that this should be too.

Can you explain a little bit what you mean by this? I think the other "special tiddlers" (like "PageTemplate", "StyleSheetLayout" etc.) are hardcoded the same way as "DefaultTiddlers" and not really much easier to customize than the DefaultTiddlers. Actually I think it is even  harder to customize these other "special tiddlers". E.g. if you look at Eric's SelectStylesheetPlugin that is intended to "customize" some special tiddlers: it takes quite some code to achieve this.

Yes you are correct that it takes some code to change say PageTemplate to AdminPageTemplate. But it can be done without hijacking or replacing any core functions. All you need to do is remove the old notification and a new one.

The removeNotificaton function in SelectThemePlugin shows how easy this can be.

Even easier and what I was really thinking of is the tiddlerTemplates:
config.tiddlerTemplates = {
1: "ViewTemplate",

2: "EditTemplate"
};

Changing ViewTemplate to AdminViewTemplate is as easy as:

config.tiddlerTemplates["1"] = "AdminViewTemplate";

What I am really driving at is that all such settings and special tiddlers should at least provide 'hooks' for plugins to allow easy customization. It does not necessarily have to be as easy as the above example. TiddlyWiki is so extremely versatile and easy to modify.... I guess I am just a at a loss as to why this is the one exception to the rule. Is it just plai n and simple inertia? Anyway...... I'm sure Jeremy will have a good reason if he decides not to make this change.


Cheers,
Saq





Udo Borkowski

unread,
Jul 14, 2007, 7:00:37 AM7/14/07
to Tiddly...@googlegroups.com
That is a fallback.....

but this "fallback" is used "all the time" !

The only place in the core code that calls refreshPageTemplate is refreshAll() and this calls refreshPageTemplate() (i.e. no title defined).

function refreshAll()
{
    refreshPageTemplate();
    refreshDisplay();
...
}


So refreshPageTemplate always uses the "PageTemplate" tiddler, at least from what I read in the code. This makes me wonder why the SelectThemePlugin is able to customize the PageTemplate ...


Udo

Saq Imtiaz

unread,
Jul 14, 2007, 7:12:58 AM7/14/07
to Tiddly...@googlegroups.com
Actually Udo, we are both correct.

The refreshAll function is very rarely used. Apart from the refreshDisplay macro (Why do we have that?) the only time it is called is when refreshColorPalette is called. Which exposes a scenario in which SelectTheme could fail... but it was written before ColorPalette was introduced.

The other usage of refreshPageTemplate is in the notifications. I would go as far as to say that this is the main usage. When it is called by store.notify, it is passed the title from the notifications. This is the mechanism used to update the PageTemplate on each edit... and the mechanism SelectTheme uses to switch the PageTemplate. Replace the notification and notify!

This actually begs the questions: Why does refreshAll call the individual functions for refreshing the different stylesheets with hardcoded values? It would be far better to do a store.notifyAll(); call. Less code, more versatile. It cant be a safety feature since its only used right now by the rather unused refreshDisplay macro and for ColorPalette notifications.

Cheers,
Saq

Jeremy Ruston

unread,
Jul 14, 2007, 8:17:13 AM7/14/07
to Tiddly...@googlegroups.com
I've been bothered right from the beginning that the "defaultTiddlers"
title is hardcoded in the way that it is. But the way that I had
wanted to fix it was to change the PageTemplate so that it referenced
the defaultTiddlers tiddler directly like this:

<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay' macro='story defaultTiddlers'></div>
</div>

As it happens, it would make it possible to embed multiple <<story>>
macros in the page template.

So, under that approach, Saq's presentation macro would be a
replacement for the <<story>> macro - either overriding and extending
the built-in macro, or he could provide a differently named macro and
have people modify their PageTemplate (conceivably applying the new
macro automatically if it detects that the shadow PageTemplate hasn't
been overridden).

What do you think?

Cheers

Jeremy


--
Jeremy Ruston
mailto:jer...@osmosoft.com
http://www.tiddlywiki.com

Paco Rivière

unread,
Jul 15, 2007, 7:39:14 AM7/15/07
to TiddlyWikiDev
This would also benefit the localization, making it more 'world-
friendly'

On deciding whatever solution, pls. remember 'there is also life out
of your only lingo'

On Jul 14, 11:46 am, "Saq Imtiaz" <lew...@gmail.com> wrote:

Udo Borkowski

unread,
Jul 16, 2007, 7:01:53 AM7/16/07
to Tiddly...@googlegroups.com
I've been bothered right from the beginning that the "defaultTiddlers"
title is hardcoded in the way that it is. But the way that I had
wanted to fix it was to change the PageTemplate so that it referenced
the defaultTiddlers tiddler directly like this:

<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay' macro='story defaultTiddlers'></div>
</div>

I am not sure if this is going to the right direction. Introducing a new "story" macro would have a lot of consequences for other code. Currently we always have ONE story in the TiddlyWiki and code can refer to this through the window.story variable. With a story macro it may be possible to have more than one. (Or am I misunderstanding/"misguessing" the semantic of the story macro?)

Also there is no longer a way to get the list of "tiddlers initially displayed in the TiddlyWiki". E.g. I have a macro/command that closes all tiddlers and just displays the ones from the "DefaultTiddlers". I don't know how I could achieve this using the modified PageTemplate approach (without "re-rendering" the whole HTML page).

To me the simplest way to cover Saq's request is to hide the access to the "DefaultTiddlers" tiddler inside a function (e.g. getDefaultTiddlers()). Whenever code needs the defaultTiddlers they can call this function. Plugins (or localizators) may hijack/overwrite this function for customization. The getDefaultTiddlers function would be as simple as this:

function getDefaultTiddlers()
{
    return store ? store.getTiddlerText("DefaultTiddlers") : "";
}



Martin Budden

unread,
Jul 16, 2007, 9:22:33 AM7/16/07
to Tiddly...@googlegroups.com
I agree with Udo on his point about introducing a new "story" macro. This will have consequences for other code, and will make things more complicated and less understandable for plugin-developers.

However, I disagree with the idea of having a new "getDefaultTiddlers" function. Instead, "defaultTiddlers" should be a property (member variable) of story. Then restart becomes:

function restart()
{
    invokeParamifier(params,"onstart");
    if(story.isEmpty()) {
        var defaultParams = store.getTiddlerText(story.defaultTiddlers).parseParams("open",null,false);
        invokeParamifier(defaultParams,"onstart");
    }
    window.scrollTo(0,0);
}

The initial value of story.defaultTiddlers could be specified in PageTemplate:

<div id='tiddlerDisplay' tiddler='DefaultTiddlers'></div>

cf MainMenu:

<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>

Martin

Udo Borkowski

unread,
Jul 16, 2007, 12:19:50 PM7/16/07
to Tiddly...@googlegroups.com
However, I disagree with the idea of having a new "getDefaultTiddlers" function. Instead, "defaultTiddlers" should be a property (member variable) of story. Then restart becomes:

Associating the defaultTiddlers with the story object seems to be a good idea.

However I don't like the idea we introduce another member variable the code must directly access.

What about an extra Story function to access this member

Story.prototype.getDefaultTiddlers() = function() {
    return this.defaultTiddlers;
}

and some code to initialize that member (like in Martin's proposal).

The restart becomes:

function restart()
{
    invokeParamifier(params,"onstart");
    if(story.isEmpty()) {
        var defaultParams = store.getTiddlerText (story.getDefaultTiddlers()).parseParams("open",null,false);

        invokeParamifier(defaultParams,"onstart");
    }
    window.scrollTo (0,0);
}
 

Not to access the "defaultTiddlers" member directly but through an accessor function seems to be "good practice" etc...


Udo

----------
Udo Borkowski
http://www.abego-software.de



Reply all
Reply to author
Forward
0 new messages