create new tag
, view all tags

Feature Proposal: Make it easier to create and manage custom skins.


To encourage talented designers to create great looking skins for twiki.

MartinCleaver recently raised the question why TWiki does not have the rich selection of custom skins available for other software such as Word Press or Moveable Type. I suspect the short answer for this is that, as currently set up, TWiki makes it remarkably hard to design a new skin. In other software packages I've worked with, new skins can be created with as little as two or three files. I'd like to see what we can do to move TWiki closer to this.


After giving it a bit of thought and some discussion on TWikiIRC I'd like to propose a few changes that would make it easier to create and manage custom skins in TWiki:

  1. Clean up template directory - Currently all template files from all skins are dumped in the same directory. With the proliferation of skin-specific templates (PatternSkin is now up to 33 templates!), it's becoming a pain just to keep track of template files associated with various skins.
    • Proposed: Organize the template directory by skin (e.g. ~twiki/templates/PatternSkin). This might require abandoning the web-specific skin feature (which some have commented is not really needed now due to SupportTopicSpecificTemplates).
  2. Provide a simple/flexible foundation - Both Pattern and Classic skins have become pretty complex making it quite complicated to build a custom skin using either of these as a base.
    • Proposed: create a stripped-down but complete skin that custom skins could leverage. Ideally, this skin would be designed to inherit as much style information as possible from the custom skin base styles.
  3. Clarify template/css inheritance - In order to allow skin designers to start with a very simple skin (e.g. designating just a few type and color styles), it would be useful to have any required templates or styles to default back to what's provided by the "bare-bones" skin mentioned in number 2.
    • Proposed: Provide mechanism for a custom skin to designate another skin to provide missing templates or styles.

During discussion of this, it was observed that it would be nice to have a mechinism to insert comments in templates files which are stripped out in rendering. No sooner asked then given! See Bugs:Item85. smile

-- LynnwoodBrown - 11 Jul 2005

Impact and Available Solutions


If necessary, user documentation of new features introduced by this proposal.


Example uses of features introduced by proposal.


Any comments on how the feature is implemented or could be improved


I am definitely in support of (2) and (3) but don't quite see the necessity of (1). In particular, many skins will just change a few templates but inherit others, so it will be more confusing to have separate directories, won't it?

-- ThomasWeigert - 12 Jul 2005

It would be useful if new skins could inherit from pattern skin (or any other css enabled skin).

-- ArthurClemens - 12 Jul 2005

(1) is to ease the maintenance of skins. Installing and removing skins would be as easy as to copy/remove a directory. It's also easier to develop skins if the only templates in your directory are your's (so you don't need to wade through 50+ files in the template directory to find yours)

-- RafaelAlvarez - 12 Jul 2005

I never felt comfortable with the template setup of the default or the pattern skin, ie the logic of its parts (DEFs and INCLUDEs). So the NatSkin approaches templating somehow different which at least makes subtemplating more comfortable. Here's the docu of it.

-- MichaelDaum - 12 Jul 2005

ConsolidateFunctionalityFromSkins has a stack of related stuff, as does BetterTemplateSystem.

We also discussed (and indeed, thanks to Vinod have: PatternSkinUsingTT2Templates) a TemplateToolkit implementation of the skin layer.

I imagine there are a ton of TT2 skins and, more importantly, trained graphics designers who already know how to do stuff in TT2. CgiApplicationFramework allows application designers to choose which templating system they want to use.

O'Wiki had composite furniture pages. They'd be no shame in leveraging that investment.

-- MartinCleaver - 19 Jul 2005

Back when I was thinking about re-writing TWiki as an OO approach I was much more concerned with configuration control standardization - "One Method To Rule Them All". I chose YAML since it can be dumped into a form that Perl can read back quickly, and the human-readbale text files only need to be re-parsed if they have changed since the dump. In effect, the configuration is compiled. This makes it even faster than the system CrawfordCurrie is using in Dakar. Even more so since the skin templates are - in effect - compiled as well.

I looked to YAML as an easy and human readable way of implementing the configuration for a number of reasons. Among them was that it would be easy to translate the present configuration system, not least of all the template system. However it also allowed ease of modification because of the way it was structured and facilitiated the use of common data strcutures. The details could be 'in-line' or in a separate file.

But the killer is that YAML files are sooooo asy to read and modify. Unlike the present system they make the structure very clear; unlike other template systems mentioned they focus on the strcuture of the document rather than make you edit a sort-of-image-without-the-content of it.

Much of what follows might not make sense without a rudimentary understanding of YAML, so please look at the above link so you can understnd the basic "grammar" of YAML. Please; I don;t want to go into the YAM vs. XML vs RDF. YAML is lightweight and fast.

Lets beging with a simple peiece of YAML.
My idea was a bit forward looking: the render engine was intended to be all plugins for different types of source files and languages - a 'chanin of responsibility' model. So there was a part of the config that read:

       # If you can't find your language in this list, don't use this
       language: [ C, en,  en_US, en_GB, ISO-8859-1, ISO-8859-15 ]
       # this says what this skin can render
       # if the topic type isn't in this list don't use ths skin
       render:   [ txt, html, htm, twikiml ]
This describes two arrays.

The "perl" that the YAMLparser generats from this is

      'CONSTRAINTS' => {
        'language' => [
        'render' => [
Or, of course, it could be saved with Storable::freeze and retrieved with Storable::thaw= which would be a lot faster.

So why use YAML instead of writing the conffig files in perl like the LocalSite.cfg in Dakar?
Because YAML is good at dealign with structured data, ordered lists, arrays and so forth. This makes it suited for describing templates.

# Macros # These are the base macros common to all templats in this skin # If you want to share macros between skins, out the macros in files # Each macro, whether file or inline text does only one thing # A remote - URI(ftp) acts like a file # style=file is shorthand for URI(file://...) Pa binary dump format using the perl Storable::freeze and Storable::thaw.

I appreciate that this is not within scope, but the beauty of this kind of config is that you can design to include features that the present generation of code does not use without impacting compatability. Compare this with what would happen if a present skin had an undocumented "%NEWFEATURE{}%" in it.

The various compenents that the render engine would need form the set of macros. These are really no different from the present representation except that they can be shared by putting them in a file. The file can be accessible in the local file ssytem or via FTP or HTTP. No doubt with suitable support it could use other remote protocols as well. Perl has libraries to support these.

    # Macros
    # These are the base macros common to all templats in this skin
    # If you want to share macros between skins, out the macros in files
    # Each macro, whether file or inline text does only one thing
    # A remote - URI(ftp) acts like a file
    # style=file is shorthand for URI(file://...)
            style: file
            value: twiki/some/file/name
            style: text
                - '<table width="100%" border="0" cellpadding="3" cellspacing="0">'
                - '<tr bgcolor="%WEBBGCOLOR%">'
                - '<td valign="top">'
                - 'Topic <b>%TOPIC%</b> . { %TMPL:P{"topicaction"}% }'
                - '</td></tr></table>'
        simpleheader: ......
        titleaction:  ......
        headerhelp:   ......
        webaction:    ......
        heading:      ......
            style: text
            value: [ "<br width=80%>" ]
            style: uri 
            value: ftp://anonymous:PASSWD@twiki.org/path/to/remoteheading.txt
        # exec is depreciated for security reasons
            style: exec
            value: '/usr/local/bin/menubuilder -left -expand=%WEB%'
    # End of macros
To pull it all together, the last section of the config file describes how the view, edit etc are made up.

This means that all the information about a skin is in one place, one file. It may depend on other files, but that dependency is very clear, as the MACRO section enumerates.

           # "use" is the key so the value has to be a list
           use: [ stylesheets styles ]
           # this is really just to show we can
               - Skin-Name "%SKINNAME%"
               - Mode view
              # we can define the body as a flat, ordered lsit or we can
              # use more detailed strcuture.  This version is a list.
              # Use the explicit format rather than the "here doc"
              # because of '#' and '%'
              # The lines are quoted
              - '#PageTop'
              - '<form name="main" action="%SCRIPTURLPATH%/view%SCRIPTSUFFIX%/%WEB%/">'
              - '%TMPL:DEF{"titleaction"}% %REVTITLE% %TMPL:END%'
              - '%TMPL:DEF{"webaction"}% %WEBTOPICLIST% %TMPL:END%'
              - '%TMPL:P{"standardheader"}%'
              - '</form>'
              - '%TEXT%'
              - '%META{"form"}%'
              - '%META{"attachments"}%'
              - '%TMPL:DEF{"topicaction"}%'
              - '%EDITTOPIC%'
              - '%TMPL:P{"sep"}% <a href="%SCRIPTURLPATH%/attach%SCRIPTSUFFIX%/%WEB%/%TOPIC%">Attach</a>'
             - '%REVISIONS% %TMPL:END%'
              - '%TMPL:P{"standardfooter"}%'
              - '<table width="100%" border="0" cellpadding="3" cellspacing="0">'
              - '<tr>'
              - '<td valign="top">'
              - 'Revision %REVINFO% %META{"parent" prefix="<br />Parents: "}%'
              - '</td>'
              - '<td width="40%" valign="top">'
              - '%WEBCOPYRIGHT%'
              - '</td></tr>'
              - '<tr><td colspan=2> %META{"moved"}% </td></tr>'
              - '</table>'
              - '#PageBottom'
            use: [ stylesheets styles ]
                - javascript

See also http://webgen.rubyforge.org/documentation/filehandler/index.html

-- AntonAylward - 19 Jul 200

Edit | Attach | Watch | Print version | History: r9 < r8 < r7 < r6 < r5 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r9 - 2005-07-19 - AntonAylward
  • 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-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.