Recent Changes - Search:

Cookbook

PmWiki

pmwiki.org

CSSInWikiPages

Summary: Apply CSS styles via wiki pages
Status: Stable
Version: 2006-12-24
Prerequisites: pmwiki-2.0
Maintainer: DaveG
Categories: Layout CSS
Download: stylepage.phpΔ

Question

Can I apply style sheet information to wiki pages on the fly by editing a wiki page?

Answer

Yes. Here are three possible approaches:

Markup

(from pmwiki-users) The easiest mechanism allows styles to be applied using wiki markup. Create a stylesheet markup that looks something like:

   (:stylesheet:)
      .class { ... }
      element { ... }
   (:stylesheetend:)

Then someone who wants to incorporate stylesheet settings from another page can do it with (:include:):

   (:include Site.DefaultStyleSheet:)

The above stylesheet rule can look like this:

   Markup('stylesheet', '<[=',
     "/\\(:stylesheet:\\)(.*?)\\(:stylesheetend:\\)/sei",
     "\$GLOBALS['HTMLStylesFmt'][] = PSS('$1')");

If you want the stylesheet text to be invisible, simply use

>>comment<<
(:stylesheet:)
  .class { ... }
  element { ... }
(:stylesheetend:)
>><<

Implementation

In order to implement the above, place the Markup code above in config.php or another local configuration file.

Skin

Sometimes you might want the wiki to apply the sheet automatically without having to use (:include:).

You can apply styles to a page using the skin by putting something like the following in skin.php and typing css code into Site.StyleSheet:

global $pagename, $SiteGroup, $HTMLStylesFmt;

$pn = FmtPageName("$SiteGroup.StyleSheet", $pagename);
$page = ReadPage($pn, READPAGE_CURRENT);
if (!$page) { "The stylesheet page doesn't exist"; }
$stylesheettext = $page['text'];
$HTMLStylesFmt['skincss'] = $stylesheettext;

In any case, be careful with allowing CSS to be arbitrarily applied to a wiki page.

Note that loading of style pages will add the css styles to the html page head, and if you specify a lot of styles it will slow down page loading, especially as the browser may need to reinterprete values already received via the normal skin's css file(s). The script below addresses this by having the style page written into a cached file.

Another solution: stylepage.php

Download stylepage.phpΔ and install in your cookbook folder and add to config.php:

include_once("$FarmD/cookbook/stylepage.php");

This adds the markup (:stylepage:), which will load css code from a default style page (set to Site.StyleSheet, but configurable), or by inserting a different page name in the markup, like (:stylepage Group.MyStyleSheet:), will load the css code from the page mentioned.

New: By default other style pages need to be in the $SiteGroup, so they can have the special protection this group offers. Setting $EnableDefautGroupStylesOnly= 0; will lift this restriction and allows style pages to be assigned in any group. You can also specify a different default group from $SiteGroup by setting $DefaultStyleGroup = 'GroupName'; GroupName being the name of this group, for example 'StyleGroup'.

In addition if you set $EnableStylePage = 1; in config.php it will load the default style page for all pages in your wiki, without need to use markup (:stylepage:).

This script is based on the code above, slightly modified and extended. The new version adds caching of style pages in a pub/cache/ directory, and loads the style sheet via standard HTML link syntax, improving downloading.

Contributor: HansB

Release Notes stylepage.php

  • 2006-12-24: Bugfixed new recipe specific cache variables.
  • 2006-11-10: Added new recipe specific Cache variables, to give admins option of different cache location.
  • 2006-10-28: Added $RecipeInfo
  • 2006-08-29a: Modified password check to allow @nopass.
  • 2006-08-29: Fixed $EnableStylePage and caching routine.
  • 2006-08-25: Released much improved version with new css file caching.

Discussion / Questions / Comments

Add latest questions here underneath at the top please!

Here's an alternative markup that's a bit more concise & robust and doesn't need to be surrounded in a >>comment<<:

Markup('css', '<[=',
    "/\\(:css:\\)(.*?)\\(:cssend:\\)/sei",
    "PZZ(NoCache( \$GLOBALS['HTMLStylesFmt'][] = PSS('$1') ))" );

What's different here is that the tags surrounding the CSS are (:css:) and (:cssend:), the NoCache disables the HTML caching which would otherwise break as we're adding stuff to the page header, and PZZ ensures that the CSS isn't shown in the page contents. On a separate note, since we're extracting the CSS in the middle of the wikimarkup conversion, this simple way won't get rid of the <:vspace> that are inserted in the resulting CSS for each blank line. --EemeliAro December 21, 2007, at 04:32 PM

Request:
Could working examples be given on the markup options please? I have tried in the sandbox, but couldn't make it work. I try to use stylesheet markup with table cells.

Try this on a page. If it does not work check your page's HTML source. The style should have been added in the <style> section underneath <!--HTMLHeader--> (~HansB)

(:stylesheet:)
#wikitext table td {color:red; background:yellow; }
(:stylesheetend:)

I haven't been able to get the wiki engine to actually apply the stylesheet using the markup method yet. As for the link in the template, that worked in IE but not Firefox, which (probably for security reasons) didn't let me apply the CSS to the page prior to viewing it, apparently(?). It seems like there must be a better way to incorporate the text of a wiki page directly without having to browse to the page and use the page action. How could we do that? Can the engine apply something directly from the unmarked-up text of a wiki page before rendering the page? -- JonHaupt

The issue with Firefox is that it looks at the Content-type: header of a result to decide if it's a valid CSS page or not. PmWiki's ?action=source returns the source as "text/plain" (and not "text/css"), so Firefox ignores it. --Pm

I fixed the markup problem (missing colon). Now the markup works, except that the text inside (:stylesheet:)...(:stylesheetend:) ends up being included in a page. (fixed with comment markup - thanks HansB) -- JonHaupt

Notes

  • This recipe was last tested on PmWiki version: 2.1.beta20
  • This recipe requires at least PmWiki version: 2

Releases

0.1 - January 12, 2006
1.0 - January 26, 2006 ~ resolved error in markup, resolved issues with skin version, now they both work.

Comments

$EnableStylePage = 1; should be put before include_once("$FarmD/cookbook/stylepage.php"); to make the global include work. Thanks for this fine recipe just what I was looking for :-) Bart August 17, 2006, at 05:38 AM

Note, if you can't get that to work (as I can't), you can enable the Site.AllGroupHeader and add the (:stylepage:) there to enable the CSSInWikiPages for the entire site.Pico August 27, 2006, at 02:17 PM
The $EnableStylePage = 1; isn't going to work in most cases as the IF statement if ($EnableStylePage == 1) { LoadStylePage($DefaultStylePage); } is contained within the function itself and therefore will only be encountered on a page in which the function gets called anyway. How could this problem be fixed? - JonHaupt
I fixed this now, and improved the caching routine, as it failed sometime to cache a file. HansB August 29, 2006, at 04:31 AM

This is so cool. But I'm having trouble tring to use a style in PageTopMenu on your skins (FixFlow). All works fine when I'm on that page, but on other pages, the text from PageTopMenu appears without the style included. I tried placing the enable line in config.php, and the style directive in Site.AllGroupHeader, but nothing works for this particular use. Pico August 26, 2006, at 09:23 PM

What css styling are you trying to use? HansB
List styling. I've been trying out different navigational menu systems. Specifically, the CSS I am using to test this out is located here http://exploding-boy.com/images/cssmenus/menus.html (I downloaded the gifs to the pub/cache). On the PageTopMenu I am using
(:stylepage:)
(:div1 id=tabsF:)
*[[GroupName.|%anything%DisplayedName%%]]
*etc
As I mentioned, it works fine when I am on that page: it displays namvigational menu above the #tabnav .lnav and .rnav frim FixFlow, but on other pages, the list is unstyled. Pico August 27, 2006, at 07:46 AM
Put markup (:stylepage Site.FixflowStyle:) on Site.AllGroupHeader, not Site.PageTopMenu. You still may get some interference from .nav class styling and also colors from a color css file at #topnav hover. The whole PageTopMenu is in a div topmenu with class .nav. If you just want those image tabs it may be better to edit the fixflow template as well.
Yes AllGroupHeader works. Note to others who read this: See AllGroupHeader for instructions on enabling it in config.php.

To open up the PageTopMenu for other menu systems it may be best to do the following:

  • In the skin template remove class='nav' from div id='topnav'
  • In color css files change #topnav li a:hover and #topnav li a:active to #topnav .nav li a:hover and #topnav .nav li a:active
  • In PageTopMenu, if you want to use the standard pipe style menu, put the li items in >>rnav nav<< or >>lnav nav<< divs.
  • If you want to use img tabs put the li items in a >>tabs<< div, and use %tabs%link word%% inside each link. corrected!!
For me, I have to use div directives: (:div id=tabs:) and [[SomePage|%tabs%Link text%%]]. I can't get >>tabs<< to work (and it doesn't matter what I call the style (%tabsnot%Link text%%) because I just need a span for many cool approaches, e.g. pure css popups(offsite) Pico August 27, 2006, at 06:41 PM

I quite like those tabs and may facilitate easier adaption in the above manner in a future skin release. HansB

Thanks for the help and responsiveness. Pico August 27, 2006, at 01:39 PM

I find that using this recipe and AuthUser causes me to have to login 2 times. If I comment this out include_once("$FarmD/cookbook/stylepage.php"); then I can just login one time. What could be causing this? Where should the include be placed in reference to AuthUser ? JB March 27, 2007

It seems like it's probably asking you to login because the stylesheet page might not be read-accessible without a login. I think I have it after authuser in mine. You might want to make sure the stylesheet page is read-accessible though. - JonHaupt

See Also

Contributors

Edit - History - Print - Recent Changes - Search
Page last modified on December 21, 2007, at 04:33 PM