Guillaume Kulakowski : leZRSS 1.0 RC1 (template pour flux RSS dans eZ Publish)

A mon avis, le gros défaut du module de syndication d'eZ Publish est le fait de ne pas faire appel au système de template.

Dans le cadre d'un site web classique, cela ne dérange pas, mais dans le cas d'un planet comme celui de Fedora-Fr j'avais des besoins particuliers :

  • L'URL du billet n'est pas l'URL de l'objet eZ mais celui du billet sur le blog de provenance
  • L'ajout des hackergotchis

Dans un cadre plus professionnel citons aussi qu'il m'arrive de détourner le système de RSS pour faire, par exemple, du podcast.

Bref, en voyant des allusions au système d'export RSS dans les notes de version d'eZ Publish 4.3 alapha 1, j'étais confiant en une telle implémentation mais malheureusement ce n'est toujours pas le cas. C'est donc pour palier à cette lacune que j'ai développé leZRSS.

Qu'est-ce que leZRSS apporte ?

  • Le module rss2/feed identique à /rss/feed mais utilisant le système de template (override possible selon le type d'objet).
  • Un opérateur fetch permettant de récupérer la liste de tous les flux RSS de la plateforme.

Je n'ai pas encore proposé cet extension sur la forge d'eZ Publish car le secteur des flux RSS est déjà pas mal squatté et je n'avais pas envie de faire un YARSSE (Yet Another RSS Extension). Donc le projet est hébergé sur ma forge.

Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Guillaume Kulakowski le 28/02/2010 14:01

Gilles Guirand : eZ Find et ses utilisations alternatives : Faire un nuage de tags

eZ Find Logo

eZ Find est une extension native d'eZ Publish, maintenant disponible dans les diverses installations du CMS. Mon précédent billet donne une courte définition du fonctionnement d'eZ Find, de son couplage avec Solr, et de sa relation avec les datatypes.

eZ Find est généralement présenté et vendu comme un moteur de recherche, et les utilisateurs (et développeurs) peuvent donc s'attendre à un mécanisme du type :

  • Je saisie une expression libre
  • J'envoie ma recherche
  • J'obtiens une liste de résultat, et j'applique quelques tris (alphabétique, dates, pertinence) et quelques filtres disponibles (par rubriques, par facettes, etc.)

Cependant, le cadre d'exploitation d'eZ Find est plus vaste que ce schéma fonctionnel. Ce billet décrit un cas d'utilisation certes relativement inutile mais signification d'une utilisation alternative d'eZ Find : construire un nuage de tags.

A partir d'un exemple simple, on peut facilement en déduire d'autres cas d'utilisation qui facilitent énormément le développement de certains projets, comme par exemple les agrégateurs de contenus, les portails et autres mécanismes de navigations complexes dans un catalogue.

Comment construire un nuage de tags sur eZ Publish ?

La seule méthode un peu optimisée et fonctionnelle de procéder actuellement est l'utilisation d'un opérateur de template qui explore la base de données, et notamment la table ezkeyword. Le package ezwebin propose l'opérateur eztagcloud, qui est facile à déployer et à utiliser.

  • Voici un exemple d'appel de l'opérateur dans un template
<div>
   {eztagcloud( hash( 'class_identifier', 'billet', 'parent_node_id', 2 ) )}
</div>
 

Avantages de l'opérateur

Les fonctions fetch natives ne permettent pas de lister un ensemble de keywords en fonction des paramètres utiles (subtree, classes, etc.), c'est donc la seule façon "économique" et "optimisée" de procéder. Les opérateurs permettent souvent aux développeurs eZ Publish avancés d'optimiser certains traitements, en économisant le nombre de requêtes SQL par exemple, ou en facilitant certains algorithmes laborieux à transposer avec le langage de template (par exemple le calcul des pourcentages des styles CSS inline dans cet opérateur)

Inconvénients de l'opérateur

L'écriture de ce type d'opérateur est peu accessible aux développeurs occasionnels, et la manipulation du SQL est une pratique dangereuse si le modèle de données eZ Publish est mal maîtrisé (prise en compte des versions, des visibilités, des langues, des droits...). Par ailleurs cet opérateur encapsule la logique algorithmique du calcul des pourcentages transmis au "font-size" en style inline. Les amoureux du CSS full externe, ou de l'accessibilité devront donc adapter cet opérateur à leur besoin.

Comment construire un nuage de tags avec eZ Find ?

Comprendre le concept de facettes

Derrière ce terme "géométrique" se cache un concept finalement assez simple et naturel, que l'on pourrait appeler : "groupement des résultats pour un champs", à savoir :

  • Supposons qu'un résultat de recherche contienne 100 billets
  • Sur ces 100 billets, on peut lister 20 mots clés distincts associés
  • Parmi ces 20 mots clés, le mot clés A est associé à 10 billets, le mot clés B est associé à 5 billets, et ainsi dessuite

On peut transposer cet exemple sur tous les attributs et meta données d'une classe (name, dates, auteur, attribut quelconque), et même obtenir N listes de facettes sur N attributs et méta différents

Construite le nuage de mots clés avec des facettes

Cet exemple de code montre comment construire sa requête eZ Find, récupérer les facettes résultantes sur l'attribut "tags" de type "keywords", et gérer le poids des keywords en fonction d'un algorithme simplifié (j'ai un peu triché sur cet aspect, puisque ce n'est pas l'objet de la démonstration).

{def $search_keywords=fetch( ezfind , search,
      hash( query , '',
        'facet', array( 
            hash('field', 'billet/tags', 'sort', 'alpha', 'limit', 100 )),
        'class_id', array('billet'),
        'filter', array('not', 'billet/tags:""'),
        'subtree_array', array(2)
        ))}
    
{def $search_extras_keywords=$search_keywords['SearchExtras']}
{def $search_count_keywords=$search_keywords['SearchCount']}
 
<li id="blog_block_{$bloc_count}" class="colonne_block">
   <h1>Tags ezfind :</h1>
    
    <div class="tagclouds {$current_css}">
    {foreach $search_extras_keywords.facet_fields[0].nameList as $facetID =&gt; $name}
                
        {def $keyword_count = $search_extras_keywords.facet_fields[0].countList[$facetID]}
        {def $percent = $keyword_count|div( $search_count_keywords )|mul( 200 )|floor|sum( 100 ) }
            <a href={concat( $root_blog_node.url_alias, '/(tag)/', $name )|ezurl()} style="font-size: {$percent}%" title="{$keyword_count} billets taggés '{$name}' // ">{$name|wash()}</a>, 
        {undef $percent}
 
    {/foreach}
 
    </div>
</li>
{undef $search_extras_keywords $search_keywords $search_count_keywords}
 

Quelques astuces & clés de compréhensions

  • La recherche sur une chaine vide (query , '') est une technique permettant d'explorer l'ensemble des contenus indexés, en appliquant uniquement les filtres et limitations utiles (class_id, subtree_array par exemple)
  • L'opérateur 'NOT' n'est pas natif et nécessite un petit 'hack' proposé par Bruce Morrison, qui sera sans doute disponible dans les futures versions d'eZ Find
  • Par défaut les facettes sur des datatypes 'keywords' sont présentés en minuscule. Ce n'est pas un bug, mais une fonctionnalité visant à homogénéiser la casse sur les syntaxes similaires (eZ Publish, ez Publish, Ez Publish, etc.). Cependant lorsqu'on est confiant dans la qualité de sa saisie (puisqu'on utilise une extension d'autocomplétion par exemple), il peut être souhaitable de ne pas forcer l'utilisation du minuscule. Pour cela il faut désactiver le filtre solr.LowerCaseFilterFactory dans le fichier /extension/ezfind/java/solr/conf/schema.xml
<!-- eZ Find: This field type is dedicated to ez publish keywords.  --> 
<fieldtype name="keyword" class="solr.TextField" positionIncrementGap="100"> 
     <analyzer type="index"> 
       <tokenizer class="solr.PatternTokenizerFactory" pattern=", *" /> 
       <filter class="solr.TrimFilterFactory" />               
       <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> 
       <!--<filter class="solr.LowerCaseFilterFactory"/>--> 
       <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> 
     </analyzer> 
     <analyzer type="query"> 
       <tokenizer class="solr.PatternTokenizerFactory" pattern=", *" /> 
       <filter class="solr.TrimFilterFactory" /> 
       <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> 
       <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> 
       <filter class="solr.LowerCaseFilterFactory"/> 
       <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> 
     </analyzer> 
</fieldtype>
 
Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Gilles Guirand le 23/02/2010 00:11

Charles-Christian Croix : MySQL Innodb nouvelle notes de configuration et d'optimisation

Pour compléter une note précédente sur Innodb et UTF8 et le billet sur les premières notes de configuration et d'optimisation de MySQL Innodb voici quelques notes de configuration de MySQL supplémentaire et complémentaire avec le moteur de base de donnée Innodb. Note toujours valable _ pour toute solution d'hébergement ou architecture MySQL est... Lire MySQL Innodb nouvelle notes de configuration et d'optimisation

Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Charles-Christian Croix le 16/02/2010 10:23

Jean-Luc NGUYEN : 01 Informatique : article à lire sur le statut de salarié et auto-entrepreneur

Aujourd’hui est paru 01 Informatique de cette semaine où apparait un article concernant une entrevue avec un développeur LAMP eZ Publish, salarié et auto-entrepreneur, très intéressant, à lire donc.

http://acidre.com/presse-statut-auto-entrepreneur/

Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Jean-Luc NGUYEN le 11/02/2010 23:43

Gilles Guirand : My gandbox.fr's slides talk from the 2010 eZ Community Day in Geneva

On 2010 January 21, for the eZ Community Day in Geneva, i tried to tanslate in english language some of my "french" blog posts i write on http://www.gandbox.fr. There is my "english" slides from this talk :

List of the french blog post i used for my talk

Working with Google Maps :

Building an UWA Widget (Netvibes / iGoogle) :

Building a custom RSS :

Slideshare presentation

Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Gilles Guirand le 24/01/2010 22:08

Damien Pobel : Nouveau serveur

Après les déboires récents de mon premier serveur Dedibox, j'ai reçu courant décembre un mail m'annonçant la fin du support de ma Dedibox V1 fin janvier 2010 et l'obligation de migrer vers une autre machine. J'envisageais depuis un bon moment de changer de serveur, cela n'a fait que précipiter les choses. Et j'ai finalement choisi un serveur Kimsufi 750G qui semble mieux fourni que les Dedibox XL pour le même prix (aux frais d'installation près si on paie pas à l'année).

La migration à l'identique est quasiment terminée mais je compte bien exploiter au mieux les 4Go de RAM (quel changement en comparaison du Go que j'avais avant). Je vais m'intéresser de plus près à la configuration de MySQL pour exploiter ces nouvelles ressources et je vais enfin pouvoir installer l'extension eZ Find sur mes différents sites eZ Publish.

En attendant un rapide benchmark sur pwet.fr avec siege sur les 200 pages les plus vues m'a montré que cette machine est capable de servir quelque chose comme 40 pages / seconde sans broncher là ou l'ancienne machine était capable de servir péniblement 7 pages / secondes. Il y a de la place pour quelques nouveaux projets!

Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Damien Pobel le 17/01/2010 23:42

Gilles Guirand : eZ Find et la gestion des datatypes

J'ai publié une "mini" contribution sur la gestion des relations d'objet(s) dans eZ Find. Cette contribution est relativement confidentielle (exploitation marginale), mais constitue une bonne occasion pour présenter le fonctionnement d'eZ Find et sa relation avec les datatypes. eZ Find est une extension encore sous exploitée, alors qu'elle constitue une avancée majeure d'eZ Publish sur la cible "système d'information professionnel", au côté des extensions EZSI ou encore CMIS.

Voir la page du projet ezfsolrdocumentfieldobjectrelation

eZ Find en quelques mots "faciles à comprendre"

  • eZ Find est une "interface" entre eZ Publish (le CMS) et Solr (le moteur de recherche)
  • Solr est un moteur de recherche autonome, qui s'exécute comme un service JAVA, et qui fonctionne en mode REST, à savoir :
    • Lors d'une publication, eZ Find prépare le contenu dans une URL et le "pousse" vers Solr (HTTP)
    • Lors d'une recherche (full text, filtres, facettes), eZ Find prépare la question dans une URL et demande à eZ Find la réponse

Toutes ces opérations complexes sont "masquées" pour le développeur, qui doit uniquement se soucier de bien formuler ses requêtes dans son habituel langage de template : fecth( ezfind, search, params...). La puissance d'eZ Find réside dans cette simplicité d'exploitation, au profit de le puissance fonctionnelle de Solr et des "questions" que l'on peut formuler, notamment sur la pertinence (façon google) ou sur les classifications à facettes.

eZ Find est les datatypes

eZ Publish fonctionne sur le concept de "datatype", à savoir des types de données "riches" permettant de représenter des lignes de textes, des numériques, des dates, mais aussi des types de données plus complexes ou exotiques comme des images, des vidéos, des relations d'objet(s) ou de la géolocalisation. eZ Publish permet également de définir ses propres datatypes, on peut donc comprendre que les correspondances entre les types de données eZ Publish et les types de données Solr nécessite quelques paramétrages, selon 2 cas de figures :

  • Les correspondances de données parfaitement symétriques : ligne de texte = string
  • Les correspondances de données "sur mesure" : relations d'objets (et gestion des sous attributs)

Pour définir ces correspondances eZ Find propose un fichier de paramétrage extension/ezfind/settings/ezfind.ini

Fonctionnement de la classe ezfSolrDocumentFieldObjectRelation

L'aspect "sur mesure" de la correspondance entre les datatypes eZ Publish et les types de données eZ Find implique un "point de vue" de développement dans la façon de gérer les cas particuliers et complexes. L'indexation des relations d'objets multiples est une bonne illustration de l'éternel dilemme du développeur : "jusqu'où faut-il aller ?"

Comportement natif de ezfSolrDocumentFieldObjectRelation

Tous les objets en relation permettent de générer un unique champs "text" par concaténation de tous les attributs de tous les objets. On obtient ainsi un contenu indexé de type "objet1/attribut1 objet1/attribut2 objet2/attribut1 objet2/attribut2". Cette logique est tout à fait adaptée à la recherche "full text", mais inadaptée à l'exploitation de facette. Pour un objet en relation dont le "name" est "mon objet en relation", on obtient les facettes suivantes sur "myclass/myattribute" :

  • "mon" (10 résultats)
  • "objet" (3 résultats)
  • "en" (30 résultats)
  • "relation" (5 résultats)

Comportement de l'évolution ezfSolrDocumentFieldObjectRelation

La gestion des facettes devient possible, en spécifiant un attribut en particulier ou alors en invoquant le "name". La page du projet montre quelques exemples de codes basiques. En exploitant l'exemple précédent, on obtient alors l'unique facette suivante :

  • "mon objet en relation" (3 résultats)

Gestion des filtres de type string

Un fois les facettes générées, il est nécessaire de construire le lien permettant de filtrer les résultats par "mon objet en relation". eZ Find (ou plutôt Solr) exige logiquement que les chaînes de caractères (string) soient encapsulées par des "doubles côtes".

Cet extrait de code (un peu complexe) montre comment étendre le search.tpl pour générer des filtres pour les chaînes de caractères : filtres par "text line", "keywords" ou "relation d'objet(s)"

{foreach $search_extras.facet_fields[$index].nameList as $facetID =&gt; $name}
  {if $name|trim|count_chars|gt(0)}
    <li>
      {if $search_extras.facet_fields[$index].field|compare('facet_fields')}
       {def $url_link = concat($search_extras.facet_fields[$index].queryLimit[$facetID]|explode(':').0,':"',$name|urlencode,'"')}
      {else}
       {def $url_link = $search_extras.facet_fields[$index].queryLimit[$facetID]|wash}
      {/if}
      <a title="{$search_extras.facet_fields[$index].countList[$facetID]} Réponse(s) trouvée(s) dans les '{$name|wash}' // " href={concat( $baseURI, '&facet_field=', $facetField|wash, '&filter[]=', $url_link )|ezurl}>{$name|wash}</a> ({$search_extras.facet_fields[$index].countList[$facetID]})
      {undef $url_link}
    </li>
  {/if}
{/foreach}
 
 

A noter : L'opérateur urlencode n'est pas natif (fonction PHP) et doit être déclaré dans template.ini.append.php :

  • PHPOperatorList[urlencode]=urlencode
Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Gilles Guirand le 13/01/2010 21:33

Guillaume Kulakowski : Bonne année : 2010 année du changement

Bonne année à tous !

Certains l'auront peut-être remarqué, mais j'ai moins blogué cette année que les années précédentes. Les raisons en sont essentiellement les suivantes :

  • Moins d'activité personnelle au sein du groupe des ambassadeurs du Projet Fedora. Je lui préfère actuellement le groupe Package Maintainers. La raison est surement que je fais de plus en plus de commerce/marketing et de moins en moins de dev' pure à mon travail, je compense donc avec Fedora-Fr et le Fedora Project.
  • Moins de temps (nouvel appart', vie de couple, pas mal de taf', etc.).
  • La concurrence de Twitter : en effet, plus je Twitt' et malheureusement moins je blog (ça mériterait une étude sociologique au sein de la blogosphère ;-).)
  • Peut-être aussi moins de trucs intéressant à dire ?

Je vais donc essayer de faire mieux en 2010, surtout que des projets intéressants arrivent :

L'année 2010 sera aussi pour moi un grosse année de changement. En effet :

  • Je vais achever ma vie de célibataire et me marier (Juin 2010) avec Emma.
Voila, que l'année 2010 soit au moins aussi bonne que la 2009 !
Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Guillaume Kulakowski le 11/01/2010 11:50

Jérôme Vieilledent : Utilisation d'un SSO dans eZ Publish

Parfois, lors du développement d'une application web, il est nécessaire de s'interfacer avec le ou les logiciels et/ou sites web du client afin de garder une session commune et cohérente au sein de sa bulle applicative.

Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Jérôme Vieilledent le 18/12/2009 17:02

Jean-Luc NGUYEN : eZ Publish : saisir du contenu directement en HTML

Un petit tip pour ceux qui souhaitent saisir du contenu directement en HTML sans filtrage d’eZ Publish dans l’extension ezoe :

Surcharger le fichier content.ini :

[literal]
AvailableClasses[]
# The class 'html' is disabled by default because it gives editors the
# possibility to insert html and javascript code in XML blocks.
# Don't enable the 'html' class unless you really trust all users who has
# privileges to edit objects containing XML blocks.
AvailableClasses[]=html

Voilà ! C’est surtout à activer lorsque ce n’est pas une assistante de communication qui est responsable du contenu, mais plutôt un webmaster qui désire maitriser le HTML avec des classes CSS de partout pour du HTML complexe. Fini les hacks ou les FCKEditor… Et le contenu reste en BDD en XML !

Bookmark logos Delicious Blogmark Google Bookmark Linkedin Yahoo! Bookmark Partager sur Facebook Twitter Publié par Jean-Luc NGUYEN le 17/12/2009 16:11