Create a different look and feel for different sections of your web site

Learn how to create a different look and feel for your site, using only CSS sleight-of-hand.

This tutorial is updated for Plone 3.0.

From the 2.0.4 release notes: The body tag now has an HTML class attribute, so you can skin different sections of the site with different styles. Prefix is "section-" and then the Short Name (partial URL) of the item in the root folder. This can be customized if you want this to work on all levels instead of just the root level, or to return multiple classes. This only works for the folders immediately under the root folder, though it can be customized by changing the getSectionFromURL script appropriately. It also does not work for areas of the site such as Site Map or Search, which are not driven off of a page template.

Here's how it works:

In the main template there is a script that generates, on the fly, a class for each section of the site. The script is called "getSectionFromURL".

If you have a section on your website called, say, "Products", and you look at the page source for one of the pages in that section, you'll see that Plone has created a class in the body tag called "section-products". It uses the shortname of the folder, which is also its object name in the database.

In your stylesheets, prefix whatever style you want to be different for that section with:

.section-foldername

replacing "foldername" with the id or short name of the folder in question. For example, this code would change the background image for the Products section of your site.

body.section-products {
    background-image: url(gradient2.png);
}

MODIFY THE CODE FOR THE PORTAL LOGO (if you're doing this on version 3.0, you'll also need to look into how to override viewlets):

For this to work, we want to modify the code in the logo viewlet such that it doesn't output a dynamically generated logo.jpg found in the root of your site. Instead, it can be configured to spit out a CSS ID that can then be styled.

By default, Plone ships with this code: [see plone.app.layout.viewlets.logo.pt to see the code. plone.org keeps eating my code and trying to render it]

Change this code such that you comment out the existing code and add this new banner code:

 

 

The second snippet will return whatever the #banner is specified as in your stylesheets. Add CSS to support this code (note that you can use getSectionFromURL to do more than just adjust your logo

you can affect almost any element on your page). The only weak issue here is that if you change the shortname of your section, your styling will be broken. For example, this is specific to a section with a shortname of foo:

.section-foo #banner { margin: 1em; background-image: url(banner-foo.gif); background-repeat: no-repeat; }

Alternately, you can specify a base CSS class that is more generic.

#banner { background-image:url(&dtml-portal_url;/banner.jpg); }

and then inside each of your folders on your site (on the end user side, not in the ZMI), add an image named banner.jpg. Plone's ability to acquire will pick up the nearest "banner.jpg" it finds.

If you want to do more than change the logo or banner, the getSectionFromURL comes in even more handy.

EXAMPLES OF OTHER THINGS YOU CAN CHANGE IN YOUR STYLESHEETS:

body { background-image: url(gradient.png); }

/* this is specific to a section with a shortname of foo */ body.section-foo { background-image: url(gradient2.png); }

#visual-portal-wrapper { background-color:#000; }

/* this is specific to a section with a shortname of foo */ .section-foo #visual-portal-wrapper { background: white; margin: auto; width: 883px; position: relative; }

#portal-logo { margin: 1em; background-image: url(logo.jpg); background-repeat: no-repeat; }

/* this is specific to a section with a shortname of foo */ .section-foo #portal-logo { margin: 1em; background-image: url(logo-foo.gif); background-repeat: no-repeat; }

and so on...

Customizing style for any folder

Posted by Paul Janecek at Aug 30, 2006 03:06 PM
This "How-to" mentions that the 'getSectionFromURL' script only creates section names for the first level of folders, and suggests that this can be 'easily' modified. I found this post by Mike Hyde that gives the details of how this can be done (http://sourceforge.net/[…]/message.php?msg_id=13659449). Here is Mike's modification to 'getSectionFromURL':
 
 * Customise 'getSectionFromURL' (from plone_scripts)
 * Edit the last line from:
 return "section-" + contentPath[0]
 to:
 return " ".join(["section-" + "-".join(contentPath[:d+1]) for d in range(len(contentPath))])
 
After making this change, you can use the .css described in the original post above. Please follow the link to Mike's original post for a detailed explanation.

Here's an example of how I used this to change the logo of a folder at level 3:
First, I used the drop down menu in the ZMI to add a folder named "images" and an image named "logo-blue.jpg". I then added this line to PloneCustom.css:
.section-resources-articles-local #portal-logo { background: url("images/logo-blue.jpg") transparent no-repeat; }

Now when I navigate to the "resources" > "articles" > "local" folder, the logo changes to the "logo-blue.jpg" image.

One more fix dealing with spaces

Posted by Robert Anderson at Oct 20, 2006 02:26 AM
Classes in CSS are not allowed to have spaces in them but short names in Plone may contain spaces. I modified the above multi-level getSectionFromURL change to just drop the spaces. To make valid classes if your Folders contain spaces make the "return ..." line look like the following two lines:

    allchars = "".join([chr(x) for x in range(256)])
    return " ".join([c.translate(allchars,' ') for c in [
      "section-" +"-".join(contentPath[:d+1]) for d in range(len(contentPath))]])

Note this seems to work fine in Zope 2.9.5/Plone 2.1.4, but could cause conflicts since it's possible for multiple short names do translate to the same "space-free" CSS class string.

Does this work for Plone 3.0?

Posted by Alexander Bandar at Nov 29, 2007 08:39 PM
Hello,

I'm trying, like many other users here, to modify the look of my folders on a per-folder basis. I've scoured these forums and Google, and have tried every work-around and hack I've found (about 5) over the last 3 days. None of them have worked for me. I'd _really_ like to simply use the technique posted here (the ".section-foldername" workaround, and modify the PloneCustom.css). I've reproduced these changes to the letter, and nothing looks different.

Question 1: has anyone used this technique successfully with Plone 3.0? (Zope 2.10.5).

Question 2: has anyone come up with a way to modify skins on a per-folder basis in Plone 3.0? (Regardless of how inconvenient?)

Thanks so much.

Yes it works in PLone 3

Posted by Winn King at Nov 29, 2007 11:54 PM
You may be running into a cacheing issue. Just today, I was modifying my first plone 3 site TTW, and found the changes didn't appear until I restarted Zope. I read about this issue somewhere on the users list. The fix (I just tested and it works) was to turn on debug mode in portal_css. Now, changes I make in the custom folder appear as soon as I refresh (or rather ctrl-F5). This wasn't necessary prior to Plone 3.
Hope that helps.

But could you modify individual pages separately?

Posted by Alexander Bandar at Nov 30, 2007 02:11 PM
Thanks for your reply! However, I _do_ have debug mode on, cacheing disabled, and I even regularly restart Zope, and I _can_ see changes I make TTW to the base.css, customPlone.css, public.css, etc. But what I can't seem to do is to make, for example, a CSS for one folder, and a CSS for a different folder. Nor can I individually address specific elements of different folders using the .section-"foldername" identifier. (Even something as simple as using a different logo.jpg for different foldres). I've seen various techniques posted online to change the "look" of different folders within the same Plone site, but try as I might I can't get any of those workarounds to work. Any other thoughts?

same problem

Posted by Jeff at Jan 23, 2008 08:27 PM
i too am struggling with the same problem with 3.0. we have different departments, each with its own look and feel. i am simply trying to replicate *ONE* of them in plone from our current website, to see if we could use plone to start replacing some of our departments with a CMS. however, this seemingly simple task has been a bear. i feel like i'm standing outside heaven, looking in, and butting my (bloody) head up against the city walls.. :P after a couple of weeks of looking around, i haven't gotten even as far as alexbandar.. i've read pretty much everything i could get my hands (or mouse) on, but to no avail. i simply can't figure how one is supposed to change templates/skins for each department. heck, even how to change the main site template is beyond me.. this is so frustrating.. i feel like plone is gorgeously designed, but too complex (or, at least, inadequately documented). i am at a loss..

example 3.0 site

Posted by Winn King at Jan 24, 2008 12:59 AM
Perhaps and example will help? This is a very simple 3.0 site that has a different header for the inside pages than the home page.
http://www.i40widening.com/
Use Firebug or Web Developement toolbar to take a look at the css. The only thing I used to make the front page different was this css:
.section-front-page #portal-top {
background: url(++resource++i40widening.theme.images/homeheader.jpg) transparent no-repeat;
padding-top: 263px;
}
.section-front-page #portal-logo {
display: none;
}

One thing to note about 3.0 is that it no longer uses CSS to place the logo. So this technique may not help you get different logos for each department folder but it should work for most anything else you want to do styling wise.