Aller au contenu. | Aller à la navigation

Outils personnels

Navigation

Vous êtes ici : Accueil / Articles / Creating a viewlet with five.grok

Creating a viewlet with five.grok

Par Vincent Fretin publié 07/07/2009 11:40, Dernière modification 28/01/2010 14:36
I show you how to use five.grok to easily insert a warning box when an ATDocument is expired.

I already talked about five.grok to create viewlets. In this article, I show you how to use five.grok to easily insert a warning box when an ATDocument is expired.

I assume you have the paster and i18ndude commands in your PATH. I generally install those eggs in a virtualenv like that:

$ virtualenv -p /usr/bin/python2.4 dev
$ . dev/bin/activate
(dev)$ easy_install ZopeSkel
(dev)$ easy_install i18ndude

Creating a Plone buidlout with grok

Start by creating a Plone 3.3rc3 buildout with paster create -t plone3_buildout and look at five.grok's buildout.cfg (svn co http://svn.zope.org/repos/main/five.grok) to see how to add latest five.grok to your buildout.

Finally your buildout.cfg should look like this:

[buildout]
parts =
    zope2
    instance
extends = http://dist.plone.org/release/3.3rc3/versions.cfg
versions = versions
find-links = http://dist.plone.org/release/3.3rc3
eggs =
develop =

[versions]
five.grok = 1.0b1
grokcore.annotation = 1.0.1
grokcore.component = 1.7
grokcore.formlib = 1.1
grokcore.security = 1.0
grokcore.site = 1.0.1
grokcore.view = 1.7
grokcore.viewlet = 1.0
martian = 0.11
zope.app.publisher = 3.5.1
zope.app.zcmlfiles = 3.4.3
zope.component = 3.4.0
zope.i18n = 3.6.0
zope.securitypolicy = 3.4.1

[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}
skip-fake-eggs =
   zope.app.publisher
   zope.component
   zope.i18n

[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
user = admin:admin
http-address = 8080

eggs =
    Plone
    ${buildout:eggs}
    five.grok

zcml =
    five.grok-meta
    five.grok

Creating a plone product

Now go to the src directory, create a plone product:

$ paster create -t plone my.viewlets
Enter namespace_package (Namespace package (like plone)) ['plone']: my
Enter package (The package contained namespace package (like example)) ['example']: viewlets
Enter zope2product (Are you creating a Zope 2 Product?) [False]:
Enter version (Version) ['1.0']:
Enter description (One-line description of the package) ['']: My viewlets with Grok
[...]

Edit my.viewlets/setup.py to declare the egg as as Plone plugin. The end of the file should look like this:

entry_points="""
[z3c.autoinclude.plugin]
target = plone
""",
)

Return to parent directory and modify your buildout.cfg to add my.viewlets:

[buildout]
develop =
    src/my.viewlets

[instance]
eggs =
    ...
    my.viewlets

Then execute:

python2.4 bootstrap.py
bin/buildout

Creating a viewlet with grok

Then go to src/my.viewlets/my/viewlets directory. All paths mentioned below are relative to this directory.

Content of the viewlets.py module:

from five import grok
from plone.app.layout.viewlets.interfaces import IBelowContentTitle
from Products.ATContentTypes.interface.document import IATDocument

grok.templatedir("templates")

class ExpiredContentViewlet(grok.Viewlet):
    grok.viewletmanager(IBelowContentTitle)
    grok.context(IATDocument)

Create a templates directory with a expiredcontentviewlet.pt template file in it:

<dl tal:condition="context/isExpired"
    class="portalMessage warning">
  <dt i18n:domain="plone"
      i18n:translate="">
    Warning
  </dt>
  <dd i18n:domain="my.viewlets"
      i18n:translate="text_expired_document">
    This document is expired since
    <span i18n:name="expiration_date"
          tal:define="plone_view context/@@plone"
          tal:replace="python:plone_view.toLocalizedTime(context.ExpirationDate(), long_format=1)">
      expiration date
    </span>.
  </dd>
</dl>

Content of the configure.zcml file:

<configure xmlns="http://namespaces.zope.org/zope"
           xmlns:grok="http://namespaces.zope.org/grok"
           xmlns:i18n="http://namespaces.zope.org/i18n"
           i18n_domain="my.viewlets">

  <i18n:registerTranslations directory="locales" />

  <grok:grok package=".viewlets" />

</configure>

For now, create an empty locales directory.

Start your instance with bin/instance fg, create a Page (ATDocument) and set the expire date to yesterday. Voilà!

expired_doc.png

Localization of the product

Now I'll show you how to localize your product product.

Create an update-l10n.sh script:

i18ndude rebuild-pot --pot locales/my.viewlets.pot --create my.viewlets .
i18ndude sync --pot locales/my.viewlets.pot locales/*/LC_MESSAGES/my.viewlets.po

Make the script executable:

chmod u+x update-l10n.sh

Execute the script:

./update-l10n.sh

It will failed for the the i18ndude sync because there is no translations yet, that's fine. The i18ndude rebuilt-pot command generate the locales/my.viewlets.pot file which contain all extracted strings to be translated.

Create a folder for the french translation:

mkdir -p locales/fr/LC_MESSAGES/

Initialize a french translation. I usually do this with msginit command (install the gettext package on Ubuntu to have the command):

msginit -i locales/my.viewlets.pot -o locales/fr/LC_MESSAGES/my.viewlets.po

This command do a copy of the pot and modify some headers in the po file. Now open locales/fr/LC_MESSAGES/my.viewlets.po and finish to modify the headers:

"Language-Code: fr\n"
"Language-Name: French\n"
"Domain: my.viewlets\n"

Replace all PACKAGE by my.viewlets. You can remove VERSION and remove the first comment "PLEASE EDIT THE LINES BELOW CORRECTLY". Perfect!

Now open the file with poedit for example and translate the only string you have. The french translation is:

Ce document est expiré depuis ${expiration_date}.

If you need to generate again the pot file and synchronize all translations, execute again ./update-l10n.sh.

Restart your instance to see the french translation.