MySkin: select, create and edit your favorite stylesheet


Theme support available in 1.2!

This page refers to beta functionality supported until Wikka 1.1.x. As of version 1.2 Wikka introduces support for 100%-modular themes: check this page for more information or this tutorial to learn how to design custom themes.
 

Following the suggestions of JsnX and JavaWoman, and using code I had written for the WikkaSkinEditor action, I've created a new action that allows registered users to create their own custom skin and modify it to their taste. Feel free to test it and give your feedback.

Current version: 2.2


2.2
2.1

To do

How to use it


After installing the code (see below), just add to one of your pages {{myskin}} and start playing

How to install it


1. Create the action (actions/myskin.php)

  1. <?php
  2.  
  3. /**
  4.  * Allows users to select alternate skins and to edit their custom skins.
  5.  *
  6.  * This action allows the user to select a skin among those available in
  7.  * the Wikka css folder. A form allows to display the markup of each skin.
  8.  * Registered user can create it and modify their own custom skin. The
  9.  * first creation of a custom user skin consists in the generation of a new
  10.  * css stylesheet containing the default wikka CSS settings (as specified
  11.  * in the Wikka config file) and stored with the name of the user. Once a
  12.  * custom user skin exists, the owner of the skin can modify it, overwrite
  13.  * it with an existing skin, or restore the default settings. Wikka
  14.  * administrators have write access to all the skins.
  15.  *
  16.  * Cookies must be enabled for the selector to work and the css folder must
  17.  * be write-accessible to the script in order to read, edit and save skins.
  18.  *
  19.  * @package     Actions
  20.  * @name        MySkin
  21.  *
  22.  * @author       {@link http://wikka.jsnx.com/DarTar DarTar}
  23.  * @version      2.2
  24.  * @since         Wikka 1.1.X
  25.  *
  26.  * @output       displays a form for selecting alternate skins and edit
  27.  *              custom user skins.
  28.  * @todo       -integrate with UserSettings.
  29.  */
  30.  
  31.  
  32. // get skin names
  33. $defaultskin = $this->config['stylesheet'];
  34. $currentskin = (!$this->GetCookie('wikiskin')) ? $defaultskin : $this->GetCookie('wikiskin'); # JW 2005-07-08 FIX possibly undefined cookie
  35. $postedskin = $_POST["skin"];
  36. $myskin = strtolower($this->GetUserName().".css");
  37.  
  38. // build form chunks
  39. $setskin = '<input type="submit" name="action" value="Set skin" />';
  40. $showsource = '<input type="submit" name="action" value="Show source" />';
  41. $hidesource = '<input type="submit" name="action" value="Hide source" />';
  42. $editsource = '<input type="submit" name="action" value="Edit source" />';
  43. $savesource = '<input type="submit" name="action" value="Save modified source" />';
  44. $createskin = '<input type="submit" name="action" value="Create my skin" />';
  45. $importskin = '<input type="submit" name="action" value="Save current skin as my skin" />';
  46. $restoreskin = '<input type="submit" name="action" value="Restore to default settings" />';
  47.  
  48. // functions
  49.  
  50. function WriteSkin($file, $content){
  51.     $css_file = fopen("css/".$file, "w+");
  52.     fwrite($css_file, $content);
  53.     fclose($css_file);
  54. }
  55.  
  56. function ReadSkin($file){
  57.     $source = fopen("css/".$file, "r");
  58.     $css_content = fread($source, filesize("css/".$file));
  59.     fclose($source);
  60.     return $css_content;
  61. }
  62.  
  63.  
  64. echo $this->Format("=== Select a Wikka skin:  === --- ");
  65. switch ($_POST["action"]) {
  66.  
  67.     case "Save modified source":
  68.     // saves modified skin to file
  69.     WriteSkin($currentskin, $_POST["mod_css_content"]);
  70.     // no break - skin is automatically updated
  71.  
  72.     case "Set skin":
  73.     // change current skin and reload page
  74.     // begin change by AlexRust - May 28 2009
  75.     //$this->SetPersistentCookie("wikiskin", $postedskin);
  76.     $this->SetSkin($postedskin);
  77.     // end change by AlexRust - May 28 2009
  78.     $this->Redirect($this->href());
  79.     break;
  80.  
  81.     case "Save current skin as my skin":
  82.     // import and save current skin as user skin
  83.     if ($this->GetUser() && file_exists("css/".$myskin)) {
  84.         $css_content = ReadSkin($currentskin);
  85.         WriteSkin($myskin, $css_content);
  86.         $this->SetPersistentCookie("wikiskin", $myskin);
  87.         $this->Redirect($this->href());
  88.  
  89.     }
  90.     break;
  91.  
  92.     case "Create my skin":
  93.     // first time user skin creation
  94.     if ($this->GetUser() && !file_exists("css/".$myskin)) {
  95.         $css_content = ReadSkin($defaultskin);
  96.         WriteSkin($myskin, $css_content);
  97.         $this->SetPersistentCookie("wikiskin", $myskin);
  98.         $this->Redirect($this->href());
  99.     }
  100.     break;
  101.  
  102.     case "Restore to default settings":
  103.     // restore user skin to default settings
  104.     if ($this->GetUser() && file_exists("css/".$myskin)) {
  105.         $css_content = ReadSkin($defaultskin);
  106.         WriteSkin($myskin, $css_content);
  107.         $this->SetPersistentCookie("wikiskin", $myskin);
  108.         $this->Redirect($this->href());
  109.     }
  110.     break;
  111.  
  112.     case "Show source":
  113.     // open a readonly textarea with skin source
  114.     $css_contents = ReadSkin($currentskin);
  115.     $showskin = '<textarea id="skinedit" name="display_css_content" cols="80" rows="15" readonly="readonly">'.$css_contents.'</textarea><br />';
  116.     $submit = $hidesource;
  117.     break;
  118.  
  119.     case "Edit source":
  120.     // open an editable textarea with skin source
  121.     $css_contents = ReadSkin($currentskin);
  122.     $showskin = '<textarea id="skinedit" name="mod_css_content" cols="80" rows="15">'.$css_contents.'</textarea><br />';
  123.     $submit = $savesource;
  124.     break;
  125.  
  126. }
  127.  
  128. $handle = opendir('css/');
  129.  
  130. // retrieve skin list
  131. $skinlist = '<select name="skin">';
  132. // put on top of the list the default and custom skin
  133. $defaultselected = ($defaultskin == $currentskin)? " selected=\"selected\"" : "";
  134. $myselected = ($myskin == $currentskin)? " selected=\"selected\"" : "";
  135. $skinlist .= '<option value="'.$defaultskin.'"'.$defaultselected.'>(Default skin: '.$defaultskin.')</option>';
  136.  
  137. if ($this->GetUser() && file_exists("css/".$myskin)) $skinlist .= '<option value="'.$myskin.'"'.$myselected.'>(My skin: '.$myskin.')</option>';
  138.  
  139. // get other skins
  140. $noskinmask = '^('.$defaultskin.'|'.$myskin.'|xml.css|print.css|\.(.*))$';
  141. while (false !== ($file = readdir($handle))) {
  142.     if (!preg_match('/'.$noskinmask.'/', $file)) {
  143.         $selected = ($file == $currentskin)? " selected=\"selected\"" : "";
  144.         $skinlist .= '<option value="'.$file.'"'.$selected.'>'.$file.'</option>';
  145.     }
  146. }
  147. $skinlist .= '</select>';
  148.  
  149. // give write access to the skin owner and to admins
  150. if (!isset($submit)) {
  151.     $submit = ($this->IsAdmin() || $currentskin == $myskin)? $editsource : $showsource;
  152. }
  153.  
  154. // create form
  155. print $this->FormOpen("","","post");
  156. print $skinlist.$setskin."<br /><br />".$showskin.$submit."<br /><br />\n";
  157.  
  158. // show user skin options
  159. if ($this->GetUser()) {
  160.     if  (!file_exists("css/".$myskin)) {
  161.         $mysubmit = $createskin;
  162.     } else {
  163.         $myskinname = "(".$myskin.")";
  164.         $mysubmit = ($currentskin == $myskin)? $restoreskin : $importskin.$restoreskin;
  165.     }
  166.     print $this->Format(" ---- === My skin ".$myskinname." === --- ");
  167.     print $mysubmit;
  168. }
  169.  
  170. // close form
  171. print $this->FormClose();
  172. closedir($handle);
  173. ?>


2. Modify the wikka core (wikka.php)

Add the following code in ./wikka.php immediately after the //COOKIES section.

Note: This section has moved to ./libs/Wakka.class.php, and the following can be placed after the GetCookie($name) function.

Updated 5/5/2009 by PezHore: Corrected the reference of cookie 'skin' to 'wikiskin', and changed the cookie retrieval from $skin = $_COOKIE['wikiskin] to use GetCookie function. Also removed the duplicate functions

    // SKINS
    function GetSkin()
    {
        if ($this->GetUser())
        {
            $skin = $_SESSION['wikiskin'];
        } else
        {
            if ($_COOKIE['wikiskin'])
            {
                $skin = $this->GetCookie('wikiskin');
            } else
            {
                $skin = $this->GetConfigValue("stylesheet");
            }
        }
        return $skin;
    }

    function SetSkin($skin)
    {
        if ($this->GetUser())
        {
            $_SESSION['wikiskin'] = $skin;
        } else
        {
            $this->SetPersistentCookie('wikiskin', $skin);
        }  
    }


3. Modify the Wikka Header (actions/header.php)

To allow skin selection a small modification of the header is needed:

original actions/header.php
<link rel="stylesheet" type="text/css" href="css/<?php echo $this->GetConfigValue("stylesheet") ?>" />


modified actions/header.php
<link rel="stylesheet" type="text/css" href="css/<?php echo $this->GetSkin() ?>" media="screen" />


4. Add the following system options

original wikka.config.php
      "stylesheet" => "wikka.css",


modified wikka.config.php
      "stylesheet" => "wikka.css",
      "allow_select_skin" => "1",
      "display_custom_skins" => "1",
      "allow_create_custom_skin" => "1",
      "allow_display_skin_source" => "1",



Understanding the system options




CategoryUserContributions CategoryLayout
There are 38 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki