Brian Rosenthal's Weblog

3/20/2005

Customizing plone sites

Filed under: — brian @ 3:09 pm

Well, I’ve now customized a fair enough amount of plone sites to publish a few helpful hints on the subject. Here’s what I’ve learned.

Who should read this article

This article is written for someone who knows how to program, knows a bit about python, and wants to learn more about setting up plone web sites. It is written for people who want to do significant customization of the look and feel of plone sites and want a quick read on how I did this one in particular. I have included much of the code I used for the customization here, to better describe exactly how I did what I did. You will need a bit of exposure to Zope Page Templates. To try this out, you will need to have plone installed on your Zope web server.

1. Overview

Customizing a plone site is usually nothing more than customizing the default skin, so it’s in that light that you want to think about it.

I’m going to describe how I recently customized a plone site to look like letsgetready.org. The new site is here. There were many things involved that are common for plone customizations. They are:

  1. Having a splash page
  2. Rebuilding the main menu to be “section-aware”
  3. Rebuilding the left menu to use only published content.
  4. Making image alignment work
  5. Properly handling external links
  6. Adding a link in the footer to manage the site.
  7. Changing the logo
  8. Optimizing for performance.

2. Getting started.

2a. Uploading images:

Create a folder /images/ off the root and upload images there throughout this project. You might want to do this part entirely in advance, or not.

3. Customize the columns

We want to have two columns (not three), so go and set that in the properties of the root of the plone site. There is a list of portlets to be displayed on the left side and the right side. Remove those on the right and leave only the navigation on the front. You might want to leave logging in on the left.

4. Set the colors

That would be here:
plone_styles/base_properties (for setting colors)

5. Change the footer and colophon to what you want.

plone_templates/colophon (making it smaller and adding link to RoboCommerce)
plone_templates/footer (adding a “manage” link to /folder_contents")
The styles here are in:
plone_styles/plone.css

Colophon:


<p i18n:translate="text_conforms_to_standards" class="discreet">
        Powered by <a target="blank" href="http://www.plone.org">Plone</a>
        and <a target="blank"
        href="http://www.robocommerce.com">RoboCommerce</a>
</p>

Footer:


<span i18n:translate="description_copyright" tal:omit-tag="">
© 1998-2005 Let's Get Ready! 45 Columbus Avenue New York, NY 10023-6992.
<a href="folder_contents">manage</a>
</span>

6. Remove most of this, to not include the byline (leave the date modified here)
plone_content/document_byline (to remove the username)

7. I wanted this on the bottom left, so I customized its look:
plone_templates/global_searchbox

8. Change the logo:
plone_images/logo.jpg (to logo.gif, possibly)… note, you must also change the base_properties to do this
Also, change the logo’s position here:
plone_styles/plone.css

9. Make external links open in _blank windows, and also not have little icons next to them by looking in this file:
plone_ecmascript/plone_javascripts.css (to make external links not have an icon next to them)

Here is the link, valid as of March, 2005:
http://plone.org/documentation/how-to/open-external-links-in-new-window

10. This is where we’re going to put the main menu:
plone_templates/global_sections

Remove most of it, and instead use a macro defined in
/includes
… called top_menu. Notice how it is “section-aware":


<div tal:omit-tag="" metal:define-macro="top_menu">
<table cellpadding=0 cellspacing=0 border=0 align=left>
<tr>
<td><a href="/about/"><img alt="About"
		border=0
        tal:define="selected python:test(here.getSectionFromURL() == 'section-about', 1, 0)"
        tal:attributes="src python:test(selected, '/images/mainmenu/about_selected.gif'
                                , '/images/mainmenu/about_unselected.gif');
                       onmouseout python:test(selected
                              , 'this.src='/images/mainmenu/about_selected.gif''
                              , 'this.src='/images/mainmenu/about_unselected.gif'');"
	onmouseover="this.src='/images/mainmenu/about_mouseover.gif';"
	onmouseout="this.src='/images/mainmenu/about_unselected.gif';"
	src="/images/mainmenu/about_unselected.gif"></a></td>
<td bgcolor="white"><img src="/images/tp.gif" width="1" height="1"></td>
<td><a href="/programs/"><img alt="Programs"
		border=0
        tal:define="selected python:test(here.getSectionFromURL() == 'section-programs', 1, 0)"
        tal:attributes="src python:test(selected, '/images/mainmenu/programs_selected.gif'
                                            , '/images/mainmenu/programs_unselected.gif');
                                       onmouseout python:test(selected
                              , 'this.src='/images/mainmenu/programs_selected.gif''
                              , 'this.src='/images/mainmenu/programs_unselected.gif'');"
	onmouseover="this.src='/images/mainmenu/programs_mouseover.gif';"
	onmouseout="this.src='/images/mainmenu/programs_unselected.gif';"
	src="/images/mainmenu/programs_unselected.gif"></a></td>
<td bgcolor="white"><img src="/images/tp.gif" width="1" height="1"></td>
<td><a href="/get_involved/"><img alt="Get Involved"
		border=0
        tal:define="selected python:test(here.getSectionFromURL() == 'section-get_involved', 1, 0)"
        tal:attributes="src python:test(selected, '/images/mainmenu/getinvolved_selected.gif'
                        , '/images/mainmenu/getinvolved_unselected.gif');
                       onmouseout python:test(selected
                              , 'this.src='/images/mainmenu/getinvolved_selected.gif''
                              , 'this.src='/images/mainmenu/getinvolved_unselected.gif'');"
	onmouseover="this.src='/images/mainmenu/getinvolved_mouseover.gif';"
	onmouseout="this.src='/images/mainmenu/getinvolved_unselected.gif';"
	src="/images/mainmenu/getinvolved_unselected.gif"></a></td>
<td bgcolor="white"><img src="/images/tp.gif" width="1" height="1"></td>
<td><a href="/resources/"><img alt="College Access Resources"
		border="0"
        tal:define="selected python:test(here.getSectionFromURL() == 'section-resources', 1, 0)"
        tal:attributes="src python:test(selected, '/images/mainmenu/resources_selected.gif'
                                , '/images/mainmenu/resources_unselected.gif');
                       onmouseout python:test(selected
                              , 'this.src='/images/mainmenu/resources_selected.gif''
                              , 'this.src='/images/mainmenu/resources_unselected.gif'');"
	onmouseover="this.src='/images/mainmenu/resources_mouseover.gif';"
	onmouseout="this.src='/images/mainmenu/resources_unselected.gif';"
	src="/images/mainmenu/resources_unselected.gif"></a></td>
<td bgcolor="white"><img src="/images/tp.gif" width="1" height="1"></td>
<td><a href="/donate/"><img alt="Donate"
		border="0"
        tal:define="selected python:test(here.getSectionFromURL() == 'section-donate', 1, 0)"
        tal:attributes="src python:test(selected, '/images/mainmenu/donate1_selected.gif'
                            , '/images/mainmenu/donate1_unselected.gif');
                       onmouseout python:test(selected
                              , 'this.src='/images/mainmenu/donate1_selected.gif''
                              , 'this.src='/images/mainmenu/donate1_unselected.gif'');"
	onmouseover="this.src='/images/mainmenu/donate1_mouseover.gif';"
	onmouseout="this.src='/images/mainmenu/donate1_unselected.gif';"
	src="/images/mainmenu/donate1_unselected.gif"></a></td>
<td><img src="/images/mainmenu/end.gif"></td>
</tr>
</table>
</div>

11. plone/get_menu should be a python method to get a string that can be put in the left menu.

	

# get the section… contentPath = context.portal_url.getRelativeContentPath(context) obj = context parents = [] for i in range(0,len(contentPath) - 1): parents.append(obj.getParentNode()) obj = obj.getParentNode() parents.reverse() parents.append(context) print ‘<div id="left_menu">’ if len(parents) > 0: title = parents[0].get_short_title() print ‘'’<a class="level1″ href="%s">%s”’ % (parents[0].absolute_url_path(), title) for obj in parents[0].objectValues(): if (obj.id == ‘index_html’): continue if hasattr(context, ‘portal_workflow’): workflow = context.portal_workflow try: title = obj.get_short_title() if workflow.getInfoFor(obj,’review_state’)==’published’: print ‘'’<div class="level2″><a class="level2″ href="%s">%s</a> <div style="margin: 0px; padding: 0px;"><img src="/images/menu/TopLevelBar.gif"></div> ‘'’ % (obj.absolute_url_path(), title) for obj2 in obj.objectValues(): if (obj2.id == ‘index_html’): continue if workflow.getInfoFor(obj2,’review_state’)==’published’: print ‘'’<a class="level3″ href="%s">> %s”’ % (obj2.absolute_url_path(), obj2.get_short_title()) for obj3 in obj2.objectValues(): if (obj3.id == ‘index_html’): continue if workflow.getInfoFor(obj3,’review_state’)==’published’: print ‘'’<a class="level4″ href="%s">> %s”’ % (obj3.absolute_url_path(), obj3.get_short_title()) for obj4 in obj3.objectValues(): if (obj4.id == ‘index_html’): continue if workflow.getInfoFor(obj4,’review_state’)==’published’: print ‘'’<a class="level5″ href="%s">> %s”’ % (obj4.absolute_url_path(), obj4.get_short_title()) for obj5 in obj4.objectValues(): if (obj5.id == ‘index_html’): continue if workflow.getInfoFor(obj5,’review_state’)==’published’: print ‘'’<a class="level6″ href="%s">> %s”’ % (obj5.absolute_url_path(), obj5.get_short_title()) print ‘</div>’ except: pass print ‘</div>’ return printed

12. We’ll need a function like this:
plone/get_short_title
… because sometimes we’ll need a shorter title to go into the menu. NOTE: You’ll have to add this property short_title in the ZMI (just under the plone root):

try:
    chain = context.aq_chain
except:
    chain = [context]
if chain[0].hasProperty('short_title'):
    return getattr(context, 'short_title')
else:
    return context.title_or_id()

13. plone_templates/header

Eyeball this and see what is not necessary. We don’t need a minimum width requirement… we don’t need different stylesheets for small, medium, and large text…

14. plone_styles/ploneCustom.css

Here is where any left_menu styles should go.

15. plone_portlets/portlet_navigation (to change the look and features of the menu)

Here is where get_menu should be called, and I replaced the entire contents of portlet_navigation to the following (contents of the macro, not the file)


<div class="left_navigation" tal:content="structure here/get_menu"></div>

16. Allowing end-users to manage content on the homepage.

The homepage was built by just creating a template: index_html in the root. It has access to all methods, so it can basically copy header and main_document from the skins.

However, you want a user to be able to manage its contents.

Here is how you do that. You add something like this to the homepage, where homepage_content/left and …/right are valid content nodes in plone:

<div tal:content="structure here/homepage_content/left/CookedBody"
    style="position: absolute; top: 247px; left: 0px;">
</div>
<div tal:content="structure here/homepage_content/right/CookedBody"
    style="position: absolute; top: 420px; left: 490px;">
</div>

Mozilla Scrapbook

Filed under: — brian @ 2:48 pm

Mozilla has a scrapbook extension which lets you store web sites for later viewing, without requiring a network. This is really important if you’re viewing news articles that might expire or anything that you want to arhive. Here s the link:

Mozilla’s scrapbook extension

It has some advanced featured you’ll want to check out: you can edit your page, you can select to preserve javascript…

The shortcut once you install it is Alt-K, and you’ll want to install it and immediately update it because the latest version is not 0.12, I just cannot find the link to the latest version…

Mozilla Web Developer Tools 0.8

Filed under: — brian @ 2:45 pm

1. If you develop web pages, install the Developer Tools located here (or a more recent version if you can find one):
Web Developer Tools v0.8

This will add a toolbar to your mozilla browser with menus to help you do the following:
1. Forms -> View details lets you easily view the details of forms on the screen
2. CSS -> View CSS wil list out all of the CSS files so you can figure out what is causing your page to look the way it does. You can even edit the CSS on the fly to experiment around with different options.
3. Forms -> Convert POSTs to GETS will let you generate links that you can embed in other places
4. Information -> Display ID and Class Details will actually show you the id and class of any block elements on the page.
5. Information -> Display Topographic Information will show you the z-index levels on the page
6. Miscellaneous -> Clear Cache is a quick link to clear your cache.
7. Outline -> Block Elements and Outline->Table Cells
8. Resize -> 800 x 600 is good if you’re interested.
9. Validation -> Validate HTML and Validate CSS
10. There is a quick link to view source

Powered by WordPress