Creating portlets with editable static content
This How-to applies to:
Plone 2.1.x
This How-to is intended for:
Integrators, Customizers
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
portletsin 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 Templatein yourportal_skins/customdirectory.
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
Propertiesand 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_viewthat 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_slotsorright_slotsproperty 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 newlinesproperty 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.
GRRR!
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?
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
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
WARNING: this causes my zope to spin
Trying this (and variants of it) caused my zope to eat itself (100% CPU, no responding). I recommend trying a different approach.
Well...
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
<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
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
<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…
</a>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
</tal:block>
</div>
</body>
</html>
Works Perfectly
How can I add a form folder in a portlet using a similar method?
<dd class="portletItemSingle odd" tal:content="structure here/getBody">Content</dd>
thanks in advance,
Jagadish
A little trouble
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
Plone 3.0?
You don't need 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
Use a buildout
i18n
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
Where exactly is the path to the image?
"scale='thumb'" not working
"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: