create new tag
, view all tags
Note: This topic has been refactored by ThomasWeigert in that discussions related to defects in search paths have been moved to TemplatePathBuginTWiki4x00. This discussion pertains primarily to making the search path configurable.

The template path description is odd

The skin path as described in TWikiTemplates seems a bit counterintuitive in that it puts .tmpl files in front of those in topics.

Note: The original topic had a rendition of the template path omitting some portion assumed (incorrectly, I believe) to be deprecated. Please see that by looking at rev38. The quote below shows what actually is in the system.

The quote below illustrates the template path in TWiki 4.0:

  1. If template name ends in .tmpl, templates/script (note that the template name may include skin information).
  2. templates/web/script.skin.tmpl for each skin on the skin path
  3. templates/script.skin.tmpl for each skin on the skin path
  4. templates/web/script.tmpl
  5. templates/script.tmpl
  6. Attempt to parse the template name into webName.topicName
  7. If the parse attempt was successful, do not capitalize the name of the script or web, and only for this step set web = webName and script = topicName
    1. The TWiki topic web.script
  8. The TWiki topic web.skinSkinscriptTemplate for each skin on the skin path
  9. The TWiki topic %TWIKIWEB%.skinSkinscriptTemplate for each skin on the skin path
  10. The TWiki topic web.scriptTemplate
  11. The TWiki topic %TWIKIWEB%.script%

In above, please read

  • script refers to the script name, e.g view, edit
  • skin refers to a skin name, e.g dragon, pattern. All skins are checked at each stage, in the order they appear in the skin path.
  • Note that when a template is taken from topic, the first character of the script and skin names are capitalized.
  • web refers to the current web

Let's assume I want to override viewtopicactionbuttons.pattern.tmpl using an overriding skin named csa. Currently, the viewtopicactionbuttons template file will be searched for in the following places, when the current web is Thisweb and the skin path is csa,pattern:

  1. templates/viewtopicactionbuttons.csa.tmpl
  2. templates/viewtopicactionbuttons.pattern.tmpl
  3. templates/viewtopicactionbuttons.tmpl
  4. Thisweb.CsaSkinViewtopicactionsTemplate
  5. Thisweb.PatternSkinViewtopicactionsTemplate
  6. Thisweb.ViewtopicactionsTemplate
  7. TWiki06x00.CsaSkinViewtopicactionsTemplate
  8. TWiki06x00.PatternSkinViewtopicactionsTemplate
  9. TWiki06x00.Viewtopicactionbuttons Template

This is broken for at least three reasons:

  • The only way to override a standard skin template is to put a file in the templates directory, which requires shell access.
  • There is no way to override a standard skin template on a web-by-web basis.
  • The TWiki web shouldn't be altered in this way, because it's supposed to be considered to be read-only.

Therefore, the search path ought to be:

  1. The TWiki topic web.SkinSkinScriptTemplate for each skin on the skin path
  2. The TWiki topic web.ScriptTemplate
  3. The TWiki topic Main.SkinSkinScriptTemplate for each skin on the skin path
  4. The TWiki topic Main.ScriptTemplate
  5. templates/script.skin.tmpl for each skin on the skin path
  6. templates/script.tmpl

-- Contributors: MeredithLesly


You're right. It's countrintuitive. The path was keep for backward compatibility.

Hmm... Pluggable Template Search Mechanism?

-- RafaelAlvarez - 21 Mar 2006

It was my understanding that there was no skin path in Cairo, so I assume you mean for compatibility during the development of Dakar?

-- MeredithLesly - 21 Mar 2006

Actually, Cairo has a path (see TWiki::Store::_readTemplateFile). From the doc:

Reads a template, constructing a candidate name for the template thus: 
$name.$skin.tmpl, and looking for a file of that name first in templates/$web and
then if that fails in templates/. If a template is not found, tries to parse $name 
into a web name and a topic name, and read topic $Web.${Skin}Skin${Topic}Template. 
If $name does not contain a web specifier, $Web defaults to TWiki::twikiWebname. 
If no skin is specified, topic is ${Topic}Template. If the topic exists, checks access
permissions and reads the topic without meta-data. In the event that the read fails 
(template not found, access permissions fail) returns the empty string "". skin, web 
and topic names are forced to an upper-case first character when composing user topic

As we didn't know what would break if we change the search order, we keep it as is.

-- RafaelAlvarez - 21 Mar 2006

I'd be on for injecting a SiteTemplatesDir into the search order, so that the administrator could specify templates that override any supplied with TWiki.

Can someone confirm whether this is a good idea and whether it is necessary?

-- MartinCleaver - 21 Jun 2006

There are two questions here: "can I do this now" and "what should we do".

IMHO the first of these is answered "no". It's already too complicated.

The second of these I believe should be fixed by the introduction of a template search variable, like @INC. This would default like the current search path but could be overridden for custom search paths.

-- CrawfordCurrie - 21 Jun 2006

Since the path is a bit insane, it would probably be better if, instead of default to the current search path, there would be a switch for "Cairo-compatible", where a more reasonable path would be created automatically for those who don't care about Cairo-compatibility.

-- MeredithLesly - 22 Jun 2006

Ok. So how about we first agree how we'd want to specify the path. Here's how it might look right now, for DakarRelease:


This could become a $TWiki:cfg{TemplatePath}, TWiki being told to make substitutions for ${Template} (capitalised) or ${template} (not).

Abstracting it into a setting would allow me to add, e.g.

pub being my prefered place for css, jpgs, & related tmpl files.

Going forward we might want to consider how we specify $pub/$web/ - this assumes a certain directory layout. Should we worry about that now or agree on a naming scheme such as $web{pub}/ or the suchlike?

This would make a great little project for someone with a bit of time wanting to learn to hack TWiki: useful for a student to put on a resume, etc.

-- MartinCleaver - 06 Jul 2006

Sample implementation, awaiting feedback.

Advantage over the previous algorithm: 1 flexible path 2 it doesn't scan beyond the point needed

Do people think this is useful? I'd prefer feedback to get alignment and buy-in before proceeding.

-- MartinCleaver - 07 Jul 2006

The array

    my @templatePath = qw ($TWiki::cfg{TemplatesDir}/$web/$template.$skin.tmpl

would in a real implementation come from TWiki:cfg{TemplatePath}

TWiki currently lacks the ContentAccessSyntax to specify an attachment to a web, topic, necessitating...


... intended to designate that a template is in pub/Main/MyTheme/$template.tmpl

Until approach is ratified...

If you want to put templates in pub (a la MoreWebBasedTWikiManagement), having an override lib and modifying your copy of Templates.pm as below will work in the short-term, and keep your code changes separate to those in the distribution.

$ diff site-lib/TWiki/Templates.pm lib/TWiki/Templates.pm
<       foreach my $tmplDir ("$TWiki::cfg{SiteTemplateDir}",
<                          "$TWiki::cfg{TemplateDir}/$web",
>        foreach my $tmplDir ( "$TWiki::cfg{TemplateDir}/$web",

And in LocalSite.cfg: $TWiki::cfg{SiteTemplateDir} = '/home/user/public_html/twiki/pub/Main/MyTheme';

-- MartinCleaver - 08 Jul 2006

Don't forget that AttachContentPlugin (the plugin formerly known as CacheContentPlugin) lets you specify content in the topic and have the resulting expanded text wind up in an attachment. This is how I do my custom CSS, for example, as it allows me a) to avoid editing files in the shell and b) lets me use variables without penalty.

-- MeredithLesly - 08 Jul 2006

Good point. I should use that, thanks.

-- MartinCleaver - 08 Jul 2006

>           $name =~ m!(.*)/.*?!;
>           $this->{VARS}->{"templateDir"} = $1;
>           $this->{VARS}->{"templateName"} = $name;
>           if ($this->{VARS}->{"templateDir"} eq $TWiki::cfg{'SiteTemplateDir'}) {
>               $this->{VARS}->{"templateDirURL"} = $TWiki::cfg{'SiteTemplateURL'};
>             } else {
>               $this->{VARS}->{"templateDirURL"} = 'inaccessible';
>             }

Allows $TWiki::cfg{SiteTemplateDirURL} to be exposed as TMPL:P{templateDirURL}, so you can keep files of a theme together.

-- MartinCleaver - 12 Jul 2006

Obviously the template path has to be exposed somehow. What did you have in mind? configure? Or preferences? Personally I think configure is the only sensible way to go.

I'm a little bit nervous of the support implications of someone configuring their path, and then having their twiki come down around their ears. The default path needs more than careful thought; it needs careful documenation, too, so that the impact of changing the path is clear.

Are you proposing this for 4.1? If so, you need to add a link in WhatIsIn04x01

-- CrawfordCurrie - 14 Jul 2006

Yes, in configure

-- MartinCleaver - 23 Jul 2006

I do not sense an agreement on this topic.

Both the basic feature and the spec if implemented are being discussed with no conclusion. So not yet ready for 4.1.

Discussion needs to continue becore ready for release meeting decision.

-- KennethLavrsen - 27 Sep 2006

I see that there are several positions:

  • Make the template search path configurable and store in a config variable, such as $TWiki::cfg{SiteTemplateDir}
  • Change the template search algorithm to prefer user editable directories over the system directory
  • Get rid of most of the complexity and rely more on cover, skin, and topic-specific template settings.
  • Leave as is

We should first converge on the style of solution, then work out the details. See also the discussion in TWikiTemplates (I cannot believe somebody would have said there that things are being deprecated without having a decision here) and Bugs:Item2907.

-- ThomasWeigert - 01 Oct 2006

The base config of TWiki has 146 files in the templates directory. With all plugins linked it that exceeds 400. For newcomers this is simply insane, and for old-timers its not much better.

I had a graphic designer complain bitterly about this set up. Having a SiteTemplateDir made our lives a lot more sane.

-- MartinCleaver - 02 Oct 2006

Martin, I don't understand which option you are arguing for. How does having a SiteTemplateDir help dealing with the 146 files?

-- ThomasWeigert - 02 Oct 2006

If a conclusion is reached, please feel free to re-open http://develop.twiki.org/~twiki4/cgi-bin/view/Bugs/Item2907

Looking at this from a customer perspective, there are fourrequirements

  1. Be able to select skins
  2. Be able to override certain templates on a per user, per web or per topic basis, without changing the whole skin
  3. Define templates into topics to make them definable/supportable by end users
  4. Keep it simple
I felt constrained to maintain the existing search path when extending TWiki to support 1, 2, and 3, at the cost of 4. i agree with Martin that there are too many templates, but mucking with the search path is not the way to reduce that number. Merging templates that have common functionality, in the way I did when I merged all the oops templates into messages.tmpl, is the right approach. That there are still 146 template files just indicates that no-one else has pitched in to help simplify them.

Templates are sort of like modules in a programming language. Think about them in object-oriented terms. We want to be able to define a base set of functionality, and then subclass that functionality. We want to be able to select which particular subclasses we use in any given context. If we do this properly, there could be one template file for "standard twiki" and one template file for each additional skin.

-- CrawfordCurrie - 02 Oct 2006

But really, if we use your analogy from your last paragraph, it does not matter then whether you have 50 files or 1 file with 50 subclasses. That is just a matter of preference of organizing the code. The complexity is in how the subclasses interact to generate the whole thing.

Personally, I find the merged oops file very difficult to penetrate. It took a lot less work to understand how to create an oops before all the message magic set in... it is much more consistent now, though...

-- ThomasWeigert - 02 Oct 2006

> How does having a SiteTemplateDir help dealing with the 146 files?

Well, the designer says cover the xyz skin. And then puts all overriding files in on attachment directory. So they've created a subclass on a topic that is now portable, and does not have to care that the other 146 (or 400) files exist.

Everything the designer does is kept separate from the base 146 file template file install. All files that the designer cares about in one directory.

So to add to the four above: 5) Cater to the needs of designer as separate to site installer.

-- MartinCleaver - 02 Oct 2006

I see. You meant as an organizational principle, not as a way of reducing the number of files. The designer will still need to understand the files in templates/ unless she rewrites a skin from scratch. And even then she will need to understand that somethings are required in the template to work (e.g., forms rely on templates and some archane %REPEAT% there....

We should come to some conclusion as to whether we override templates by putting them into attachment directories, or by putting them into the data directory. Either is fine, but please, let's come up with a consistent scheme.

Let's not just add a number of additional locations.

I am ok with having to update my pages if we pick a currently unsupported location...

-- ThomasWeigert - 02 Oct 2006

I would hope that the implentation - whatever may get changed - first of all takes performance into consideration. Ie. not too much searching for possible template files.

Secondly. Templates is something which is near voodoo now. Keep it simple.

Third. Try not to make upgrading a pain. There are 1000s of TWiki installations out there and 4.1 should not be yet another upgrade pain.

-- KennethLavrsen - 02 Oct 2006

Well, by spec there are a bunch of variations to be searched just in a single directory. So if you want additional directories, without removing existing ones, than there will be more to search.

I could see removing the search in templates/<web>/ in favor of a user accessible directory, such as in pub/<web>/ . I don't think many people are even aware of the subdirectory to templates trick. However, in that case we would have to search the newly made directory first, to allow web-specific overriding of the templates directory.

-- ThomasWeigert - 03 Oct 2006

> 3. Define templates into topics to make them definable/supportable by end users

I personally hope this doesn't mean that templates would only be editable as topics. Before falling in love with TWiki, we tried Krang as a base for rapid development and deployment of websites. In Krang I had to edit the templates via the gui. The restraints and added time involved in trying to edit templates via a textarea were maddening.

Providing some method for the use of a traditional text editor should be preserved.

-- CynthiaManuel - 11 Oct 2006

While a grand rework may be a good idea, its not the thrust of my proposition.

I satisfied my need by just incorporating the <20 lines code shown above under "Until approach is ratified"

-- MartinCleaver - 11 Oct 2006

I think "Until approach is ratified" proposal and the extra config option and the whole idea is so much of a hack that no normal soul will ever understand how it works. And once we add this in core it will be impossible to remove again because of compatibility.

-- KennethLavrsen - 16 Oct 2006

In what way is it a hack? Providing 1) web access to the templates 2) access to all theme related stuff in the same place 3) in a manner that is portable between sites & 4) stored in a way that doesn't add meta data 5) adding revision history to .tmpl files sounds like a rounded out improvement to me.

So, in leui of anything better I will continue to use the "hack". Its small and simple enough that I can put it in a parallel library ahead of the TWiki libs in the path.

-- MartinCleaver - 17 Oct 2006

Sorry Martin. I misread your statement. I read it as if you proposed the change to be checked into the core code on SVN. But for your own purpose while waiting for a final solution - that I have no negative comments about. On the contrary thanks for sharing the hack.

-- KennethLavrsen - 19 Oct 2006

Martin, can you please clearly identify what code you are talking about when you say "I satisfied my need by just incorporating the <20 lines code shown above under 'Until approach is ratified'" as this topic is nearly impossible to follow...

-- ThomasWeigert - 19 Oct 2006

I use the code under the patches labelled 297,298c297 and 394c396,403

-- MartinCleaver - 19 Oct 2006

We need to wrap up on this one.

The original proposal was from Meredith who is not driving this one.

Do we have an actual proposal?

Is anyone ready to drive it to implementation?

Otherwise this ends up in the big parking lot because there nothing we can vote for or against right now and no committed implementer.

-- KennethLavrsen - 23 Oct 2006

I am in favor of simplification of the path... there seems to be some speedup opportunity. But anything that is simpler will be not backwards compatible. I am willing to change my installation over, asssuming that the basic capabilities of overriding the default path per web are preserved. But we need to hear from others.

I think few people will really be affected by a change here so the sooner a backwards incompatible change is made the better, if one is to be made.

-- ThomasWeigert - 23 Oct 2006

"simplification of the path" is not something anyone can make a decision from.

We need an actual proposal so we can assess the impact and make a decision. The compatibility issue - if the proposal is not too dramatic - may not be such a big deal - if the proposal it put together wisely.

It seemed that there was a good proposal to make the path configurable. The issue was then choosing the right default and the syntax for it.

-- KennethLavrsen - 28 Oct 2006

Ok. Let me summarize the status, as I perceive it to be from your description:

  1. It is agreed to make a change to the search path for templates
  2. It is agreed to use the mechanism described above
  3. The precise path and syntax needs to be defined.
  4. The whole proposal needs to be concisely summarized and presented.

Please correct. If it is that simple, I can handle....

-- ThomasWeigert - 28 Oct 2006

That pretty well sums it up the way I see it.

-- KennethLavrsen - 28 Oct 2006

OK. I am done with the implementation. Here is my proposal (ready to patch):

  1. I have adopted the idea mentioned above of having a template path. This would be a variable in config, say $TWiki::cfg{TemplatePath}. The path would hold, by default, the current search path for the templates, i.e.,
    $TWiki::cfg{TemplatePath} = '$TWiki::cfg{TemplateDir}/$web/$name.$skin.tmpl,$TWiki::cfg{TemplateDir}/$name.$skin.tmpl,$TWiki::cfg{TemplateDir}/$web/$name.tmpl,$TWiki::cfg{TemplateDir}/$name.tmpl,$web.$skinSkin$nameTemplate,$TWiki::cfg{SystemWebName}.$skinSkin$nameTemplate,$web.$nameTemplate,$TWiki::cfg{SystemWebName}.$nameTemplate';
    As you can see, the path may contain variables $skin, $web, and $name which will be expanded to the skin name, web name, and template name, respectively. (Of course, it can contain also twiki variables, such as %PUBURL%, but whatever it is, it needs to be topic independent.)
  2. The function TWiki::Templates::_readTemplateFile is adjusted to take into account this template search path.
  3. So if you want to have a different path, say, put the current pub directory ahead of everything else, that is an easy change.

In the process of doing so, I fixed a bug in the current search algorithm which failed one test case in the unit tests (the test case was changed to give the wrong result, but that was documented) and it fixed a second test case which was wrong (but was not documented to be incorrect).

The performance is unaffected by this change when measured with ab.

Please advise whether you want this in the code base. I think the above suggestion is a good one.

Note that CC's concern still holds, people can screw up their TWiki installation by changing the template search path to something wrong....

-- ThomasWeigert - 10 Nov 2006

I do not have a great detailed insight on templates but from the high level view it seems like a good approach. And for sure I can screw up my TWiki installation even more with most other configure parameters.

-- KennethLavrsen - 10 Nov 2006

If I don't hear anything by tomorrow, I will put my changes into the code.

-- ThomasWeigert - 11 Nov 2006

Sounds good to me.

/me wonders how much of his code (above) was used.

-- MartinCleaver - 13 Nov 2006

I used your idea and the code outline. The details of your code did not really work, at least not on my installation.... Also, your algorithm examined way too many variants of names... I also changed the cfg variable syntax to be consistent with TWiki, and less perl-like...

Your idea was a very good one, and it allowed to streamline the template code also. If you put your site locations in front, it will pick that up first.

Note the following restrictions: files are either named *.tmpl, or they follow wiki name syntax, with a .txt extension.

-- ThomasWeigert - 13 Nov 2006

Glad it was useful. I'm not surprised the code wasn't functional as I didn't test it smile

Not sure what you mean by Also, your algorithm examined way too many variants of names - I think it offered the same variants as before... but I'll wait for 4.1 and see whether how it does.

Thanks for the implementation! big grin

-- MartinCleaver - 13 Nov 2006

Some more explanation:

1. The template path is set up as a config parameter TemplatePath. The standard path would be (reformatted to be easier readable):

$TWiki::cfg{TemplatePath} = 
The separator I used is a comma, but we could change that (I think a comma is used elsewhere in configure).

2. The template code in TWiki::Templates::__readTemplateFile is changed to examine the template path instead of the algorithm to expand templates being hard-wired.

First split the template path

    my @skinList = split( /\,\s*/, $skins );
    my $nrskins = $#skinList;
    my @templatePath = split (/\s*,\s*/, $TWiki::cfg{TemplatePath});
    my @candidates;
If the name is of the form "web.name", separate it out.
    if( $name =~ /^(.+)\.(.+?)$/ ) {
       $web = $1;
       $name = $2;
Now, for every template on the path, look at all the skins applied
    $nrskins = 0 if $nrskins < 0;
    foreach my $template ( @templatePath ) {
      for ( my $idx=0; $idx<=$nrskins; $idx++ ) {
Expand the $skin, $web, $name variables.
     my $file = $template;
     my $userdir = 0;
     # also need to do %PUBURL% etc.?
     # push the first time even if not modified
     my $skin = $skinList[$idx] || '';
     my $webName = $web || '';
     my $tmplName = $name || '';
     unless ( $file =~ m/.tmpl$/ ) {
       # Could also use $Skin, $Web, $Name to indicate uppercase
       $userdir = 1;
       $skin = ucfirst($skin);
       $webName = ucfirst($webName);
       $tmplName = ucfirst($tmplName);
     $file =~ s/\$skin/$skin/geo;
     $file =~ s/\$web/$webName/geo;
     $file =~ s/\$name/$tmplName/geo;
Now $file holds a possible template name. Check whether it is there. If so, we are done. Otherwise continue to find the next candidate.
          my ($candidatename, $candidatevalidate, $candidateretrieve);

     if ( $userdir ) {
       # candidate in user directory
       my ($web1, $name1) = $session->normalizeWebTopicName($web, $file);

       if( validateTopic($session,$store,$session->{user},$name1,$web1) ) {
         next if (defined($this->{files}->{$name1}));
         #recursion prevention.
         $this->{files}->{$name1} = 1;
         return retrieveTopic( $store, $web1, $name1 );
     } else {
       if( validateFile( $file )) {
         next if (defined($this->{files}->{$name}));
         #recursion prevention.
         $this->{files}->{$name} = 1;
            return TWiki::readFile( $file );

-- ThomasWeigert - 15 Nov 2006

Checked in the code so that it can be examined further. r11996

-- ThomasWeigert - 17 Nov 2006

Looks okay at first blush but I can't budget the headspace to really examine it at present.

-- MartinCleaver - 17 Nov 2006

I think however, that the other important case now does not work

make a new skin that should augment whatever skin you have, in the twiki.tmpl, add %TMPL::INCLUDE{'twiki'}% , which used to include the next twiki.tmpl in the skin path (to enable many levels of over- riding, and add only the TMPL:DEF's that you are changing (the rest are inherited from the twiki.tmpl below.

it looks like the 'default' or un-named skin twiki.tmpl file is not included, thus stopping us from building ontop of it.

I think Crawford went to some lengths to make the un-named default skin the end of the lookup path, and I'm hoping thats all that is missing from your implementation

-- SvenDowideit

To verify what you are saying... You want the following to happen:

Say you have a skin ABC with templates like view.ABC.tmpl, etc. However, there is no skin twiki.ABC.tmpl, and therefore, you would expect that twiki.tmpl is used when %TMPL::INCLUDE{'twiki'}% is called for the ABC skin?

-- ThomasWeigert

ah, yes, thats one case, where you are specialising / adding to the view skin

the case i'm doing right now, only has a twiki.ABC.tmpl , and contains only (mmm, for example)


blah blha

so like your example, is able to add / modify the existing definition of any normal enough skin, depending on the skin path fallbacks to follow the order specified in the SKIN variable, and if its still not satisfied, falls back to the default skin.

so to extend the above eg.

if SKIN=ABC,webpermissions,pattern

then the 'twiki' include would be satisfied by twiki.pattern.tmpl (as WebPermissionsPlugin only supplies an oopsmore - again using the same principle)

however, if SKIN=ABC (as in the zengarden case, I'm re-using as much as possible from the default skin)

the 'twiki' include used to be satisfied by the default skin.

if you look at the old code, there was some recursive lookup used to allow each layer inthe template chain to TMPL::INCLUDE{'twiki'}, and for each lookup to go to the next lower level.

Neat huh

-- SvenDowideit

Sven, I looked at both your examples, and I think they work already in the current implementation. I must be misunderstanding something.

Does the following test case capture both of your examples?

sub test_pathOtherUses {
    my $this = shift;
    my $data;

    write_template( 'view.ABC','the view.ABC.tmpl template' );
    write_template( 'edit.pattern','the edit.pattern.tmpl template');
    write_template( 'twiki','the twiki.tmpl template');

    $data = $tmpls->readTemplate('twiki', 'ABC,pattern', '' );
    $this->assert_str_equals('the twiki.tmpl template', $data );

    $data = $tmpls->readTemplate('edit', 'ABC,pattern', '' );
    $this->assert_str_equals('the edit.pattern.tmpl template', $data );

This test case passes.

-- ThomasWeigert - 22 Nov 2006

while i've not got time to spend on it now, I'm able to say 2 things :/

i think your testcases are too trivial to expose real usages, and

you don't seem to me to be coving the use and fallback of the twiki.tmpl, which happens via a script tmpl, nor are you coving the case where the default skin is used via several others -

On the presumption that

  • that I have actually found an issue
  • you havn't using those test cases

then there must be more to how everything interacts frown

does readTemplate evaluate the template? - are you testing the effects of TMPL::INCLUDEs and their interaction with the template path?

I'm very very unsure on how it works, but i'm quite sure that alot of us are currently relying on that un-sure system - makes me think that fixing it, as your work is, should happen at the beginning of a development cycle, not near the end.

-- SvenDowideit

Sven, the only routine that was rewritten was TWiki::Templates::readTemplateFile. All that this routine does is to find a template amongst the many locations it can be at. So the test cases should be trivial: Put templates in certain locations, with skins there or not, and then try to see if you retrieve the right template.

There really is not much complexity here. The problem is just that the algorithm we are implementing appears unknown. I implemented the algorithm that is documented in the pod section plus the "requested feature" that a period is allowed in the name of a *.tmpl file but not in the topic templates (*.txt).

TMPL::INCLUDES do not affect the template path, as far as I understand. There are only the following factors:

  • the name of the template requested
  • the sequence of skins applied
  • where the templates are actually located, and
  • which templates are present.
The test cases vary these.

Note that there is no such thing as requesting a template "via" some other template as far as readTemplateFile is concerned: it is given the name of a requested template and a seqence of skins, and looks through a set of locations to find a matching template.

-- ThomasWeigert - 22 Nov 2006

presuming that the current release is supposed to be in feature freeze, this work is nowhere near close enough to being well defined . Its clear that CC managed to re-write it without breaking existing oddness (ok, after some iterations) much closer to the begining of the development cycle, by doing the research necessary to tease out the existing functionality. Whereas Thomas is still hoping that we can tell him the spec - which is quite unrealistic, as many twiki customisers don't visit here, nor see the work in progress until its cooked.


-- SvenDowideit - 22 Nov 2006

Not quite. I coded up what was documented and what was in the test cases. Turns out that there is use cases out there which were not supported by the test cases nor by what is written up in the documentation. In fact, the feature that Michael describes above was definitely not part of the design discussions when we added the topic-specific templates, as you can see from the relevant discussions back then in Codev.

I am not asking you to tell me the spec. But when there are usages that people have found to exploit that were not documented or in test cases, then we should not be surprised that they are discovered this way.

All this said, I don't care one way or the other. I have implemented this feature because

  • it was requested by several people and supported on this topic and
  • I was told by Kenneth to go ahead with the implementation.

Crawford managed not to break the previous usage because the usage that are showing up now were not supported before his implementation. Remember, we did not have topic-specific templates then. I went back to Cairo and Beijing to look at the previous implementations and clearly each time the "spec" changed without there being any description of that.

The undocumented use cases that you and Michael managed to find are also unique to PatternSkin and NatSkin and not utilized in other skins. In particular, not in Classic skin.

Either way, you can have configurable template paths now (a feature that a lot of people asked for above) by helping me ferret out undocumented use cases or we can postpone this until after the release and ferret it out then (risking that people discover and utilize further undocumented use cases that make this harder later).

-- ThomasWeigert - 22 Nov 2006

I may be out in the left field here, but I don't think that TWiki is whatever happens to work by accident in the current implementation. With this attitude we will never get this beast under control. All that said, I have updated the current implementation to support all the undocumented uses cases.

-- ThomasWeigert - 22 Nov 2006

Anyway, let's not loose sight of where this topic started from: that it is impossible to override templates in the template directory for a given skin. Example: I want to override, in my user topic, viewtopbar.pattern.tmpl to do something specific to my application. There is no way of doing so.

Configurable search paths allow this, if the user so desires.

-- ThomasWeigert - 23 Nov 2006

Thomas, thanks very much for all your effort to grok the specs and docu of the template lookup mechanism and trying to make sense of it. Note, however that specs+docu are never covering all of the code. The code itself is the very last instance you have to read and understand, not the specs nor the docu. These are only there to help you to understand the code but are never complete in itself. Just my 2c about that.

Anyway, I am learning more about the template lookup from day to day. And this page is a nice source of new possibilities that are availiable now that you refactored and enhanced these means. For example I was not aware that I can have Web.SkinSkinTestTemplate when setting the VIEW_TEMPLATE to Web.Test

-- MichaelDaum - 23 Nov 2006

Michael, I do realize that the code is the final arbiter, but also, we should not cultivate that.

In particular, with respect to template lookup, we have changes to the code over the TWiki versions which is not supported by the concurrent changes to the doco and inline description of the algorithm. When that happens, there are two explanations: the doco is wrong or the code is wrong. It is not always the case that the doco is wrong.

Getting Web.SkinSkinTestTemplate when setting the VIEW_TEMPLATE to Web.Test (using the skin skin) is the basic example, from the doco. This was the first match you got in Cairo, the other choice was Web.TestTemplate

-- ThomasWeigert - 23 Nov 2006

Coming to your starting point of your mission "how to customize the viewtopbar.pattern.tmpl " you don't need alter the template lookup system to do that AFAICS. As you probably know already, you just need to create a viewtopbar.thomas.tmpl and set the SKINPATH to thomas, pattern. This works with the old template lookup systems and is a well documented practice. So at what point didn't the system meet your requirements and forced you to rework the template lookup system? Pardon me, if it is already written somewhere above and I missed it. But your previous comment does not completely justify your attempts.

Btw. for me using the full $web.$topic name to set the VIEW_TEMPLATE was the most intuitive thing to do in a TWikiApplication.

-- MichaelDaum - 23 Nov 2006

Yes, but that was not the request in the above. The goal was to change pattern skin locally, not to create a new skin, that we now are looking for at every lookup.

The second request above was to simplify the lookup mechanism to allow a user defined central location for template files.

-- ThomasWeigert - 23 Nov 2006

All skins for TWiki and i.e. Pattern and Nat are written to easily override "strategic" parts of it. In general, you'd never change a preloaded skin but override part of its definitions in another template file. One template file does not make up a complete skin but covers part of it. The fact that TWiki looks up all templates for thomas in the above example is not a problem of the template lookup mechanism itself but of TWiki not caching its findings in a persistant way. I doubt it it worth it til prooven wrong.

-- MichaelDaum - 23 Nov 2006


-- SvenDowideit - 08 Dec 2006

Edit | Attach | Watch | Print version | History: r67 < r66 < r65 < r64 < r63 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r67 - 2006-12-08 - SvenDowideit
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2018 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.