Développer un plugin, injection automatique, 2e partie

On va maintenant s’intéresser à la partie affichage côté public en relation avec l’un des deux behaviors en question (voir le billet d’hier à ce sujet).

Pour cela, jetons un œil au fichier _public.php où tout est traité :

<?php
/**
 * @brief a11yConfig, a plugin for Dotclear 2
 *
 * @package Dotclear
 * @subpackage Plugins
 *
 * @author Franck Paul, Biou and contributors
 *
 * @copyright Franck Paul carnet.franck.paul@gmail.com
 * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
 */

if (!defined('DC_RC_PATH')) {return;}

require dirname(__FILE__) . '/_widgets.php';

$core->addBehavior('publicHeadContent', array('a11yconfigPublic', 'publicHeadContent'));
$core->addBehavior('publicTopAfterContent', array('a11yconfigPublic', 'publicTopAfterContent'));
$core->addBehavior('publicFooterContent', array('a11yconfigPublic', 'publicFooterContent'));

class a11yconfigPublic
{
    public static function publicHeadContent($core, $_ctx)
    {
        $core->blog->settings->addNamespace('a11yConfig');
        if (!(boolean) $core->blog->settings->a11yConfig->active) {
            return;
        }

        echo
        dcUtils::cssLoad($core->blog->getPF('a11yConfig/lib/css/accessconfig.min.css')) .
        dcUtils::cssLoad($core->blog->getPF('a11yConfig/css/public.css')) .
        dcUtils::jsLoad($core->blog->getPF('a11yConfig/js/public.js')) .
        dcUtils::jsLoad($core->blog->getPF('a11yConfig/lib/js/accessconfig.min.js'));
    }

    public static function publicTopAfterContent($core, $_ctx)
    {
        $core->blog->settings->addNamespace('a11yConfig');
        if (!(boolean) $core->blog->settings->a11yConfig->active) {
            return;
        }

        if (!(boolean) $core->blog->settings->a11yConfig->injection) {
            return;
        }

        if ((integer) $core->blog->settings->a11yConfig->position !== 0) {
            return;
        }

        $params = [
            "Font"             => (boolean) $core->blog->settings->a11yConfig->font,
            "LineSpacing"      => (boolean) $core->blog->settings->a11yConfig->linespacing,
            "Justification"    => (boolean) $core->blog->settings->a11yConfig->justification,
            "Contrast"         => (boolean) $core->blog->settings->a11yConfig->contrast,
            "ImageReplacement" => (boolean) $core->blog->settings->a11yConfig->image
        ];

        echo a11yconfigPublic::render($core->blog->settings->a11yConfig->label, $params);
    }

    public static function publicFooterContent($core, $_ctx)
    {
        $core->blog->settings->addNamespace('a11yConfig');
        if (!(boolean) $core->blog->settings->a11yConfig->active) {
            return;
        }

        if (!(boolean) $core->blog->settings->a11yConfig->injection) {
            return;
        }

        if ((integer) $core->blog->settings->a11yConfig->position !== 1) {
            return;
        }

        $params = [
            "Font"             => (boolean) $core->blog->settings->a11yConfig->font,
            "LineSpacing"      => (boolean) $core->blog->settings->a11yConfig->linespacing,
            "Justification"    => (boolean) $core->blog->settings->a11yConfig->justification,
            "Contrast"         => (boolean) $core->blog->settings->a11yConfig->contrast,
            "ImageReplacement" => (boolean) $core->blog->settings->a11yConfig->image
        ];

        echo a11yconfigPublic::render($core->blog->settings->a11yConfig->label, $params);
    }

    # Widget function
    public static function a11yconfigWidget($w)
    {
        global $core;

        $core->blog->settings->addNamespace('a11yConfig');
        if (!(boolean) $core->blog->settings->a11yConfig->active) {
            return;
        }

        if ($w->offline) {
            return;
        }

        $params = [
            "Font"             => ($w->font ? true : false),
            "LineSpacing"      => ($w->linespacing ? true : false),
            "Justification"    => ($w->justification ? true : false),
            "Contrast"         => ($w->contrast ? true : false),
            "ImageReplacement" => ($w->image ? true : false)
        ];

        return a11yconfigPublic::render($w->buttonname, $params);
    }

    # Render function
    private static function render($label, $params)
    {
        $options = [
            "Prefix"           => "a42-ac",
            "Modal"            => true,
            "Font"             => true,
            "LineSpacing"      => true,
            "Justification"    => true,
            "Contrast"         => true,
            "ImageReplacement" => true
        ];
        $options = array_merge($options, $params);

        return
        '<div class="widget" id="accessconfig" data-accessconfig-buttonname="' .
        ($label ? html::escapeHTML($label) : __('Accessibility parameters')) . '" ' .
        'data-accessconfig-params=\'' . json_encode($options) . '\'>' .
            '</div>';
    }
}

Je vais détailler ce qui a été modifié depuis la dernière version.

Premièrement, lignes 19 et 20, enregistrement des deux traitements liés aux deux behaviors publicTopAfterContent (utilisé si on choisi l’insertion dans l’entête du blog) et publicFooterContent (utilisé pour l’insertion en pied de page).

Les deux traitements, lignes 38 à 62 pour le premier et lignes 64 à 88 pour le second, sont quasiment identiques à la seule différence près que le test de la position choisie diffère.

Dans l’ordre, on vérifie que le plugin est actif, sinon on sort, puis on vérifie que l’insertion est activée, sinon on sort, puis on vérifie que la position correspond au traitement, sinon on sort, puis on prépare les éléments nécessaires (libellés et options) pour la fonction qui génèrera le code requis.

J’ai d’ailleurs modifié la fonction de traitement du widget pour qu’elle utilise aussi cette fonction de génération du code requis ; ça permettra de simplifier la maintenance si celui-ci venait à évoluer.

Pour être tout à fait complet, on pourrait également « factoriser » les deux traitements ajoutés ce jour vu qu’ils partagent quasiment le même code. Je vous laisse faire l’exercice si ça vous chante !

Pour info, les deux behaviors que j’utilise sont présents dans les jeux de template. Voilà celui de l’entête, dans le fichier _top.html (je prends comme exemple le jeu de template dotty, mais on les retrouve aussi dans mustek et currywurst), à la ligne 15 :

<div class="header">
		<ul class="skip-links" id="prelude">
			<li><a href="#main">{{tpl:lang To content}}</a></li>
			<li><a href="#blognav">{{tpl:lang To menu}}</a></li>
			<li><a href="#search">{{tpl:lang To search}}</a></li>
		</ul>

	<header class="banner" role="banner">
		<h1 class="site-title"><a class="site-title__link"
			href="{{tpl:BlogURL}}"><span class="site-title__text">{{tpl:BlogName encode_html="1"}}</span></a></h1>
		<p class="site-baseline">{{tpl:BlogDescription}}</p>
	</header>

	<!-- # --BEHAVIOR-- publicTopAfterContent -->
	{{tpl:SysBehavior behavior="publicTopAfterContent"}}

	{{tpl:SimpleMenu class="nav header__nav"}}
</div>

Et pour le pied de page, dans le fichier _footer.html, à la ligne 15 également :

<p id="gotop"><a href="#prelude">{{tpl:lang Page top}}</a></p>

<footer class="footer" id="footer" role="contentinfo">
	<tpl:IfWidgets type="custom">
		<div class="widgets footer__widgets" id="blogcustom">
	        <h2 class="blogcustom__title">{{tpl:lang Blog info}}</h2>
			{{tpl:Widgets type="custom"}}
		</div> <!-- # End #custom widgets -->
	</tpl:IfWidgets>

	{{tpl:SysBehavior behavior="publicInsideFooter"}}

	<p>{{tpl:SysPoweredBy}}</p>
</footer>
{{tpl:SysBehavior behavior="publicFooterContent"}}

{{tpl:include src="user_footer.html"}}

Côté public (partie visible du blog), une fois l’insertion automatique activée avec une position en entête sur le thème Berlin, voilà ce qu’on obtient :

a11yConfig : insertion automatique en entête du thème Berlin, déc. 2019

Libre à vous ensuite de styler ce bouton en fonction de vos envies et de vos goûts, mais on sort du cadre de ces billets !


Pour la suite, on verra comment mettre en place une balise template — sachant qu’on peut d’ores et déjà utiliser la balise widget pour intégrer le bouton à l’endroit que l’on souhaite (voir l’aparté à ce sujet dans ce billet). Pas certain qu’il faille conserver cette partie là à terme dans la version finale du plugin, on en reparlera.

Puis on se tournera enfin vers l’application de l’outil d’Access42 sur l’administration de Dotclear ; après tout il n’y a pas de raison de ne pas proposer ça ici aussi. Comme je dis souvent, le backend est le le frontend des administrateurs et rédacteurs ;-)

Ajouter un commentaire

Les commentaires peuvent être formatés en utilisant la syntaxe Markdown Extra.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/14433

Haut de page