Federico Cargnelutti

Simple is better than complex. Complex is better than complicated. | @fedecarg

Adding theme support to your Zend Framework application

with 22 comments

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.

About these ads

Written by Federico

September 20, 2009 at 10:43 pm

Posted in Frameworks, Open-source, PHP

22 Responses

Subscribe to comments with RSS.

  1. 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

  2. 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

  3. 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

  4. True, thanks for pointing that out :)

    Federico

    September 21, 2009 at 4:56 pm

  5. [...] 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

  6. 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

  7. Not really. A Layout is not a theme, and a theme can have multiple Layouts.

    Federico

    September 22, 2009 at 6:25 am

  8. 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

  9. 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

  10. (the last try…)

    To protect .phtml files add this to the .htaccess:

    <Files ~ ".(ini|txt|phtml)$">
    Order allow,deny
    Deny from all
    </Files>

    typografia

    November 6, 2009 at 12:58 pm

  11. 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

  12. Default site = Full site
    Custom site = Mobile site

    Federico

    February 8, 2010 at 10:18 am

  13. This does not work so well if you are using the conventional modular structure.

    Greg

    April 1, 2010 at 6:57 pm

  14. 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

  15. 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

  16. Fixed

    Federico

    August 26, 2010 at 10:37 am

  17. 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

  18. Make sure to pass the same value to $layout->setLayoutPath() and $view->setScriptPath()

    Federico

    August 26, 2010 at 10:19 pm

  19. 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

  20. 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

  21. 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

  22. 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


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 1,033 other followers