Personal tools
You are here: Home Documentation How-tos Creating portlets with editable static content
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Creating portlets with editable static content

Warning: This item is marked as outdated.

This How-to applies to: Plone 2.1.x
This How-to is intended for: Integrators, Customizers

This how-to shows you how to create portlets which display static content pulled from a content object. Essentially, it demonstrates how to display the contents of a Document in a the left and right slots with some formatting, but the technique is useful for other content types as well. This lets portal managers (who are not necessarily HTML or ZPT savvy) alter the content of the portlet easily.

Many sites wish to display portlets with static content, for example advertising certain site features or offering general information. However, site managers typically do not want to manipulate portlet page templates directly or use the ZMI to customise existing ones. Often, they don't even wish to use HTML.

There are tools out there to let you create dynamic portlets, most notably the CMFContentPanels product, and SimplePortlet in the Collective. However, if you don't wish to install a new product or manage a new content type, or if you wish to reuse existing content objects in a portlet, the method below may be useful:

  • Create a Plone folder portlets in your Plone root
  • Add a document with the id info.

Make sure you created these from inside Plone, not from the ZMI. Managers can edit this using kupu, for example.

Note: You must create the document which will be used to hold the portlet content before you install the portlet by adding it to your left_slots or right_slots properties (see below). In the example, the document is found at <plone-site>/portlets/info. You can use a document found elsewhere if you adjust the call to the portlet macro in left_slots or right_slots below.

  • Add the following Page Template in your portal_skins/custom directory.

There is no need to modify this unless you know what you're doing; the portlet template is generic, like all page templates in Zope/Plone, and will pull content from a context, which we will define in the left_slots or right_slots properties shortly:

    <div metal:define-macro="portlet" tal:omit-tag="">
        <tal:block>
            <dl class="portlet">
                <dt class="portletHeader" tal:content="here/title_or_id">Title</dt>
                <dd class="portletItemSingle odd" tal:content="structure here/getText">Content</dd>
            </dl>
        </tal:block>
    </div>

Call it portlet_document_view (portlet_document_view.pt if you put it on the file system).

NOTE: If you use the Test tab in the ZMI to test this portlet, you will get an error. That is because it is not being called with a context it understands. This is perfectly fine - read on.

  • To display the portlet, go to the ZMI, find the Plone site root (or whatever folder you wish the portlet to be displayed in), click Properties and add to either left_slots or right_slots the following:
      portal/portlets/info/portlet_document_view
    

Adjust the path as appropriate. This line basically means: Find the object /portets/info found in the portal root (the portal object, which is provided automatically no matter what your portal is called), and apply the portlet_document_view template do it. That is, the object at /porlets/info becomes the context of the portlet. The template, as shown above, dictates how the contents of the document should be displayed, which in this case means rendering it using the portlet styles and only showing the body.

Other uses of the same pattern

This approach can of course be customised to support different base content types and methods of display. For instance, if you had an Archetypes based type with a TextField called body, and did not want to display a portlet header you could use:

   <div metal:define-macro="portlet" tal:omit-tag="">
        <tal:block>
            <dl class="portlet">
                <dt class="portletHeader" tal:content="here/title_or_id">Title</dt>
                <dd class="portletItemSingle odd" tal:content="structure here/getBody">Content</dd>
            </dl>
        </tal:block>
    </div>

Or, let's say that instead of displaying text, you want the portlet to display images.

  • Create a standard Image object inside Plone, e.g. in the folder /images, with the id my-image
  • Create a portlet called portlet_image_view that contains:
       <div metal:define-macro="portlet" tal:omit-tag="">
            <tal:block>
                <dl class="portlet">
                    <dt class="portletHeader" tal:content="here/title_or_id">Title</dt>
                    <dd class="portletItemSingle odd" 
                        tal:content="structure python:here.tag(scale='thumb')">Image</dd>
                </dl>
            </tal:block>
        </div>
    

This will display an image and scale it to the thumnail size.

  • In te left_slots or right_slots property in the root of your portal, or indeed in any folder (you may have to add the property, in which case you should add a new lines property from the Properties tab on the relevant object in the ZMI), add:
        portal/images/my-image/portlet_image_view
    

The recently released ExtendedPortlets product could also be useful for allowing managers even more control over how portlets are displayed.

by Martin Aspeli last modified February 15, 2006 - 23:28
Contributors: Martin Aspeli, Chris Mills
All content is copyright Plone Foundation and the individual contributors.

"scale='thumb'" not working

Posted by Johannes Graumann at February 17, 2006 - 17:43

"tal:content="structure python:here.tag(scale=thumb)" from the image example does not work for me - error indicates that a float si required. I set out to scale an Image in the portlet to columnTwoWidth and achieved this by doing the following: 1) redefine columnTwoWidth to an absolute pixel-value (200px) in portal_skins/custom/base_properties 2) change the code to:

[0])/float(here.width)))">

GRRR!

Posted by Johannes Graumann at February 17, 2006 - 17:45

How does one insert code here properly? Anyway relevant part should be:

python:here.tag(scale=(float(here.base_properties.columnTwoWidth.split(p)[0])/float(here.width)))

Image offset possible?

Posted by Johannes Graumann at February 17, 2006 - 17:52

Is it possible to tweak the image example such, that the image - which in this case is wider than the portlet - is flush with the portlet frame on the right edge (e.g.) ans "spills out" of it at the left? Hints?

can't get it to work

Posted by Mark Oehlberg at May 24, 2006 - 19:40

I keep getting: AttributeError: portlet_document_view in my error log and my page spews out a huge error page. I followed these instructions exactly and tried to tinker around with the paths but nothing I do seems to work.

Naming

Posted by Martin Aspeli at May 24, 2006 - 23:28
Almost certainly, the object isn't called portlet_document_view. Did you create the page template through-the-web, in portal_skins/custom? If so, did you give it a name 'portlet_document_view'? Or if you put it on the filesystem, did you give it a name 'portlet_document_view.pt' (note the extension is only used in a filesystem based product)? Can you see it in one of the subfolders of portal_skins?

WARNING: this causes my zope to spin

Posted by Floyd May at May 24, 2006 - 21:09

Trying this (and variants of it) caused my zope to eat itself (100% CPU, no responding). I recommend trying a different approach.

Well...

Posted by Martin Aspeli at May 24, 2006 - 23:25
There could be any number of reasons why that may happen, which may either be your fault or the fault of some product you have installed. Google "debug spinning Zope" and then get back to me. This code does work, at least for a lot of people including customers of mine.

Note that when 2.1.3 is out and I find some time, there will be a much simpler and more reliable way to do this, and I'll try to update this.

The template I'm using for Plone 2.5

Posted by Jon Stahl at August 30, 2006 - 16:49
looks like this...

<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
i18n:domain="plone">
<body>
<div metal:define-macro="portlet" tal:omit-tag="">
<tal:block>
<dl class="portlet" tal:attributes="id here/id">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a tal:attributes="href here/title_or_id">Title</a>
<span class="portletTopRight"></span></dt>
<dd class="portletItemSingle odd" tal:content="structure here/CookedBody">Content</dd>
<dd class="portletFooter">
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
</tal:block>
</div>

i18n expansion

Posted by Lars Reimann at November 1, 2006 - 10:26
hi, portlets are working fine with this method.

however, my content is not translated into the second language available on my site.
ive translated it via plone but the translated content is not displayed when switching languages.
is there a way to enhance this method of portlet creation to support multi-language?

Need to fetch the translation first

Posted by Alexander Pilz at September 11, 2007 - 12:09
You could try to fetch the translation of the current context to the current default language. The following works for me:

<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
i18n:domain="plone">

<body>

<div metal:define-macro="portlet" tal:omit-tag="">
<tal:block define="heretrans here/getTranslation">

<dl class="portlet" tal:attributes="id heretrans/id">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a tal:attributes="href heretrans/id" tal:content="heretrans/Title">Title</a>
<span class="portletTopRight"></span>
</dt>

<dd class="portletItem odd" tal:content="structure heretrans/CookedBody">Content</dd>

<dd class="portletFooter">
<a href=""
class="tile"
tal:attributes="href heretrans/id"
i18n:translate="box_morelink">
More&hellip;
</a>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
</tal:block>
</div>
</body>
</html>

Works Perfectly

Posted by Autumm Caines at November 6, 2006 - 17:53
This approach worked very well for me, no errors, simple and easy

How can I add a form folder in a portlet using a similar method?

Posted by Jagadish Metla at March 24, 2007 - 20:53
Thank you for the info. The approach worked for my document content. I want to also make a portlet slot for a a Form Folder with its contents (fields and action adapters). Can we accomplish it by a similar approach? I am not sure what I should edit here to suit form folder contents:

<dd class="portletItemSingle odd" tal:content="structure here/getBody">Content</dd>

thanks in advance,

Jagadish

A little trouble

Posted by Joe Ersinghaus at April 10, 2007 - 20:48
I'm getting a 'Site Error' upon browser refresh when I add 'portal/portlets/info/portlet_document_view' to "right_slots" in properties.

1. I've placed portlet_document_view.pt in my skin product template directory. Is this the right place for it?

2. In the "Add a document with the id info" step - I created an html "Page" within the plone folder "portlets". Is this correct?


Thanks,
Joe

System is Plone 2.5.2/Enfold Server 3.0

A little help

Posted by Martin Sorg at April 13, 2007 - 22:07
I run in the same problem. When I renamed the portlet "portlet_document" instead of "portlet_document_view" it worked.

Plone 3.0?

Posted by Bruce Bolingbroke at October 24, 2007 - 20:12
Can this approach also work with Plone 3.0?

You don't need it

Posted by Martin Aspeli at October 24, 2007 - 21:15
It may work via a Classic Portlet, I haven't really tried it.

However, there's a better way in Plone 3. Just install the plone.portlet.static portlet and you can edit it from the "Manage portlets" page, right in the portlet configuration.

There is one problem, though - the edit widget is just a text box, there's no WYSIWYG editor (kupu). We'll have this resolved reasonably soon, though - it's implemented on a branch of plone.app.form, which should make it into Plone 3.1. You can use it already (it's the fschulze-optilude-usw branch) if you're feeling adventurous.

Martin

plone.portlet.static portlet

Posted by Bruce Bolingbroke at October 24, 2007 - 21:25
Thanks for the quick response Martin. Sorry for the n00b question, but how do I install/where do I find the plone.portlet.static portlet?

Use a buildout

Posted by Martin Aspeli at October 24, 2007 - 21:32
Take a look at http://plone.org/documentation/tutorial/buildout, in particular http://plone.org/documentation/tutorial/buildout/installing-a-third-party-product. You can just list plone.portlet.static in the eggs and zcml sections of your buildout.cfg, and it should work.

i18n

Posted by Bruce Bolingbroke at October 30, 2007 - 20:10
Martin,

One of the above posts has an i18n fix which allows us to translate the page with the portlet content. It works beautifully with plone 2.5.x. Unfortunately, it looks like plone.portlet.static portlet has no translation support, right?

Bruce

How To do this with Images

Posted by Janusz at August 26, 2008 - 00:58
I don't understand, should i replace tal:content="here/title_or_id" , with id of the image? "here/my-image" ???
Where exactly is the path to the image?

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by