8 min read

(For more resources on Agile, see here.)

Building themes in Yii

In Yii, each theme is represented as a folder consisting of view files, layout files, and relevant resource files such as images, CSS files, JavaScript files, and so on. The name of a theme is the same as its folder name. By default, all themes reside under the same folder WebRoot/themes. Of course, as is the case with all other application settings, this default folder can be configured to be a different one. To do so, simply alter the basePath and the baseUrl properties of the themeManager application component.

Contents under a theme folder should be organized in the same way as those under the application base path. For example, all view files must be located under views/, layout view files under views/layouts/, and system view files under views/ system/. For example, if we have created a new theme, called custom, and we want to replace the update view of our ProjectController with a new view under this theme, we need to create a new update.php view file and save it in our application project as themes/custom/views/project/update.php.

Creating a Yii theme

Let’s take this for a spin to give our TrackStar application a little facelift. We need to name our new theme and create a folder under the Webroot/themes folder with this same name. We’ll exercise our extreme creativity and call our new theme, new.

Create a new folder to hold this new theme located at Webroot/themes/new. Also under this newly created folder, create two other new folders called css/ and views/. The former is not required by the theming system, but helps us keep our CSS organized. The latter is required if we are going to make any alterations to our default view files, which we are. As we are going to change the main.php layout file just a little, we need yet another folder under this newly created views/ folder called layouts/ (remember the folder structure needs to mirror that in the default Webroot/protected/views/ folder).

Now let’s make some changes. As our view file markup is already referencing CSS class and ID names currently defined in the Webroot/css/main.css file, the fastest path to a new face on the application is to use this as a starting point, and make changes to it as needed to implement a new design. Of course, this is not a requirement, as we could re-create every single view file of our application in the new theme. However, to keep things simple, we’ll create our new theme by making a few changes to the main.css file that was auto-generated for us when we created the application, as well as the primary layout file, main.php.

To begin with, let’s make a copy of these two files and place them in our new theme folder. Copy Webroot/css/main.css to Webroot/themes/new/css/main.css and also copy Webroot/protected/views/layouts/main.php to Webroot/themes/new/views/layouts/main.php.

Now, open the newly copied version of the main.css file remove the contents and then add all of the following:

body
{
margin: 0;
padding: 0;
color: #555;
font: normal 10pt Arial,Helvetica,sans-serif;
background: #d6d6d6 url(background.gif) repeat-y center top;
}

#page
{
margin-bottom: 20px;
background: white;
border: 1px solid #898989;
border-top:none;
border-bottom:none;
}

#header
{
margin: 0;
padding: 0;
height:100px;
background:white url(header.jpg) no-repeat left top;
border-bottom: 1px solid #898989;
}

#content
{
padding: 20px;
}

#sidebar
{
padding: 20px 20px 20px 0;
}

#footer
{
padding: 10px;
margin: 10px 20px;
font-size: 0.8em;
text-align: center;
border-top: 1px solid #C9E0ED;
}

#logo
{
padding: 10px 20px;
font-size: 200%;
/* HIDES LOGO TEXT */
text-indent:-5000px;
}

#mainmenu
{
background:white url(bg2.gif) repeat-x left top;
border-top:1px solid #CCC;
border-bottom: 1px solid #7d7d7d;
}

#mainmenu ul
{
padding:6px 20px 5px 20px;
margin:0px;
}

#mainmenu ul li
{
display: inline;
}

#mainmenu ul li a
{
color:#333;
background-color:transparent;
font-size:12px;
font-weight:bold;
text-decoration:none;
padding:5px 8px;
}

#mainmenu ul li a:hover, #mainmenu ul li a.active
{
color: #d11e1e;
background-color:#ccc;
text-decoration:none;
}

div.flash-error, div.flash-notice, div.flash-success
{
padding:.8em;
margin-bottom:1em;
border:2px solid #ddd;
}

div.flash-error
{
background:#FBE3E4;
color:#8a1f11;
border-color:#FBC2C4;
}

div.flash-notice
{
background:#FFF6BF;
color:#514721;
border-color:#FFD324;
}

div.flash-success
{
background:#E6EFC2;
color:#264409;
border-color:#C6D880;
}

div.flash-error a
{
color:#8a1f11;
}

div.flash-notice a
{
color:#514721;
}

div.flash-success a
{
color:#264409;
}

div.form .rememberMe label
{
display: inline;
}

div.view
{
padding: 10px;
margin: 10px 0;
border: 1px solid #C9E0ED;
}

div.breadcrumbs
{
font-size: 0.9em;
padding: 10px 20px;
}

div.breadcrumbs span
{
font-weight: bold;
}

div.search-form
{
padding: 10px;
margin: 10px 0;
background: #eee;
}

.portlet
{

}

.portlet-decoration
{
padding: 3px 8px;
background:white url(bg2.gif) repeat-x left top;
}

.portlet-title
{
font-size: 12px;
font-weight: bold;
padding: 0;
margin: 0;
color: #fff;
}

.portlet-content
{
font-size:0.9em;
margin: 0 0 15px 0;
padding: 5px 8px;
background:#ccc;
}

.operations li a
{
font: bold 12px Arial;
color: #d11e1e;
display: block;
padding: 2px 0 2px 8px;
line-height: 15px;
text-decoration: none;
}

.portlet-content ul
{
list-style-image:none;
list-style-position:outside;
list-style-type:none;
margin: 0;
padding: 0;
}

.portlet-content li
{
padding: 2px 0 4px 0px;
}

.operations
{
list-style-type: none;
margin: 0;
padding: 0;
}

.operations li
{
padding-bottom: 2px;
}

.operations li a
{
font: bold 12px Arial;
color: #0066A4;
display: block;
padding: 2px 0 2px 8px;
line-height: 15px;
text-decoration: none;
}

.operations li a:visited
{
color: #d11e1e;
}

.operations li a:hover
{
background: #fff;
}

You may have noticed that some of these changes are referencing image files that do not yet exist in our project. We have added a background.gif image reference in the body declaration, a new bg2.gif image referenced in the #mainmenu ID declaration and a new header.jpg image in the #header ID declaration. These can be viewed, downloaded and used by viewing the site online or accessing the images directly from http://www.yippyii.com/trackstar/themes/new/css/background.gif, http://www.yippyii.com/trackstar/themes/new/css/bg2.gif, and http://www.yippyii.com/trackstar/themes/new/css/header.jpg.

We need to place these new images into the same CSS folder we are using for this theme, namely Webroot/themes/new/css/.

After these changes are in place, we need to make a couple of small adjustments to our main.php layout file in this new theme. For one, we need to alter the markup in the <head> element to properly reference our new main.css file. Currently the main.css file is being pulled in via this line:

<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()-
>request->baseUrl; ?>/css/main.css" />

This is referencing the application request baseUrl property to construct the relative path to the CSS file. However, we want to use our new main.css file located in our new theme. For this, we can lean on the theme manager application component, defined by default to use the Yii built-in CThemeManager.php class. We access the theme manager in the same way as we access other application components. So, rather than use the request base URL, we should use the one defined by the theme manager, which knows what theme the application is using at any given time. So, we need to alter the above line in /themes/new/views/layouts/main.php as follows:

<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()-
>theme->baseUrl; ?>/css/main.css" />

Once we configure our application to use our new theme (something we have not yet done), this baseUrl will resolve to a relative path to where our theme folder resides.

The other small change we need to make is to remove the display of the application title from the header. As we altered our CSS to use a new image file to provide our header and logo information, we don’t need to display the application name in this section. So, again in /themes/new/views/layouts/main.php, we simply need to change this:

<div id="header">
<div id="logo"><?php echo CHtml::encode(Yii::app()->name); ?></div>
</div><!-- header -->

To the following:

<div id="header"></div><!-- header image is embeded into the #header
declaration in main.css -->

We have put in a comment to remind us where our header image is defined.

One final change we need to make is to the other two layout files used in the application that we are not copying over to our new theme folder, namely protected/views/layouts/column1.php and protected/views/layouts/column2.php. These two layout files also use the main layout file via explicit calls to the beginContent() and endContent(). These files were auto-generated by the Gii code generation tool, and are explicitly referencing the main layout file in protected/views/layouts/ folder. We need to change the input specified to the beginContent() method so that, if available, our new theme layout will be used. Open both the column1.php and column2.php files and change the following line of code:

$this->beginContent('application.views.layouts.main');

To be the following:

$this->beginContent('/layouts/main');

Now, once we configure the application to use our new theme, it will first look for a main.php layout in the themes folder and use that file.

LEAVE A REPLY

Please enter your comment!
Please enter your name here