Template unification
Discussion topic around the simplification and standardising of distributed skin templates. Raised in
SimplifySkinCreation.
Introduction
Motivation:
- Default templates and pattern skin templates have drifted apart. It is no longer possible to set a skin and trust that functionalities will just work.
- The differences in setup make it more difficult for skin adaptors to build upon one of the skins.
- TWiki core code makes (undocumented) assumptions what is in the template. For instance the search template should have a number of
SPLIT tags.
Tasks:
- Agree on a common architecture
- Rebuild/adapt either or both default skin and pattern skin
- Core code should be less stringent on what is in the templates, or these requirements should be documented
I don't expect us to find quick agreement. Let us discuss the differences between the skins in detail.
Differences between default and pattern templates
Localisation support
Base templates currently do not have text localisation support. It makes the templates simpler, but it might be a problem for skin developers that do not know which translatable texts are available. One of the goals of standardising might be to provide these translatable texts.
Architecture
Default
to be written
Pattern
Note: I have made a couple of small changes to the existing pattern templates (revision 13179) to make the structure a bit more clear: all non-view base templates now include app.pattern.tmpl.
The way pattern templates are set up is derived from
NatSkin. It is based around a html skeleton where template modules stick in. For pattern:
view includes
page (html page) includes
body (html body).
The body html defines a skeleton for modular page parts (top bar, left bar) that can be "switched on" by using
TMPL:INCLUDE - if not included the parts are not there. The top bar template is self-contained: it includes html and a
CSS definition that defines the height.
Base template
Default
twiki.tmpl is the base template that defines building blocks plus the base html tags. It includes:
- Common (shared) modules like
sep and texts as Log out
- Common modules as
script and windowtitle that provides "inserts" in subtemplates. For instance, windowtitle includes titleaction that is defined in other templates.
- Common modules such as
standardheader that can be emptied in subtemplates if not used.
- A base structure for modules:
htmldoctype, head, bodystart, main, bodyend
- A base structure for the main content block:
-
main includes simpleheader, content and standardfooter
-
simpleheader is for templates other than view
-
content is assumed to be defined by subtemplates
Possibly because the html setup is simple, is it possible to mix html tags with template building blocks. For more complex html the html tags would better be grouped apart.
Pattern
twiki.pattern.tmpl does only exist for compatibility with existing plugins that expect a
twiki.tmpl. For this reason it includes
oops.pattern.tmpl.
The base template for pattern is
page.pattern.tmpl. This provides a number of stub modules to be defined in subtemplates:
windowtitle,
javascript,
styles,
body. The shared tags like
sep are in
contants.pattern.tmpl.
So the base template is in fact split up in
page,
body and
constants.
View
Both default skin and pattern defined module
content for the text contents. But the contents of
content is very different:
Default:
%TMPL:DEF{"content"}%
%TEXT%
#TopicEnd
%TMPL:P{"form"}%%TMPL:P{"attachments"}%
%TMPL:P{"topicinfo"}%%TMPL:END%
Pattern:
%TMPL:DEF{"content"}%%TMPL:P{"toolbar"}%
%TMPL:P{"topicpathinfo"}%%TMPL:P{"beforetext"}%%TMPL:P{"formattop"}%%TMPL:P{"attachmentsattop"}%
<div class="patternContent">%TMPL:P{"textcontent"}%
%TMPL:P{"aftertext"}%%TMPL:P{"formatbottom"}%%TMPL:P{"attachmentsatbottom"}%
</div><!-- /patternContent-->
%TMPL:P{"topicaction"}%%TMPL:P{"topicinfo"}%%TMPL:END%
With pattern a lot happens around the topic text: a
toolbar for the top action buttons;
topicpathinfo for the breadcrumb;
beforetext for any content that should be displayed above the topic text (like
aftertext for content below); = formattop= if a form is placed before the topic text (like
formatbottom for a form below); likewise for attachments.
textcontent contains
broadcastmessage and the topic text. But pattern's
textcontent is quite similar to default's
contents. Please note that all additions around the text contents have been requested by the community.
For default by putting
%TEXT% inside
%TMPL:DEF{"textcontent"}%%TEXT%%TMPL:END%, the two skins already become far more compatible. For instance my BlogAddOn works again for default skin.
We should discuss where
BROADCASTMESSAGE really belongs. Perhaps we can do this by thinking about a more general notification mechanism as outlined in
RelayAlertsToTopicTop.
The really new additions are
beforetext and
aftertext. I would really like to see this into the default templates as they prove to be handy to plug in site-wide content such as a
TagMe.
Other templates
To be written.
Miscellaneous notes
To incorporate or comment upon
-
edit.tmpl defines module focus that is not used (yet)
--
Contributors: ArthurClemens - 18 Mar 2007
today, What I really want, is one twiki.css file, that contains all the core css classes, id's and values. Tomorrow, I guess I'll want the default.css that contains the same for the default skin, and then the same for the classic skin :). I'm not quite sure what it'll take to get all the undocumented things together, but it would sure help alot
Yeah, I made the default skin as simple as possible. I'm working as fast as I can to release the
CssZenGardenContrib, so you can see what that gives twiki users - my breif for it however was to make things as simple to understand as possible.
--
SvenDowideit - 19 Mar 2007
Is that really all?
--
ArthurClemens - 19 Mar 2007
i doubt it, but thats the 'wish for the day' today... I'm not in any way suggesting you do it - I actually think I shall be writing a script to extract as much as possible, so that it does not become an out of date list. But I thought i'd let you know where I'm up to.
--
SvenDowideit - 19 Mar 2007
My 'wish for the day' today is to resolve the
textcontent vs
content issue in default, pattern and nat. The differences have already been outlined above. Basically that's the main reason why I am shipping different VIEW_TEMPLATEs for default/nat and pattern. While it is enuf for default/nat to override the
content macro, this same viewtemplate will remove useful stuff from pattern that unfortunately was moved into this macro (see above).
--
MichaelDaum - 20 Mar 2007
brilliant! the 'wish for the day' meme
is useful - I think
beforetext and
aftertext are more obvious - as an onlooker,
content and
textcontent don't reveal much about their intent.
--
SvenDowideit - 20 Mar 2007
Michael, would it work for you if we add
TMPL:DEF{"textcontent"} for default skin?
yes, we could use a more descriptive name for
content. Something like
decoratedcontent?
--
ArthurClemens - 20 Mar 2007
Actually, content is content. Adding some adjective only confuses. Content is the net data that the user/writer produces. The term
textcontent is rather off as this area may contain image data also, produced by the user. Please make it
content again in pattern. That's my 'wish for the day' (for yesterday).
--
MichaelDaum - 21 Mar 2007
The content also contains form data and attachments, plus the broadcastmessage. I could imagine the text contents is called
topictext.
--
ArthurClemens - 21 Mar 2007
I have changed pattern view template to use
content as well. This
will cause some problems for add-ons that have been customized to pattern skin.
Now I think for more integration default skin (and nat) should add DEFs:
- formattop, formatbottom
- beforetext, aftertext
--
ArthurClemens - 07 Apr 2007
How about a bit of consistency and rename
formattop/formatbottom and
beforetext/aftertext to
contentheader/contentfooter and
formheader/formfooter.
--
MichaelDaum - 10 Apr 2007
Because it really
is "form at the top" (of the page). Alternative naming could be
formbeforetopic and
formaftertopic. But "topic" is not that specific: does it include the moved info text for example?
--
ArthurClemens - 10 Apr 2007
(Heh, I always read format-top instead of form-at-top).
There are even
formstart /
formend in addition to
formattop /
formatbottom.
The
formstart is used to start the form containing the surrounding div and the form tag itself. That's paralleled in function by
formend.
The
formattop and
formatbottom are "inside" those. The
formattop is always empty in standard PatternSkin. Only
formatbottom is used to hold the formfields. But these are already in a
form macro.
So we could eliminate
formatop and
formatbottom easily.
--
MichaelDaum - 10 Apr 2007
There is a difference in use. Actually, they are for different users. I've used
formstart and
formend to make the listing inside
TMPL:DEF{"content"} readable: just
TMPL:P inside, preferable no markup. So this is for readability for the template maintainer.
formattop and
formatbottom is targeted to the TWiki App writer that simply wants to override the layout for a topic. So in a topic template he may change
%TMPL:DEF{"formattop"}%%TMPL:END%
%TMPL:DEF{"formatbottom"}%%TMPL:P{"form"}%%TMPL:END%
to
%TMPL:DEF{"formattop"}%%TMPL:P{"form"}%%TMPL:END%
%TMPL:DEF{"formatbottom"}%%TMPL:END%
to change the location of the form.
--
ArthurClemens - 10 Apr 2007
If
thats all it does, you can replace it with some cleverness like I did in the
MoveableTypeSkin to cater for
one-column,
two-column-left,
two-column-right,
three-column . In moveable type, they require different
HTML and class names depending on layout. (basically a bunch of IF's)
--
SvenDowideit - 11 Apr 2007
Could you elaborate on your approach? Is it css-only?
--
ArthurClemens - 11 Apr 2007
no, its TWiki Variable based - I set MOVEABLETYPE_COLUMNS=two-column-right, and then use IF's in the tmpl file to render the
HTML differently. Its actually more complex in that skin, because I also cater for URLPARAMs, though i'm thinking of removing that to a 'demo version' of the skin.
--
SvenDowideit - 12 Apr 2007
I still can't read what suggestions you have for
formattop. Could you abstract out the mechanism and put it into words?
--
ArthurClemens - 12 Apr 2007
Arthur, it'll be easier fro you to look at the tmpl in
MoveableTypeSkin - thats why I released it. But basically, if you defined a FORMATOP (gosh what a bad name, i keep reading
format top) in your preferences, you can then do an
%<nopIF{"$FORMATOP = 'top'" then="%TMPL:P{form}%"}%
of course, I'd normally do something like that using css, but in the
MoveableType case, 'they' do different html, so I had to find a way too.
--
SvenDowideit - 16 Apr 2007
Setting a variable to put the form at the top makes it easier for end users. But someone who wants to create a custom template needs to set the variable next to customizing template modules. Perhaps both mechanisms can exists side by side.
--
ArthurClemens - 16 Apr 2007
i am of the opinion that the skins are too complex, which means we should zero in on the simplest single thing - I'm not convinced that my suggestion is that, but adding placeholders (the same issue as the existing pluginHandler system) does not feel right either.
In fact, I've just thought of a massive missing functionality that would probably make both our ideas go away.
What we're missing, is to be able to re-define a template section, re-usingthe previous definition:
in twiki.tmpl
%TMPL:DEF{content}%%TEXT%%TMPL:END%
in twiki.formatop.tmpl
%TMPL:DEF{content}%%TMPL:P{formt}%%TMPL:P{content}%%TMPL:END%
there is definitely a bit of detailed design needed to workout the expansion order, especially in complex cases...
One of the worries I have with the
formatop,
formatbottom anchor concept, is that it presuposes that we manage to forsee the most important use cases for future users, (leading to the same issue we have with API changes when we learn better approaches), or jsut as badly, give skin desingers a process that will make everyone want for anchors that are really only relevant to small user bases.
--
SvenDowideit - 16 Apr 2007
TWiki can't deal with nested macro definition outlined in
twiki.formatop.tmpl right now. I've resolved that in a couple of places along the following pattern:
in some.tmpl:
%TMPL:DEF{"defaultcontent"}%%TEXT%%TMPL:END%
%TMPL:DEF{"content"}%%TMPL:P{"defaultcontent"}%%TMPL:%END%
So if I want to redefine
content in a new skin, I don't have to copy-paste the previous content of it and then extend it. Instead I reuse the
defaultcontent
in some.other.tmpl:
%TMPL:DEF{"content"}%%TMPL:P{"form"}%%TMPL:P{"defaultcontent"}%%%TMPL:END%
That's a pattern that works on the current template engine, admitted not as powerful and nice as being able to redefine the same macro
%TMPL:DEF{"content}% .... %TMPL:P{"content"}% ... %TMPL:END%
Let's sum up the means for templating at hand right now in the standard engine that are actively used in one or the other skin:
- placeholder macros: tmpl:p{some-non-existing-macro}
- placeholder includes: tmpl:include{some-non-existing-file}
- default macros: tmpl:def{section} - tmpl:p{defaultsection}
- conditional markup: %if
- conditional templates: tmpl:p{context="..." then=".." else="..."}
- plain twiki preference variables: %somevar%
- (forgotten some?)
A skin author has to be aware of all of these possibilities and use them wisely. There's no clear preference which of these patterns is
preferable. You have to decide from case to case. When do you use them?
--
MichaelDaum - 19 Apr 2007
I have adopted
contentheader and
contentfooter.
--
ArthurClemens - 26 May 2007
I have adopted
contentheader and
contentfooter.
--
ArthurClemens - 27 May 2007