Damien's avatar

Damien Pobel / blog

Curious geek and (sometimes grumpy) software engineer ;-)

Twig pagelayout pour les modules legacy dans eZ Publish 5

(English version available on share.ez.no)

Je suis en train de mettre à jour le Planète eZ Publish.fr à la dernière version d'eZ Publish 5. J'en profite pour passer en revue les problèmes ou les fonctionnalités manquantes que j'avais recontrés lors de la mise en place de la version avec eZ Publish 5 en décembre dernier. L'un de ces problèmes concernait les différences entre les pages générées par les modules legacy (ezinfo/about, planet/search, ...) et le reste du site. En effet, en 5.0, il n'était pas possible d'utiliser un pagelayout Twig avec un module legacy, et donc le résultat de ces modules étaient toujours injectés dans le bon vieux pagealyout.tpl. À partir des n 2013.4 et 5.1, il est maintenant possible d'utiliser un pagelayout Twig avec les modules legacy. Il s'agit d'une fonctionnalité intéressante dans l'optique d'une mise à jour progressive vers la nouvelle stack, mais certains éléments autour de cette fonctionnalités sont intéressants.

Pour commencer, la version initiale a été ajoutée par Joe Kepley via une pull request. Il mérite un grand bravo pour ça :-)

Ensuite, en travaillant sur une amélioration, j'ai ajouté la possibilité de définir ce pagelayout par siteaccess ou groupe de siteaccess. Il n'y a pas de configuration sémantique, donc pour configurer le pagelayout à utiliser avec les modules legacy, il faut écrire la configuration suivante dans ezpublish.yml :

parameters:
  ezpublish_legacy.planete.module_default_layout: PlanetBundle::pagelayout.html.twig

Dans cet exemple, planete est le nom du siteaccess et la valeur est évidemment le chemin vers le template.

Enfin, avec quelques changements, le même pagelayout peut être utilisé pour les modules legacy comme pour le reste du site. Le principal changement et potentiellement le seul à apporter concerne le block content pour qu'il tienne compte de l'éxécution d'un module legacy. Une simple condition sur la variable module_result permet de détecter le contexte :

<!DOCTYPE html>
<html lang="fr-FR">
<!-- ... -->

<body>
{% block content %}
    {% if module_result %}
        {# we are in a legacy rendered module #}
        {{ module_result.content|raw }}
    {% endif %}
{% endblock %}
</body>
</html>

Rien de compliqué, non ? Il s'agit là d'un des nombreux ponts entre eZ Publish legacy et la nouvelle stack eZ Publish 5. Vous voulez en apprendre plus ? Si j'étais vous, je m'inscrirais à la prochaine eZ UnConference #2. Sans conteste, le moyen le plus rapide de tout apprendre ou presque sur eZ Publish 5!

Mise à jour à 14h30: cette fonctionnalité est documentée avec un exemple utilisant l'héritage de template Twig.

Using the eZ Publish REST API v2 with cURL

Lately, I've been testing and fixing several issues with the eZ Publish REST API v2. To manually test it, I use cURL (man curl) because it's widely available, well documented, and like any other command line tool, you can use it together with others text processing tools (grep, xmllint, xsltproc, ...). I'm writing this post as a memo for me but I'm sure some people will find it useful as well.

The whole REST API v2 is specified in the ezpublish-kernel git repository. Yes, that's a huge document, because the REST API is huge :-) A shorter introduction/documentation is also available in the eZ Publish documentation.

Note: to keep this post short and readable, the command results are not in the post itself but the whole command line session is available on this page

Basic GET requests

Let's start with a simple GET request on the root of the API:

curl -u "admin:ezpublish" -i http://ezpublish5.loc/api/ezp/v2/
  • -u "admin:ezpublish" allows to authenticate on the website with the Basic Auth which is the default authentication method.
  • -i tells the cURL to display the HTTP response headers

By default, the response is formatted in XML. If you prefer to get the result as JSON, you have to specify it by setting the Accept header with the -H parameter:

curl -u "admin:ezpublish" -i -H "Accept: application/json" \
http://ezpublish5.loc/api/ezp/v2/

Of course, it's possible to retrieve more useful data with the REST API, for instance to read the metadata of the /Media folder (id 41):

curl -u "admin:ezpublish" -i \
-H "Accept: application/vnd.ez.api.ContentInfo+json" \
http://ezpublish5.loc/api/ezp/v2/content/objects/41

If you want to get the whole Content with its attributes:

curl -u "admin:ezpublish" -i \
-H "Accept: application/vnd.ez.api.Content+json" \
http://ezpublish5.loc/api/ezp/v2/content/objects/41

The only difference between the last two calls is the Accept header which allows to tell to the system what data I want.

The GET requests allow to read pretty much everything in the content repository. That's cool but we can do cooler tasks provided we enrich our HTTP vocabulary :-)

Publish an image

To publish a content, we have to first create a draft and then to actually publish it.

Create the image draft

The creation of the draft is done with a POST request on /api/ezp/v2/content/objects with a body containing the required and structured data. As for the response, it's possible to use either JSON or XML in input. In the following examples, I use the JSON way:

curl -u "admin:ezpublish" -i -H "Accept: application/json" \
-H "Content-Type: application/vnd.ez.api.ContentCreate+json" \
-H "Expect:" -X POST -d @createimage.json \
http://ezpublish5.loc/api/ezp/v2/content/objects
  • -X POST tells cURL to do a POST request
  • -d @createimage.json tells cURL to put the content of the file createimage.json in the request body. Without the @, the value right after the -d switch is put in the request body.
  • -H "Content-Type: application/vnd.ez.api.ContentCreate+json" indicates that the body of the request is a content create struct in JSON.

The -H "Expect:" might sound a bit weird. Actually, this is to prevent cURL from automatically filling this header in a request with a body which is not really useful in the context of a REST API. If you want to learn more on this header, take a look at the RFC 2616 which defines HTTP 1.1

Publish the draft

Our draft is now created, we just have to publish it, this is done by issuing a PUBLISH request on the resources corresponding to the newly created draft (The content id is taken from the response of the draft creation request).

curl -u "admin:ezpublish" -i -X PUBLISH \
http://ezpublish5.loc/api/ezp/v2/content/objects/135/versions/1

PUBLISH is a custom HTTP verb, depending on various configuration details, this kind of request may not be accepted. In such case, it's possible to emulate it with a POST request having the custom header X-HTTP-Method-Override set to PUBLISH:

curl -u "admin:ezpublish" -i -X POST \
-H "X-HTTP-Method-Override: PUBLISH" \
http://ezpublish5.loc/api/ezp/v2/content/objects/135/versions/1

Both requests do exactly the same. After one of these commands, you should see a new image under the /Media/Images/ called eZ Systems logo created with the REST API.

Screenshot of the
admin interface showing the image created with the REST
API

And then ?

Going over all available operations would be a tad long and useless. In any case, the basics remain the same: with an HTTP request on a given resource eventually with a structured body, you can do all operations on the content repository. That's just awesome!

eZ Community UnConference #2

eZ Unconference #2
banner

La seconde édition de la eZ UnConference se déroulera les 27, 28 et 29 mai 2013 à proximité de Montpellier (à Palavas pour être exact). La première édition était une vraie réussite, je suis sûr que la seconde sera encore meilleure. Déjà, contrairement à Cologne au mois d'Octobre, le soleil est (presque) garanti ;-) et la plage n'est vraiment, mais alors vraiment pas loin!

Au programme, des ateliers sur eZ Publish 5, Symfony 2, l'API REST, la backward compatibility avec eZ Publish 4 et tout autre sujet que vous apporterez sur la partie unconference!

En plus, en plaçant le logo et un lien vers le site de l'évènement, il est possible d'obtenir une réduction de 20%, ce serait dommage de s'en priver.

Et enfin, un espace expert lounge est prévu où il sera possible pendant toute la durée de la UnConference de poser toute sorte de questions techniques à l'ingéniérie eZ et surtout d'obtenir des réponses (on fera le maximum).

Alors, on se voit là bas ?

Theme Gtk2, Gtk3 et Qt4 unifié

Après le changement de disque dur de mon PC portable, j'ai réinstallé Ubuntu 12.10 The Quantal Quetzal. Bien que plutôt agréablement surpris par Unity, celui-ci ne correspond pas à mon usage. En effet, depuis quelques années j'utilise un environnement graphique basé sur Openbox principalement pour ses performances et le fait de pouvoir presque tout faire avec des raccourcis claviers.

Un problème courant avec ce type d'environnement est l'intégration d'applications venant de GNOME ou KDE qui se retrouvent souvent avec le thème par défaut ou des styles complètement différents. Quelques lignes de configuration suffisent à obtenir un ensemble cohérent pour les applications Gtk2, Gtk3 et Qt4.

Pour Gtk2, le fichier ~/.gtkrc-2.0 permet de configurer le thème à utiliser. L'application gtk-theme-switch2 disponible dans le paquet gtk-theme-switch permet de générer une version de base. Le fichier généré inclut le fichier ~/.gtkrc-2.0.mine dans lequel il est possible faire des ajustements par rapport au thème. Le mien est disponible sur Github.

Pour Gtk3, le fichier ~/.config/gtk-3.0/settings.ini permet de régler le thème à utiliser et divers paramètres. Là encore, mon fichier de configuration est disponible sur Github.

Enfin pour Qt4, le fichier de configuration est ~/.config/Trolltech.conf mais celui-ci assez compliqué... Le plus simple est d'installer le paquet qt4-qtconfig qui fournit l'application qtconfig-qt4. Celle-ci permet notamment de choisir Gtk+ comme style d'interface graphique. Les applications Qt prennent alors le même style que les applications Gtk.

Au final, le thème utilisé par les applications écrites avec différents toolkits est cohérent, par exemple entre Firefox (Gtk2), nautilus (Gtk3) et Virtualbox (Qt4), les différences sont minimes :

Theme Gtk2, Gtk3 et Qt4
unifié