Comment étendre vos rapports de trackers en moins de 10 minutes ?
ou plus génériquement " Comment exploiter l'architecture ouverte des trackers Codendi ? "
Date de publication : 01/03/2011.
Par
Nicolas Terray (Codendi.org)
Dans ce tutoriel je vais vous montrer comment exploiter la fonctionnalité d'extension de Codendi avec le nouveau système de tracker de la v 4.2 et son architecture en plugin.
Cet article va être un peu technique et va contenir du code PHP et des CSS. Si vous êtes d'accord avec ça ou si vous êtes curieux, alors on y va
Commentez
0. Introduction
I. Créer un plugin
II. Créer un nouvel "affichage"
III. Ajouter de la mise en forme
0. Introduction
Dans ce tutoriel je vais vous montrer comment exploiter la fonctionnalité d'extension de Codendi avec le nouveau système de tracker de la v 4.2 et son architecture en plugin.
Cet article va être un peu technique et va contenir du code PHP et des CSS. Si vous êtes d'accord avec ca ou si vous êtes curieux, alors on y va

J'imagine que vous savez ce qu'est un
rapport.
Au cas où : dans un
tracker, un rapport vous permet de rechercher des artefacts en fonction de critères. Jusqu'à maintenant, vous pouvez afficher les résultats de vos requêtes sous deux formes : les tableaux ou les graphiques.
Exemple d'affichage de vos recherches dans les trackers sous forme de tableau
Le sujet de ce tuto est donc de créer une nouvelle façon d'afficher vos requêtes dans les trackers.
Peut-être que vous utilisez Codendi pour gérer vos « user stories » si vous êtes dans un environnement agile ? Jusqu'à maintenant vous ne pouvez pas voir vos artifacts sous forme de post-it pour ressembler à votre tableau de sprint. Trop triste pas vrai ? Je suis toujours déçu quand l'interface ne ressemble pas à la réalité.
Exemple de tableau Kanban board, extrait d'un article sur Dr Bobbs
sur « comment créer un effet post-it avec du CSS3 et de l'HTML5 ». On va voir si l'on peut l'implémenter dans Codendi. Prenez une version Codendi 4.2, relevez vos manches, c'est parti !

I. Créer un plugin
Tout d'abord, vous devez créer un plugin. Pour ça, vous pouvez copier un plugin existant, supprimer les éléments non utiles et le renommer. Ou encore mieux, utiliser le
wizard
pour la création de plugin.
$ cd /usr/share/codendi/plugins
$ ln -s ../codendi_tools/plugins/plugincreationwizard
|
Installer et activer ce plugin dans l'administration des plugins. Ensuite, utiliser le wizard (http://example.com/plugins/plugincreationwizard/) pour créer le squelette de votre nouveau plugin. Dans notre cas, on va l'appeler « tableau ». Activer l'espace web et les styles CSS mais pas besoins des db, mvc, cgi, etc Le code généré a été créé dans /usr/share/codendi/plugins/board/
Installez le,
activez le>,
même s'il ne fait rien pour l'instant.
II. Créer un nouvel "affichage"
Editer
/
usr
/
share
/
codendi
/plugins/
board
/
include
/
boardPlugin.class.php
pour ajouter des hooks.
On ne va pas implémenter
tous les
hooks
nécessaires
puisqu'on ne veut pas importer de
xml
et
qu'on n'a rien à stocker dans la base. On
n'a
que
10
minutes !
class boardPlugin extends Plugin {
const RENDERER_TYPE = 'plugin_board';
public function __construct($id) {
parent::__construct($id);
$this->_addHook('cssfile', 'cssFile', false);
$this->_addHook('tracker_report_renderer_types' , 'tracker_report_renderer_types', false);
}
@paramarray$types
public function tracker_report_renderer_types($params) {
$params['types'][self::RENDERER_TYPE] = 'Board';
}
|
Bien. Vous devriez pouvoir choisir "tableau" dans la liste déroulante des différents types d'affichages lors de la création d'un nouveau rapport comme ceci :
Maintenant,
on
ajoute
des
hooks
supplémentaires pour créer un nouvel affichage :
public function __construct($id) {
parent::__construct($id);
$this->_addHook('cssfile', 'cssFile', false);
$this->_addHook('tracker_report_renderer_types' , 'tracker_report_renderer_types', false);
$this->_addHook('tracker_report_renderer_instance', 'tracker_report_renderer_instance', false);
}
@paramarray$params
string
array
@return
public function tracker_report_renderer_instance($params) {
if ($params['type'] == self::RENDERER_TYPE) {
require_once('Board_Renderer.class.php');
$params['instance'] = new Board_Renderer(
$params['row']['id'],
$params['report'],
$params['row']['name'],
$params['row']['description'],
$params['row']['rank'],
$this
);
}
}
Et créer Board_Renderer.class.php (à côté de boardPlugin.class.php)
plugin = $plugin;
}
@paramarray$matching_ids
@param$request
@returnstring
public function fetch($matching_ids, $request) {
return '';
}
public function getIcon() {
return '<img src="'. $this->plugin->getThemePath().'/images/renderer.png" />';
}
public function delete() {}
public function getType() {
return 'plugin_board';
}
public function processRequest(TrackerManager $tracker_manager, $request, $current_user) {
}
public function fetchWidget() {
return '';
}
public function update() {
return true;
}
public function duplicate($from_renderer, $field_mapping) { }
public function afterSaveObject($renderer) { }
}
|
Ouais
!
On peut créer notre nouvel affichage
\o/
Maintenant, on va essayer
d'afficher
quelque chose d'intéressant.
On va le faire avec la méthode
php
fetch. Un des paramètres est $matching_ids
C'est la liste des artefacts
qui
correspondent à votre recherche
, séparés par des virgules.
On va l'utiliser pour afficher vos artefacts. On remplace la méthode
fetch
par quelque chose de plus utile tel que :
public function fetch($matching_ids, $request) {
$html = '';
$total_rows = $matching_ids['id'] ? substr_count($matching_ids['id'], ',') + 1 : 0;
if (!$total_rows) {
return 'Nothing to display';
}
$sql = "SELECT A.id AS id, CVT.value AS title
FROM tracker_artifact AS A
LEFT JOIN (
tracker_changeset_value AS CV
INNER JOIN tracker_semantic_title as ST ON (CV.field_id = ST.field_id)
INNER JOIN tracker_changeset_value_text AS CVT ON (CV.id = CVT.changeset_value_id)
) ON (A.last_changeset_id = CV.changeset_id)
WHERE A.id IN (". $matching_ids['id'] .")";
$dao = new DataAccessObject();
$html .= '<div class="tracker_renderer_board"><ul>';
foreach ($dao->retrieve($sql) as $row) {
$html .= '<li>';
$html .= '<a href="/tracker/?aid='. $row['id'] .'">';
$html .= '<p class="tracker_renderer_board_title">bug #'. $row['id'] .'</p>';
$html .= '<p class="tracker_renderer_board_content"> '. $row['title'] .'</p>';
$html .= '</a>';
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
|
III. Ajouter de la mise en forme
Vous pouvez
aller voir
votre résultat dans votre navigateur mais quelques règles CSS manquent.
On fait un copier/coller
et
on adapte
les CSS proposés
par Christian Heilmann.
Editer
plugins/
board
/www/
themes
/default/
css
/style.css
et ajouter les règles suivantes:
.tracker_renderer_board p {
font-size:100%;
font-weight:normal;
margin: 0;
}
.tracker_renderer_board ul, .tracker_renderer_board li{
list-style:none;
}
.tracker_renderer_board ul{
overflow:hidden;
padding:3em;
}
.tracker_renderer_board ul li a{
text-decoration:none;
color:#000;
background:#ffc;
display:block;
height:10em;
width:10em;
padding:1em;
-moz-box-shadow:5px 5px 7px rgba(33,33,33,1);
-webkit-box-shadow: 5px 5px 7px rgba(33,33,33,.7);
box-shadow: 5px 5px 7px rgba(33,33,33,.7);
-moz-transition:-moz-transform .15s linear;
-o-transition:-o-transform .15s linear;
-webkit-transition:-webkit-transform .15s linear;
}
.tracker_renderer_board ul li{
margin:1em;
float:left;
}
.tracker_renderer_board ul li p.tracker_renderer_board_title {
font-size:140%;
font-weight:bold;
padding-bottom:10px;
}
.tracker_renderer_board ul li p.tracker_renderer_board_content {
font-family:"Reenie Beanie",arial,sans-serif;
font-size:180%;
}
.tracker_renderer_board ul li a{
-webkit-transform: rotate(-6deg);
-o-transform: rotate(-6deg);
-moz-transform:rotate(-6deg);
}
.tracker_renderer_board ul li:nth-child(even) a{
-o-transform:rotate(4deg);
-webkit-transform:rotate(4deg);
-moz-transform:rotate(4deg);
position:relative;
top:5px;
}
.tracker_renderer_board ul li:nth-child(3n) a{
-o-transform:rotate(-3deg);
-webkit-transform:rotate(-3deg);
-moz-transform:rotate(-3deg);
position:relative;
top:-5px;
}
.tracker_renderer_board ul li:nth-child(5n) a{
-o-transform:rotate(5deg);
-webkit-transform:rotate(5deg);
-moz-transform:rotate(5deg);
position:relative;
top:-10px;
}
.tracker_renderer_board ul li a:hover,ul li a:focus{
box-shadow:10px 10px 7px rgba(0,0,0,.7);
-moz-box-shadow:10px 10px 7px rgba(0,0,0,.7);
-webkit-box-shadow: 10px 10px 7px rgba(0,0,0,.7);
-webkit-transform: scale(1.25);
-moz-transform: scale(1.25);
-o-transform: scale(1.25);
position:relative;
z-index:5;
}
|
Je vous laisse lire
cet article
pour plus de détails sur les règles CSS.
Une seule chose manque encore : la police ouverte
Reenie Beanie
.
Ajouter simplement le tag associé dans le
hook
correspondant dans le plugin :
function cssFile($params) {
if (strpos($_SERVER['REQUEST_URI'], '/tracker/') === 0) {
echo '<link rel="stylesheet" type="text/css" href="'.$this->getThemePath().'/css/style.css" />';
echo '<link href="http://fonts.googleapis.com/css?family=Reenie+Beanie:regular" rel="stylesheet" type="text/css" />';
}
}
}
|
Et voilà!
Vos artefacts affichés sous forme de post-it !
Merveilleux,
pas vrai
?
Avec quelques lignes de code,
on a créé
un nouvel affichage pour les rapports.
Bien entendu, il y a encore
du travail pour parfaire le plugin : permettre l'import/export de la structure XML, le stocker dans la base de données, ajouter des colonnes et permettre le cliquer/glisser, mais l'objectif de ce tutoriel n'était pas de réinventer la roue
Vous aussi développez vos propres plugins et
partagez les. Ça m'intéresse de voir ce que vous avez fait ! Si vous avez des problèmes, postez vos questions sur la liste de distribution des développeurs
Codendi devel
sur le site communautaire
www.codendi.org


Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.