Connexion S'inscrire

Connectez-vous

Login *
Mot de passe *
Se souvenir de moi

Créer un compte

Les champs marqués d'un astérisque (*) sont requis.
Nom *
Login *
Mot de passe *
Vérification mot de passe *
Email *
Vérification email *
Captcha *

Création d'un composant Joomla (partie 10) Gestion des catégories en administration


Dans cette partie,  nous allons rajouter la gestion des catégories dans notre composant pour permettre de regrouper les guitaristes selon leur type de musique; exemple : jazz, blues, country... Si vous êtes arrivés directement sur cette page, peut-être que vous aimeriez commencer par le début: Partie 1 | Partie 2 | Partie 3 | Partie 4 | Partie 5 | Partie 6 | Partie 7 | Partie 8 | Partie 9

1 Introduction

Joomla a facilité gestion des catégories en mettant en place un composant central (com_categories) que n'importe quel autre composant peut utiliser. Dans le passé, j'ai l'habitude de créer une table dans mes composant pour sauvegarder les catégories mais la technique que nous allons voir dans ce tutoriel rend la tâche beaucoup plus facile. Nous avons déjà dans le tutoriel précédent, ajouter un champ catid dans notre table (dans la base de données) pour sauvegarder l'id de la catégorie du guitariste. Toute la partie 10 se passe au côté administration donc dans le dossier administrator.

2 Ajout de la catégorie dans le formulaire d'édition

Nous allons donc ouvrir le XML du formulaire pour y ajouter le champ catégorie. Le fichier à ouvrir est donc models/forms/guitariste.xml. Nous ferrons deux modifications dans ce fichier. La première consiste à indiquer à Joomla le chemin de la classe qui gère le type category qui n'est pas un type de champ classique de Joomla. Dans l'avenir nous verrons comment créer un champ de formulaire dans Joomla. La deuxième consiste à rajouter l'élément au formulaire.

Dans la balise fieldset qui va contenir le champ catégorie, nous devons ajouter la propriété addfieldpath et lui donner comme valeur le chemin vers dossier contenant la classe utilisée pour gérer le type category. La balise fieldset devrait ressembler à ceci après modification :


<fieldset addfieldpath="/administrator/components/com_categories/models/fields">

L'élément à ajouter dans le formulaire qui va être logiquement avant ou après le nom du guitariste sera comme ceci:


<field name="catid" type="category"
        extension="com_djguitariste"
        required="true"
        label="JCATEGORY"
        description="JFIELD_CATEGORY_DESC"
        class="inputbox" />

Notons que le type de champ category à une propriété extension qui lui est propre. Cette propriété lui permet de gérer des catégories de plusieurs extensions séparément.

Le contenu au complet de ce fichier après la modification devrait ressembler à ceci:


<?xml version="1.0" encoding="utf-8"?>
<form>
  <fieldset addfieldpath="/administrator/components/com_categories/models/fields">
    <field id="state" name="state" type="list"
      label="JSTATUS"
      description="JFIELD_PUBLISHED_DESC"
      class="input span12 small"
      size="1"
      default="1"
      >
        <option value="1">JPUBLISHED</option>
        <option value="0">JUNPUBLISHED</option>
        <option value="2">JARCHIVED</option>
        <option value="-2">JTRASHED</option>
      
      </field>
      
  
    <field name="id" type="text" 
      default="0" label="JGLOBAL_FIELD_ID_LABEL"
      readonly="true" class="readonly"
      description="JGLOBAL_FIELD_ID_DESC" />
      
      <field name="name" type="text" 
        label="COM_DJGUITARISTE_FIELD_NAME_LABEL"
        description="COM_DJGUITARISTE_FIELD_NAME_DESC"
        required="true"
        class="inputbox" />
        
      <field name="catid" type="category"
        extension="com_djguitariste"
        required="true"
        label="JCATEGORY"
        description="JFIELD_CATEGORY_DESC"
        class="inputbox" />
        
      <field name="picture" type="media" 
        directory="guitaristes" preview="true" 
        label="COM_DJGUITARISTE_FIELD_PICTURE_LABEL" 
        description="COM_DJGUITARISTE_FIELD_PICTURE_DESC" />
        
      <field name="intro" type="editor" 
        label="COM_DJGUITARISTE_FIELD_INTRO_LABEL"
        description="COM_DJGUITARISTE_FIELD_INTRO_DESC" 
        filter="safehtml" />
        
      <field name="biography" type="editor" 
        label="COM_DJGUITARISTE_FIELD_BIOGRAPHY_LABEL"
        description="COM_DJGUITARISTE_FIELD_BIOGRAPHY_DESC" 
        filter="safehtml" />
        
      <field name="youtube_video" type="text" 
        label="COM_DJGUITARISTE_FIELD_YOUTUBE_VIDEO_LABEL"
        description="COM_DJGUITARISTE_FIELD_YOUTUBE_VIDEO_DESC"
        class="inputbox" />
        
      <field name="website" type="url" 
        label="COM_DJGUITARISTE_FIELD_WEBSITE_LABEL"
        description="COM_DJGUITARISTE_FIELD_WEBSITE_DESC"
        class="inputbox" />
        
      <field name="facebook" type="url" 
        label="COM_DJGUITARISTE_FIELD_FACEBOOK_LABEL"
        description="COM_DJGUITARISTE_FIELD_FACEBOOK_DESC"
        class="inputbox" />
  </fieldset>
</form>

 

Maintenant nous allons ajouter le champ dans notre layout pour le voir dans le formulaire. le layout est donc le fichier edit.php qui se trouve dans views/guitariste/tmpl/. L'ajout de l'élément du champ catégorie se fait exactement comme les autres élément que nous avons fait dans le passé :


<div class="control-group">
  <div class="control-label">
	<?php echo $this->form->getLabel('catid'); ?>
  </div>
  <div class="controls">
	<?php echo $this->form->getInput('catid'); ?>
  </div>
</div>

Le contenu du layout au complet devrait ressembler à ceci:


<?php
defined('_JEXEC') or die;

JHtml::_('behavior.tooltip');
JHtml::_('behavior.formvalidation');
?>
<script type="text/javascript">
    Joomla.submitbutton = function(task)
    {
        if(task == 'guitariste.cancel' || document.formvalidator.isValid(document.id('djguitariste-guitariste-form'))){
            <?php //echo $this->form->getField('descrption')->save(); ?>
            Joomla.submitform(task, document.getElementById('djguitariste-guitariste-form'));
        }else{
            alert('<?php echo $this->escape(JText::_('JGLOBAL_VALIDATION_FORM_FAILED')); ?>')
        }

    }  
</script>

<form action="<?php echo JRoute::_('index.php?option=com_djguitariste&layout=edit&id='.(int)$this->item->id); ?>" 
method="post" name="adminForm" id="djguitariste-guitariste-form" class="form-validate">
  <div class="row-fluid">
    <div class="span10 form-horizontal">
      <fieldset>
        <ul class="nav nav-tabs">
          <li class="active">
            <a href="#details" data-toggle="tab">
            <?php echo empty($this->item->id)? JText::_('COM_DJGUITARISTE_ADDING_NEW_GUITARISTE'): JText::sprintf('COM_DJGUITARISTE_EDIT_GUITARISTE', $this->item->id); ?>
            </a>
          </li>
        </ul>
        <div class="tab-content">
          <div class="tab-pane active" id="details">
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('id'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('id'); ?>
              </div>
            </div>
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('name'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('name'); ?>
              </div>
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('catid'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('catid'); ?>
              </div>
            </div>
                        
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('picture'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('picture'); ?>
              </div>
            </div>
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('intro'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('intro'); ?>
              </div>
            </div>
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('biography'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('biography'); ?>
              </div>
            </div>
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('youtube_video'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('youtube_video'); ?>
              </div>
            </div>
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('website'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('website'); ?>
              </div>
            </div>
            <div class="control-group">
              <div class="control-label">
                <?php echo $this->form->getLabel('facebook'); ?>
              </div>
              <div class="controls">
                <?php echo $this->form->getInput('facebook'); ?>
              </div>
            </div>
          </div>
          <input type="hidden" name="task" value="" />
          <?php echo JHtml::_('form.token'); ?>
        </div>
      </fieldset>
    
    </div>
    
    <!-- le sidebar pour publier et dépublier-->
    <div class="span2">
      <h4 class="title"><?php echo JText::_('JDETAILS'); ?></h4>
      <hr />
      <fieldset class="form-vertical">
        <div class="control-group">
          <div class="control-label">
            <?php echo $this->form->getLabel('state'); ?>
          </div>
          <div class="controls">
            <?php echo $this->form->getInput('state'); ?>
          </div>
        </div>  
      </fieldset>
    </div>
    
  </div>
</form>

 

3 Création du fichier d'aide à l'action (Helper) pour la création d'une menu navigation à gauche de la vue liste

Comme le nom l'indique, les fichiers d'aide à l'action sont souvent des classes abstraite avec des méthodes statiques à utiliser dans différents endroits ou y a le besoin. Ceci évite de réécrire un même code plusieurs fois. Dans le dossier de notre composant en administration, nous allons créer un dossiers nommé helpers qui contiendra tous les fichiers  d'aides à l'action. Dans le dossier helpers, nous allons créé u nouveau fichier PHP nommé djguitariste.php. Ce fichier va contenir la classe abstraite qu'on va nommé DJGuitaristeHelper qui va contenir la méthode addSubmenu qui s'occupe de la création de notre menu de navigation. Nous ferrons appel à la méthode addEntry de la classe abstraite JHtmlSidebar pour ajouter des éléments à notre menu. Voici le contenu du fichier:


<?php
defined('_JEXEC') or die;


abstract class DJGuitaristeHelper
{
  public static function addSubmenu($viewName = 'guitaristes'){
    JHtmlSidebar::addEntry(
      JText::_('COM_DJGUITARISTE_SUBMENU_DJGUITARISTE'),
      'index.php?option=com_djguitariste&view=guitaristes',
      $viewName == 'guitaristes'
    );
    
    JHtmlSidebar::addEntry(
      JText::_('COM_DJGUITARISTE_SUBMENU_CATEGORIES'),
      'index.php?option=com_categories&extension=com_djguitariste',
      $viewName == 'categories'
    );
    
    if($viewName == 'categories'){
      JToolbarHelper::Title(
        JText::sprintf('COM_DJGUITARISTE_CATEGORIES_TITLE', JText::_('COM_DJGUITARISTE')),
        'djguitariste-categories'
      );
    }
  }
}

4 Modification du fichier controller.php

Dans le fichier controller.php qui se trouve à la racine du dossier de notre composant (toujours en administration), nous allons rajouter l'inclusion de notre helper dans la méthode display :


require_once JPATH_COMPONENT.'helpers/djguitariste.php';

5 Modification du fichier de la vue liste

Nous commencerons par le fichier view.html.php qui se trouve dans views/guitaristes/. Dans la méthode display, nous allons appeler la méthode addSubmenu de notre helper pour créer notre menu et le mettre dans la barre d'à côté (sidebar). Voici les lignes à rajouter dans la méthode display.


DJGuitaristeHelper::addSubmenu('guitaristes');
$this->sidebar = JHtmlSidebar::render();

Après modification, Le contenu du fichier view.html.php devrait ressembler à ceci:


<?php
defined('_JEXEC') or die;

class DJGuitaristeViewGuitaristes extends JViewLegacy
{
  public function display($tpl = null)
  {
    $items = $this->get('Items');
    $this->items = &$items;
    
    DJGuitaristeHelper::addSubmenu('guitaristes');
    $this->sidebar = JHtmlSidebar::render();
    
    //Appel de la fonction pour créer la barre d'outil
    $this->addToolbar();
    
    parent::display($tpl);
    
  }
  
  protected function addToolbar(){
    JToolbarHelper::title(JText::_('COM_DJGUITARISTE_MANAGE_GUITARISTES'));
    JToolbarHelper::addNew('guitariste.add');
    JToolbarHelper::editList('guitariste.edit');
    JToolbarHelper::publish('guitaristes.publish');
    JToolbarHelper::unpublish('guitaristes.unpublish');
    JToolbarHelper::deleteList('', 'guitaristes.delete');
    
    JToolbarHelper::divider();
    
    //plus tard nous verons comment mettre un lien pour aller sur une page d'aide externe
    JToolbarHelper::help('JHELP_COMPONENTS_DJGUITARISTE_GUITARISTES_EDIT');
  }
  
}

Dans le layout de la vue liste (default.php) qui se trouve dans views/guitaristes/tmpl/, nous allons faire la modification pour afficher le sidebar. La première balise div qui vient juste après l'ouverture de la balise form devrait être remplacer par ce block de code:


  <?php if(!empty($this->sidebar)): ?>
    <div id="j-sidebar-container" class="span2">
      <?php echo $this->sidebar; ?>
    </div>
    <div id="j-admin-container" class="span10 j-toggle-main" style="float:right;">
  <?php else: ?>
    <div id="j-admin-container">
  <?php endif; ?>

Le contenu du layout default.php au complet devrait ressembler à ceci :


<?php
defined('_JEXEC') or die;
?>

<form action="<?php echo JRoute::_('index.php?option=com_djguitariste&view=djguitariste.guitariste'); ?>" method="post" name="adminForm" id="adminForm">

  <?php if(!empty($this->sidebar)): ?>
    <div id="j-sidebar-container" class="span2">
      <?php echo $this->sidebar; ?>
    </div>
    <div id="j-admin-container" class="span10 j-toggle-main" style="float:right;">
  <?php else: ?>
    <div id="j-admin-container">
  <?php endif; ?>
  
    <table class="table table-striped" id="guitaristes">
      <thead>
        <tr>
          <th width="1%">
            <input type="checkbox" name="checkall-toggle" value="" title="<?php echo JText::_('JGLOBAL_CHECK_ALL'); ?>" onclick="Joomla.checkAll(this)" />
          </th>
          <th width="1%" style="min-width:55px;" class="nowrap center">
            <?php echo JText::_('JSTATUS'); ?>
          </th>
          <th class="title">
            <?php echo JText::_('COM_DJGUITARISTE_NAME'); ?>
          </th>
          <!--th width="10%" class="nowrap hidden-phone">
            <?php //echo JText::_('COM_DJGUITARISTE_STYLE'); ?>
          </th-->
          <th width="1%" class="nowrap center">
            <?php echo JText::_('JGRID_HEADING_ID'); ?>
          </th>
        </tr>
      </thead>
      <tbody>
      <?php foreach($this->items as $i => $item){ ?>
        <tr class="row<?php echo $i % 2; ?>">
          <td class="center">
            <?php echo JHtml::_('grid.id', $i, $item->id); ?>
          </td>
          <td class="center">
            <?php echo JHtml::_('jgrid.published', $item->state, $i, 'guitaristes.', true, 'cb', $item->publish_up, $item->publish_down); ?>
          </td>
          <td class="nowrap">
            <a href="/<?php echo JRoute::_('index.php?option=com_djguitariste&view=guitariste&layout=edit&id='.(int)$item->id); ?>">
              <?php echo $item->name; ?>
            </a>
          </td>
          <td class="center">
            <?php echo $item->id; ?>
          </td>
        </tr>
      <?php } ?>
      </tbody>
    </table>
    <input type="hidden" name="task" value="" />
    <input type="hidden" name="boxchecked" value="0" />
    <?php echo JHtml::_('form.token'); ?>
  </div>
</form> 

6 Ajout d'une définition de niveau d'accès (ACL: Access Level Control)

Pour que la gestion des catégories fonctionne, Joomla a besoin d'un fichier access.xml qui doit être créer à la racine du dossier de notre composant (toujours dans le dossier administrator) au même niveau que controller.php, djguitariste.xml... Ce fichier définit les droit d'accès en précisant quel groupe a le droit de configurer le composant et quel groupe peut utiliser les autres fonctionnalités. Le composant com_categories de Joomla a aussi besoin de ce fichier pour savoir les actions qui sont  autorisées pour l'utilisateur courant. Voici le contenu du fichier access.xml :


<?xml version="1.0" encoding="utf-8"?>
<access component="com_djguitariste">
    <section name="component">
        <action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
        <action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
        <action name="core.create" title="JACTION_CREATE" description="JACTION_CREATE_COMPONENT_DESC" />
        <action name="core.delete" title="JACTION_DELETE" description="JACTION_DELETE_COMPONENT_DESC" />
        <action name="core.edit" title="JACTION_EDIT" description="JACTION_EDIT_COMPONENT_DESC" />
        <action name="core.edit.state" title="JACTION_EDITSTATE" description="JACTION_EDITSTATE_COMPONENT_DESC" />
        <action name="core.edit.own" title="JACTION_EDITOWN" description="JACTION_EDITOWN_COMPONENT_DESC" />
    </section>
    <section name="category">
        <action name="core.create" title="JACTION_CREATE" description="COM_CATEGORIES_ACCESS_CREATE_DESC" />
        <action name="core.delete" title="JACTION_DELETE" description="COM_CATEGORIES_ACCESS_DELETE_DESC" />
        <action name="core.edit" title="JACTION_EDIT" description="COM_CATEGORIES_ACCESS_EDIT_DESC" />
        <action name="core.edit.state" title="JACTION_EDITSTATE" description="COM_CATEGORIES_ACCESS_EDITSTATE_DESC" />
        <action name="core.edit.own" title="JACTION_EDITOWN" description="COM_CATEGORIES_ACCESS_EDITOWN_DESC" />
    </section>
</access>

À partir de maintenant, la gestion des catégories devrait marcher. Un clic sur catégorie dans le menu de gauche de la vue liste devrait emmener à la page liste des catégorie et vous aurez la barre d'outils pour Ajouter, Publier, Supprimer... et dans le formulaire d'édition, vous allez pouvoir sélection dans quelle catégorie mettre le guitariste.

7 Affichage de la catégorie sur la vue liste

Nous allons maintenant modifier la méthode getListQuery de notre modèle pour retourner la catégorie. Comme dans la table des guitaristes nous avons juste sauvegardé l'id de la catégorie, nous allons faire une jointure avec la table des catégories pour récupérer le titre de la catégorie. Cliquez ici pour savoir plus sur les requêtes avec Joomla. Donc nous allons ouvrir le fichier guitaristes.php qui se trouve dans le dossier models pour modifier la requête. Voici le contenu du fichier après modification :


<?php
defined('_JEXEC') or die;

class DJGuitaristeModelGuitaristes extends JModelList
{
  
  public function getListQuery()
  {
    $db = $this->getDbo();
    $query = $db->getQuery(true);
    $query->select('a.id, a.name, a.state, a.publish_up, a.publish_down');
    $query->from($db->quoteName('#__djguitariste_items').' AS a');
    
    $query->select('c.title AS category');
    $query->join('LEFT', $db->quoteName('#__categories').' AS c ON c.id = a.catid');
    
    return $query;
  }
  
}

Nous allons maintenant modifier la vue liste pour afficher la catégorie. Le fichier default.php se trouve dans views/guitaristes/tmpl/. Dans le la balise td qui affiche le nom du guitariste, juste après la fermeture de la balise a , nous allons ajouter le code suivant :


<p class="small">
  <?php echo $this->escape($item->category); ?>
</p>

Dans le prochain tutoriel, nous allons utiliser les catégories sur le site (côté client). Lire la suite


  • Dernière modification le jeudi, 28 septembre 2017 15:16
  • 926
Docteur Joomla

Après plus de 10 ans d'expérience en Joomla, je lance ce Blog pour partager mes connaissances avec les autres développeurs Joomla.