Comment créer une base de connaissance juste avec Joomla 4?

Comment créer une base de connaissance avec Joomla 4?

Joomla est un CMS très puissant lorsqu'il s'agit de gérer du contenu. Et lorsque l'on combine le contenu et les overrides, il n'y a plus de limites excepté celles de votre imagination. Pour vous le prouver, nous allons donc réaliser une base de connaissance en suivant ce tutoriel dédié à Joomla 4.

Pourquoi vouloir créer une base de connaissance avec Joomla ?

  • Parce que votre base de connaissance sera propulsée par Joomla
    Vous pourrez la gérer facilement, comme n'importe quel contenu géré par Joomla. Ajouter et/ou modifier les contenus de votre base de connaissance sera alors très simple.
  • Car il est inutile d'installer et de maintenir une extension pour ça
    Pas d'extension à installer et à maintenir. Pas de courbe d'apprentissage. Oubliez les CCK lourds et autres page builders, vous n'avez besoin que de Joomla.
  • Pour développer vos compétences grâce aux overrides
    Tout ce que vous avez à faire est de suivre ce tutoriel pour créer votre base de connaissance en quelques minutes. Toutes les étapes y sont clairement expliquées et illustrées.
  • Pour que vous gardiez une complète maîtrise de votre référencement
    Parce que votre base de connaissance est construite avec com_content, vous pourrez gérer facilement chaque balise title et meta description suivant vos objectifs.
  • et parce que Joomla est gratuit pour tous et pour toujours.
    Grâce à la magie de Joomla, créer cette puissante base de connaissance est gratuit et vous n'aurez jamais de licence à payer.

Comment construire une base de connaissance

Schématiquement, une base de connaissance est une liste d'articles affichés et groupés selon leurs catégories. Pour aider les utilisateurs à trouver rapidement les ressources, un moteur de recherche est très souvent utilisé et affiché en haut de ce genre de page.

Maintenant que nous avons défini ceci, il est plus facile de comprendre comment nous allons créer cette base de connaissance simplement avec Joomla. Nous allons devoir :

  • créer les catégories (et sous-catégories éventuelles)
  • ajouter les articles dans chaque catégorie
  • et créer le moteur de recherche

Pour pouvoir gérer facilement votre base de connaissance, je vous conseille (fortement) de créer une première catégorie (que vous pouvez nommer "Base de connaissance") et de créer autant de catégories enfant que nécessaire. Ajoutez une courte description à vos catégories. La structure de vos catégories devrait ressembler à quelque chose comme ceci :

List of categories - base de connaissance avec Joomla

Ensuite, ajoutez votre contenu en créant tous vos articles dans chacune des catégories.

List of articles - base de connaissance avec Joomla

Affichons maintenant notre base de connaissance

Dans ce tutoriel, nous allons afficher la barre de recherche en haut de la page et les catégories seront affichées en dessous.

Pour réaliser cela, nous avons besoin de créer un nouveau module Recherche avancée pour afficher notre barre de recherche. Vous ne le savez peut-être pas mais Joomla possède nativement un très puissant moteur de recherche (Recherche avancée) et nous allons l'utiliser.

Le composant Recherche avancée

Pour être très efficace, votre base de connaissance doit disposer d'un moteur de recherche dédié. C'est à dire que tous les résultats renvoyés par ce moteur de recherche doivent être en relation avec le contenu de votre base de connaissance (et non de votre blog ou de tout autre partie de votre site Web). Cela est possible avec Joomla et c'est ce que nous allons paramétrer maintenant.

  1. Ouvrez le panneau des composants en cliquant sur l'icône dasn le menu gauche.

    Joomla 4 - base de connaissance avec Joomla
  2. Dans Recherche avancée, cliquez sur Index.

    Joomla 4 - base de connaissance avec Joomla
  3. Sur cette page sont affichés tous les contenus qui ont été indéxés par ce composant natif de Joomla. Cliquez sur le bouton Index dans le menu supérieur pour indexer les derniers contenus que vous venez d'ajouter.

    Joomla 4 - Smart Search component
  4. Dans le menu gauche, cliquez sur Filtres.

  5. Maintenant, nous allons créer le filtre dédié à notre base de connaissance. Cliquez sur le bouton Nouveau dans le menu supérieur.

  6. Indiquez un nom pour votre filtre (Search KB dans cet exemple).

    Joomla 4 - Smart Search settings
  7. Cliquez sur Recherche par catégorie et sélectionnez uniquement les catégories contenant les articles de votre base de connaissance.

  8. Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Le module Recherche avancée

  1. Depuis le panneau d'administration, cliquez sur l'icône + affiché à côté de Modules.

    Joomla - Module creation
  2. Dans la liste, cherchez et cliquez sur Recherche avancée.

    Joomla - Module articles category creation
  3. Choisissez un titre pour votre module (p.ex: Recherche Base de connaissance).

  4. Dans le paramètre Filtre de recherche, sélectionnez le filtre que vous venez de créer à l'étape précédente (Search KB).

  5. Ajustez les autres paramètres en fonction de vos préférences et de vos besoins :

    Joomla - Module smart search options
  6. N'oubliez pas de choisir une position de module de votre template qui soit au dessus de la position affichant le contenu et d'assigner votre module à la bonne page.

  7. Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Le lien de menu

Eh oui, pour afficher notre base de connaissance, il nous faut créer un lien de menu. Rien de très compliqué ici, comme vous allez le constater.

  1. Depuis le panneau d'administration, cliquez sur Menus dans le menu de gauche.

    Joomla - Creating a menu item
  2. Sélectionnez votre menu et cliquez sur l'icône + pour créer un nouveau lien de menu.

    Joomla - Creating a new menu item
  3. Indiquez le titre de votre lien de menu (p.ex: Base de connaissance) et si besoin, personnalisez son alias.

  4. Dans Type de lien de menu *, sélectionnez Articles puis Liste de toutes les catégories.

  5. Dans Catégorie principale *, sélectionnez la catégorie Base de connaissance créée plus tôt.

  6. Ajustez les autres paramètres en suivant les exemples ci-dessous:

  7. Onglet Catégories

    Joomla - Module Smart Search options
  8. Onglet Catégorie

    Joomla - Module Smart Search options
  9. Réglez les options et les paramètres des autres onglets.

  10. Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Jouons maintenant avec les overrides

Nous arrivons à la partie technique de ce tutorial mais pas de panique, vous allez voir que c'est plutôt simple :)

Le module Recherche avancée

Commençons avec le module Recherche avancée. Nous allons le customiser en utilisant quelques classes CSS de Bootstrap (le framework du template Cassiopeia).

  1. Depuis le panneau d'administration, cliquez sur Système dans le menu gauche.

  2. Dans la partie dédiée aux templates, cliquez sur Site Templates.

  3. Cliquez sur votre template frontend (Cassiopeia, dans cet exemple).

  4. Cliquez sur l'onglet Créer des substitutions.

  5. Dasn la liste des modules, cliquez sur mod_finder.

  6. Une fois le processus de création terminé, revenez sur l'onglet Editeur.

  7. Dans la liste de gauche, cliquez sur html puis sur mod_finder.

    Ici, vous avez un fichier:

    • default.php

  8. Parce que vous pouvez avoir envie ou besoin de créer d'autres overrides de ce module, vous allons copier ce fichier.

    • COpiez tous le contenu du fichier default.php
    • Cliquez sur le bouton Nouveau fichier dasn le menu supérieur
    • Dans la partie gauche de la fenêtre, cliquez d'abord sur mod_finder pour sélectionner ce dossier.
    • Dans la partie droite de la fenêtre, remplissez le champ avec le nom de votre nouveau fichier (override-kb par example).
    • Sélectionnez le type de fichier que vous voulez créer: php et cliquez sur le bouton Créer.
      Joomla - Template folder structure
    • Maintenant, votre nouveau fichier doit apparaitre sous le fichier Default.php dans le dossier mod_finder.
    • Votre fichier Default.php est maintenant votre fichier maitre si vous avez besoin de créer d'autres overrides pour le module mod_finder.
  9. Cliquez sur le fichier override-kb.php pour l'ouvrir dans l'éditeur (à droite de votre écran). Logiquement, votre fichier est vide.

  10. Copiez la totalité du code ci-dessous:

    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  mod_finder
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Router\Route;
    use Joomla\Module\Finder\Site\Helper\FinderHelper;
    
    // Load the smart search component language file.
    $lang = $app->getLanguage();
    $lang->load('com_finder', JPATH_SITE);
    
    $input = '<input type="text" name="q" id="mod-finder-searchword' . $module->id . '" class="py-4 z-depth-2 js-finder-search-query form-control form-control-lg" value="' . htmlspecialchars($app->input->get('q', '', 'string'), ENT_COMPAT, 'UTF-8') . '"'
    	. ' placeholder="Search in the knowledge base..." size="150" aria-label="Search" />';
    
    $showLabel  = $params->get('show_label', 0);
    $labelClass = (!$showLabel ? 'sr-only ' : '') . 'finder';
    $label      = '<label for="mod-finder-searchword' . $module->id . '" class="text-center text-white pb-4 d-none d-sm-block h3 ' . $labelClass . '">' . $params->get('alt_label', Text::_('JSEARCH_FILTER_SUBMIT')) . '</label>';
    
    $output = '';
    
    if ($params->get('show_button', 0))
    {
    	$output .= $label;
    	$output .= '<div class="mod-finder__search input-group">';
    	$output .= $input;
    	$output .= '<span class="input-group-append">';
    	$output .= '<button class="btn btn-primary" type="submit"><span class="fas fa-search icon-black" aria-hidden="true"></span> ' . Text::_('JSEARCH_FILTER_SUBMIT') . '</button>';
    	$output .= '</span>';
    	$output .= '</div>';
    }
    else
    {
    	$output .= $label;
    	$output .= $input;
    }
    
    /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
    $wa = $app->getDocument()->getWebAssetManager();
    $wa->registerAndUseScript('com_finder', 'com_finder/finder.js', [], ['defer' => true]);
    
    Text::script('MOD_FINDER_SEARCH_VALUE', true);
    
    /*
     * This segment of code sets up the autocompleter.
     */
    if ($params->get('show_autosuggest', 1))
    {
    	$wa->usePreset('awesomplete');
    	$app->getDocument()->addScriptOptions('finder-search', array('url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component')));
    }
    ?>
    <form class="mx-auto form-control-lg w-75 mod-finder js-finder-searchform form-search" action="<?php echo Route::_($route); ?>" method="get" role="search">
    	<?php echo $output; ?>
    
    	<?php $show_advanced = $params->get('show_advanced', 0); ?>
    	<?php if ($show_advanced == 2) : ?>
    		<br>
    		<a href="<?php echo Route::_($route); ?>" class="mod-finder__advanced-link"><?php echo Text::_('COM_FINDER_ADVANCED_SEARCH'); ?></a>
    	<?php elseif ($show_advanced == 1) : ?>
    		<div class="mod-finder__advanced js-finder-advanced">
    			<?php echo HTMLHelper::_('filter.select', $query, $params); ?>
    		</div>
    	<?php endif; ?>
    	<?php echo FinderHelper::getGetFields($route, (int) $params->get('set_itemid', 0)); ?>
    </form>
  11. apuis copiez-le dans votre fichier override-kb.php.

  12. Joomla - Template files editor
  13. Cliquez sur le bouton Enregistrer et fermer.

Quelques explications à propos de ce code
  • Ligne 21: py-4 z-depth-2
    J'ai ajouté ici quelques classes CSS spécifiques pour avoir du padding et une ombre portée autour de la barre de recherche.
  • Ligne 21: placeholder
    N'hésitez pas à personnaliser le placeholder (le texte qui est affiché dans la barre de recherche) ainsiq que sa taille (150 dans cet exemple).
  • Ligne 26: text-center text-white pb-4 d-none d-sm-block h3
    Ces classes CSS seront appliquées au label qui est affiché au dessus de la barre de recherche. Dans cet exemple, le label est affiche dans une balise H3 en blanc et qu'il ne sera pas affiché sur mobile. Vous pouvez très bien modifier ces choix selon vos besoins.
  • Ligne 61: mx-auto form-control-lg w-75
    Ces classes CSS seront appliquées au formulaire : centré, grand format et avec une largeur de 75%.

Découvrir les overrides de Joomla

Si vous avez besoin d'inspiration ou de conseils sur les overrides de Joomla, voici +50 exemples gratuits pour vous aider et vous inspirer.

Joomla Overrides

Le contenu

Il est temps de prendre une grande respiration car nous allons maintenant modifier les vues category et categories de com_content (tout va bien se passer!).

Comme nous venons de le voir, créez tout d'abord l'override du composant com_content avec les vues category et categories.

La vue categories

Juste pour rappel, categories est la vue qui affiche toutes les catégories de notre base de connaissance.

Par défaut dans le dossier com_content / categories, vous avez deux fichiers:

  • default.php et default_items.php.
  • Ouvrez le fichier default_items.php dans l'éditeur.
  • Copiez tout le code ci-dessous :
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Router\Route;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    if ($this->maxLevelcat != 0 && count($this->items[$this->parent->id]) > 0) :
    ?>
    	<div class="row com-content-categories__items">
    		<?php foreach ($this->items[$this->parent->id] as $id => $item) : ?>
    		 
              <div class="col-lg-4 col-sm-12">	
              <?php if ($this->params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) : ?>
    			
                <div class="p-3 m-3 com-content-categories__item">
    				
                	<h3 class="page-header item-title">
    					<i class="bleu fas fa-folder mr-1"></i><a class="bleu" href="<?php echo Route::_(RouteHelper::getCategoryRoute($item->id, $item->language)); ?>">
    					<?php echo $this->escape($item->title); ?></a>
    					<?php if ($this->params->get('show_cat_num_articles_cat') == 1) :?>
    						<!--<span class="badge badge-info">
    							<?php echo Text::_('COM_CONTENT_NUM_ITEMS'); ?>&nbsp;
    							<?php echo $item->numitems; ?>
    						</span>-->
                            <br /><span class="nombre-articles">
                          	<?php echo $item->numitems; ?>
                            <?php echo JText::_('COM_CONTENT_NUM_ITEMS'); ?>&nbsp;
    					</span>
    					<?php endif; ?>
    					<?php if (count($item->getChildren()) > 0 && $this->maxLevelcat > 1) : ?>
    						<button
    							type="button"
    							id="category-btn-<?php echo $item->id; ?>"
    							data-target="#category-<?php echo $item->id; ?>"
    							data-toggle="collapse"
    							class="btn btn-secondary btn-sm float-right"
    							aria-label="<?php echo Text::_('JGLOBAL_EXPAND_CATEGORIES'); ?>"
    						>
    							<span class="fas fa-plus" aria-hidden="true"></span>
    						</button>
    					<?php endif; ?>
    				</h3>
    				<?php if ($this->params->get('show_description_image') && $item->getParams()->get('image')) : ?>
    					<img src="<?php echo $item->getParams()->get('image'); ?>" alt="<?php echo htmlspecialchars($item->getParams()->get('image_alt'), ENT_COMPAT, 'UTF-8'); ?>">
    				<?php endif; ?>
    				<?php if ($this->params->get('show_subcat_desc_cat') == 1) : ?>
    					<?php if ($item->description) : ?>
    						<div class="com-content-categories__description category-desc">
    							<?php echo HTMLHelper::_('content.prepare', $item->description, '', 'com_content.categories'); ?>
    						</div>
    					<?php endif; ?>
    				<?php endif; ?>
    
    				<?php if (count($item->getChildren()) > 0 && $this->maxLevelcat > 1) : ?>
    					<div class="com-content-categories__children collapse fade" id="category-<?php echo $item->id; ?>">
    					<?php
    					$this->items[$item->id] = $item->getChildren();
    					$this->parent = $item;
    					$this->maxLevelcat--;
    					echo $this->loadTemplate('items');
    					$this->parent = $item->getParent();
    					$this->maxLevelcat++;
    					?>
    					</div>
    				<?php endif; ?>
    			</div>
    			<?php endif; ?>
                </div>
    		<?php endforeach; ?>
    	</div>
    <?php endif; ?>
  • et copiez le dans le fichier default_items.php.
  • Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Explications. Dans cet exemple, j'ai ajouté quelques classes CSS Bootstrap CSS classes pour afficher 3 categories par ligne (ligne 22), un peu de padding aet de margin (lidne 25) ainsi qu'une icône bleue juste devant le titre de chaque catégorie (ligne 28). Naturellement, vous pouvez conservez ces modifications ou les adapter au design de votre site.

La vue category

Juste pour rappel, la vue category est celle où tous les articles d'une catégorie de votre base de connaissance sont affichés.

Par défaut dans le dossier com_content / category, vous avez 7 fichiers :

Joomla - Structure folder
  • Pour votre information, les fichiers Default presentent les articles dans un tableeau. Donc, nous ne modifierons que les fichiers Blog pour afficher notre base de connaissance. Copiez chaque code ci-dessous et copiez les dans leurs fichiers respectifs (com_content / category / ...).
  • le fichier blog.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Factory;
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Layout\FileLayout;
    
    $app = Factory::getApplication();
    
    $this->category->text = $this->category->description;
    $app->triggerEvent('onContentPrepare', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $this->category->description = $this->category->text;
    
    $results = $app->triggerEvent('onContentAfterTitle', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $afterDisplayTitle = trim(implode("\n", $results));
    
    $results = $app->triggerEvent('onContentBeforeDisplay', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $beforeDisplayContent = trim(implode("\n", $results));
    
    $results = $app->triggerEvent('onContentAfterDisplay', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $afterDisplayContent = trim(implode("\n", $results));
    
    ?>
    <div class="p-4 com-content-category-blog blog" itemscope itemtype="https://schema.org/Blog">
    	<?php if ($this->params->get('show_page_heading')) : ?>
    		<div class="page-header">
    			<h1><?php echo $this->escape($this->params->get('page_heading')); ?> </h1>
    		</div>
    	<?php endif; ?>
    
    	<?php if ($this->params->get('show_category_title', 1) or $this->params->get('page_subheading')) : ?>
    		<h2 class="bleu"> <?php echo $this->escape($this->params->get('page_subheading')); ?>
    			<?php if ($this->params->get('show_category_title')) : ?>
    				<span class="subheading-category"><i class="fas fa-book-open mr-2"></i><?php echo $this->category->title; ?></span>
    			<?php endif; ?>
    		</h2>
    	<?php endif; ?>
    	<?php echo $afterDisplayTitle; ?>
    
    	<?php if ($this->params->get('show_cat_tags', 1) && !empty($this->category->tags->itemTags)) : ?>
    		<?php $this->category->tagLayout = new FileLayout('joomla.content.tags'); ?>
    		<?php echo $this->category->tagLayout->render($this->category->tags->itemTags); ?>
    	<?php endif; ?>
    
    	<?php if ($beforeDisplayContent || $afterDisplayContent || $this->params->get('show_description', 1) || $this->params->def('show_description_image', 1)) : ?>
    		<div class="category-desc clearfix">
    			<?php if ($this->params->get('show_description_image') && $this->category->getParams()->get('image')) : ?>
    				<img src="<?php echo $this->category->getParams()->get('image'); ?>" alt="<?php echo htmlspecialchars($this->category->getParams()->get('image_alt'), ENT_COMPAT, 'UTF-8'); ?>">
    			<?php endif; ?>
    			<?php echo $beforeDisplayContent; ?>
    			<?php if ($this->params->get('show_description') && $this->category->description) : ?>
    				<?php echo HTMLHelper::_('content.prepare', $this->category->description, '', 'com_content.category'); ?>
    			<?php endif; ?>
    			<?php echo $afterDisplayContent; ?>
    		</div><hr>
    	<?php endif; ?>
    
    	<?php if (empty($this->lead_items) && empty($this->link_items) && empty($this->intro_items)) : ?>
    		<?php if ($this->params->get('show_no_articles', 1)) : ?>
    			<p><?php echo Text::_('COM_CONTENT_NO_ARTICLES'); ?></p>
    		<?php endif; ?>
    	<?php endif; ?>
    
    	<?php $leadingcount = 0; ?>
    	<?php if (!empty($this->lead_items)) : ?>
    		<div class="com-content-category-blog__items blog-items items-leading <?php echo $this->params->get('blog_class_leading'); ?>">
    			<?php foreach ($this->lead_items as &$item) : ?>
       				<div class="pl-2 py-4 com-content-category-blog__item blog-item"
    					itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
                  			<?php
    						$this->item = & $item;
    						echo $this->loadTemplate('item');
    						?>                      
    				</div><br />
          
    				<?php $leadingcount++; ?>
    			<?php endforeach; ?>
    		</div>
    	<?php endif; ?>
    
    	<?php
    	$introcount = count($this->intro_items);
    	$counter = 0;
    	?>
    
    	<?php if (!empty($this->intro_items)) : ?>
    		<div class="list-group list-group-flush com-content-category-blog__items blog-items <?php echo $this->params->get('blog_class'); ?>">
    		<?php foreach ($this->intro_items as $key => &$item) : ?>
    			<div class="p-4 list-group-item com-content-category-blog__item blog-item"
    				itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
    					<?php
    					$this->item = & $item;
    					echo $this->loadTemplate('item');
    					?>
    			</div>
    		<?php endforeach; ?>
    		</div>
    	<?php endif; ?>
    
    	<?php if (!empty($this->link_items)) : ?>
    		<div class="com-content-category-blog__items-more items-more">
    			<?php echo $this->loadTemplate('links'); ?>
    		</div>
    	<?php endif; ?>
    
    	<?php if ($this->maxLevel != 0 && !empty($this->children[$this->category->id])) : ?>
    		<div class="com-content-category-blog__children cat-children">
    			<?php if ($this->params->get('show_category_heading_title_text', 1) == 1) : ?>
    				<h3> <?php echo Text::_('JGLOBAL_SUBCATEGORIES'); ?> </h3>
    			<?php endif; ?>
    			<?php echo $this->loadTemplate('children'); ?> </div>
    	<?php endif; ?>
    	<?php if (($this->params->def('show_pagination', 1) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?>
    		<div class="com-content-category-blog__navigation w-100">
    			<?php if ($this->params->def('show_pagination_results', 1)) : ?>
    				<p class="com-content-category-blog__counter counter float-right pt-3 pr-2">
    					<?php echo $this->pagination->getPagesCounter(); ?>
    				</p>
    			<?php endif; ?>
    			<div class="com-content-category-blog__pagination">
    				<?php echo $this->pagination->getPagesLinks(); ?>
    			</div>
    		</div>
    	<?php endif; ?>
    </div>

Explications. Ici, j'ai ajouté un peu de padding (lignes 33 et 77), une classe pour afficher le texte en bleu (ligne 41) ainsiq u'une icône juste devant le titre de la catégorie (ligne 43). J'ai aussi ajouté quelques classes CSS Bootstrap CSS à la liste des articles (lignes 96 et 98). Là aussi, vous pouvez conserver ces modifications ou les adapter en fonction du design de votre site.

  • Le fichier blog_children.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Factory;
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Router\Route;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    $lang   = Factory::getLanguage();
    $user   = Factory::getUser();
    $groups = $user->getAuthorisedViewLevels();
    
    if ($this->maxLevel != 0 && count($this->children[$this->category->id]) > 0) : ?>
    
    	<?php foreach ($this->children[$this->category->id] as $id => $child) : ?>
    		<?php // Check whether category access level allows access to subcategories. ?>
    		<?php if (in_array($child->access, $groups)) : ?>
    			<?php if ($this->params->get('show_empty_categories') || $child->numitems || count($child->getChildren())) : ?>
    			<div class="com-content-category-blog__child">
    				<?php if ($lang->isRtl()) : ?>
    				<h3 class="page-header item-title">
    					<?php if ( $this->params->get('show_cat_num_articles', 1)) : ?>
    						<span class="badge badge-info tip">
    							<?php echo $child->getNumItems(true); ?>
    						</span>
    					<?php endif; ?>
    					<a href="<?php echo Route::_(RouteHelper::getCategoryRoute($child->id, $child->language)); ?>">
    					<?php echo $this->escape($child->title); ?></a>
    
    					<?php if ($this->maxLevel > 1 && count($child->getChildren()) > 0) : ?>
    						<a href="#category-<?php echo $child->id; ?>" data-toggle="collapse" data-toggle="button" class="btn btn-sm float-right" aria-label="<?php echo Text::_('JGLOBAL_EXPAND_CATEGORIES'); ?>"><span class="fas fa-plus" aria-hidden="true"></span></a>
    					<?php endif; ?>
    				</h3>
    				<?php else : ?>
    				<h3 class="page-header item-title"><a href="<?php echo Route::_(RouteHelper::getCategoryRoute($child->id, $child->language)); ?>">
    					<?php echo $this->escape($child->title); ?></a>
    					<?php if ( $this->params->get('show_cat_num_articles', 1)) : ?>
    						<span class="badge badge-info">
    							<?php echo Text::_('COM_CONTENT_NUM_ITEMS'); ?>&nbsp;
    							<?php echo $child->getNumItems(true); ?>
    						</span>
    					<?php endif; ?>
    
    					<?php if ($this->maxLevel > 1 && count($child->getChildren()) > 0) : ?>
    						<a href="#category-<?php echo $child->id; ?>" data-toggle="collapse" data-toggle="button" class="btn btn-sm float-right" aria-label="<?php echo Text::_('JGLOBAL_EXPAND_CATEGORIES'); ?>"><span class="fas fa-plus" aria-hidden="true"></span></a>
    					<?php endif; ?>
    				</h3>
    				<?php endif; ?>
    
    				<?php if ($this->params->get('show_subcat_desc') == 1) : ?>
    				<?php if ($child->description) : ?>
    					<div class="com-content-category-blog__description category-desc">
    						<?php echo HTMLHelper::_('content.prepare', $child->description, '', 'com_content.category'); ?>
    					</div>
    				<?php endif; ?>
    				<?php endif; ?>
    
    				<?php if ($this->maxLevel > 1 && count($child->getChildren()) > 0) : ?>
    				<div class="com-content-category-blog__children collapse fade" id="category-<?php echo $child->id; ?>">
    					<?php
    					$this->children[$child->id] = $child->getChildren();
    					$this->category = $child;
    					$this->maxLevel--;
    					echo $this->loadTemplate('children');
    					$this->category = $child->getParent();
    					$this->maxLevel++;
    					?>
    				</div>
    				<?php endif; ?>
    			</div>
    			<?php endif; ?>
    		<?php endif; ?>
    	<?php endforeach; ?>
    <?php endif;
  • Le fichier blog_item.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Factory;
    use Joomla\CMS\Language\Associations;
    use Joomla\CMS\Layout\LayoutHelper;
    use Joomla\CMS\Router\Route;
    use Joomla\CMS\Uri\Uri;
    use Joomla\Component\Content\Administrator\Extension\ContentComponent;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    // Create a shortcut for params.
    $params = $this->item->params;
    $canEdit = $this->item->params->get('access-edit');
    $info    = $params->get('info_block_position', 0);
    
    // Check if associations are implemented. If they are, define the parameter.
    $assocParam = (Associations::isEnabled() && $params->get('show_associations'));
    
    ?>
    
    <?php echo LayoutHelper::render('joomla.content.intro_image', $this->item); ?>
    
    <div class="item-content">
    	<?php if ($this->item->stage_condition == ContentComponent::CONDITION_UNPUBLISHED || strtotime($this->item->publish_up) > strtotime(Factory::getDate())
    		|| (!is_null($this->item->publish_down) && strtotime($this->item->publish_down) < strtotime(Factory::getDate()))) : ?>
    		<div class="system-unpublished">
    	<?php endif; ?>
    
    	<?php echo LayoutHelper::render('joomla.content.blog_style_default_item_title', $this->item); ?>
    
    	<?php if ($canEdit) : ?>
    		<?php echo LayoutHelper::render('joomla.content.icons', array('params' => $params, 'item' => $this->item)); ?>
    	<?php endif; ?>
    
    	<?php // Todo Not that elegant would be nice to group the params ?>
    	<?php $useDefList = ($params->get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date')
    		|| $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam); ?>
    
    	<?php if ($useDefList && ($info == 0 || $info == 2)) : ?>
    		<?php echo LayoutHelper::render('joomla.content.info_block', array('item' => $this->item, 'params' => $params, 'position' => 'above')); ?>
    	<?php endif; ?>
    	<?php if ($info == 0 && $params->get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
    		<?php echo LayoutHelper::render('joomla.content.tags', $this->item->tags->itemTags); ?>
    	<?php endif; ?>
    
    	<?php if (!$params->get('show_intro')) : ?>
    		<?php // Content is generated by content plugin event "onContentAfterTitle" ?>
    		<?php echo $this->item->event->afterDisplayTitle; ?>
    	<?php endif; ?>
    
    	<?php // Content is generated by content plugin event "onContentBeforeDisplay" ?>
    	<?php echo $this->item->event->beforeDisplayContent; ?>
    
    	<?php echo $this->item->introtext; ?>
    
    	<?php if ($info == 1 || $info == 2) : ?>
    		<?php if ($useDefList) : ?>
    			<?php echo LayoutHelper::render('joomla.content.info_block', array('item' => $this->item, 'params' => $params, 'position' => 'below')); ?>
    		<?php endif; ?>
    		<?php if ($params->get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
    			<?php echo LayoutHelper::render('joomla.content.tags', $this->item->tags->itemTags); ?>
    		<?php endif; ?>
    	<?php endif; ?>
    
    	<?php if ($params->get('show_readmore') && $this->item->readmore) :
    		if ($params->get('access-view')) :
    			$link = Route::_(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language));
    		else :
    			$menu = Factory::getApplication()->getMenu();
    			$active = $menu->getActive();
    			$itemId = $active->id;
    			$link = new Uri(Route::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false));
    			$link->setVar('return', base64_encode(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language)));
    		endif; ?>
    
    		<?php echo LayoutHelper::render('joomla.content.readmore', array('item' => $this->item, 'params' => $params, 'link' => $link)); ?>
    
    	<?php endif; ?>
    
    	<?php if ($this->item->stage_condition == ContentComponent::CONDITION_UNPUBLISHED || strtotime($this->item->publish_up) > strtotime(Factory::getDate())
    		|| (!is_null($this->item->publish_down) && strtotime($this->item->publish_down) < strtotime(Factory::getDate()))) : ?>
    	</div>
    	<?php endif; ?>
    </div>
    
    <?php // Content is generated by content plugin event "onContentAfterDisplay" ?>
    <?php echo $this->item->event->afterDisplayContent; ?>
  • Le fichier blog_links.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Router\Route;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    ?>
    
    <ol class="com-content-category-blog__links nav nav-tabs nav-stacked">
    	<?php foreach ($this->link_items as &$item) : ?>
    		<li class="com-content-category-blog__link">
    			<a href="<?php echo Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language)); ?>">
    				<?php echo $item->title; ?></a>
    		</li>
    	<?php endforeach; ?>
    </ol>

Une dernière étape pour la route...

Maintenant, revenz au module Recherche avancée que vous avez créé plus tôt.

Ouvrez le et dans l'onglet Paramètres avancés sélectionnez override-kb (ou le nom que vous avez donné à votre override) dans le paramètre Type de mise en page.

Joomla - Module parameter

Lorsque c'est fait, cliquez sur le bouton Enregistrer et fermer.

Le frontend

J'ai rajouté quelques modifications CSS mais si vous avez suivi avec attention toutes les étapes de ce tutoriel, votre base de connaissance devrait ressembler à quelque chose comme ça :

Joomla Knowledge Base Override

La vue Catégories

Joomla Knowledge Base Override

La vue Catégorie

Le Joomla Override Challenge

En association avec Viviana Menzel, nous avons créé le non-officiel Joomla Override Challenge. Le but est de créer chaque mois, une override basée sur une extension native de Joomla ou sur un projet. Si vous souhaitez participer, n'hésitez pas à contacter Viviana ou moi :)

Joomla est un CMS très puissant lorsqu'il s'agit de gérer du contenu. Et lorsque l'on combine le contenu et les overrides, il n'y a plus de limites excepté celles de votre imagination. Pour vous le prouver, nous allons donc réaliser une base de connaissance en suivant ce tutoriel dédié à Joomla 4.

Pourquoi vouloir créer une base de connaissance avec Joomla ?

  • Parce que votre base de connaissance sera propulsée par Joomla
    Vous pourrez la gérer facilement, comme n'importe quel contenu géré par Joomla. Ajouter et/ou modifier les contenus de votre base de connaissance sera alors très simple.
  • Car il est inutile d'installer et de maintenir une extension pour ça
    Pas d'extension à installer et à maintenir. Pas de courbe d'apprentissage. Oubliez les CCK lourds et autres page builders, vous n'avez besoin que de Joomla.
  • Pour développer vos compétences grâce aux overrides
    Tout ce que vous avez à faire est de suivre ce tutoriel pour créer votre base de connaissance en quelques minutes. Toutes les étapes y sont clairement expliquées et illustrées.
  • Pour que vous gardiez une complète maîtrise de votre référencement
    Parce que votre base de connaissance est construite avec com_content, vous pourrez gérer facilement chaque balise title et meta description suivant vos objectifs.
  • et parce que Joomla est gratuit pour tous et pour toujours.
    Grâce à la magie de Joomla, créer cette puissante base de connaissance est gratuit et vous n'aurez jamais de licence à payer.

Comment construire une base de connaissance

Schématiquement, une base de connaissance est une liste d'articles affichés et groupés selon leurs catégories. Pour aider les utilisateurs à trouver rapidement les ressources, un moteur de recherche est très souvent utilisé et affiché en haut de ce genre de page.

Maintenant que nous avons défini ceci, il est plus facile de comprendre comment nous allons créer cette base de connaissance simplement avec Joomla. Nous allons devoir :

  • créer les catégories (et sous-catégories éventuelles)
  • ajouter les articles dans chaque catégorie
  • et créer le moteur de recherche

Pour pouvoir gérer facilement votre base de connaissance, je vous conseille (fortement) de créer une première catégorie (que vous pouvez nommer "Base de connaissance") et de créer autant de catégories enfant que nécessaire. Ajoutez une courte description à vos catégories. La structure de vos catégories devrait ressembler à quelque chose comme ceci :

List of categories - base de connaissance avec Joomla

Ensuite, ajoutez votre contenu en créant tous vos articles dans chacune des catégories.

List of articles - base de connaissance avec Joomla

Affichons maintenant notre base de connaissance

Dans ce tutoriel, nous allons afficher la barre de recherche en haut de la page et les catégories seront affichées en dessous.

Pour réaliser cela, nous avons besoin de créer un nouveau module Recherche avancée pour afficher notre barre de recherche. Vous ne le savez peut-être pas mais Joomla possède nativement un très puissant moteur de recherche (Recherche avancée) et nous allons l'utiliser.

Le composant Recherche avancée

Pour être très efficace, votre base de connaissance doit disposer d'un moteur de recherche dédié. C'est à dire que tous les résultats renvoyés par ce moteur de recherche doivent être en relation avec le contenu de votre base de connaissance (et non de votre blog ou de tout autre partie de votre site Web). Cela est possible avec Joomla et c'est ce que nous allons paramétrer maintenant.

  1. Ouvrez le panneau des composants en cliquant sur l'icône dasn le menu gauche.

    Joomla 4 - base de connaissance avec Joomla
  2. Dans Recherche avancée, cliquez sur Index.

    Joomla 4 - base de connaissance avec Joomla
  3. Sur cette page sont affichés tous les contenus qui ont été indéxés par ce composant natif de Joomla. Cliquez sur le bouton Index dans le menu supérieur pour indexer les derniers contenus que vous venez d'ajouter.

    Joomla 4 - Smart Search component
  4. Dans le menu gauche, cliquez sur Filtres.

  5. Maintenant, nous allons créer le filtre dédié à notre base de connaissance. Cliquez sur le bouton Nouveau dans le menu supérieur.

  6. Indiquez un nom pour votre filtre (Search KB dans cet exemple).

    Joomla 4 - Smart Search settings
  7. Cliquez sur Recherche par catégorie et sélectionnez uniquement les catégories contenant les articles de votre base de connaissance.

  8. Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Le module Recherche avancée

  1. Depuis le panneau d'administration, cliquez sur l'icône + affiché à côté de Modules.

    Joomla - Module creation
  2. Dans la liste, cherchez et cliquez sur Recherche avancée.

    Joomla - Module articles category creation
  3. Choisissez un titre pour votre module (p.ex: Recherche Base de connaissance).

  4. Dans le paramètre Filtre de recherche, sélectionnez le filtre que vous venez de créer à l'étape précédente (Search KB).

  5. Ajustez les autres paramètres en fonction de vos préférences et de vos besoins :

    Joomla - Module smart search options
  6. N'oubliez pas de choisir une position de module de votre template qui soit au dessus de la position affichant le contenu et d'assigner votre module à la bonne page.

  7. Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Le lien de menu

Eh oui, pour afficher notre base de connaissance, il nous faut créer un lien de menu. Rien de très compliqué ici, comme vous allez le constater.

  1. Depuis le panneau d'administration, cliquez sur Menus dans le menu de gauche.

    Joomla - Creating a menu item
  2. Sélectionnez votre menu et cliquez sur l'icône + pour créer un nouveau lien de menu.

    Joomla - Creating a new menu item
  3. Indiquez le titre de votre lien de menu (p.ex: Base de connaissance) et si besoin, personnalisez son alias.

  4. Dans Type de lien de menu *, sélectionnez Articles puis Liste de toutes les catégories.

  5. Dans Catégorie principale *, sélectionnez la catégorie Base de connaissance créée plus tôt.

  6. Ajustez les autres paramètres en suivant les exemples ci-dessous:

  7. Onglet Catégories

    Joomla - Module Smart Search options
  8. Onglet Catégorie

    Joomla - Module Smart Search options
  9. Réglez les options et les paramètres des autres onglets.

  10. Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Jouons maintenant avec les overrides

Nous arrivons à la partie technique de ce tutorial mais pas de panique, vous allez voir que c'est plutôt simple :)

Le module Recherche avancée

Commençons avec le module Recherche avancée. Nous allons le customiser en utilisant quelques classes CSS de Bootstrap (le framework du template Cassiopeia).

  1. Depuis le panneau d'administration, cliquez sur Système dans le menu gauche.

  2. Dans la partie dédiée aux templates, cliquez sur Site Templates.

  3. Cliquez sur votre template frontend (Cassiopeia, dans cet exemple).

  4. Cliquez sur l'onglet Créer des substitutions.

  5. Dasn la liste des modules, cliquez sur mod_finder.

  6. Une fois le processus de création terminé, revenez sur l'onglet Editeur.

  7. Dans la liste de gauche, cliquez sur html puis sur mod_finder.

    Ici, vous avez un fichier:

    • default.php

  8. Parce que vous pouvez avoir envie ou besoin de créer d'autres overrides de ce module, vous allons copier ce fichier.

    • COpiez tous le contenu du fichier default.php
    • Cliquez sur le bouton Nouveau fichier dasn le menu supérieur
    • Dans la partie gauche de la fenêtre, cliquez d'abord sur mod_finder pour sélectionner ce dossier.
    • Dans la partie droite de la fenêtre, remplissez le champ avec le nom de votre nouveau fichier (override-kb par example).
    • Sélectionnez le type de fichier que vous voulez créer: php et cliquez sur le bouton Créer.
      Joomla - Template folder structure
    • Maintenant, votre nouveau fichier doit apparaitre sous le fichier Default.php dans le dossier mod_finder.
    • Votre fichier Default.php est maintenant votre fichier maitre si vous avez besoin de créer d'autres overrides pour le module mod_finder.
  9. Cliquez sur le fichier override-kb.php pour l'ouvrir dans l'éditeur (à droite de votre écran). Logiquement, votre fichier est vide.

  10. Copiez la totalité du code ci-dessous:

    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  mod_finder
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Router\Route;
    use Joomla\Module\Finder\Site\Helper\FinderHelper;
    
    // Load the smart search component language file.
    $lang = $app->getLanguage();
    $lang->load('com_finder', JPATH_SITE);
    
    $input = '<input type="text" name="q" id="mod-finder-searchword' . $module->id . '" class="py-4 z-depth-2 js-finder-search-query form-control form-control-lg" value="' . htmlspecialchars($app->input->get('q', '', 'string'), ENT_COMPAT, 'UTF-8') . '"'
    	. ' placeholder="Search in the knowledge base..." size="150" aria-label="Search" />';
    
    $showLabel  = $params->get('show_label', 0);
    $labelClass = (!$showLabel ? 'sr-only ' : '') . 'finder';
    $label      = '<label for="mod-finder-searchword' . $module->id . '" class="text-center text-white pb-4 d-none d-sm-block h3 ' . $labelClass . '">' . $params->get('alt_label', Text::_('JSEARCH_FILTER_SUBMIT')) . '</label>';
    
    $output = '';
    
    if ($params->get('show_button', 0))
    {
    	$output .= $label;
    	$output .= '<div class="mod-finder__search input-group">';
    	$output .= $input;
    	$output .= '<span class="input-group-append">';
    	$output .= '<button class="btn btn-primary" type="submit"><span class="fas fa-search icon-black" aria-hidden="true"></span> ' . Text::_('JSEARCH_FILTER_SUBMIT') . '</button>';
    	$output .= '</span>';
    	$output .= '</div>';
    }
    else
    {
    	$output .= $label;
    	$output .= $input;
    }
    
    /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
    $wa = $app->getDocument()->getWebAssetManager();
    $wa->registerAndUseScript('com_finder', 'com_finder/finder.js', [], ['defer' => true]);
    
    Text::script('MOD_FINDER_SEARCH_VALUE', true);
    
    /*
     * This segment of code sets up the autocompleter.
     */
    if ($params->get('show_autosuggest', 1))
    {
    	$wa->usePreset('awesomplete');
    	$app->getDocument()->addScriptOptions('finder-search', array('url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component')));
    }
    ?>
    <form class="mx-auto form-control-lg w-75 mod-finder js-finder-searchform form-search" action="<?php echo Route::_($route); ?>" method="get" role="search">
    	<?php echo $output; ?>
    
    	<?php $show_advanced = $params->get('show_advanced', 0); ?>
    	<?php if ($show_advanced == 2) : ?>
    		<br>
    		<a href="<?php echo Route::_($route); ?>" class="mod-finder__advanced-link"><?php echo Text::_('COM_FINDER_ADVANCED_SEARCH'); ?></a>
    	<?php elseif ($show_advanced == 1) : ?>
    		<div class="mod-finder__advanced js-finder-advanced">
    			<?php echo HTMLHelper::_('filter.select', $query, $params); ?>
    		</div>
    	<?php endif; ?>
    	<?php echo FinderHelper::getGetFields($route, (int) $params->get('set_itemid', 0)); ?>
    </form>
  11. apuis copiez-le dans votre fichier override-kb.php.

  12. Joomla - Template files editor
  13. Cliquez sur le bouton Enregistrer et fermer.

Quelques explications à propos de ce code
  • Ligne 21: py-4 z-depth-2
    J'ai ajouté ici quelques classes CSS spécifiques pour avoir du padding et une ombre portée autour de la barre de recherche.
  • Ligne 21: placeholder
    N'hésitez pas à personnaliser le placeholder (le texte qui est affiché dans la barre de recherche) ainsiq que sa taille (150 dans cet exemple).
  • Ligne 26: text-center text-white pb-4 d-none d-sm-block h3
    Ces classes CSS seront appliquées au label qui est affiché au dessus de la barre de recherche. Dans cet exemple, le label est affiche dans une balise H3 en blanc et qu'il ne sera pas affiché sur mobile. Vous pouvez très bien modifier ces choix selon vos besoins.
  • Ligne 61: mx-auto form-control-lg w-75
    Ces classes CSS seront appliquées au formulaire : centré, grand format et avec une largeur de 75%.

Découvrir les overrides de Joomla

Si vous avez besoin d'inspiration ou de conseils sur les overrides de Joomla, voici +50 exemples gratuits pour vous aider et vous inspirer.

Joomla Overrides

Le contenu

Il est temps de prendre une grande respiration car nous allons maintenant modifier les vues category et categories de com_content (tout va bien se passer!).

Comme nous venons de le voir, créez tout d'abord l'override du composant com_content avec les vues category et categories.

La vue categories

Juste pour rappel, categories est la vue qui affiche toutes les catégories de notre base de connaissance.

Par défaut dans le dossier com_content / categories, vous avez deux fichiers:

  • default.php et default_items.php.
  • Ouvrez le fichier default_items.php dans l'éditeur.
  • Copiez tout le code ci-dessous :
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Router\Route;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    if ($this->maxLevelcat != 0 && count($this->items[$this->parent->id]) > 0) :
    ?>
    	<div class="row com-content-categories__items">
    		<?php foreach ($this->items[$this->parent->id] as $id => $item) : ?>
    		 
              <div class="col-lg-4 col-sm-12">	
              <?php if ($this->params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) : ?>
    			
                <div class="p-3 m-3 com-content-categories__item">
    				
                	<h3 class="page-header item-title">
    					<i class="bleu fas fa-folder mr-1"></i><a class="bleu" href="<?php echo Route::_(RouteHelper::getCategoryRoute($item->id, $item->language)); ?>">
    					<?php echo $this->escape($item->title); ?></a>
    					<?php if ($this->params->get('show_cat_num_articles_cat') == 1) :?>
    						<!--<span class="badge badge-info">
    							<?php echo Text::_('COM_CONTENT_NUM_ITEMS'); ?>&nbsp;
    							<?php echo $item->numitems; ?>
    						</span>-->
                            <br /><span class="nombre-articles">
                          	<?php echo $item->numitems; ?>
                            <?php echo JText::_('COM_CONTENT_NUM_ITEMS'); ?>&nbsp;
    					</span>
    					<?php endif; ?>
    					<?php if (count($item->getChildren()) > 0 && $this->maxLevelcat > 1) : ?>
    						<button
    							type="button"
    							id="category-btn-<?php echo $item->id; ?>"
    							data-target="#category-<?php echo $item->id; ?>"
    							data-toggle="collapse"
    							class="btn btn-secondary btn-sm float-right"
    							aria-label="<?php echo Text::_('JGLOBAL_EXPAND_CATEGORIES'); ?>"
    						>
    							<span class="fas fa-plus" aria-hidden="true"></span>
    						</button>
    					<?php endif; ?>
    				</h3>
    				<?php if ($this->params->get('show_description_image') && $item->getParams()->get('image')) : ?>
    					<img src="<?php echo $item->getParams()->get('image'); ?>" alt="<?php echo htmlspecialchars($item->getParams()->get('image_alt'), ENT_COMPAT, 'UTF-8'); ?>">
    				<?php endif; ?>
    				<?php if ($this->params->get('show_subcat_desc_cat') == 1) : ?>
    					<?php if ($item->description) : ?>
    						<div class="com-content-categories__description category-desc">
    							<?php echo HTMLHelper::_('content.prepare', $item->description, '', 'com_content.categories'); ?>
    						</div>
    					<?php endif; ?>
    				<?php endif; ?>
    
    				<?php if (count($item->getChildren()) > 0 && $this->maxLevelcat > 1) : ?>
    					<div class="com-content-categories__children collapse fade" id="category-<?php echo $item->id; ?>">
    					<?php
    					$this->items[$item->id] = $item->getChildren();
    					$this->parent = $item;
    					$this->maxLevelcat--;
    					echo $this->loadTemplate('items');
    					$this->parent = $item->getParent();
    					$this->maxLevelcat++;
    					?>
    					</div>
    				<?php endif; ?>
    			</div>
    			<?php endif; ?>
                </div>
    		<?php endforeach; ?>
    	</div>
    <?php endif; ?>
  • et copiez le dans le fichier default_items.php.
  • Lorsque vous avez terminé, cliquez sur le bouton Enregistrer et fermer.

Explications. Dans cet exemple, j'ai ajouté quelques classes CSS Bootstrap CSS classes pour afficher 3 categories par ligne (ligne 22), un peu de padding aet de margin (lidne 25) ainsi qu'une icône bleue juste devant le titre de chaque catégorie (ligne 28). Naturellement, vous pouvez conservez ces modifications ou les adapter au design de votre site.

La vue category

Juste pour rappel, la vue category est celle où tous les articles d'une catégorie de votre base de connaissance sont affichés.

Par défaut dans le dossier com_content / category, vous avez 7 fichiers :

Joomla - Structure folder
  • Pour votre information, les fichiers Default presentent les articles dans un tableeau. Donc, nous ne modifierons que les fichiers Blog pour afficher notre base de connaissance. Copiez chaque code ci-dessous et copiez les dans leurs fichiers respectifs (com_content / category / ...).
  • le fichier blog.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Factory;
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Layout\FileLayout;
    
    $app = Factory::getApplication();
    
    $this->category->text = $this->category->description;
    $app->triggerEvent('onContentPrepare', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $this->category->description = $this->category->text;
    
    $results = $app->triggerEvent('onContentAfterTitle', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $afterDisplayTitle = trim(implode("\n", $results));
    
    $results = $app->triggerEvent('onContentBeforeDisplay', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $beforeDisplayContent = trim(implode("\n", $results));
    
    $results = $app->triggerEvent('onContentAfterDisplay', array($this->category->extension . '.categories', &$this->category, &$this->params, 0));
    $afterDisplayContent = trim(implode("\n", $results));
    
    ?>
    <div class="p-4 com-content-category-blog blog" itemscope itemtype="https://schema.org/Blog">
    	<?php if ($this->params->get('show_page_heading')) : ?>
    		<div class="page-header">
    			<h1><?php echo $this->escape($this->params->get('page_heading')); ?> </h1>
    		</div>
    	<?php endif; ?>
    
    	<?php if ($this->params->get('show_category_title', 1) or $this->params->get('page_subheading')) : ?>
    		<h2 class="bleu"> <?php echo $this->escape($this->params->get('page_subheading')); ?>
    			<?php if ($this->params->get('show_category_title')) : ?>
    				<span class="subheading-category"><i class="fas fa-book-open mr-2"></i><?php echo $this->category->title; ?></span>
    			<?php endif; ?>
    		</h2>
    	<?php endif; ?>
    	<?php echo $afterDisplayTitle; ?>
    
    	<?php if ($this->params->get('show_cat_tags', 1) && !empty($this->category->tags->itemTags)) : ?>
    		<?php $this->category->tagLayout = new FileLayout('joomla.content.tags'); ?>
    		<?php echo $this->category->tagLayout->render($this->category->tags->itemTags); ?>
    	<?php endif; ?>
    
    	<?php if ($beforeDisplayContent || $afterDisplayContent || $this->params->get('show_description', 1) || $this->params->def('show_description_image', 1)) : ?>
    		<div class="category-desc clearfix">
    			<?php if ($this->params->get('show_description_image') && $this->category->getParams()->get('image')) : ?>
    				<img src="<?php echo $this->category->getParams()->get('image'); ?>" alt="<?php echo htmlspecialchars($this->category->getParams()->get('image_alt'), ENT_COMPAT, 'UTF-8'); ?>">
    			<?php endif; ?>
    			<?php echo $beforeDisplayContent; ?>
    			<?php if ($this->params->get('show_description') && $this->category->description) : ?>
    				<?php echo HTMLHelper::_('content.prepare', $this->category->description, '', 'com_content.category'); ?>
    			<?php endif; ?>
    			<?php echo $afterDisplayContent; ?>
    		</div><hr>
    	<?php endif; ?>
    
    	<?php if (empty($this->lead_items) && empty($this->link_items) && empty($this->intro_items)) : ?>
    		<?php if ($this->params->get('show_no_articles', 1)) : ?>
    			<p><?php echo Text::_('COM_CONTENT_NO_ARTICLES'); ?></p>
    		<?php endif; ?>
    	<?php endif; ?>
    
    	<?php $leadingcount = 0; ?>
    	<?php if (!empty($this->lead_items)) : ?>
    		<div class="com-content-category-blog__items blog-items items-leading <?php echo $this->params->get('blog_class_leading'); ?>">
    			<?php foreach ($this->lead_items as &$item) : ?>
       				<div class="pl-2 py-4 com-content-category-blog__item blog-item"
    					itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
                  			<?php
    						$this->item = & $item;
    						echo $this->loadTemplate('item');
    						?>                      
    				</div><br />
          
    				<?php $leadingcount++; ?>
    			<?php endforeach; ?>
    		</div>
    	<?php endif; ?>
    
    	<?php
    	$introcount = count($this->intro_items);
    	$counter = 0;
    	?>
    
    	<?php if (!empty($this->intro_items)) : ?>
    		<div class="list-group list-group-flush com-content-category-blog__items blog-items <?php echo $this->params->get('blog_class'); ?>">
    		<?php foreach ($this->intro_items as $key => &$item) : ?>
    			<div class="p-4 list-group-item com-content-category-blog__item blog-item"
    				itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
    					<?php
    					$this->item = & $item;
    					echo $this->loadTemplate('item');
    					?>
    			</div>
    		<?php endforeach; ?>
    		</div>
    	<?php endif; ?>
    
    	<?php if (!empty($this->link_items)) : ?>
    		<div class="com-content-category-blog__items-more items-more">
    			<?php echo $this->loadTemplate('links'); ?>
    		</div>
    	<?php endif; ?>
    
    	<?php if ($this->maxLevel != 0 && !empty($this->children[$this->category->id])) : ?>
    		<div class="com-content-category-blog__children cat-children">
    			<?php if ($this->params->get('show_category_heading_title_text', 1) == 1) : ?>
    				<h3> <?php echo Text::_('JGLOBAL_SUBCATEGORIES'); ?> </h3>
    			<?php endif; ?>
    			<?php echo $this->loadTemplate('children'); ?> </div>
    	<?php endif; ?>
    	<?php if (($this->params->def('show_pagination', 1) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?>
    		<div class="com-content-category-blog__navigation w-100">
    			<?php if ($this->params->def('show_pagination_results', 1)) : ?>
    				<p class="com-content-category-blog__counter counter float-right pt-3 pr-2">
    					<?php echo $this->pagination->getPagesCounter(); ?>
    				</p>
    			<?php endif; ?>
    			<div class="com-content-category-blog__pagination">
    				<?php echo $this->pagination->getPagesLinks(); ?>
    			</div>
    		</div>
    	<?php endif; ?>
    </div>

Explications. Ici, j'ai ajouté un peu de padding (lignes 33 et 77), une classe pour afficher le texte en bleu (ligne 41) ainsiq u'une icône juste devant le titre de la catégorie (ligne 43). J'ai aussi ajouté quelques classes CSS Bootstrap CSS à la liste des articles (lignes 96 et 98). Là aussi, vous pouvez conserver ces modifications ou les adapter en fonction du design de votre site.

  • Le fichier blog_children.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Factory;
    use Joomla\CMS\HTML\HTMLHelper;
    use Joomla\CMS\Language\Text;
    use Joomla\CMS\Router\Route;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    $lang   = Factory::getLanguage();
    $user   = Factory::getUser();
    $groups = $user->getAuthorisedViewLevels();
    
    if ($this->maxLevel != 0 && count($this->children[$this->category->id]) > 0) : ?>
    
    	<?php foreach ($this->children[$this->category->id] as $id => $child) : ?>
    		<?php // Check whether category access level allows access to subcategories. ?>
    		<?php if (in_array($child->access, $groups)) : ?>
    			<?php if ($this->params->get('show_empty_categories') || $child->numitems || count($child->getChildren())) : ?>
    			<div class="com-content-category-blog__child">
    				<?php if ($lang->isRtl()) : ?>
    				<h3 class="page-header item-title">
    					<?php if ( $this->params->get('show_cat_num_articles', 1)) : ?>
    						<span class="badge badge-info tip">
    							<?php echo $child->getNumItems(true); ?>
    						</span>
    					<?php endif; ?>
    					<a href="<?php echo Route::_(RouteHelper::getCategoryRoute($child->id, $child->language)); ?>">
    					<?php echo $this->escape($child->title); ?></a>
    
    					<?php if ($this->maxLevel > 1 && count($child->getChildren()) > 0) : ?>
    						<a href="#category-<?php echo $child->id; ?>" data-toggle="collapse" data-toggle="button" class="btn btn-sm float-right" aria-label="<?php echo Text::_('JGLOBAL_EXPAND_CATEGORIES'); ?>"><span class="fas fa-plus" aria-hidden="true"></span></a>
    					<?php endif; ?>
    				</h3>
    				<?php else : ?>
    				<h3 class="page-header item-title"><a href="<?php echo Route::_(RouteHelper::getCategoryRoute($child->id, $child->language)); ?>">
    					<?php echo $this->escape($child->title); ?></a>
    					<?php if ( $this->params->get('show_cat_num_articles', 1)) : ?>
    						<span class="badge badge-info">
    							<?php echo Text::_('COM_CONTENT_NUM_ITEMS'); ?>&nbsp;
    							<?php echo $child->getNumItems(true); ?>
    						</span>
    					<?php endif; ?>
    
    					<?php if ($this->maxLevel > 1 && count($child->getChildren()) > 0) : ?>
    						<a href="#category-<?php echo $child->id; ?>" data-toggle="collapse" data-toggle="button" class="btn btn-sm float-right" aria-label="<?php echo Text::_('JGLOBAL_EXPAND_CATEGORIES'); ?>"><span class="fas fa-plus" aria-hidden="true"></span></a>
    					<?php endif; ?>
    				</h3>
    				<?php endif; ?>
    
    				<?php if ($this->params->get('show_subcat_desc') == 1) : ?>
    				<?php if ($child->description) : ?>
    					<div class="com-content-category-blog__description category-desc">
    						<?php echo HTMLHelper::_('content.prepare', $child->description, '', 'com_content.category'); ?>
    					</div>
    				<?php endif; ?>
    				<?php endif; ?>
    
    				<?php if ($this->maxLevel > 1 && count($child->getChildren()) > 0) : ?>
    				<div class="com-content-category-blog__children collapse fade" id="category-<?php echo $child->id; ?>">
    					<?php
    					$this->children[$child->id] = $child->getChildren();
    					$this->category = $child;
    					$this->maxLevel--;
    					echo $this->loadTemplate('children');
    					$this->category = $child->getParent();
    					$this->maxLevel++;
    					?>
    				</div>
    				<?php endif; ?>
    			</div>
    			<?php endif; ?>
    		<?php endif; ?>
    	<?php endforeach; ?>
    <?php endif;
  • Le fichier blog_item.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Factory;
    use Joomla\CMS\Language\Associations;
    use Joomla\CMS\Layout\LayoutHelper;
    use Joomla\CMS\Router\Route;
    use Joomla\CMS\Uri\Uri;
    use Joomla\Component\Content\Administrator\Extension\ContentComponent;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    // Create a shortcut for params.
    $params = $this->item->params;
    $canEdit = $this->item->params->get('access-edit');
    $info    = $params->get('info_block_position', 0);
    
    // Check if associations are implemented. If they are, define the parameter.
    $assocParam = (Associations::isEnabled() && $params->get('show_associations'));
    
    ?>
    
    <?php echo LayoutHelper::render('joomla.content.intro_image', $this->item); ?>
    
    <div class="item-content">
    	<?php if ($this->item->stage_condition == ContentComponent::CONDITION_UNPUBLISHED || strtotime($this->item->publish_up) > strtotime(Factory::getDate())
    		|| (!is_null($this->item->publish_down) && strtotime($this->item->publish_down) < strtotime(Factory::getDate()))) : ?>
    		<div class="system-unpublished">
    	<?php endif; ?>
    
    	<?php echo LayoutHelper::render('joomla.content.blog_style_default_item_title', $this->item); ?>
    
    	<?php if ($canEdit) : ?>
    		<?php echo LayoutHelper::render('joomla.content.icons', array('params' => $params, 'item' => $this->item)); ?>
    	<?php endif; ?>
    
    	<?php // Todo Not that elegant would be nice to group the params ?>
    	<?php $useDefList = ($params->get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date')
    		|| $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam); ?>
    
    	<?php if ($useDefList && ($info == 0 || $info == 2)) : ?>
    		<?php echo LayoutHelper::render('joomla.content.info_block', array('item' => $this->item, 'params' => $params, 'position' => 'above')); ?>
    	<?php endif; ?>
    	<?php if ($info == 0 && $params->get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
    		<?php echo LayoutHelper::render('joomla.content.tags', $this->item->tags->itemTags); ?>
    	<?php endif; ?>
    
    	<?php if (!$params->get('show_intro')) : ?>
    		<?php // Content is generated by content plugin event "onContentAfterTitle" ?>
    		<?php echo $this->item->event->afterDisplayTitle; ?>
    	<?php endif; ?>
    
    	<?php // Content is generated by content plugin event "onContentBeforeDisplay" ?>
    	<?php echo $this->item->event->beforeDisplayContent; ?>
    
    	<?php echo $this->item->introtext; ?>
    
    	<?php if ($info == 1 || $info == 2) : ?>
    		<?php if ($useDefList) : ?>
    			<?php echo LayoutHelper::render('joomla.content.info_block', array('item' => $this->item, 'params' => $params, 'position' => 'below')); ?>
    		<?php endif; ?>
    		<?php if ($params->get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
    			<?php echo LayoutHelper::render('joomla.content.tags', $this->item->tags->itemTags); ?>
    		<?php endif; ?>
    	<?php endif; ?>
    
    	<?php if ($params->get('show_readmore') && $this->item->readmore) :
    		if ($params->get('access-view')) :
    			$link = Route::_(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language));
    		else :
    			$menu = Factory::getApplication()->getMenu();
    			$active = $menu->getActive();
    			$itemId = $active->id;
    			$link = new Uri(Route::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false));
    			$link->setVar('return', base64_encode(RouteHelper::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language)));
    		endif; ?>
    
    		<?php echo LayoutHelper::render('joomla.content.readmore', array('item' => $this->item, 'params' => $params, 'link' => $link)); ?>
    
    	<?php endif; ?>
    
    	<?php if ($this->item->stage_condition == ContentComponent::CONDITION_UNPUBLISHED || strtotime($this->item->publish_up) > strtotime(Factory::getDate())
    		|| (!is_null($this->item->publish_down) && strtotime($this->item->publish_down) < strtotime(Factory::getDate()))) : ?>
    	</div>
    	<?php endif; ?>
    </div>
    
    <?php // Content is generated by content plugin event "onContentAfterDisplay" ?>
    <?php echo $this->item->event->afterDisplayContent; ?>
  • Le fichier blog_links.php
    <?php
    /**
     * @package     Joomla.Site
     * @subpackage  com_content
     *
     * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
     * @license     GNU General Public License version 2 or later; see LICENSE.txt
     */
    
    defined('_JEXEC') or die;
    
    use Joomla\CMS\Router\Route;
    use Joomla\Component\Content\Site\Helper\RouteHelper;
    
    ?>
    
    <ol class="com-content-category-blog__links nav nav-tabs nav-stacked">
    	<?php foreach ($this->link_items as &$item) : ?>
    		<li class="com-content-category-blog__link">
    			<a href="<?php echo Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language)); ?>">
    				<?php echo $item->title; ?></a>
    		</li>
    	<?php endforeach; ?>
    </ol>

Une dernière étape pour la route...

Maintenant, revenz au module Recherche avancée que vous avez créé plus tôt.

Ouvrez le et dans l'onglet Paramètres avancés sélectionnez override-kb (ou le nom que vous avez donné à votre override) dans le paramètre Type de mise en page.

Joomla - Module parameter

Lorsque c'est fait, cliquez sur le bouton Enregistrer et fermer.

Le frontend

J'ai rajouté quelques modifications CSS mais si vous avez suivi avec attention toutes les étapes de ce tutoriel, votre base de connaissance devrait ressembler à quelque chose comme ça :

Joomla Knowledge Base Override

La vue Catégories

Joomla Knowledge Base Override

La vue Catégorie

Le Joomla Override Challenge

En association avec Viviana Menzel, nous avons créé le non-officiel Joomla Override Challenge. Le but est de créer chaque mois, une override basée sur une extension native de Joomla ou sur un projet. Si vous souhaitez participer, n'hésitez pas à contacter Viviana ou moi :)

Daniel Dubois - auteur à web-eau.net

A propos de Daniel

Passionné par le Web depuis 2007, Daniel défend la veuve et l'orphelin du web en créant des sites respectueux du W3C. Fort de son expérience, il partage ses connaissances dans un état d'esprit open source. Très impliqué en faveur du CMS Joomla depuis 2014, il est également conférencier et fondateur du Joomla User Group Breizh.

web-eau.net

29800 Landerneau

06 74 50 27 99

daniel@web-eau.net

Liens rapides