[Avancé] GCweb : Ajout de champs personnalisés

le 05/08/2011 dans GCweb #bibliothèque#GCstar#GCweb#php#web

Si comme moi vous avez ajouté des champs personnalisés au sein de votre collection GCstar (voir cet article), vous voudrez sans doute les afficher au sein de GCweb. Or, actuellement, GCweb ne permet pas de récupérer ces champs dans le fichier .gcs de la collection ni, pour l'instant, de les définir manuellement et donc ne les affiche pas. Nous allons voir ici comment faire.

Prérequis

Avant de se lancer, il faut déjà :

Intégration à GCweb

La première étape consiste à faire comprendre à GCweb que notre collection GCstar contient des champs additionnels, autres que les champs par défaut définis pour chacun des types de collection.

La définition des champs pris en compte par GCweb se fait dans le fichier fieldstypes.php qui se trouve dans le répertoire conf/ ; mieux en faire une sauvegarde avant de le modifier.

Une fois ouvert ce fichier, on peut voir que pour chaque type de collection (GCbooks, GCcomics, GCfilms…) est défini une liste (un tableau en fait) de l'ensemble des champs prédéfinis, répartis en fonction de leur type (numeric, date, list…). Par exemple, pour les collections de type GCbooks voilà ce que cela donne :

'GCbooks' => array(
  'numeric' => array('id','rank','pages','rating'),
  'date' => array('publication','added','acquisition'),
  'string' => array('isbn','title','édition','description','comments','translator','artist'),
  'bool' => array('read'),
  'list' => array('authors','publisher','language','serie','format','genre','location'),
  'image' => array('cover','backpic'),
  'unknow' => array(''),
  'url' => array('web')
),

C'est ce fichier qu'il va nous falloir modifier, en ajoutant, pour le type de collection qui nous intéresse, les champs personnalisés en fonction de leut type.

Pour cela, ouvrez dans un éditeur de texte le fichier .gcs de la collection à laquelle vous avez ajouter des champs personnalisés. Vous devriez, au tout début du fichier, voir une balise __ puis une section présentant les champs que vous avez définis, comme cela :

<fields>
  <field displayed="Scénario" flat="true" group="Champs utilisateur" history="true" init="" label="Scénario" type="single list" value="gcsfield1" />
  <field displayed="Dessin" flat="true" group="Champs utilisateur" history="true" init="" label="Dessin" type="single list" value="gcsfield2" />
  <field displayed="Encrage" flat="true" group="Champs utilisateur" history="true" init="" label="Encrage" type="single list" value="gcsfield6" />
  <field displayed="Couleur" flat="true" group="Champs utilisateur" history="true" init="" label="Couleur" type="single list" value="gcsfield3" />
  <field displayed="Lettrage" flat="true" group="Champs utilisateur" history="true" init="" label="Lettrage" type="single list" value="gcsfield4" />
  <field displayed="Divers" group="Champs utilisateur" init="" label="Divers" type="long text" value="gcsfield5" />
</fields>

Il vous faut alors repérer leur identifiant qui se trouve être la valeur de l'attribut value (en fin de ligne), ainsi que leur type. Par exemple, dans mon cas, si je souhaite intégrer à GCweb le champ concernant le scénariste d'une bande dessinée, il me faut ajouter le champ gcsfield1 dans le tableau du type list dans la collection GCbooks. Cependant, plutôt que de modifier les champs pour les collections GCbooks, mieux vaut « créer » un nouveau type de collection (en effet peut-être avez-vous plusieurs collections de type GCbooks et certaines ne sont pas concernées par l'ajout de champs). Ainsi, on copie la section du fichier fieldstypes.php correspondant au type de collection qui nous intéresse et on le colle dessous, on modifie son titre et on rajoute les champs personnalisés. L'exemple suivant rend les choses beaucoup plus claires :

'BD_Perso' => array(
  'numeric' => array('id','rank','pages','rating'),
  'date' => array('publication','added','acquisition'),
  'string' => array('isbn','title','édition','description','comments','translator','artist'),
  'bool' => array('read'),
  'list' => array('authors','publisher','language','serie','format','genre','location','gcsfield1','gcsfield2','gcsfield3','gcsfield4','gcsfield6'),
  'image' => array('cover','backpic'),
  'unknow' => array(''),
  'url' => array('web')
),

Maintenant, GCweb connaît les champs et peut donc les traiter. Il nous reste à voir comment les afficher.

Affichage dans GCweb

Pour afficher le contenu de nos champs personnalisés dans GCweb, il faut modifier les fichiers qui régissent l'organisation des données, qui se trouvent dans templates/default.

Pour chaque type de collection, plusieurs fichiers gèrent l'affichage, en fonction de la vue demandée, cette dernière correspondant au « préfixe » des fichiers. Ainsi, le fichier item_GCbooks.php gère l'affichage des données lorsque l'on accède à la notice complète d'un livre. Pour la collection qui vous intéresse, faites une copie de chacun des fichiers la concernant et renommez-les en remplaçant le type de la collection par le nom que vous avez donné à la section créée précédemment dans le fichier fieldstypes.php. Dans mon cas, j'ai copié tous les fichiers concernant le type GCbooks et les ai renommés en utilisant l'intitulé « BD_Perso » (par exemple item_BD_Perso.php).

Ce sont ces fichiers que nous allons modifier par la suite. Pour ma collection de bandes dessinées, je souhaitais faire apparaître les champs concernant les scénaristes, les dessinateurs, les encreurs, les coloristes et les lettreurs, mais seulement dans la vue présentant l'ouvrage. Il a donc fallu que je modifie le fichier item_BD_Perso.php.

Dans ce fichier, repérez la ligne

  <h2><?php aff($item['title'])?></h2>

qui permet d'afficher le titre du livre dans la vue par item, en dessous de la mosaïque présentant les couvertures. Quatre lignes plus loin, vous devez trouver ce bloc (ou approchant pour un autre type de collection) :

<?php
    if (test($item['authors']))       echo '<li><span class="label">'.__('Auteurs').' :   </span><span class="info">'.filter('authors==',$item['authors']).'</span></li>';
    if (test($item['publisher']))     echo '<li><span class="label">'.__('Éditeur').' :   </span><span class="info">'.filter('publisher==',$item['publisher']).'</span></li>';
    if (test($item['serie']))         echo '<li><span class="label">'.__('Collection').' :</span><span class="info">'.filter('serie==',$item['serie']).'</span></li>';
    if (test($item['genre']))         echo '<li><span class="label">'.__('Genre').' :     </span><span class="info">'.filter('genre==',$item['genre']).'</span></li>';
    if (test($item['isbn']))          echo '<li><span class="label">'.__('ISBN').' :      </span><span class="info">'.convert($item['isbn']).'</span></li>';
    if (test($item['pages']))         echo '<li><span class="label">'.__('Pages').' :     </span><span class="info">'.convert($item['pages']).'</span></li>';
    if (test($item['language']))      echo '<li><span class="label">'.__('Langue').' :    </span><span class="info">'.convert($item['language']).'</span></li>';
    if (test($item['publication']))   echo '<li><span class="label">'.__('Publié le').' : </span><span class="info">'.convert($item['publication']).'</span></li>';
    if (test($item['added']))         echo '<li><span class="label">'.__('Ajouté le').' : </span><span class="info">'.convert($item['added']).'</span></li>';
    if (test($item['web']))           echo '<li><a href="'.convert($item['web']).'">'.__('Source').'</a></li>';
?>

Pour afficher les champs que j'avais créés dans GCstar, voilà comment j'ai transformé ce bloc (bien aidé par jonas sur le forum de GCweb – voir la discussion) :

<?php
  if (test($item['serie']))         echo '<li><span class="label">'.__('Série').' :</span><span class="info">'.filter('serie==',$item['serie']).'</span></li>';
  if (!in_array('Collectif', $item['authors'])) {echo (($item['authors'] != 'Collectif') ? '<li><span class="label">'.__('Auteurs').' :   </span><span class="info">'.filter('authors==',$item['authors']).'</span></li>' : '');}
  echo '<div style="padding-left: 20px;"><hr><span style="font-variant: small-caps;">Détails</span>';
  if (test($item['gcsfield1']))       echo '<li><span class="label">'.__('Scénario').' :   </span><span class="info">'.filter('gcsfield1==',$item['gcsfield1']).'</span></li>';
  if (test($item['gcsfield2']))       echo '<li><span class="label">'.__('Dessin').' :   </span><span class="info">'.filter('gcsfield2==',$item['gcsfield2']).'</span></li>';
  if (test($item['gcsfield6']))       echo '<li><span class="label">'.__('Encrage').' :   </span><span class="info">'.filter('gcsfield6==',$item['gcsfield6']).'</span></li>';
  if (test($item['gcsfield3']))       echo '<li><span class="label">'.__('Couleurs').' :   </span><span class="info">'.filter('gcsfield3==',$item['gcsfield3']).'</span></li>';
  if (test($item['gcsfield4']))       echo '<li><span class="label">'.__('Lettrage').' :   </span><span class="info">'.filter('gcsfield4==',$item['gcsfield4']).'</span></li>';
  echo '<hr></div>';
  if (test($item['publisher']))     echo '<li><span class="label">'.__('Éditeur').' :   </span><span class="info">'.filter('publisher==',$item['publisher']).'</span></li>';
  if (test($item['publication']))   echo '<li><span class="label">'.__('Publié en').' : </span><span class="info">'.filter('publication==',$item['publication']).'</span></li>';
  if (test($item['genre']))         echo '<li><span class="label">'.__('Genre').' :     </span><span class="info">'.filter('genre==',$item['genre']).'</span></li>';
  if (test($item['isbn']))          echo '<li><span class="label">'.__('ISBN').' :      </span><span class="info">'.convert($item['isbn']).'</span></li>';
  if (test($item['pages']))         echo '<li><span class="label">'.__('Pages').' :     </span><span class="info">'.convert($item['pages']).'</span></li>';
  if (test($item['language']))      echo '<li><span class="label">'.__('Langue').' :    </span><span class="info">'.convert($item['language']).'</span></li>';
  if (test($item['added']))         echo '<li><span class="label">'.__('Ajouté le').' : </span><span class="info">'.convert($item['added']).'</span></li>';
  if (test($item['web']))           echo '<li><a href="'.convert($item['web']).'">'.__('Source').'</a></li>';
?>

J'ai apporté quelques modifications supplémentaires (dans la vue en nuage ainsi que dans la recherche avancée) mais l'exemple précédent suffit à saisir la démarche. À vous d'adapter à vos besoins.

Une fois que vous avez fait toutes les modifications souhaitées, uploadez l'ensemble des fichiers de votre modèle vers templates/default/.

Il reste encore une étape à franchir avant de pouvoir admirer le résultat.

Configuration

Pour pouvoir afficher les champs personnalisés définis dans GCstar dans GCweb, nous avons créé un nouveau modèle de collection. Or, GCweb se base sur les informations contenues dans le fichier .gcs de votre collection pour déterminer le modèle à utiliser. Il faut donc « tromper » GCweb et lui indiquer quel modèle utiliser pour notre collection.

Pour ce faire, repérez l'identifiant de votre collection dans GCweb (première collection, identifiant 0, deuxième collection, identifiant 1, etc.) et avec votre éditeur de texte, créez un nouveau document appelé config.complement.php dans lequel vous mettez

<?php
  $conf['collections'][0]['type']='BD_Perso';
?>

en remplaçant bien sûr « 0 » par l'identifiant de votre collection et « BD_Perso » par le nom de modèle que vous avez choisi. Une fois ce document enregistré, il faut l'uploader dans le répertoire conf/ de GCweb et le tour est joué.

Problème(s)

Nuage de tags Année de publication

Cette section du mode « cloud » m'affichait deux messages d'erreur :

Warning: ksort() expects parameter 1 to be array, null given in /var/www/b/bo/bou/boucard.brice.perso.neuf.fr/public_html/mylibrary/inc/func4tpl.php on line 929
 
Warning: Invalid argument supplied for foreach() in /var/www/b/bo/bou/boucard.brice.perso.neuf.fr/public_html/mylibrary/inc/func4tpl.php on line 931

Après avoir sollicité Jonas sur le forum, il a finalement repéré le problème (voir ici) : en effet, « "year" n'est pas un champs de gcstar, il est créer par gcweb à partire d'un champs de "date". » Pour résoudre le problème, il faut éditer le fichier plugins/items_years.php. En effet, vous devriez y trouver cette section :

# collection type GCbooks
if ($collec['type'] == 'GCbooks') {
    if ($item['publication'] != $conf['champVide'])
        $item['year'] = substr($item['publication'],-4);
    else
        $item['year'] = $conf['champVide'];
}

Il faut la modifier en y ajoutant le modèle de votre collection, dans mon cas :

# collection type GCbooks
if ($collec['type'] == ('GCbooks' || 'BD_Perso')) {
    if ($item['publication'] != $conf['champVide'])
        $item['year'] = substr($item['publication'],-4);
    else
        $item['year'] = $conf['champVide'];
}

Et vous ne devriez plus voir ces messages d'erreur. S'ils persistent, rendez-vous dans la configuration de GCweb et videz le cache de la base de données.