Change the look and feel of a folder and its subfolders

If you want a subfolder to have a different appearance than the rest of your site, you can add a simple page template and a stylesheet to a folder that affects it and all of its subfolders.

It is actually fairly easy to add a stylesheet and/or extra page content by overriding the main_template. We build a new main_template in a folder which simply calls the main_template for our parent folder, and passes in a few paramter blocks,

We do this by finding the folder in the ZMI, and adding a Page Template named main_template.

This main_template should look like:

  <metal:page define-macro="master">
    <metal:block use-macro="container/[path_to_parent]/main_template/macros/master">
      <metal:block metal:fill-slot="top_slot">
        <metal:block metal:define-slot="top_slot" />
      </metal:block>
      <div metal:fill-slot="css_slot">
        <style type="text/css" media="screen"
        tal:content="string: @import url($portal_url/[path_to_stylesheet];">
        </style>
        <metal:block metal:define-slot="css_slot" />
      </div>
      <div metal:fill-slot="main">
        [before content]
        <metal:bodytext metal:define-slot="main" tal:content="nothing">
          Page body text
        </metal:bodytext>
        [after content]
      </div>
    </metal:block>
  </metal:page>

There are four strings in this template in square brackets that you would want to fill in:

  1. [path_to_parent] is the path to this folder from the Plone site folder. (you might think you can use here/aq_inner/aq_parent, but that makes a loop when this template is used in subfolders...)
  2. In the css_slot section, the [path_to_stylesheet] is the path to where you have the special stylesheet for this folder.
  3. in the main slot, you can add [before content] which will be just before the content of every page's content (but with the stylesheet can of course be placed wherever you want on the page)
  4. at the bottom of the main slot, you can similarly add something to the page.

This works by intercepting requests for the main_template made by pages in this part of the containment hierarchy, and calling the main_template in force further down, with various parameters passed -- namely the main, css_slot, and top_slot parameters.

Note that, as coded, this allows the same trick to be applied in a subfolder of this one -- both added style sheets will appear in those areas.

Examples Needed

Posted by Max Spiller at Jan 18, 2005 08:21 PM
For clarification, I think a few code examples would help in understanding what is happening in each of these places: [path_to_parent], [path_to_stylesheet],[before content]and [after content].

Some examples

Posted by andre at Mar 18, 2005 09:12 AM
Supposing that you have a plone site with the name 'my_site' and a folder 'foo' with a subfolder 'bar',..

[path_to_parent]
  ..when you add the described main_template in the folder 'bar', your [path_to parent] is 'foo/bar'.

[path_to_stylesheet]
  ..when you want to refer to a stylesheet named 'my_style.css' in the folder 'foo', [path_to_stylesheet] is 'foo/my_style.css'. If you want to refer to a stylesheet anywhere in your skins, it's just the name of the stylesheet file.

[before_content] and [after_content]
  ..can be any valid XHTML or TAL or METAL, e.g. '<div class="beforeContent"> Boo! </div>'. It will be rendered into the XHTML of your page just like all the content from the other templates.

Path_to_parent Ammendment

Posted by sdownie at Apr 11, 2005 02:36 PM
Actually, the [path_to_parent], when you add the described main_template in the folder bar, is "foo", not "foo/bar".

In my case, I created a new folder ("custom") at the root of a Plone instance. This was the code that brought the new "main_template" to life without prompting errors:

[ metal:block use-macro="container/main_template/macros/master" ]

(I've replaced the angle brackets with square brackets to protect the innocent.)

Thanks for the great tip!

Clean XHTML and no hardcoded paths!

Posted by Brian Ryer at May 07, 2005 06:12 AM
Thanks for providing this little nugget to Plone cusomisation. Sometimes what seems simple to many is mind numbingly puzzling to me!

Substituting this metal:block for the div element used as an example in the original post has two advantages. The path to your custom stylesheet will be found without hard coding the folder name in your template. Additionally the metal:block element doesn't cause a problem with XHTML validation that the out of place div element did.


<pre>
      <metal:block metal:fill-slot="css_slot">
        <style type="text/css" media="screen"
        tal:define="tfolder python:here_url;
                          x python:tfolder.rfind('/');
                          thisfolder python:tfolder[:x]"
        tal:content="structure string: <!-- @import url($thisfolder/sectionCustom.css); -->">
        </style>
        <metal:block metal:define-slot="css_slot" />
      </metal:block>
<pre>

Here is the code listing for my comment above

Posted by Brian Ryer at May 07, 2005 06:18 AM
I obvioulsy don't post here often enough otherwise I would have perhaps been able to avoid the embarrassment of posting invisible (i.e. unescaped) code. Sorry about that. Won't happen again (I hope!).

<pre>
      &lt;metal:block metal:fill-slot="css_slot"&gt;
        &lt;style type="text/css" media="screen"
        tal:define="tfolder python:here_url;
                          x python:tfolder.rfind('/');
                          thisfolder python:tfolder[:x]"
        tal:content="structure string: &lt;!-- @import url($thisfolder/sectionCustom.css); --&gt;"&gt;
        &lt;/style&gt;
        &lt;metal:block metal:define-slot="css_slot" /&gt;
      &lt;/metal:block&gt;
<pre>

And I still didn't close the PRE tabs, jeesh!

Posted by Brian Ryer at May 07, 2005 06:19 AM
So much for impressing the locals, eh?

Hi

Posted by tiosiowteng at Jul 17, 2006 06:48 AM
Very Good

How I Get it to Work

Posted by Joseph Method at May 23, 2005 10:30 PM
The only way I've gotten this to work is by copying main_template and header into the folder, and altering the header. Otherwise, it parses main_template but fails to fill css_slot, no matter what I do.

What's in the Style sheet

Posted by Aaron Moline at Jul 12, 2005 02:16 PM
Could someone give an example of how to create the sytle sheet to point to the gif you want to use on that folder?