Wiki source for MySkin
===== 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 [[Docs:WhatsNew12 | version 1.2]] Wikka introduces support for 100%-modular **themes**: check [[Docs:WikkaThemes | this page]] for more information or this [[http://blog.wikkawiki.org/2009/09/11/how-to-design-themes-for-wikkawiki/ | tutorial]] to learn how to design custom themes.
<<::c::
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==
~-Added JW's patches
==2.1==
~-variables are initialized;
~-added a bunch of system-configurable options;
~-renamed user skins to ##user_username.css##;
~-skin storage: cookies for non registered users / sessions for registered users;
~-added titles to form elements;
~-added "Hide source" button, as per NilsLindenberg's suggestion;
~-renamed "my skin" as "custom skin", as per JavaWoman's suggestion;
==To do==
~-store user skins in DB;
=== 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)##==
%%(php;1)
<?php
/**
* Allows users to select alternate skins and to edit their custom skins.
*
* This action allows the user to select a skin among those available in
* the Wikka css folder. A form allows to display the markup of each skin.
* Registered user can create it and modify their own custom skin. The
* first creation of a custom user skin consists in the generation of a new
* css stylesheet containing the default wikka CSS settings (as specified
* in the Wikka config file) and stored with the name of the user. Once a
* custom user skin exists, the owner of the skin can modify it, overwrite
* it with an existing skin, or restore the default settings. Wikka
* administrators have write access to all the skins.
*
* Cookies must be enabled for the selector to work and the css folder must
* be write-accessible to the script in order to read, edit and save skins.
*
* @package Actions
* @name MySkin
*
* @author {@link http://wikka.jsnx.com/DarTar DarTar}
* @version 2.2
* @since Wikka 1.1.X
*
* @output displays a form for selecting alternate skins and edit
* custom user skins.
* @todo -integrate with UserSettings.
*/
// get skin names
$defaultskin = $this->config['stylesheet'];
$currentskin = (!$this->GetCookie('wikiskin')) ? $defaultskin : $this->GetCookie('wikiskin'); # JW 2005-07-08 FIX possibly undefined cookie
$postedskin = $_POST["skin"];
$myskin = strtolower($this->GetUserName().".css");
// build form chunks
$setskin = '<input type="submit" name="action" value="Set skin" />';
$showsource = '<input type="submit" name="action" value="Show source" />';
$hidesource = '<input type="submit" name="action" value="Hide source" />';
$editsource = '<input type="submit" name="action" value="Edit source" />';
$savesource = '<input type="submit" name="action" value="Save modified source" />';
$createskin = '<input type="submit" name="action" value="Create my skin" />';
$importskin = '<input type="submit" name="action" value="Save current skin as my skin" />';
$restoreskin = '<input type="submit" name="action" value="Restore to default settings" />';
// functions
function WriteSkin($file, $content){
$css_file = fopen("css/".$file, "w+");
fwrite($css_file, $content);
fclose($css_file);
}
function ReadSkin($file){
$source = fopen("css/".$file, "r");
$css_content = fread($source, filesize("css/".$file));
fclose($source);
return $css_content;
}
echo $this->Format("=== Select a Wikka skin: === --- ");
switch ($_POST["action"]) {
case "Save modified source":
// saves modified skin to file
WriteSkin($currentskin, $_POST["mod_css_content"]);
// no break - skin is automatically updated
case "Set skin":
// change current skin and reload page
// begin change by AlexRust - May 28 2009
//$this->SetPersistentCookie("wikiskin", $postedskin);
$this->SetSkin($postedskin);
// end change by AlexRust - May 28 2009
$this->Redirect($this->href());
break;
case "Save current skin as my skin":
// import and save current skin as user skin
if ($this->GetUser() && file_exists("css/".$myskin)) {
$css_content = ReadSkin($currentskin);
WriteSkin($myskin, $css_content);
$this->SetPersistentCookie("wikiskin", $myskin);
$this->Redirect($this->href());
}
break;
case "Create my skin":
// first time user skin creation
if ($this->GetUser() && !file_exists("css/".$myskin)) {
$css_content = ReadSkin($defaultskin);
WriteSkin($myskin, $css_content);
$this->SetPersistentCookie("wikiskin", $myskin);
$this->Redirect($this->href());
}
break;
case "Restore to default settings":
// restore user skin to default settings
if ($this->GetUser() && file_exists("css/".$myskin)) {
$css_content = ReadSkin($defaultskin);
WriteSkin($myskin, $css_content);
$this->SetPersistentCookie("wikiskin", $myskin);
$this->Redirect($this->href());
}
break;
case "Show source":
// open a readonly textarea with skin source
$css_contents = ReadSkin($currentskin);
$showskin = '<textarea id="skinedit" name="display_css_content" cols="80" rows="15" readonly="readonly">'.$css_contents.'</textarea><br />';
$submit = $hidesource;
break;
case "Edit source":
// open an editable textarea with skin source
$css_contents = ReadSkin($currentskin);
$showskin = '<textarea id="skinedit" name="mod_css_content" cols="80" rows="15">'.$css_contents.'</textarea><br />';
$submit = $savesource;
break;
}
$handle = opendir('css/');
// retrieve skin list
$skinlist = '<select name="skin">';
// put on top of the list the default and custom skin
$defaultselected = ($defaultskin == $currentskin)? " selected=\"selected\"" : "";
$myselected = ($myskin == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$defaultskin.'"'.$defaultselected.'>(Default skin: '.$defaultskin.')</option>';
if ($this->GetUser() && file_exists("css/".$myskin)) $skinlist .= '<option value="'.$myskin.'"'.$myselected.'>(My skin: '.$myskin.')</option>';
// get other skins
$noskinmask = '^('.$defaultskin.'|'.$myskin.'|xml.css|print.css|\.(.*))$';
while (false !== ($file = readdir($handle))) {
if (!preg_match('/'.$noskinmask.'/', $file)) {
$selected = ($file == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$file.'"'.$selected.'>'.$file.'</option>';
}
}
$skinlist .= '</select>';
// give write access to the skin owner and to admins
if (!isset($submit)) {
$submit = ($this->IsAdmin() || $currentskin == $myskin)? $editsource : $showsource;
}
// create form
print $this->FormOpen("","","post");
print $skinlist.$setskin."<br /><br />".$showskin.$submit."<br /><br />\n";
// show user skin options
if ($this->GetUser()) {
if (!file_exists("css/".$myskin)) {
$mysubmit = $createskin;
} else {
$myskinname = "(".$myskin.")";
$mysubmit = ($currentskin == $myskin)? $restoreskin : $importskin.$restoreskin;
}
print $this->Format(" ---- === My skin ".$myskinname." === --- ");
print $mysubmit;
}
// close form
print $this->FormClose();
closedir($handle);
?>
%%
== 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
%%(php)
// 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##**
%%(php)
<link rel="stylesheet" type="text/css" href="css/<?php echo $this->GetConfigValue("stylesheet") ?>" />
%%
**modified ##actions/header.php##**
%%(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##**
%%(php)
"stylesheet" => "wikka.css",
%%
**modified ##wikka.config.php##**
%%(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 ===
~-##stylesheet## --- Defines the system stylesheet;
~-##allow_select_skin## --- Allows users to switch stilesheet;
~-##display_custom_skins## --- Displays custom skins in the list of selectable stylesheets;
~-##allow_create_custom_skin## --- Allows registered users to create custom skins;
~-##allow_display_skin_source## --- Allows users to display (and edit) the source of a skin;
----
CategoryUserContributions CategoryLayout
<<===Theme support available in 1.2!===
This page refers to beta functionality supported until Wikka 1.1.x. As of [[Docs:WhatsNew12 | version 1.2]] Wikka introduces support for 100%-modular **themes**: check [[Docs:WikkaThemes | this page]] for more information or this [[http://blog.wikkawiki.org/2009/09/11/how-to-design-themes-for-wikkawiki/ | tutorial]] to learn how to design custom themes.
<<::c::
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==
~-Added JW's patches
==2.1==
~-variables are initialized;
~-added a bunch of system-configurable options;
~-renamed user skins to ##user_username.css##;
~-skin storage: cookies for non registered users / sessions for registered users;
~-added titles to form elements;
~-added "Hide source" button, as per NilsLindenberg's suggestion;
~-renamed "my skin" as "custom skin", as per JavaWoman's suggestion;
==To do==
~-store user skins in DB;
=== 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)##==
%%(php;1)
<?php
/**
* Allows users to select alternate skins and to edit their custom skins.
*
* This action allows the user to select a skin among those available in
* the Wikka css folder. A form allows to display the markup of each skin.
* Registered user can create it and modify their own custom skin. The
* first creation of a custom user skin consists in the generation of a new
* css stylesheet containing the default wikka CSS settings (as specified
* in the Wikka config file) and stored with the name of the user. Once a
* custom user skin exists, the owner of the skin can modify it, overwrite
* it with an existing skin, or restore the default settings. Wikka
* administrators have write access to all the skins.
*
* Cookies must be enabled for the selector to work and the css folder must
* be write-accessible to the script in order to read, edit and save skins.
*
* @package Actions
* @name MySkin
*
* @author {@link http://wikka.jsnx.com/DarTar DarTar}
* @version 2.2
* @since Wikka 1.1.X
*
* @output displays a form for selecting alternate skins and edit
* custom user skins.
* @todo -integrate with UserSettings.
*/
// get skin names
$defaultskin = $this->config['stylesheet'];
$currentskin = (!$this->GetCookie('wikiskin')) ? $defaultskin : $this->GetCookie('wikiskin'); # JW 2005-07-08 FIX possibly undefined cookie
$postedskin = $_POST["skin"];
$myskin = strtolower($this->GetUserName().".css");
// build form chunks
$setskin = '<input type="submit" name="action" value="Set skin" />';
$showsource = '<input type="submit" name="action" value="Show source" />';
$hidesource = '<input type="submit" name="action" value="Hide source" />';
$editsource = '<input type="submit" name="action" value="Edit source" />';
$savesource = '<input type="submit" name="action" value="Save modified source" />';
$createskin = '<input type="submit" name="action" value="Create my skin" />';
$importskin = '<input type="submit" name="action" value="Save current skin as my skin" />';
$restoreskin = '<input type="submit" name="action" value="Restore to default settings" />';
// functions
function WriteSkin($file, $content){
$css_file = fopen("css/".$file, "w+");
fwrite($css_file, $content);
fclose($css_file);
}
function ReadSkin($file){
$source = fopen("css/".$file, "r");
$css_content = fread($source, filesize("css/".$file));
fclose($source);
return $css_content;
}
echo $this->Format("=== Select a Wikka skin: === --- ");
switch ($_POST["action"]) {
case "Save modified source":
// saves modified skin to file
WriteSkin($currentskin, $_POST["mod_css_content"]);
// no break - skin is automatically updated
case "Set skin":
// change current skin and reload page
// begin change by AlexRust - May 28 2009
//$this->SetPersistentCookie("wikiskin", $postedskin);
$this->SetSkin($postedskin);
// end change by AlexRust - May 28 2009
$this->Redirect($this->href());
break;
case "Save current skin as my skin":
// import and save current skin as user skin
if ($this->GetUser() && file_exists("css/".$myskin)) {
$css_content = ReadSkin($currentskin);
WriteSkin($myskin, $css_content);
$this->SetPersistentCookie("wikiskin", $myskin);
$this->Redirect($this->href());
}
break;
case "Create my skin":
// first time user skin creation
if ($this->GetUser() && !file_exists("css/".$myskin)) {
$css_content = ReadSkin($defaultskin);
WriteSkin($myskin, $css_content);
$this->SetPersistentCookie("wikiskin", $myskin);
$this->Redirect($this->href());
}
break;
case "Restore to default settings":
// restore user skin to default settings
if ($this->GetUser() && file_exists("css/".$myskin)) {
$css_content = ReadSkin($defaultskin);
WriteSkin($myskin, $css_content);
$this->SetPersistentCookie("wikiskin", $myskin);
$this->Redirect($this->href());
}
break;
case "Show source":
// open a readonly textarea with skin source
$css_contents = ReadSkin($currentskin);
$showskin = '<textarea id="skinedit" name="display_css_content" cols="80" rows="15" readonly="readonly">'.$css_contents.'</textarea><br />';
$submit = $hidesource;
break;
case "Edit source":
// open an editable textarea with skin source
$css_contents = ReadSkin($currentskin);
$showskin = '<textarea id="skinedit" name="mod_css_content" cols="80" rows="15">'.$css_contents.'</textarea><br />';
$submit = $savesource;
break;
}
$handle = opendir('css/');
// retrieve skin list
$skinlist = '<select name="skin">';
// put on top of the list the default and custom skin
$defaultselected = ($defaultskin == $currentskin)? " selected=\"selected\"" : "";
$myselected = ($myskin == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$defaultskin.'"'.$defaultselected.'>(Default skin: '.$defaultskin.')</option>';
if ($this->GetUser() && file_exists("css/".$myskin)) $skinlist .= '<option value="'.$myskin.'"'.$myselected.'>(My skin: '.$myskin.')</option>';
// get other skins
$noskinmask = '^('.$defaultskin.'|'.$myskin.'|xml.css|print.css|\.(.*))$';
while (false !== ($file = readdir($handle))) {
if (!preg_match('/'.$noskinmask.'/', $file)) {
$selected = ($file == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$file.'"'.$selected.'>'.$file.'</option>';
}
}
$skinlist .= '</select>';
// give write access to the skin owner and to admins
if (!isset($submit)) {
$submit = ($this->IsAdmin() || $currentskin == $myskin)? $editsource : $showsource;
}
// create form
print $this->FormOpen("","","post");
print $skinlist.$setskin."<br /><br />".$showskin.$submit."<br /><br />\n";
// show user skin options
if ($this->GetUser()) {
if (!file_exists("css/".$myskin)) {
$mysubmit = $createskin;
} else {
$myskinname = "(".$myskin.")";
$mysubmit = ($currentskin == $myskin)? $restoreskin : $importskin.$restoreskin;
}
print $this->Format(" ---- === My skin ".$myskinname." === --- ");
print $mysubmit;
}
// close form
print $this->FormClose();
closedir($handle);
?>
%%
== 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
%%(php)
// 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##**
%%(php)
<link rel="stylesheet" type="text/css" href="css/<?php echo $this->GetConfigValue("stylesheet") ?>" />
%%
**modified ##actions/header.php##**
%%(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##**
%%(php)
"stylesheet" => "wikka.css",
%%
**modified ##wikka.config.php##**
%%(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 ===
~-##stylesheet## --- Defines the system stylesheet;
~-##allow_select_skin## --- Allows users to switch stilesheet;
~-##display_custom_skins## --- Displays custom skins in the list of selectable stylesheets;
~-##allow_create_custom_skin## --- Allows registered users to create custom skins;
~-##allow_display_skin_source## --- Allows users to display (and edit) the source of a skin;
----
CategoryUserContributions CategoryLayout