Allowing users to customize the look of your application is always welcomed. Here is one approach using Zend Framework.
First lets look at the directory structure for creating a themeable application.
Typical Layout:
root
— private
— public
—— css
—— js
—— images
You’ll notice that all our publicly available files for stylesheets, javascript and images are placed in the public folder. We are going to alter this by placing them into a sub-folder under public called ‘default’.
Our structure now looks like this.
root
— private
— public
—— default
——— css
——— js
——— images
What this allows us to do is encapsulate all our files/assets into a single folder that we can now easily reference. All our themes and their assets should now follow the same naming convention as our ‘default’ folder.
Adding a theme to our structure now looks like this
root
— private
— public
—— default
——— css
——— js
——— images
—— modern
——— css
——— js
——— images
In our application bootstrap we add the following line of code (around where you initialize the session)
$session = Zend_Registry::get('Zend_Session'); //change this to match how you store your sessions
if (!isset($session->theme))
$session->theme = 'default';
To easily use this in our application lets create a view helper.
class My_View_Helper_Theme
{
/**
* Returns site base url based on the current theme
*
*
* @return string
*/
public function theme($content = '', $prependBase = true)
{
if ($prependBase)
{
$baseUrl = Zend_Controller_Front::getInstance()->getRequest()->getBaseUrl();
}
else
{
$baseUrl = '';
}
$session = Zend_Registry::get('Zend_Session'); //change this to match how you store your sessions
$url = $baseUrl . $session->theme . $content;
}
}
In our view we can now use our view helper to fetch the correct file from the current theme.
<img src="<?php echo $this->theme('/images/blankslate.jpg') ?>" />
We can make our view helper a little more helpful by adding a fallback to the default if the file doesn’t exist in the theme.
class My_View_Helper_Theme
{
/**
* Returns site base url based on the current theme
*
*
* @return string
*/
public function theme($content = '', $prependBase = true)
{
if ($prependBase)
{
$baseUrl = Zend_Controller_Front::getInstance()->getRequest()->getBaseUrl();
}
else
{
$baseUrl = '';
}
$session = Zend_Registry::get('Zend_Session'); //change this to match how you store your sessions
$url = '/public/' . $session->theme . $content;
$location = DOCUMENT_ROOT . $url;
if (file_exists($location))
{
return $baseUrl . $url;
}
else
{
// If theme doesn't exist then use the default theme
$url = '/public/default' . $content;
return $baseUrl . $url;
}
}