Thursday, March 25, 2010

Yii and Themes

In the face of a total site redesign today, I realized I should begin using the themes features of Yii. This is where some of the true beauty of MVC comes into play.

Without a custom theme set up, the theme will default to the views in the /protected/views/ directory. Once you set up a theme, whenever it cannot find a specific view in the theme directory, it will go back to the default in the /protected/views/ directory and check there.

This is the guide reference on themes: http://www.yiiframework.com/doc/guide/topics.theming


To begin, I created my new theme directory (called 'site_001') under the mywebapp/themes/ directory like so:
/themes/site_001/views/ 

I then copied my existing views into the new theme folder. I now have a full backup of the site feel.

I then created a second new theme, called site_002, for the new development (Note: I'm not copying in any of the views here, because I'm going to be using the defaults/existing. As I modify the views for the redesigned site, I will put the new views in this directory.)

Now, to alter the site and let it know that I want to use the other theme, I simply add the following to my /protected/main/config.php
return array(
        'theme'=>'site_002',   
        ...
    );
If I want to view the previous design, I simply set the theme to 'site_001' instead.

The new Yii 1.1.1 is apparently slightly buggy in that it's not correctly pulling in the layouts/main.php from within the theme, so that's something to watch for.
(Bug Thread)

To correct this, change the /protected/components/Controller.php as:
// public $layout = 'application.views.layouts.column1';
   public $layout = 'column1';
and edit the /themes/site_001/views/layouts/column1.php and column2.php pages:
// $this->beginContent('application.views.layouts.main');
   $this->beginContent( ... Not sure what to put here instead?!? ... ); 


(UPDATE: )

Slightly hack, but I duplicated my /protected/views/layouts/main.php as /protected/views/layouts/site_001main.php

Then, in the /themes/views/layouts/column1.php file, I ran the beginContent('application.views.layouts.site_001_main')


And, so that I don't have to mess with it in future themes, I'm actually changing it to:

$this->beginContent('application.views.layouts.'.Yii:app()->theme->name.'main');

Works like a charm. I just have to remember to create the theme version of the main.php in the /protected/views/layouts/ folder.

Or learn how to create site aliases :p

7 comments:

  1. Update 2:
    To avoid duplicated column1.php and column2.php files throughout the site, I've altered the file as such:

    if ( Yii::app()->theme )
    {

    $this->beginContent('application.views.layouts.'.Yii::app()->theme->name.'main');
    } else {
    $this->beginContent('application.views.layouts.main');
    }

    Still not ideal, but less copying files around.

    ReplyDelete
  2. Found the reference on aliases:

    http://www.yiiframework.com/doc/guide/basics.namespace

    ReplyDelete
  3. meanning full article..thank's alot

    ReplyDelete
  4. Another nice article! I'm sure I'll be back once I get to this stage in my app. I'm hoping to translate Artisteer generated themes to Yii at some point since theming is not exactly my strong point. :)

    ReplyDelete
  5. Great Post, Thanks.

    Look, this way it's a little easier, using Artisteer:
    http://www.yiiframework.com/wiki/188/converting-an-artisteer-theme-to-yii/#hh0

    Greetings from Armenia ;)

    ReplyDelete
  6. Thank you. I was looking around for a while.

    ReplyDelete
  7. Awesome, Dana. This is exactly what I was looking for. I am planning to create a new theme (beta 2) for my site SlideOnline - Definitely your post will be useful.

    ReplyDelete