SkinAlternative
Questions answered by this recipe
Downloadable skins let me alter the look of my wiki. But is there any way to alter the look WITHIN the wiki? Can I make pages which differ radically, and which don't look skinned at all?
Description
This recipe is about "wikifying" your skins, so the skin itself can be edited in the wiki
Skins do a great job of separating form from content. The form is the appearance of the page, normally set by the administrator with skins. The content is the normal text and is edited by users of the wiki. The whole point of a wiki is to make it convenient to edit content.
But for some sites, the form is the content. Maybe you spend as much time editing and tweaking the appearance of your pages as you spend tweaking the content. Or maybe you just want editing of form to be as convenient as editing of content.
The idea of this recipe is to use no skin. All the stuff that would be done by a skin is instead done within the wiki. It can be done in each individual page if you want per-page skinning. Or it can be done in Group/GroupHeader and Group/GroupFooter if you want per-group skinning. Or it can be done in Site/AllGroupHeader and footer if you use the AllGroupHeader recipe and want per-site skinning.
1. Noskin
First create a "noskin" skin: create a directory
called ...pmwiki/pub/skins/noskin
and save the following text as noskin.tmpl
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>$Titlespaced - $Groupspaced - $WikiTitle</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <!--HeaderText--> </head> <body> <!--PageText--> </body> </html>
And add the following markup to local/config.php:
Markup('skin', 'fulltext', '/\\(:skin\\s+([-\\w]+)\\s*:\\)/e', "PZZ(SetSkin(\$pagename,'$1'))");
This directive allows an individual page or group to use one of the downloaded skins. For instance, (:skin pmwiki:) at the top of a page will use the "pmwiki" skin for that page. Or (:skin noskin:) at the top of Main/GroupHeader will use our "noskin" for all pages in that group.
(I've found it convenient to leave a useful skin as the default, and then "noskin" for the groups and pages when you're ready to customize them.)
2. Embedding html
You'll most likely want to use html in your alternative to skins. This is described in the EnableHTML recipe. In short, add the following markup to your local/config.php:
Markup('html', 'fulltext', '/\\(:html:\\)(.*?)\\(:htmlend:\\)/esi', "'<:block>'.Keep(str_replace(array('>','<','&'), array('>','<','&'), PSS('$1')))"); array_unshift($EditFunctions, 'MaybeDisableEmbeddedHtml'); function MaybeDisableEmbeddedHtml($pagename,&$page,&$new) { global $ROSPatterns; if (!CondAuth($pagename,"admin")) { $ROSPatterns["/\\(:html:\\)/i"] = "[:html:]"; $ROSPatterns["/\\(:htmlend:\\)/i"] = "[:htmlend:]"; } }
The thing is, html is a security risk. If public users of your wiki could put in html themselves, they could put all kinds of malicious content. The "CondAuth" stuff above means that only people with admin authorization are allowed to use the html directives. For everyone else, the directives will be stripped from the page when they save it. This makes it safe.
3. An example page
Say you want Main/Homepage to look completely non-wiki-like. Edit the page like this:
(:skin noskin:) (:html:) <style type="text/css"> body {background-color:black; color:white;} </style> <div style="float:right"><a href="{$ScriptUrl}/{$Group}/{$Name}?action=edit">*</a></div> (:htmlend:) !! Hello! I look weird and I smell funny too
Here we've used "noskin" to disable normal skinning. We've used (:html:) to set the style for the page. And we've added a discreet asterisk hyperlink for editing the page.
4. An example group.
Say you want every page in the "Coding" group to have the same style, and you want to include some of the standard edit/print/history links.
Edit the page Coding/GroupHeader:
(:skin noskin:) (:html:) <style type="text/css"> body {background-color:rgb(240,220,200); color:rgb(0,10,50);} </style> <div style="font-size: xx-large"> <h1><a href="{$ScriptUrl}/{$Group}">{$Groupspaced}</a> (:if ! name {$Group}:)» {$Titlespaced}(:ifend:)</h1> </div> <div style="width:100%; background-color:rgb(128,128,128); font-size:xx-small;"> <a href="{$ScriptUrl}/{$Group}/{$Name}?action=edit">Edit</a> <a href="{$ScriptUrl}/{$Group}/{$Name}?action=diff">History</a> <a href="{$ScriptUrl}/{$Group}/{$Name}?action=print">Print</a> <a href="{$ScriptUrl}/{$Group}/{$Name}?action=logout">Logout</a> </div> (:htmlend:)
And edit the page Coding/GroupFooter:
---- Copyright. All rights reserved.
You'll probably want to protect these group-header and group-footer pages
by going to Coding/GroupHeader?action=attr
. See Passwords.
Notes
You can set a group header for a group, and then (:nogroupheader:) and (:nogroupfooter:) to override it for individual pages.
If you want upload some images and then incorporate them in a skin, use the path <img src="{$ScriptUrl}/upload/{$Group}/myimage.gif">
Release Notes
- 2007-09-26 some ugly bugs (also related to script security) removed; ~MateuszCzaplinski
Comments
Skin changed format in newer versions of PmWiki (2.1.16 and higher)
As HeaderText
was changed to HTMLHeader
in PmWiki 2.1.16, the "noskin" skin should probably change now to:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>$Titlespaced - $Groupspaced - $WikiTitle</title> <!--HTMLHeader--> </head> <body> <!--PageText--> <!--HTMLFooter--> </body> </html>
Note also, that using <style>
element inside <body>
, as is suggested above, is rather invalid X/HTML. My suggestion would be to use some other recipe for custom stylesheet.
See Also
Contributors
Lucian Wischik