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>
TODO:
* <missing feature which must be implemented still>
* <an issue which still needs to be fixed>
-->
</tal:block>
<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>
</ul>
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.
Caching¶
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:
WebSection_getSiteMapTree
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.
URLs¶
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¶