Elegant Asset Handling - my first Symfony Plugin “teUrlToAssetPlugin”

August 25, 2009 – 10:17 am

Most websites I work on these days have some sort of header image on almost every page - an optional “banner” if you will, that adds to the general feel of the current section of the site. Since most of these sites as also managed through a CMS setup (symfony, sfDynamicCMS + custom stuff) it is a requirement to be able to adjust these images on a per-page level, even though most pages share the same image within their section..
In short, we often have a need for flexible customization without putting the user through the nightmare of picking a picture through the admin interface every time they want to create a page.

The solution we came up with is rather simple, yet so elegant that we found it to work in all our sites - we use a storage convention based on the page URL.

For example, let’s take a page with the following url:

http://www.somesite.com/sports/outdoors/hiking

where “sports” and “outdoors” are categories, and “hiking” is a specific activity.

The required flexibility now is that the we wanted to be able to have a base-banner for the “sports” section, be able to (optionally) override this for each sub-category, and for each specific activity. As you can see, mapping the url to a directory in the webroot and working backwards would yield just that nice cascade.

Say for example we needed a banner on said page, we would want to look for the following images (in this order):

"/uploads/banner/sports/outdoors/hiking.jpg"
"/uploads/banner/sports/outdoors.jpg"
"/uploads/banner/sports.jpg"
"/uploads/banner.jpg"

Whichever picture is found first, wins.

We add the “banner” directory to be able to pull the same trick for other assets.. maybe a product manual, or a particular flash file for the footer? Never limit your options.. ;)

Now, the code that does this cascading lookup based on url is fairly trivial, but I wanted the whole thing to be very intuitive and simple for our front-end guys, so that they can easily use this functionality from within templates. Turns out this is a perfect case for the ArrayAccess interface, which allows you to access objects via array syntax.

The resulting template code looks as simple as:

$image = $assets["banner"];

and you we even let you specify the file type via an optional extension (defaults to JPG):

$image = $assets["banner.png"];
$document = $assets["manual.pdf"];
$audio = $assets["music.swf"];

As you can see, this setup makes it very easy to distribute general and specific assets throughout your site and administering the files via a wysiwyg or standalone asset manager - without cluttering up the admin area.

Hope you’ll find this as time-saving and elegant as I find it.

Have a great day,
Daniel


Filed under: Symfony — Tags: , — by Richtermeister

PHP Error: Trying to clone an uncloneable object of class ReflectionClass

August 11, 2009 – 7:35 am

I’ve recently run into this error when deploying symfony applications:

“Trying to clone an uncloneable object of class ReflectionClass”.

What’s causing this is a relatively common setting in php.ini, called “zend.ze1_compatibility_mode”, which enables php4 compatibility mode in php5. Specifically it affects a couple of object handling conventions (empty objects cast to FALSE, and - oh this is my favorite - objects are passed by value instead of by reference.. can you imagine how much fun debugging your php5 application would be if this setting didn’t actually save you by breaking things altogether?) Needless to say some hosts like to keep this turned on to me “more compatible” with the past. Also needless to say I hate some hosts.

The way around it is either changing the php.ini setting to:

zend.ze1_compatibility_mode=Off

or disabling it at runtime, before the application bootstraps, via:

ini_set("zend.ze1_compatibility_mode", "off");

Hope it helps someone.


Filed under: Rnadom Sftuf — Tags: — by Richtermeister

Powered by WordPress