plone 3
Jun 22, 2010
Injecting Plone variables into javascript
I needed access to Plone variables (specifically portal_url) from within javascript. So, I created a browser view and python script that outputs the necessary variables, and registered the view in jsregistry.xml. This turned out to be a rather simple solution.
Step 1: Create a class to output the javascript
I created a file in src/my.product/my/product/browser called CommonUtils.py and added a class GlobalJS with a __call__ method that returns a string containing the javascript. __call__ sets the content-type, creates the string containing the variable, and returns the string.
class GlobalJS(BrowserView):
def __call__(self,REQUEST,RESPONSE):
RESPONSE.setHeader('Content-Type', 'application/javascript')
js_string = "var portal_url = '%s';" % (self.context.portal_url())
return js_string
Step 2: Create a browser view pointing to the class
In src/my.product/my/product/browser/configure.zcml, I added a browser view pointing to GlobalJS, gave it a name, and added a permission. Note that the name of the file containing GlobalJS is CommonUtils.py
<browser:view for="*" name="global_js.js" class=".CommonUtils.GlobalJS" permission="zope2.View" />
Step 3: Register the view in javascript registry
Here, I register the browser view in src/my.product/my/product/profiles/default/jsregistry.xml. I needed access to portal_url before jquery was loaded, so I added the insert-before property. Note that the id is the same as the name registered in the browser view.
<javascript id="global_js.js" cacheable="True" compression="safe" cookable="True" enabled="True" expression="" inline="True" insert-before="jquery.js"/>
Now, global_js.js is loaded on every page and I have access to portal_url from within javascript.
Hope this helps someone.
Jan 26, 2010
Overriding the Title tag in Plone 3
The default title for a Plone 3 site has the page title on the left and portal title on the right, separated by an em dash. I needed to change that for a project. This how-to describes a process for overriding the page title of a buildout based Plone 3 site.
Quick Overview
You need to override the plone.htmlhead.title viewlet and create a class to render your title. The default version of the viewlet is defined in [eggs]/plone/app/layout/configure.zcml, and the class is defined in common.py. You'll need a few more things from common.py too. Override the viewlet in your own [theme]/browser/configure.zcml file, and add the location of your new class.
Getting Started
I needed to override a viewlet, but didn't know which one. A quick grep found a reference to the plone.htmlhead viewlet manager, and then one to the plone.htmlhead.title viewlet. Viewlets are found in the plone/app/layout/viewlets/configure.zcml file within the eggs area of your buildout. Here is the specific code in configure.zcml.
...
<browser:viewlet
name="plone.htmlhead.title"
manager=".interfaces.IHtmlHead"
class=".common.TitleViewlet"
permission="zope2.View"
/>
...
In this case, the plone.htmlhead.title viewlet references a class called .common.TitleViewlet. This means a file--in the same directory as configure.zcml, named common.py contains a class named TitleViewlet. Here is the TitleViewlet code from common.py.
class TitleViewlet(ViewletBase):
...
def index(self):
portal_title = safe_unicode(self.portal_title())
page_title = safe_unicode(self.page_title())
if page_title == portal_title:
return u"<title>%s</title>" % (escape(portal_title))
else:
return u"<title>%s — %s</title>" % (
escape(safe_unicode(page_title)),
escape(safe_unicode(portal_title)))
In the index method at the bottom, Plone sets the value of the <title> tag.
If the page title and the portal title are the same, the portal title is used. If not, both are used, with page title on the left and portal title on the right.
We needed to switch it, so that portal title was on the left, and page title was on the right.
What we did
To override the title viewlet, I created an entry in my theme's browser/configure.zcml file.
<!-- Our custom title viewlet -->
<browser:viewlet
name="plone.htmlhead.title"
manager="plone.app.layout.viewlets.interfaces.IHtmlHead"
class=".myTitleViewlet.TitleViewlet"
layer=".interfaces.IThemeSpecific"
permission="zope2.View"
/>
Notice that there is a new layer statement, and that the manager line includes the complete path to IHtmlHead. The class statement now points to our new class containing code to override the title.
Here is the code from myTitleViewlet.py.
from zope.interface import implements
from zope.component import getMultiAdapter
from zope.viewlet.interfaces import IViewlet
from zope.deprecation.deprecation import deprecate
from Products.CMFPlone.utils import safe_unicode
from Products.Five.browser import BrowserView
from cgi import escape
from plone.app.layout.viewlets.common import ViewletBase
class TitleViewlet(ViewletBase):
...
def index(self):
portal_title = safe_unicode(self.portal_title())
page_title = safe_unicode(self.page_title())
if page_title == portal_title:
return u"<title>%s</title>" % (escape(portal_title))
else:
return u"<title>%s | %s</title>" % (
escape(safe_unicode(portal_title)),
escape(safe_unicode(page_title)))
I needed some of the imports from the top of common.py, and added one of my own for ViewletBase. The only code that really changed is the else clause, where the order of portal_title and page_title are switched, and the em dash is replaced by a pipe (|).
A great reference for overriding the <title> tag is HTML Head Title page which is part of the Plone Theme Reference.
Sep 10, 2009
Installing plone 3 using paster
A short how-to for installing plone 3 using paster
We build most of our sites using paster (versus using the Unified Installer). Here are some simple notes we had for doing that (more information on using paster with plone can be found in the Plone documentation):
This how-to assumes you have ZopeSkel installed.
- Create a directory to house the plone installation.
mkdir /path/to/plone/install/directory
- Use paster to install buildout files.
paster create -t plone3_buildout /path/to/plone/install/directory
- Change your working directory to the new zope install.
cd /path/to/zope/install/directory
- Bootstrap the system.
python bootstrap.py
- Run buildout.
./bin/buildout
- That's it. Now, just start zope/plone.
./bin/instance start
- Or run in it the foreground (and in debug mode).
./bin/instance fg
Aug 28, 2009
Migrating portal_status_message to addPortalMessage for Plone 3
Recently we did a large migration of a site with a high level of custom development. The old site was 2.0.5, and we migrated to 3.2.2. One of the coding changes we needed to make for the migration was fixing portal_status_message to use addPortalMessage.
This is a pretty simple change, but I could not find much documentation on it around the web. We had quite a few controller python scripts that had code in them setting a portal_status_message. The code looked like:
return state.set(portal_status_message='Your comment has been sent to the web support team.')
This old code is completely ignored now, so you have to convert these to the new format.
In Plone 3, portal_status_message is now handled using a cookie, and there are special classes and methods for adding your messages to the cookie.
Now, to set a status message, do the following:
from Products.CMFPlone import PloneMessageFactory as _
context.plone_utils.addPortalMessage(_(u'Your comment has been sent to the web support team.'))
Additionally, you can pass flags to the method to indicate:
- 'info'
- 'warning'
- 'error'
like:
context.plone_utils.addPortalMessage(_(u'Your comment has been sent to the web support team.'), 'info')
For more information about the classes, interfaces, and methods, see this PLIP: http://plone.org/products/plone/roadmap/111
Aug 26, 2009
Simple way to add lightbox/thickbox support to Plone 3 site
I've been on a constant quest to find a simple way to add lightbox support to a Plone 3 site. Thanks to Products.pipbox, it is easy.
On the old Core Software Group site, I downloaded thickbox and manually added the css and js files to the portal_css and portal_js registries. It worked, but was kind of kludgy.
Thanks to Steve McMahon's Products.pipbox, it's clean and easy, and gives you a massive amount of flexibility and control. Here's all I did:
- Added Products.pipbox to my eggs section of my buildout.cfg, then ran bin/buildout
- Installed pipbox via quickinstaller
- pipbox adds a property sheet to portal_properties, which for now, you have to edit via the ZMI
- I added the following to /portal_properties/pipbox_properties -> selector specs:
- That's it. Now our portfolio page uses the lightbox popups to display screenshots of Plone sites we have built.
{type:'overlay',subtype:'image',selector:'img.image-right,img.image-left,img.image-inline', urlmatch:'/image_.+$',urlreplace:''}
Next up:
- Figure out how to control the position of the popup box.
- Figure out how to take advantage of AJAX form support in pipbox.
- Figure out how to implement AJAX tabs using pipbox.
Aug 15, 2009
Welcome to our new blog
Welcome. I hope we can provide some valuable information here for Plone users, content managers, and developers.
We at Core Software Group have been working with Zope for almost 10 years now, and with Plone for nearly 7 years! Man, that is awesome! I have always believed that Plone is the killer app for Zope, and have thoroughly enjoyed providing Plone consulting services.
During our journey down the Plone road, we have learned a ton, and it is my hope that we can share what we have learned in the past, and what we will learn in the future, on this blog, so other folks can benefit.
We have worked on Zope-only applications, built CMF-only applications, supported a variety of Plone versions, and most recently have been migrating old Plone sites to the newer Plone 3 platform.
There are an enormous amount of resources on the web for helping developers with Plone, but it always seems like the one thing you are working on does not have much documentation. Additionally, there are just some things that require the "secret decoder ring"!
When we come across oddities that require you to pat your head and rub your belly at the same time to get Plone to work just right, we will tag them with "secret decoder ring".
I hope that we can provide useful information to other developers. If you like what we've done, or have questions about what we can do, please feel free to contact us.

