Most Powerful Open Source ERP

How To Create New Widget

How To showing how to create new widgets in a stable and efficient manner.
  • Last Update:2016-02-09
  • Version:001
  • Language:en

Creating widgets is really easy. After all, it is nothing more than writing a page template to produce HTML which will be invoked by an Editor Field from an ERP5 Form which acts as the layout for a Web Section.

However, our experience is that most widgets, even for the simplest purpose, are not well written and lead to performance or stability issues in Web Sites. We would like to give here a couple of advice to write better widgets.

Table of Contents

The Basics

Here is an example of widget:

<tal:block replace="nothing">
  This widget displays <explain here what it does>
    * <missing feature which must be implemented still>
    * <an issue which still needs to be fixed>

<ul tal:define="current_web_section python:request.get('current_web_section', here)">
  <li tal:repeat="subsection python:current_web_section.WebSection_getSiteMapTree(depth=1)"><a href="#" tal:content="subsection/translated_title"
  tal:attributes="href subsection/url">Menu item</a></li>

Let us review the good practices which were followed:

  • the widget tries to use the variables provided in the REQUEST by erp5_web rendering code (aggregate_render). The variable is named current_web_section. Using REQUEST variables is a must to accelerate rendering and to stop reinventing the wheel. If you think more variables should be provided, then extend aggregate_render and/or contribute to erp5_web.
  • if the current_web_section is not available in the REQUEST, it uses the current context. This way, developers can test the widget by invoking the Page Template on a given section.
  • it tries to list objects by invoking a generic method (WebSection_getSiteMapTree) provided by erp5_web. Again, use generic methods provided by ERP5 rather than reinventing the wheel and forget something.
  • it translates content by using the translated_title property rather than the using custom TAL or even forgetting to translate. 'translated_title' and getTranslatedTitle is the best and most generic way to translate a title because they use a message catalog which depends on the portal type and possibly on the context.
  • it uses the url parameter provided by WebSection_getSiteMapTree. Make sure that you use the appropriate URL generation method when writing a widget.
  • it uses caching, but this is something which we can not see on the code since it is a property in the ZODB.


Association a widget to one of the default caches of ERP5 Web (web_site_ram_cache, web_section_ram_cache, etc.) can dramatically improve performance.

Currently, this only works for Page Template, Image, etc. But it will soon work too for ERP5 Forms. The default caches provide the following behaviour:

  • web_site_ram_cache: caches results per web site and per language
  • web_section_ram_cache: caches results per web section and per language
  • web_site_user_ram_cache: caches results per web site, per user and per language
  • web_section_user_ram_cache: caches results per web section, per user and per language

Other caches (ex. http_cache) do not apply for widgets. If you want to cache content with HTTP cache, use gadgets.

Listing Documents

If you need to display a tree of documents, a list of sections, a site map, etc. use:


and if it is not enough, try to extend it to make it more universal, more convenient, etc.

if you need to display a list of documents, always consider the following:

  • define the list of documents and the properties to display with a ListBox
  • create a ListBox renderer if the default ones are not sufficient
  • wrap everything into a page template until ERP5 Forms become cacheable (which is going to happen sooner or later)

By doing it this way, you create a strict separation between:

  • the renderer which produces the HTML code and which is implemented as a Page Template invoked by the ListBox field
  • the data mapper which is implemented by the ListBox field, which creates the list documents to display and maps their properties to those required by the renderer

One could for example create a list of articles with title, date, summary, author, number of comments by creating:

  • a ListBox field to list selected articles
  • a ListBox renderer Page Template to render articles into something which looks like a blog

The same renderer could be used by another ListBox field to render the latest products in an online shop, the latest support tickets, etc. By splitting the listing logic from the rendering logic, a given renderer can be reused in different situations.


There are 2 kinds of URLs in an ERP5 web site:

  • Those generate by absolute_url which represent the physical location of an object in the context of given virtual hosting environment. absolute_url is suitable for Web Sections, Web Sites, to display a specific page in a given version and language or for objects which do not support getPermanentURL
  • Those generated by getPermanentURL which represent a kind of abstract reference to a given content which is independent of its version, language, etc.

Never use anything else. Never use in particular getUrl, getPhysicalPath, getRelativeUrl

Related Articles