Revision [7087]
This is an old revision of MySkin made by DarTar on 2005-04-03 08:33:01.
MySkin: choose and modify your favorite skin
Give it a TestSkin try! (v.1.0)
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.0
- 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;
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
/**
* 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 users 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 1.1
* @since Wikka 1.1.6.X
*
* @output displays a form for selecting alternate skins and edit
* custom user skins.
* @todo - store custom skin in DB;
*/
if ($this->GetConfigValue("allow_select_skin") == "0") {
echo $this->Format('//Sorry, skin selection is disabled on this site//');
} else {
// initialize variables
$defaultskin = $this->GetConfigValue("default_stylesheet");
$currentskin = $this->GetSkin();
$postedskin = '';
$myskin = '';
$submit = '';
// get skin names
$postedskin = (isset($_POST["skin"]) && (strlen($_POST["skin"]) > 4))? $_POST["skin"] : $currentskin;
if ($this->GetUser()) $myskin = 'user_'.strtolower($this->GetUserName()).'.css';
// build form chunks
$setskin = '<input type="submit" name="action" value="Set skin" title="Load this skin" />';
$showsource = '<input type="submit" name="action" value="Show source" title="Display the source of '.$currentskin.'" />';
$hidesource = '<input type="submit" name="action" value="Hide source" title="Hide the source box" />';
$editsource = '<input type="submit" name="action" value="Edit source" title="Modify the source of this skin" />';
$savesource = '<input type="submit" name="action" value="Save modified source" title="Store changes to '.$currentskin.'" />';
$createskin = '<input type="submit" name="action" value="Create my skin" title="Generate a custom skin for '.$this->GetUserName().'" />';
$importskin = '<input type="submit" name="action" value="Save current skin as my skin" title="Store a copy of '.$currentskin.' as '.$myskin.'" />';
$restoreskin = '<input type="submit" name="action" value="Restore to default settings" title="Reset '.$myskin.' to the default system stylesheet ('.$defaultskin.')" />';
echo $this->Format("=== Select a skin: === --- ");
switch ($_POST["action"]) {
case "Save modified source":
// saves modified skin to file
$this->WriteSkin($currentskin, $_POST["mod_css_content"]);
// no break - skin is automatically updated
case "Set skin":
// change current skin and reload page
if (file_exists("css/".$postedskin)) {
$this->SetSkin($postedskin);
$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 = $this->ReadSkin($currentskin);
$this->WriteSkin($myskin, $css_content);
$this->SetSkin($myskin);
$this->Redirect($this->href());
}
break;
case "Create my skin":
// first-time user skin creation
if ($this->GetUser() && !file_exists("css/".$myskin)) {
$css_content = $this->ReadSkin($defaultskin);
$this->WriteSkin($myskin, $css_content);
$this->SetSkin($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 = $this->ReadSkin($defaultskin);
$this->WriteSkin($myskin, $css_content);
$this->SetSkin($myskin);
$this->Redirect($this->href());
}
break;
case "Show source":
if ($this->GetConfigValue("allow_display_skin_source") == "1") {
// open a readonly textarea with skin source
$css_contents = $this->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":
if ($this->GetConfigValue("allow_display_skin_source") == "1" || $this->IsAdmin || $currentskin == $myskin) {
// open an editable textarea with skin source
$css_contents = $this->ReadSkin($currentskin);
$showskin = '<textarea id="skinedit" name="mod_css_content" cols="80" rows="15">'.$css_contents.'</textarea><br />';
$submit = $savesource.$hidesource;
}
break;
default:
// give write access to the skin owner and to admins
switch ($this->GetConfigValue('allow_display_skin_source')) {
case '0': #hide source, no one except admins can edit skins
$submit = ($this->IsAdmin())? $editsource : '';
break;
case '1': #anyone can display source, skin owners can edit their skin, admins can edit any skin
$submit = ($this->IsAdmin() || $currentskin == $myskin)? $editsource : $showsource;
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 default skins
$noskinmask = '^('.$defaultskin.'|'.$myskin.'|xml.css|print.css|\.(.*)|user_(.*))$';
$skinlist .= '<option value="" disabled="disabled">--- Default skins: ---</option>';
while (false !== ($file = readdir($handle))) {
if (!preg_match('/'.$noskinmask.'/', $file)) {
$selected = ($file == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$file.'"'.$selected.'>'.$file.'</option>';
}
}
if ($this->GetConfigValue("display_custom_skins") == "1") {
$handle = opendir('css/');
$skinlist .= '<option value="" disabled="disabled">--- User skins: ---</option>';
while (false !== ($file = readdir($handle))) {
if (preg_match('/user_(.*)/', $file)) {
$selected = ($file == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$file.'"'.$selected.'>'.$file.'</option>';
}
}
}
$skinlist .= '</select>';
// create form
print $this->FormOpen("","","post");
print $skinlist.$setskin."<br /><br />".$showskin.$submit."<br /><br />\n";
// show user skin options
if (($this->GetConfigValue("allow_create_custom_skin") == "1") && $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);
}
?>
/**
* 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 users 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 1.1
* @since Wikka 1.1.6.X
*
* @output displays a form for selecting alternate skins and edit
* custom user skins.
* @todo - store custom skin in DB;
*/
if ($this->GetConfigValue("allow_select_skin") == "0") {
echo $this->Format('//Sorry, skin selection is disabled on this site//');
} else {
// initialize variables
$defaultskin = $this->GetConfigValue("default_stylesheet");
$currentskin = $this->GetSkin();
$postedskin = '';
$myskin = '';
$submit = '';
// get skin names
$postedskin = (isset($_POST["skin"]) && (strlen($_POST["skin"]) > 4))? $_POST["skin"] : $currentskin;
if ($this->GetUser()) $myskin = 'user_'.strtolower($this->GetUserName()).'.css';
// build form chunks
$setskin = '<input type="submit" name="action" value="Set skin" title="Load this skin" />';
$showsource = '<input type="submit" name="action" value="Show source" title="Display the source of '.$currentskin.'" />';
$hidesource = '<input type="submit" name="action" value="Hide source" title="Hide the source box" />';
$editsource = '<input type="submit" name="action" value="Edit source" title="Modify the source of this skin" />';
$savesource = '<input type="submit" name="action" value="Save modified source" title="Store changes to '.$currentskin.'" />';
$createskin = '<input type="submit" name="action" value="Create my skin" title="Generate a custom skin for '.$this->GetUserName().'" />';
$importskin = '<input type="submit" name="action" value="Save current skin as my skin" title="Store a copy of '.$currentskin.' as '.$myskin.'" />';
$restoreskin = '<input type="submit" name="action" value="Restore to default settings" title="Reset '.$myskin.' to the default system stylesheet ('.$defaultskin.')" />';
echo $this->Format("=== Select a skin: === --- ");
switch ($_POST["action"]) {
case "Save modified source":
// saves modified skin to file
$this->WriteSkin($currentskin, $_POST["mod_css_content"]);
// no break - skin is automatically updated
case "Set skin":
// change current skin and reload page
if (file_exists("css/".$postedskin)) {
$this->SetSkin($postedskin);
$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 = $this->ReadSkin($currentskin);
$this->WriteSkin($myskin, $css_content);
$this->SetSkin($myskin);
$this->Redirect($this->href());
}
break;
case "Create my skin":
// first-time user skin creation
if ($this->GetUser() && !file_exists("css/".$myskin)) {
$css_content = $this->ReadSkin($defaultskin);
$this->WriteSkin($myskin, $css_content);
$this->SetSkin($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 = $this->ReadSkin($defaultskin);
$this->WriteSkin($myskin, $css_content);
$this->SetSkin($myskin);
$this->Redirect($this->href());
}
break;
case "Show source":
if ($this->GetConfigValue("allow_display_skin_source") == "1") {
// open a readonly textarea with skin source
$css_contents = $this->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":
if ($this->GetConfigValue("allow_display_skin_source") == "1" || $this->IsAdmin || $currentskin == $myskin) {
// open an editable textarea with skin source
$css_contents = $this->ReadSkin($currentskin);
$showskin = '<textarea id="skinedit" name="mod_css_content" cols="80" rows="15">'.$css_contents.'</textarea><br />';
$submit = $savesource.$hidesource;
}
break;
default:
// give write access to the skin owner and to admins
switch ($this->GetConfigValue('allow_display_skin_source')) {
case '0': #hide source, no one except admins can edit skins
$submit = ($this->IsAdmin())? $editsource : '';
break;
case '1': #anyone can display source, skin owners can edit their skin, admins can edit any skin
$submit = ($this->IsAdmin() || $currentskin == $myskin)? $editsource : $showsource;
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 default skins
$noskinmask = '^('.$defaultskin.'|'.$myskin.'|xml.css|print.css|\.(.*)|user_(.*))$';
$skinlist .= '<option value="" disabled="disabled">--- Default skins: ---</option>';
while (false !== ($file = readdir($handle))) {
if (!preg_match('/'.$noskinmask.'/', $file)) {
$selected = ($file == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$file.'"'.$selected.'>'.$file.'</option>';
}
}
if ($this->GetConfigValue("display_custom_skins") == "1") {
$handle = opendir('css/');
$skinlist .= '<option value="" disabled="disabled">--- User skins: ---</option>';
while (false !== ($file = readdir($handle))) {
if (preg_match('/user_(.*)/', $file)) {
$selected = ($file == $currentskin)? " selected=\"selected\"" : "";
$skinlist .= '<option value="'.$file.'"'.$selected.'>'.$file.'</option>';
}
}
}
$skinlist .= '</select>';
// create form
print $this->FormOpen("","","post");
print $skinlist.$setskin."<br /><br />".$showskin.$submit."<br /><br />\n";
// show user skin options
if (($this->GetConfigValue("allow_create_custom_skin") == "1") && $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
// SKINS
function GetSkin()
{
if ($this->GetUser())
{
$skin = $_SESSION['skin'];
} else
{
if ($_COOKIE['skin'])
{
$skin = $_COOKIE['skin'];
} else
{
$skin = $this->GetConfigValue("default_stylesheet");
}
}
return $skin;
}
function SetSkin($skin)
{
if ($this->GetUser())
{
$_SESSION['skin'] = $skin;
} else
{
$this->SetPersistentCookie("skin", $skin);
}
}
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;
}
function GetSkin()
{
if ($this->GetUser())
{
$skin = $_SESSION['skin'];
} else
{
if ($_COOKIE['skin'])
{
$skin = $_COOKIE['skin'];
} else
{
$skin = $this->GetConfigValue("default_stylesheet");
}
}
return $skin;
}
function SetSkin($skin)
{
if ($this->GetUser())
{
$_SESSION['skin'] = $skin;
} else
{
$this->SetPersistentCookie("skin", $skin);
}
}
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;
}
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
"default_stylesheet" => "wikka.css",
"allow_select_skin" => "1",
"display_custom_skins" => "1",
"allow_create_custom_skin" => "1",
"allow_display_skin_source" => "1",
"allow_select_skin" => "1",
"display_custom_skins" => "1",
"allow_create_custom_skin" => "1",
"allow_display_skin_source" => "1",
Understanding the system options
- default_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