![]() |
|
Snippets |
|
Some applications want to offer various look-and-feels for each page. The online documentation already explains how to change the CSS from the server, and a bit of JavaScript will allow you to do it from the client side.
But sometimes this is not enough, and the need arises to have several sets of templates for each action. Something like:
mymodule/
templates/
indexSuccess.php # Template for index action, default theme
theme1/
indexSuccess.php # Template for index action, theme1
theme2/
indexSuccess.php # Template for index action, theme2
Thanks to the MVC architecture, this is very easy to do.
We'll suppose that theme is an attribute of the sfUser object. It contains a simple string. The way to determine the preferred theme for a given user will be left to your sagacity, as well as the way to extend the sfUser class to deliver this attribute. The interesting thing is to modify the view class to have it use the theme when the time comes to look for templates and layouts.
Create a myView.class.php file in the lib/ directory of your application, and write in:
<?php class myView extends sfPHPView { public function configure() { parent::configure(); // Grab the theme from the user (of from anywhere else) $theme = $this->getContext()->getUser()->getTheme(); // If there is a theme and if the theme feature is enabled if($theme && sfConfig::get('app_theme')) { // Look for templates in a $theme/ subdirectory of the usual template location if (is_readable($this->getDirectory().'/'.$theme.'/'.$this->getTemplate())) { $this->setDirectory($this->getDirectory().'/'.$theme); } // Look for a layout in a $theme/ subdirectory of the usual layout location if (is_readable($this->getDecoratorDirectory().'/'.$theme.'/'.$this->getDecoratorTemplate())) { $this->setDecoratorDirectory($this->getDecoratorDirectory().'/'.$theme); } } } }
To force symfony to use this view class instead of the default sfPHPView, create a module.yml in the application's config/ directory, and write in it:
all: view_class: my
The new view will look for themes only if you enabled the feature in your app.yml:
all: theme: on
Clear the cache, and the theme feature is ready.
It works like this: when a user has a defined theme, symfony will look for templates and layouts in a subdirectory named by this theme. For instance, if a user has a foobar theme, and that it requests the mymodule/myaction action, symfony will look for the template in:
apps/myapp/modules/mymodule/templates/foobar/myActionSuccess.php
and for the layout in:
apps/myapp/templates/foobar/layout.php
The beauty of this modification is that if the themed template doesn't exist, symfony will use the normal template as a fallback.
It must be pretty easy to package this into a plugin, so if you feel like doing it...
... without having trouble with your PEAR directory.
If you use the admin generator but don't like the generated html code, you either can use a custom css file to redo the style, or you have to copy the original theme from
/path/to/$PEAR/symfony/generator/sfPropelAdmin/default
and redo the html here. The problem with that technique is, that you have to manage this PEAR directory from now on, instead having the new theme located in your project folder. That's bad, because your theme will be lost if you clear your PEAR installation or decide to uninstall the symfony version and re-install another one.
After doing some research in the forums and docs, I tried to create the theme in my project directory, with the expected folder structure. I created a folder structure in my projects data dir, like this:
/path/to/$PEAR/data/generator/sfPropelAdmin/$THEME_NAME
I just copied all directories and files from the default sfPropelAdmin theme to this folder, but this didn't worked out. symfony wasn't able to find this theme. So, I created a symbolic link to this folder:
ln -s \ /path/to/$PROJECT_NAME/data/generator/sfPropelAdmin/$THEME_NAME \ /path/to/$PEAR/data/symfony/generator/sfPropelAdmin/$THEME_NAME
Now, you I modify the template to fit my needs, e.g. reset the css classes, add a new table structure and so on. After upgrading/uninstalling/installing a new copy of symfony, don't forget to check if the symbolic link still exists. If not, just re-create it, and everything should work.
If your webserver and php understoods the following of symbolic links (Windows doesn't), you can use this new theme for your sfPropelAdmin generated modules via the theme configuration handle in your generator.yml:
generator:
class: sfPropelAdminGenerator
param:
model_class: ModelClass
theme: $THEME_NAME