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

3/16/2005

Ben Edelson - A shining star

Filed under: — brian @ 12:02 pm

Ben Edelson
Ben Edelson passed away recently, and he was one of the nicest people I have ever met. He and I were both Presidential Scholars, and we met during recognition week in Washington, DC. From the week of 140 people, I kept in touch with Ben and maybe a handful of people when we went to Harvard.

At Harvard, Ben literally helped me through Organic Chemistry. Organic chemistry was so difficult for me. I couldn’t understand how to think about it. There were so many things it seemed I was just expected to understand that I didn’t. Ben was the person who explained them to me.

Ben and I lived in separate crowds in college, but I would see him often, and we would always take the time to catch up. He was studying with this Nobel Prize winner, really into chemistry research.

He was funny. Really funny. So funny, that I remember that whenever I would see him, he would say something that would make me laugh. Women flocked to him because he was not only funny, but smart, and also so deeply nice. He would always make time for people.

I don’t understand how someone like Ben could not be with us anymore. He is someone that I wanted to reconnect with, after the hectic race to feel comfortable about our careers.

3/14/2005

Netsuite

Filed under: — brian @ 1:25 pm

Good front page ui. Really interesting software package
http://www.netsuite.com/portal/home.shtml

Powered by WordPress