Making a symfony plug-in for visual theme and custom errors
I manage a growing number of symfony-based Intranet apps that share a common look-and-feel. I use the same stylesheet and images on them all, and it I am nervous every time I make Yet Another Copy of the same files, knowing that I’m duplicating them and causing trouble for myself.
Also, as I wrote in my post about custom error pages, I have error pages set up for each, and I hate copying them. So I have invested some time into building a plugin containing the visual assets and the customized error pages, so that it’s easier to keep them uniform across all the apps I work on, and so that it will be that much quicker to build new projects.
I don’t think anyone outside my company will want my plug-in, but these instructions will hopefully be useful for anyone who wants to do the same thing.
These instructions are for symfony 1.1 but they should apply equally to 1.0 and 1.2.
Plugin organization
Here are the files and directories in my plugin:
plugins/myThemePlugin/ config/ view.yml modules/ default/ config/ view.yml templates/ disabledSuccess.php error404Success.php README web/ css/ mystyles.css myerrors.css mymain.css errors/ error500.php unavailable.php images/ my_swoop.jpg bg_sfTAlert.jpg bg_sfTLock.jpg bg_sfTMessage.jpg indicator.gif tall_gradient.jpg
Using svn:externals
to install the plugin in each symfony project
I only want one copy of this thing, with version control, so I use svn:externals (for my other plugins too ).
$ svn propget svn:externals plugins myThemePlugin/ https://mysvnserver.com/svn/web/myThemePlugin sfGuardPlugin/ http://svn.symfony-project.com/plugins/sfGuardPlugin/branches/1.1/ $ svn up
Publishing the assets
The chapter on plugins in the The Definitive Guide to symfony explains:
Web assets (images, scripts, style sheets, etc.) are made available to the server. When you install a plug-in via the command line, symfony creates a symlink to the project
web/
directory if the system allows it, or copies the content of the moduleweb/
directory into the project one. If the plug-in is installed from an archive or a version control repository, you have to copy the plug-inweb/
directory by hand (as theREADME
bundled with the plug-in should mention).
As I showed above, I prefer to use svn:externals
for my plugins, so this is a bit of a problem for me. Also, I develop on Windows (with XAMPP and Cygwin), so the more elegant symlink solution is not an option. Symfony 1.2 has a task called plugin:publish_assets
that makes the copies, but that messes up my version control strategy. SO: I am going to use svn:externals
to get the web assets from my plugin too.
$ svn propset svn:externals "myThemePlugin https://my_svn_server/svn/web/myThemePlugin/web/" web $ svn propget svn:externals web myThemePlugin https://my_svn_server/svn/web/myThemePlugin/web/ $ svn up |
This lets me keep the plugin in its own repository. You could get a similar effect by just checking out the files, but it would clutter up the SVN for your main project.
The end result: I have one copy of the web assets in the SVN repository, but they’re checked out twice into each project (once under plugins/myThemePlugin/web and once under web/myThemePlugin).
view.yml files
Now the overall view.yml file in plugins/myThemePlugin/config/ sets stylesheets for my whole project:
default: stylesheets: - /myThemePlugin/css/main: { position: last } - /myThemePlugin/css/bannerhealth: {position: last} - %SF_ADMIN_WEB_DIR%/css/main - %SF_CALENDAR_WEB_DIR%/skins/aqua/theme |
And I have another one to apply some additional stylesheets to my error pages:
error404Success: metas: title: 404 Not Found stylesheets: - /sf/sf_default/css/screen.css - /sf/sf_default/css/ie.css - /myThemePlugin/css/errors: {position: last} disabledSuccess: metas: title: Temporarily Unavailable stylesheets: - /sf/sf_default/css/screen.css - /sf/sf_default/css/ie.css - /myThemePlugin/css/errors: {position: last} |
relative image paths in stylesheets and error pages
I use relative paths in my stylesheets (served out of myprojecturl/myThemePlugin/css/) so they can find the images (myprojecturl/myThemePlugin/images/):
background-image: url(../images/tall_gradient.jpg); |
I’d do the same if my error templates (like plugins/myThemePlugin/modules/default/templates/error404Success.php) used images, but they don’t.
The pages in plugins/myThemePlugin/web/errors (which are installed via svn:externals
now in web/myThemePlugin/errors) are used when things are so broken symfony can’t build template pages, so they have full HTML structure, including full stylesheet tags:
<?php $path = '..'; ?> <link rel="stylesheet" type="text/css" media="screen" href="<?php echo $path ?>/../sf/sf_default/css/screen.css" /> <!--[if lt IE 7.]> <link rel="stylesheet" type="text/css" media="screen" href="<?php echo $path ?>/../sf/sf_default/css/ie.css" /> <![endif]--> <link rel="stylesheet" type="text/css" media="screen" href="<?php echo $path ?>/css/main.css" /> <link rel="stylesheet" type="text/css" media="screen" href="<?php echo $path ?>/css/bannerhealth.css" /> <link rel="stylesheet" type="text/css" media="screen" href="<?php echo $path ?>/css/errors.css" /> |
Apache error page configuration
Finally, I tell Apache to use my customized error pages for errors in this project.
<Directory "/path/to/myproject/web"> ErrorDocument 404 /myproject/default/error404 ErrorDocument 500 /myproject/bhThemePlugin/errors/error500.php </Directory> |
There we go! Now I have a lot less to do each time I make a new app; all the pretty stuff is in my plugin, and there aren’t any surprisingly brown symfony pages to throw off any users.
What do you think? Any errors or ommissions or problems?
Thanks for this info. Any chance you can provide your plugin to the community? I’m having a heck of a time getting custom error pages to work and (once I do get them working) would also like to re-use the same code on many sites.
Thanks!
When you will publish this helpfull plugin ?? it’s working with symfony 1.4 too ?? Thanks
Sorry I didn’t read these comments right away.
These instructions are for people who want to make their own plugin. I made a plugin this way to apply my company’s visual look-and-feel to Symfony apps including error pages. It wouldn’t be useful for someone else to use, but these instructions should help you make your own.
Cheers, nathan