Adding theme support to your Zend Framework application
This is a brief explanation on how to add theme support to your Zend Framework application and how to ensure those themes are self-contained, easy to distribute and install.
Themes are very powerful and extremely easy to develop. They allow you to quickly switch between layouts and change the look and feel of your application. You can use themes to show, for example, a mobile friendly version of your site.
Making a Zend Framework application theme-able is a three-step process.
First, modify your directory structure:
application/
controllers/
library/
public/
themes/
default/
css/
images/
templates/
custom/
css/
images/
templates/
Then, edit your Bootstrap class:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initView()
{
$theme = 'default';
if (isset($this->config->app->theme)) {
$theme = $this->config->app->theme;
}
$path = PUBLIC_PATH.'/themes/'.$theme.'/templates';
$layout = Zend_Layout::startMvc()
->setLayout('layout')
->setLayoutPath($path)
->setContentKey('content');
$view = new Zend_View();
$view->setBasePath($path);
$view->setScriptPath($path);
return $view;
}
}
And finally, copy your view scripts and layouts to the templates directory:
application/
library/
public/
themes/
full-site/
css/
images/
templates/
error/
index/
partials/
layout.phtml
mobile-site/
css/
images/
templates/
Voila, mission accomplished.
Nice approach.
I’m not so keen on having anything other than images/css/js in the public directory though. Might be better to move the templates themselves somewhere else. Not quite so neat but more secure.
Tom Graham
September 21, 2009 at 3:10 pm
Well, the example above assumes that:
- You are using the Front Controller pattern and that all your requests are routed to a single file.
- You have control over your server.
- You Web server doesn’t have any rules matching phtml files.
Why do you think this way is less secure?
Federico
September 21, 2009 at 3:44 pm
Fair point, however in most example .htaccess files for Zend Framework the following rule exists:
RewriteCond %{REQUEST_FILENAME} !-f
Ofcourse it’s up to the developer to prevent access to those .phtml files :)
Tom Graham
September 21, 2009 at 3:54 pm
True, thanks for pointing that out :)
Federico
September 21, 2009 at 4:56 pm
[...] his blog today Federico Cargnelutti has posted an easy way you can add theme support (self-contained site templates) to your Zend Framework application. [...]
Webs Developer
September 21, 2009 at 7:01 pm
Ideally you would just create several layouts or themes as you call them and then switch layouts in the action controller:
$this->_helper->layout()->setLayout(‘theme_name’);
...
September 22, 2009 at 12:39 am
Not really. A Layout is not a theme, and a theme can have multiple Layouts.
Federico
September 22, 2009 at 6:25 am
I kind of agree with the first comment, I would typically put the templates somewhere in my “/application” directory.
Infact, am currently developing an application where i have my themes at “application/default/layout”, which makes me disagree with your last comment. I believe a layout is a theme, multiple layouts means multiple themes but a theme can have multiple styles (which are defined in the css).
MayorBrain
October 22, 2009 at 11:23 am
How do you build an app for different devices then (eg. PC, iPhone or Blackberry), you don’t use multiple layouts, internal style sheets and inline styles? What’s your secret? ;)
Federico
October 22, 2009 at 2:45 pm
(the last try…)
To protect .phtml files add this to the .htaccess:
typografia
November 6, 2009 at 12:58 pm
Your code examples are a bit confusing. Your structure deviates from public/theme/default to be public/theme/full-site public/theme/mobile-site
Andre Ferreira
January 21, 2010 at 7:43 pm
Default site = Full site
Custom site = Mobile site
Federico
February 8, 2010 at 10:18 am
This does not work so well if you are using the conventional modular structure.
Greg
April 1, 2010 at 6:57 pm
Federico — This is a great idea. Some commenters above are confused about the definition of a theme. If you define a theme as the presentation layer (layouts, view scripts, css, js) your method is great. I also don’t see security risks inherent to this approach – like it was stated above, it’s up to the server admin to manage file access appropriately. Thanks for sharing your insights.
Martin Rio
May 2, 2010 at 2:13 am
Hi,
i’m wondering where you get the $baseDir?
i’m getting errors
Fatal error: Uncaught exception ‘Zend_View_Exception’ with message ‘script ‘error/error.phtml’ not found in path (computer_path/application/views\scripts/)’
Any ideas?
thx,
James
James
August 26, 2010 at 10:07 am
Fixed
Federico
August 26, 2010 at 10:37 am
Hey,
thx for the quick response, but it is still not working?
$view->setScriptPath(‘/path/to/script’);
$view->setScriptPath(‘../public/themes/’.$theme.’/templates’;');
Still looking for the files in the views/scripts folder?
Anyone knows the correct path?
thx,
james
James
August 26, 2010 at 12:27 pm
Make sure to pass the same value to $layout->setLayoutPath() and $view->setScriptPath()
Federico
August 26, 2010 at 10:19 pm
If I want the end users to select the theme, what changes I need to make in the code?
in the above mentioned approach, the theme is sort-of hard coded into the config
Brian
October 11, 2010 at 2:57 pm
If I want the end users to select the theme, what changes I need to make in the code?
in the above mentioned approach, the theme is sort-of hard coded into the config
Peer Sajad
December 8, 2010 at 7:38 am
How do u access css/images/ and so on, you know, they all are not allowed by htaccess….i am confused……thank you for the post, great one. :)
star
July 21, 2011 at 2:32 pm
I realise this article is a little old, but if anyone is trying to make this work for them now and they’re getting a WSOD, it might be because “PUBLIC_PATH” isn’t defined. Go into public/index.php and add this:
// Define Public folder path
defined(‘PUBLIC_PATH’)
|| define(‘PUBLIC_PATH’, realpath(dirname(__FILE__) . ‘/../public’));
Josh
June 6, 2012 at 5:22 am