<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="https://dotclear.watch/feed/rss2/xslt" ?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>DotclearWatch / Blog - Mot-clé - 2.27</title>
    <link>https://dotclear.watch/</link>
    <atom:link href="https://dotclear.watch/feed/tag/2.27/rss2" rel="self" type="application/rss+xml" />
    <description>Suivez l'évolution du moteur de blogs Dotclear.</description>
    <language>fr</language>
    <pubDate>Mon, 27 Jul 2026 06:02:24 +0200</pubDate>
    <copyright>Tous droits réservés © Jean-Christian Denis</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>Dotclear</generator>
          <item>
        <title>Sortie de Dotclear 2.27</title>
        <link>https://dotclear.watch/Billet/Sortie-de-Dotclear-2.27</link>
        <guid isPermaLink="false">urn:md5:4222cdc9e8ec783dd063e1245efe9743</guid>
        <pubDate>Sun, 13 Aug 2023 10:00:00 +0200</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>Actualités</category>
                          <category>2.27</category>
                  <category>release</category>
                <description>&lt;p&gt;Ce dimanche 13 Août 2023 sort la version 2.27 du moteur de blogs Dotclear.&lt;/p&gt; &lt;p&gt;En plus de la sortie de cette version 2.27, le 13 Août est la date anniversaire de Dotclear et cette année le moteur de blog fête ses 20 ans d'existence ! Vous pouvez aller lui souhaiter un bon anniversaire sur &lt;a href=&quot;https://fr.dotclear.org/blog/post/2023/08/13/Dotclear-2.27&quot; hreflang=&quot;fr&quot; title=&quot;Dotclear 2.27&quot;&gt;le billet d'annonce officielle&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
C'est également l'occasion pour &lt;a href=&quot;https://dotclear.watch/Billet/La-plateforme-dotclear.watch&quot;&gt;la plateforme&lt;/a&gt; non-officielle &lt;strong&gt;dotclear.watch&lt;/strong&gt; de faire son lancement, en proposant aux développeurs toute une série de billets dédiés à l'explication des &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;évolutions de cette version 2.27&lt;/a&gt;.&lt;/p&gt;</description>
        
                  <comments>https://dotclear.watch/Billet/Sortie-de-Dotclear-2.27#comment-form</comments>
          <wfw:comment>https://dotclear.watch/Billet/Sortie-de-Dotclear-2.27#comment-form</wfw:comment>
          <wfw:commentRss>https://dotclear.watch/feed/atom/comments/58</wfw:commentRss>
              </item>
          <item>
        <title>Fichier Install d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-Install-d-un-module</link>
        <guid isPermaLink="false">urn:md5:374cf218364b206c7b7fe9a6bba42317</guid>
        <pubDate>Sun, 16 Jul 2023 20:51:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>admin</category>
                  <category>install</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>structure</category>
                  <category>theme</category>
                  <category>update</category>
                <description>&lt;p&gt;Le fichier &lt;strong&gt;Install.php&lt;/strong&gt;, placé dans &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;le dossier src&lt;/a&gt; du module, permet d'effectuer ses opérations d'installation et de mise à jour.&lt;/p&gt; &lt;p&gt;Le fichier &lt;strong&gt;Install.php&lt;/strong&gt; fait partie du processus reconnu par le gestionnaire de modules, il est donc automatiquement pris en compte coté admin si il existe.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il est placé dans le sous dossier &lt;code&gt;src&lt;/code&gt; du module,&lt;/li&gt;
&lt;li&gt;Il contient une classe du nom de &lt;code&gt;Install&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Il est dans l'espace de nom PHP &lt;code&gt;Dotclear\Plugin\monPlugin&lt;/code&gt; ou &lt;code&gt;Dotclear\Theme\monTheme&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;La classe doit étendre &lt;a href=&quot;https://dotclear.watch/Billet/La-class-Process&quot;&gt;la classe Process&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Seules les méthodes &lt;code&gt;init()&lt;/code&gt; et &lt;code&gt;process()&lt;/code&gt; sont utilisées,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce fichier est chargé en préambule de la page d'accueil de l'admin, de la page de gestion de l'apparence du blog, et de la page de gestion des plugins. Généralement il permet d'enregistrer des paramètres, de créer des tables, etc.&lt;br /&gt;
La méthode &lt;code&gt;init()&lt;/code&gt; de la classe &lt;strong&gt;doit&lt;/strong&gt; vérifier que la version installée n'existe pas ou qu'elle est à mettre à jour, elle doit renvoyer &lt;code&gt;false&lt;/code&gt; si il n'y a pas besoin d'effectuer ces opérations d'installation / mise à jour. Pour aider, &lt;a href=&quot;https://dotclear.watch/Billet/Les-classes-de-module-My&quot;&gt;la classe My&lt;/a&gt; embarque un contexte qui permet cela &lt;code&gt;My::checkContext(My::INSTALL)&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Exemple du plugin blogroll de la distribution qui ajoute une table à la base de données :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
declare(strict_types=1);

namespace Dotclear\Plugin\blogroll;

use dcCore;
use Dotclear\Core\Process;
use Dotclear\Database\Structure;
use initBlogroll;

class Install extends Process
{
    public static function init(): bool
    {
        return self::status(My::checkContext(My::INSTALL));
    }

    public static function process(): bool
    {
        if (!self::status()) {
            return false;
        }

        $schema = new Structure(dcCore::app()-&amp;gt;con, dcCore::app()-&amp;gt;prefix);

        $schema-&amp;gt;{initBlogroll::LINK_TABLE_NAME}
            -&amp;gt;link_id(&amp;#039;bigint&amp;#039;, 0, false)
            -&amp;gt;blog_id(&amp;#039;varchar&amp;#039;, 32, false)
            -&amp;gt;link_href(&amp;#039;varchar&amp;#039;, 255, false)
            -&amp;gt;link_title(&amp;#039;varchar&amp;#039;, 255, false)
            -&amp;gt;link_desc(&amp;#039;varchar&amp;#039;, 255, true)
            -&amp;gt;link_lang(&amp;#039;varchar&amp;#039;, 5, true)
            -&amp;gt;link_xfn(&amp;#039;varchar&amp;#039;, 255, true)
            -&amp;gt;link_position(&amp;#039;integer&amp;#039;, 0, false, 0)

            -&amp;gt;primary(&amp;#039;pk_link&amp;#039;, &amp;#039;link_id&amp;#039;)
            -&amp;gt;index(&amp;#039;idx_link_blog_id&amp;#039;, &amp;#039;btree&amp;#039;, &amp;#039;blog_id&amp;#039;)
            -&amp;gt;reference(&amp;#039;fk_link_blog&amp;#039;, &amp;#039;blog_id&amp;#039;, &amp;#039;blog&amp;#039;, &amp;#039;blog_id&amp;#039;, &amp;#039;cascade&amp;#039;, &amp;#039;cascade&amp;#039;)
        ;

        (new Structure(dcCore::app()-&amp;gt;con, dcCore::app()-&amp;gt;prefix))-&amp;gt;synchronize($schema);

        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier Config d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-Config-d-un-module</link>
        <guid isPermaLink="false">urn:md5:996cf791be01db13a047003087fe99f3</guid>
        <pubDate>Sun, 16 Jul 2023 14:03:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>admin</category>
                  <category>backend</category>
                  <category>config</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>structure</category>
                  <category>theme</category>
                <description>&lt;p&gt;Le fichier &lt;strong&gt;Config.php&lt;/strong&gt;, placé dans &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;le dossier src&lt;/a&gt; du module, simplifie la gestion de sa configuration.&lt;/p&gt; &lt;p&gt;Le fichier &lt;strong&gt;Config.php&lt;/strong&gt; fait partie du processus reconnu par le gestionnaire de modules, il est donc automatiquement pris en compte dans l'administration si il existe.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il est placé dans le sous dossier &lt;code&gt;src&lt;/code&gt; du module,&lt;/li&gt;
&lt;li&gt;Il contient une classe du nom de &lt;code&gt;Config&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Il est dans l'espace de nom PHP &lt;code&gt;Dotclear\Plugin\monPlugin&lt;/code&gt; ou &lt;code&gt;Dotclear\Theme\monTheme&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;La classe doit étendre &lt;a href=&quot;https://dotclear.watch/Billet/La-class-Process&quot;&gt;la classe Process&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Les 3 méthodes &lt;code&gt;init()&lt;/code&gt; et &lt;code&gt;process()&lt;/code&gt; et &lt;code&gt;render()&lt;/code&gt; sont utilisées,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cette classe simplifie la gestion de la configuration d'un module dans le sens où la partie construction de la page est déjà effectuée par le gestionnaire de modules. Seul le traitement des valeurs et le contenu du formulaire sont à la charge de la classe Config. Un lien vers cette page sera ajouté à la liste de plugins ou sur les thèmes de la page de gestion d'apparence du blog. Un lien sera également ajouté en bas de page principale de gestion du plugin si elle existe.&lt;br /&gt;
&lt;br /&gt;
Exemple complet du fichier config du thème customCSS de la distribution :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
namespace Dotclear\Theme\customCSS;

use dcCore;
use Dotclear\Core\Backend\Notices;
use Dotclear\Core\Process;
use Dotclear\Helper\File\Path;
use Dotclear\Helper\Html\Html;
use Dotclear\Helper\L10n;
use Exception;
use form;

class Config extends Process
{
    public static function init(): bool
    {
        if (My::checkContext(My::CONFIG)) {
            My::l10n(&amp;#039;main&amp;#039;);
            dcCore::app()-&amp;gt;admin-&amp;gt;css_file = Path::real(dcCore::app()-&amp;gt;blog-&amp;gt;public_path) . &amp;#039;/custom_style.css&amp;#039;;

            if (!is_file(dcCore::app()-&amp;gt;admin-&amp;gt;css_file) &amp;amp;&amp;amp; !is_writable(dirname(dcCore::app()-&amp;gt;admin-&amp;gt;css_file))) {
                throw new Exception(
                    sprintf(
                        __(&amp;#039;File %s does not exist and directory %s is not writable.&amp;#039;),
                        dcCore::app()-&amp;gt;admin-&amp;gt;css_file,
                        dirname(dcCore::app()-&amp;gt;admin-&amp;gt;css_file)
                    )
                );
            }
            self::status(true);
        }

        return self::status();
    }

    public static function process(): bool
    {
        if (!self::status()) {
            return false;
        }

        if (isset($_POST[&amp;#039;css&amp;#039;])) {
            @$fp = fopen(dcCore::app()-&amp;gt;admin-&amp;gt;css_file, &amp;#039;wb&amp;#039;);
            fwrite($fp, $_POST[&amp;#039;css&amp;#039;]);
            fclose($fp);

            Notices::message(__(&amp;#039;Style sheet upgraded.&amp;#039;), true, true);
        }

        return true;
    }

    public static function render(): void
    {
        if (!self::status()) {
            return;
        }

        $css_content = is_file(dcCore::app()-&amp;gt;admin-&amp;gt;css_file) ? file_get_contents(dcCore::app()-&amp;gt;admin-&amp;gt;css_file) : &amp;#039;&amp;#039;;

        echo
        &amp;#039;&amp;lt;p class=&amp;quot;area&amp;quot;&amp;gt;&amp;lt;label&amp;gt;&amp;#039; . __(&amp;#039;Style sheet:&amp;#039;) . &amp;#039;&amp;lt;/label&amp;gt; &amp;#039; .
        form::textarea(&amp;#039;css&amp;#039;, 60, 20, Html::escapeHTML($css_content)) . &amp;#039;&amp;lt;/p&amp;gt;&amp;#039;;
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier Frontend d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-Frontend-d-un-module</link>
        <guid isPermaLink="false">urn:md5:bc70744ae6bb3074af21de368e3b26fd</guid>
        <pubDate>Sun, 16 Jul 2023 13:48:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>frontend</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>public</category>
                  <category>structure</category>
                  <category>theme</category>
                <description>&lt;p&gt;Le fichier &lt;strong&gt;Frontend.php&lt;/strong&gt;, placé dans &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;le dossier src&lt;/a&gt; du module, permet de préparer le nécessaire à son fonctionnement en partie public.&lt;/p&gt; &lt;p&gt;Le fichier &lt;strong&gt;Frontend.php&lt;/strong&gt; fait partie du processus reconnu par le gestionnaire de modules, il est donc automatiquement pris en compte coté public si il existe.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il est placé dans le sous dossier &lt;code&gt;src&lt;/code&gt; du module,&lt;/li&gt;
&lt;li&gt;Il contient une classe du nom de &lt;code&gt;Frontend&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Il est dans l'espace de nom PHP &lt;code&gt;Dotclear\Plugin\monPlugin&lt;/code&gt; ou &lt;code&gt;Dotclear\Theme\monTheme&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;La classe doit étendre &lt;a href=&quot;https://dotclear.watch/Billet/La-class-Process&quot;&gt;la classe Process&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Seules les méthodes &lt;code&gt;init()&lt;/code&gt; et &lt;code&gt;process()&lt;/code&gt; sont utilisées,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Généralement cette classe est utilisée pour préparer des variables nécessaires au fonctionnement du module, déclarer ses templates, ajouter ses behaviors, pour la partie publique des blogs.&lt;br /&gt;
&lt;br /&gt;
Exemple du fichier Frontend.php du plugin &lt;strong&gt;blogroll&lt;/strong&gt; de la distribution :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
declare(strict_types=1);

namespace Dotclear\Plugin\blogroll;

use dcCore;
use Dotclear\Core\Process;

class Frontend extends Process
{
    public static function init(): bool
    {
        return self::status(My::checkContext(My::FRONTEND));
    }

    public static function process(): bool
    {
        if (!self::status()) {
            return false;
        }

        dcCore::app()-&amp;gt;tpl-&amp;gt;addValue(&amp;#039;Blogroll&amp;#039;, [FrontendTemplate::class, &amp;#039;blogroll&amp;#039;]);
        dcCore::app()-&amp;gt;tpl-&amp;gt;addValue(&amp;#039;BlogrollXbelLink&amp;#039;, [FrontendTemplate::class, &amp;#039;blogrollXbelLink&amp;#039;]);

        dcCore::app()-&amp;gt;addBehaviors([
            &amp;#039;initWidgets&amp;#039;        =&amp;gt; [Widgets::class, &amp;#039;initWidgets&amp;#039;],
            &amp;#039;initDefaultWidgets&amp;#039; =&amp;gt; [Widgets::class, &amp;#039;initDefaultWidgets&amp;#039;],
        ]);

        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier Backend d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-Backend-d-un-module</link>
        <guid isPermaLink="false">urn:md5:fa3c0167756c3590593aa2a46afc6459</guid>
        <pubDate>Sun, 16 Jul 2023 13:36:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>admin</category>
                  <category>backend</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>structure</category>
                  <category>theme</category>
                <description>&lt;p&gt;Le fichier &lt;strong&gt;Backend.php&lt;/strong&gt;, placé dans &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;le dossier src&lt;/a&gt; du module, permet de préparer le nécessaire à son fonctionnement pour sa partie administration.&lt;/p&gt; &lt;p&gt;Le fichier &lt;strong&gt;Backend.php&lt;/strong&gt; fait partie du processus reconnu par le gestionnaire de modules, il est donc automatiquement pris en compte dans l'administration si il existe.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il est placé dans le sous dossier &lt;code&gt;src&lt;/code&gt; du module,&lt;/li&gt;
&lt;li&gt;Il contient une classe du nom de &lt;code&gt;Backend&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Il est dans l'espace de nom PHP &lt;code&gt;Dotclear\Plugin\monPlugin&lt;/code&gt; ou &lt;code&gt;Dotclear\Theme\monTheme&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;La classe doit étendre &lt;a href=&quot;https://dotclear.watch/Billet/La-class-Process&quot;&gt;la classe Process&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Seules les méthodes &lt;code&gt;init()&lt;/code&gt; et &lt;code&gt;process()&lt;/code&gt; sont utilisées,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Généralement cette classe est utilisée pour préparer des variables nécessaires au fonctionnement du module, ajouter ses menus, favoris, behaviors, pour la partie administration des blogs.&lt;br /&gt;
&lt;br /&gt;
Exemple du fichier Backend.php du plugin &lt;strong&gt;aboutConfig&lt;/strong&gt; de la distribution :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
declare(strict_types=1);

namespace Dotclear\Plugin\aboutConfig;

use Dotclear\Core\Backend\Menus;
use Dotclear\Core\Process;

class Backend extends Process
{
    public static function init(): bool
    {
        return self::status(My::checkContext(My::BACKEND));
    }

    public static function process(): bool
    {
        if (self::status()) {
            My::addBackendMenuItem(Menus::MENU_SYSTEM);
        }

        return self::status();
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier Prepend d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-Prepend-d-un-module</link>
        <guid isPermaLink="false">urn:md5:35e77dec2b2fe2b2ee0241ae66d0a41c</guid>
        <pubDate>Sun, 16 Jul 2023 10:38:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>admin</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>prepend</category>
                  <category>public</category>
                  <category>structure</category>
                  <category>theme</category>
                <description>&lt;p&gt;Le fichier &lt;strong&gt;Prepend.php&lt;/strong&gt;, placé dans &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;le dossier src&lt;/a&gt; du module, permet de préparer le nécessaire à son fonctionnement.&lt;/p&gt; &lt;p&gt;Le fichier &lt;strong&gt;Prepend.php&lt;/strong&gt; fait partie du processus reconnu par le gestionnaire de modules, il est donc automatiquement pris en compte si il existe.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Il est placé dans le sous dossier &lt;code&gt;src&lt;/code&gt; du module,&lt;/li&gt;
&lt;li&gt;Il contient une classe du nom de &lt;code&gt;Prepend&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Il est dans l'espace de nom PHP &lt;code&gt;Dotclear\Plugin\monPlugin&lt;/code&gt; ou &lt;code&gt;Dotclear\Theme\monTheme&lt;/code&gt;,,&lt;/li&gt;
&lt;li&gt;La classe doit étendre &lt;a href=&quot;https://dotclear.watch/Billet/La-class-Process&quot;&gt;la classe Process&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Seuls les méthodes &lt;code&gt;init()&lt;/code&gt; et &lt;code&gt;process()&lt;/code&gt; sont utilisées,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Généralement cette classe est utilisée pour préparer des variables nécessaires au fonctionnement global du module ou pour ajouter des behaviors, à la fois coté admin &lt;strong&gt;et&lt;/strong&gt; coté public. Si ces définitions sont propres à l'admin ou au public, il faut utiliser les fichiers Backend.php ou Frontend.php.&lt;br /&gt;
&lt;br /&gt;
Exemple du fichier Prepend.php du plugin &lt;strong&gt;blogroll&lt;/strong&gt; de la distribution :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
declare(strict_types=1);

namespace Dotclear\Plugin\blogroll;

use dcCore;
use Dotclear\Core\Process;

class Prepend extends Process
{
    public static function init(): bool
    {
        return self::status(My::checkContext(My::PREPEND));
    }

    public static function process(): bool
    {
        if (!self::status()) {
            return false;
        }

        dcCore::app()-&amp;gt;url-&amp;gt;register(&amp;#039;xbel&amp;#039;, &amp;#039;xbel&amp;#039;, &amp;#039;^xbel(?:\/?)$&amp;#039;, [FrontendUrl::class, &amp;#039;xbel&amp;#039;]);

        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier release de Dotclear</title>
        <link>https://dotclear.watch/Billet/Fichier-release-de-Dotclear</link>
        <guid isPermaLink="false">urn:md5:26c7ccf49926dae04de1035555807f6c</guid>
        <pubDate>Fri, 14 Jul 2023 23:01:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>json</category>
                  <category>release</category>
                <description>&lt;p&gt;Avec la &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt; de Dotclear, un nouveau fichier &lt;strong&gt;release.json&lt;/strong&gt; fait son apparition.&lt;/p&gt; &lt;p&gt;Ce fichier au format &lt;strong&gt;json&lt;/strong&gt;, présent à la racine de l'installation, définit les variables susceptibles de changer d'une version à l'autre. Dans les versions précédentes de Dotclear, elles étaient définies dans des constantes principalement dans le fichier &lt;code&gt;inc/_prepend.php&lt;/code&gt;. Bien que définies autrement ces valeurs sont toujours accessibles à partir des mêmes constantes. On peut également les lire à partir de la méthode &lt;code&gt;release()&lt;/code&gt; de la classe &lt;code&gt;App&lt;/code&gt;, ces valeurs sont &quot;chargées&quot; une seule fois et ne peuvent être modifiées pendant toute l'exécution du script..&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
use Dotclear\App;

// renvoie &amp;#039;2.27&amp;#039;
echo App::release(&amp;#039;release_version&amp;#039;);

// renvoie &amp;#039;8.1&amp;#039;
echo App::release(&amp;#039;next_php&amp;#039;);

// renvoie &amp;#039;berlin,blowup,blueSilence,customCSS,ductile&amp;#039;
echo App::release(&amp;#039;distributed_themes&amp;#039;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Toutes les valeurs renvoyées par cette méthode sont de type &lt;strong&gt;string&lt;/strong&gt;. Les valeurs sous forme de tableau du fichier release seront concaténées sous forme de chaîne.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
                  <comments>https://dotclear.watch/Billet/Fichier-release-de-Dotclear#comment-form</comments>
          <wfw:comment>https://dotclear.watch/Billet/Fichier-release-de-Dotclear#comment-form</wfw:comment>
          <wfw:commentRss>https://dotclear.watch/feed/atom/comments/21</wfw:commentRss>
              </item>
          <item>
        <title>Fichier de dépôt tiers</title>
        <link>https://dotclear.watch/Billet/Fichier-de-d%C3%A9p%C3%B4t-tiers</link>
        <guid isPermaLink="false">urn:md5:863e109677409c77fbe94c8592ae92d0</guid>
        <pubDate>Fri, 14 Jul 2023 20:25:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>depot</category>
                  <category>module</category>
                  <category>plug</category>
                  <category>repository</category>
                  <category>theme</category>
                <description>&lt;p&gt;Depuis quelques versions le gestionnaire de modules de Dotclear supporte les dépôts tiers. Le fichier dcstore.xml se trouvant à la &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;racine du module&lt;/a&gt; permet de définir ce dépôt.&lt;/p&gt; &lt;p&gt;En réalité l'emplacement de ce fichier n'est pas dans le module mais là où est hébergé le dépôt tiers ! Par commodité et comme souvent le dépôt tiers est un dépôt github en le plaçant dans le module, le développeur garantit qu'il sera présent sur son dépôt.&lt;br /&gt;
L'emplacement final de ce fichier est renseigné dans le &lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-module&quot;&gt;fichier de définition du module&lt;/a&gt; dans le paramètre &lt;code&gt;'repository'&lt;/code&gt;.&lt;br /&gt;
Son contenu est écrit en xml et est calqué sur le &lt;a href=&quot;https://dotaddict.org&quot; hreflang=&quot;fr&quot; title=&quot;Dotaddict&quot;&gt;dépôt officiel Dotaddict.org&lt;/a&gt;. Voici l'exemple du plugin tweakStore :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;modules xmlns:da=&amp;quot;http://dotaddict.org/da/&amp;quot;&amp;gt;
  &amp;lt;module id=&amp;quot;tweakStores&amp;quot;&amp;gt;
    &amp;lt;name&amp;gt;Tweak stores&amp;lt;/name&amp;gt;
    &amp;lt;version&amp;gt;0.8&amp;lt;/version&amp;gt;
    &amp;lt;author&amp;gt;Jean-Christian Denis and Contributors&amp;lt;/author&amp;gt;
    &amp;lt;desc&amp;gt;Helper to manage external repositories&amp;lt;/desc&amp;gt;
    &amp;lt;file&amp;gt;https://github.com/JcDenis/tweakStores/releases/download/v0.8/plugin-tweakStores.zip&amp;lt;/file&amp;gt;
    &amp;lt;da:dcmin&amp;gt;2.26&amp;lt;/da:dcmin&amp;gt;
    &amp;lt;da:details&amp;gt;https://plugins.dotaddict.org/dc2/details/tweakStores&amp;lt;/da:details&amp;gt;
    &amp;lt;da:support&amp;gt;https://github.com/JcDenis/tweakStores&amp;lt;/da:support&amp;gt;
  &amp;lt;/module&amp;gt;
&amp;lt;/modules&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pas besoin d'explication sur son contenu, il reprend en grande partie les informations présentes dans define.php du module en ajoutant le lien vers le fichier Zip du module.&lt;br /&gt;
&lt;em&gt;N.D.L.R : En théorie un fichier de dépôt tiers pourrait contenir les informations de plusieurs modules, en pratique, je n'ai pas testé.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Il existe &lt;a href=&quot;https://plugins.dotaddict.org/dc2/details/tweakStores&quot; hreflang=&quot;fr&quot; title=&quot;Plugin tweakStores&quot;&gt;des plugins&lt;/a&gt; qui permettent de créer automatiquement ce fichier et également &lt;a href=&quot;https://open-time.net/post/2023/05/25/One-click-only&quot; hreflang=&quot;fr&quot; title=&quot;One click only - Open Time&quot;&gt;des scripts&lt;/a&gt;. (Liens non exhaustifs à titre d'exemple.)&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
                  <comments>https://dotclear.watch/Billet/Fichier-de-d%C3%A9p%C3%B4t-tiers#comment-form</comments>
          <wfw:comment>https://dotclear.watch/Billet/Fichier-de-d%C3%A9p%C3%B4t-tiers#comment-form</wfw:comment>
          <wfw:commentRss>https://dotclear.watch/feed/atom/comments/50</wfw:commentRss>
              </item>
          <item>
        <title>Fichier init d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-init-d-un-module</link>
        <guid isPermaLink="false">urn:md5:7edc6ffa28c9cee7ae40435284934ed9</guid>
        <pubDate>Fri, 14 Jul 2023 19:54:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>init</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>theme</category>
                <description>&lt;p&gt;Le fichier &lt;code&gt;_init.php&lt;/code&gt; d'un module permet principalement d'initialiser des constantes sans même que le module soit chargé. Ce fichier se place à la &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;racine du module&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Le rôle de ce fichier est de pouvoir charger des constantes avant même que le module soit chargé afin de partager avec d'autres modules certaines valeurs et ceci même si le module est désactivé.&lt;br /&gt;
Ce fonctionnement est spécial et ce fichier ne doit contenir que le minimum d'informations qui devront si possible ne pas changer à chaque version du module. &lt;em&gt;(Sinon tout l'intérêt de ce fichier est perdu.)&lt;/em&gt;&lt;br /&gt;
Généralement la classe contenue dans ce fichier permet de définir des noms de permissions ou de tables.&lt;br /&gt;
Exemple tiré du plugin &lt;strong&gt;blogroll&lt;/strong&gt; de la distribution :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
// aucun espace de nom PHP n&amp;#039;est déclaré

// Cette classe sera accessible à tous les autres modules
class initBlogroll
{
    // On définit le nom de la permission liée à blogroll
    public const PERMISSION_BLOGROLL = &amp;#039;blogroll&amp;#039;;

    // On définit le nom de la table de base de données de blogroll
    public const LINK_TABLE_NAME = &amp;#039;link&amp;#039;;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Il est recommandé de garder des noms de classe et de constantes dans le style de l'exemple ci-dessus.&lt;br /&gt;
Cette classe va permettre par exemple au plugin blogroll lui même de définir ses permissions dans son &lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-module&quot;&gt;fichier de définition&lt;/a&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
 
$this-&amp;gt;registerModule(
    // ...
    [
        &amp;#039;permissions&amp;#039; =&amp;gt; dcCore::app()-&amp;gt;auth-&amp;gt;makePermissions([
            initBlogroll::PERMISSION_BLOGROLL,
        ]),
        &amp;#039;type&amp;#039;        =&amp;gt; &amp;#039;plugin&amp;#039;,
    ]
);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Les classes de module My</title>
        <link>https://dotclear.watch/Billet/Les-classes-de-module-My</link>
        <guid isPermaLink="false">urn:md5:56d4aa0e1641bb124a2682004f6231c5</guid>
        <pubDate>Fri, 14 Jul 2023 10:27:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>module</category>
                  <category>my</category>
                  <category>plugin</category>
                  <category>theme</category>
                <description>&lt;p&gt;Dotclear &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt; propose pour les plugins et thèmes des classes d'aide pour simplifier l'écriture du code.&lt;/p&gt; &lt;p&gt;Deux classes My (qui étendent une troisième commune nommé &lt;code&gt;MyModule&lt;/code&gt;) sont disponibles, &lt;code&gt;MyPlugin&lt;/code&gt; pour les plugins et &lt;code&gt;MyTheme&lt;/code&gt; pour les thèmes, elle fournissent des méthodes statiques qui vont simplifier l'écriture des modules.&lt;/p&gt;

&lt;h5&gt;Inclusion&lt;/h5&gt;

&lt;p&gt;Pour les utiliser il suffit d'inclure dans le dossier &lt;code&gt;src&lt;/code&gt; du module un fichier My.php avec le contenu suivant :&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
/**
 * Mettre ici les informations de licence.
 */
declare(strict_types=1);

namespace Dotclear\Plugin\monPlugin;

use Dotclear\Module\MyPlugin;

class My extends MyPlugin
{
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A adapter pour un thème. Il possible d'ajouter ses propres méthodes à cette classe tant que ça n'interfère pas avec celles de MyPlugin, MyTheme et MyModule.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Utilisation&lt;/h5&gt;

&lt;p&gt;Ensuite il sera possible d'utiliser toutes les méthodes de MyPlugin (MyTheme) dans les classes du plugin (thème).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
namespace Dotclear\Plugin\monPlugin;

use Dotclear\Core\Process;
use Dotclear\Core\Backend\Page;

// Page principale de gestion du plugin
class Manage extends Process
{
    public static function init(): bool
    {
        // On vérifie que l&amp;#039;utilisateur à le droit d&amp;#039;exercer dans ce contexte
        return self::status(My::checkContext(My::MANAGE));
    }

    public static function process(): bool
    {
        if (!empty($_POST[&amp;#039;step&amp;#039;])) {
            // ...

            // On redirige la page à l&amp;#039;aide de My
            My::redirect([&amp;#039;step&amp;#039; =&amp;gt; 2]);
        }
    }

    public static function render(): void
    {
        // On utilise la classe My pour trouver le nom du plugin et des fichiers
        Page::openModule(
            My::name(),
            My::cssLoad(&amp;#039;backend&amp;#039;)
        );
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;Méthodes&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;My::define()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;protected static function define(): dcModuleDefine&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie l'instance de définition du module.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::checkContext()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;protected static function checkContext(int $context): bool&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode permet de vérifier que l'utilisateur à le droit d'exercer dans un certain contexte, elle renvoie &lt;strong&gt;true&lt;/strong&gt; si l'utilisateur à assez de droits, &lt;strong&gt;false&lt;/strong&gt; sinon. Elle prend en paramètre le contexte qui doit être vérifier. La liste des contextes prédéfinis est disponible dans les constantes de la classe My :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;0&lt;/strong&gt; : &lt;code&gt;INSTALL&lt;/code&gt; : Install context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1&lt;/strong&gt; : &lt;code&gt;PREPEND&lt;/code&gt; : Prepend context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2&lt;/strong&gt; : &lt;code&gt;FRONTEND&lt;/code&gt; : Frontend context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3&lt;/strong&gt; : &lt;code&gt;BACKEND&lt;/code&gt; : Backend context (usually when the connected user may access at least one functionnality of this module)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4&lt;/strong&gt; : &lt;code&gt;MANAGE &lt;/code&gt; : Manage context (main page of module)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5&lt;/strong&gt; : &lt;code&gt;CONFIG&lt;/code&gt; : Config context (config page of module)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;6&lt;/strong&gt; : &lt;code&gt;MENU&lt;/code&gt; : Menu context (adding a admin menu item)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7&lt;/strong&gt; : &lt;code&gt;WIDGETS&lt;/code&gt; : Widgets context (managing blog's widgets)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;8&lt;/strong&gt; : &lt;code&gt;UNINSTALL&lt;/code&gt; : Uninstall context (réservé pour le plugin Uninstaller)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::checkCustomContext()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;protected static function checkCustomContext(int $context): ?bool&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode est appelée en début de la méthode précédente &lt;strong&gt;checkContext&lt;/strong&gt; et peut être réécrite dans la classe &lt;strong&gt;My&lt;/strong&gt; du module si on en a besoin. Elle permet d'utiliser ses propres droits, ou de modifier des droits de contexte de la méthode précédente. Si &lt;strong&gt;checkCustomContext()&lt;/strong&gt; renvoie &lt;strong&gt;null&lt;/strong&gt; alors les contextes de la classe précédente seront testés.&lt;br /&gt;
Exemple avec le fichiers &lt;strong&gt;My&lt;/strong&gt; du plugin &lt;strong&gt;userPrefs&lt;/strong&gt; de la distribution :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
declare(strict_types=1);

namespace Dotclear\Plugin\userPref;

use dcCore;
use Dotclear\Module\MyPlugin;

class My extends MyPlugin
{
    protected static function checkCustomContext(int $context): ?bool
    {
        // allways limit to super admin
        return defined(&amp;#039;DC_CONTEXT_ADMIN&amp;#039;)
            &amp;amp;&amp;amp; dcCore::app()-&amp;gt;auth-&amp;gt;isSuperAdmin();
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::path()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function My::path(): string&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie le chemin du dossier du module.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::id()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;protected static function My::id(): string&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie l'identifiant du module.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::name()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;protected static function My::name(): string&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie le nom traduit du module.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::settings()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function settings(): ?dcNamespace&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie l'instance de l'espace de paramètres du module. Le module &lt;strong&gt;doit&lt;/strong&gt; utiliser son ID comme nom d'espace de paramètre pour pouvoir utiliser cette méthode.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::prefs()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function prefs(): ?dcWorkspace&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie l'instance de l'espace de préférences du module. Le module &lt;strong&gt;doit&lt;/strong&gt; utiliser son ID comme nom d'espace de préférences pour pouvoir utiliser cette méthode.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::l10n()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function l10n(string $process): void&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode charge les locales du module pour un process donné (main, public, plugin, etc...).&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::fileURL()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function fileURL(string $resource, bool $frontend = false): string&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode retourne l'URL d'un fichier de module. Cette méthode tient compte du contexte courant (admin, public). Pour forcer le retour de l'URL public dans le contexte admin, il suffit de mettre le paramètre &lt;code&gt;$frontend&lt;/code&gt; à &lt;code&gt;true&lt;/code&gt;.&lt;br /&gt;
A noter que pour les thèmes, cette méthode renvoie toujours l'URL publique.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::cssLoad()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function cssLoad(string $resource, string $media = &amp;#039;screen&amp;#039;, ?string $version = &amp;#039;&amp;#039;): string&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode retourne le code HTML pour inclure un fichier CSS &lt;code&gt;$resource&lt;/code&gt; du module.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si le paramètre &lt;code&gt;$resource&lt;/code&gt; ne commence pas par un &lt;code&gt;/&lt;/code&gt; le fichier sera cherché dans le sous dossier &lt;code&gt;css&lt;/code&gt; du module,&lt;/li&gt;
&lt;li&gt;Si l'extension du fichier n'est pas incluse à &lt;code&gt;$resource&lt;/code&gt;, elle sera ajoutée,&lt;/li&gt;
&lt;li&gt;Le type de &lt;code&gt;$media&lt;/code&gt; peut-être précisé, par défaut ce sera &lt;code&gt;screen&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Un numéro de &lt;code&gt;version&lt;/code&gt; peut-être ajouté à la fin de l'url de ressource (gestion de cache)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// Renvoie le code pour le fichier .../monPlugin/css/frontend.css
My::cssload(&amp;#039;frontend&amp;#039;);
// Renvoie le code pour le fichier .../monPlugin/style.css
My::cssLoad(&amp;#039;/style.css&amp;#039;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::jsLoad()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function jsLoad(string $resource, ?string $version = &amp;#039;&amp;#039;, bool $module = false): string&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tout comme &lt;code&gt;My::cssLoad()&lt;/code&gt; cette méthode renvoie le code HTML pour ajouter un fichier JS du module. Le paramètre &lt;code&gt;$module&lt;/code&gt; si il est à &lt;strong&gt;true&lt;/strong&gt; permet de charger &lt;code&gt;$resource&lt;/code&gt; comme un module JS.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::addBackendMenuItem()&lt;/code&gt;&lt;/strong&gt; (plugins uniquement)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function addBackendMenuItem(string $menu = Menus::MENU_PLUGINS, array $params = [], string $scheme = &amp;#039;(&amp;amp;.*)?$&amp;#039;, ?string $id = null): void&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode permet d'ajouter rapidement le module aux menus de l'administration.&lt;br /&gt;
Le menu est à choisir parmi ceux définis dans les constantes de &lt;code&gt;Dotclear\Core\Backend\Menus&lt;/code&gt; et par défaut celui des plugins :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Menus::MENU_BLOG&lt;/code&gt; =&amp;gt; 'Blog',&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Menus::MENU_SYSTEM&lt;/code&gt; =&amp;gt; 'System',&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Menus::MENU_PLUGINS&lt;/code&gt; =&amp;gt; 'Plugins',&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les paramètres :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$params&lt;/code&gt; sert à ajouter des paramètres à l'URL du menu,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$scheme&lt;/code&gt; permet de personnaliser la surbrillance du menu,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$id&lt;/code&gt; permet de spécifier un id pour l’icône de tableau de bord (Utile aux behaviors).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::icons()&lt;/code&gt;&lt;/strong&gt; (plugins uniquement)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function icons(string $suffix = &amp;#039;&amp;#039;): array&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie un tableau des chemins complets vers les icônes du modules.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::manageURL()&lt;/code&gt;&lt;/strong&gt; (plugins uniquement)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function manageUrl(array $params = [], string $separator = &amp;#039;&amp;amp;&amp;#039;): string&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode renvoie l'URL de la page principale de gestion du module. Des paramètres spéciaux peuvent être ajoutés avec &lt;code&gt;$params&lt;/code&gt;, et le séparateur des paramètres peut être modifié avec le paramètre &lt;code&gt;$separator&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;My::redirect()&lt;/code&gt;&lt;/strong&gt; (plugins uniquement)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function redirect(array $params = [], string $suffix = &amp;#039;&amp;#039;): void&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette méthode effectue une redirection en prenant l'URL de base du module, à laquelle il est possible d'ajouter des paramètres &lt;code&gt;$params&lt;/code&gt;. Le paramètre &lt;code&gt;$suffix&lt;/code&gt; permet d'ajouter par exemple le renvoi vers un onglet spécifique.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>La classe d'erreur</title>
        <link>https://dotclear.watch/Billet/La-classe-d-erreur</link>
        <guid isPermaLink="false">urn:md5:00e7d0106a099f7a69db506cc0d1c62d</guid>
        <pubDate>Fri, 14 Jul 2023 09:11:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>erreur</category>
                  <category>error</category>
                  <category>fault</category>
                <description>&lt;p&gt;Dotclear &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt; introduit une classe d'erreur nommée &lt;code&gt;Fault&lt;/code&gt; en remplacement de la fonction &lt;code&gt;__error()&lt;/code&gt; et du fichier &lt;code&gt;error.php&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;La classe &lt;code&gt;Dotclear\Fault&lt;/code&gt; n'est pas à proprement parler un gestionnaire d'erreur, elle ne se substitue pas aux Exception et Error. Elle va simplement permettre à l'application d'uniformiser son comportement sur certains défauts (erreurs) connus. Normalement seules la classe &lt;code&gt;Dotclear\App&lt;/code&gt; et les classes &lt;code&gt;Dotclear\Core\Xxx\Utility&lt;/code&gt; l'utilisent. Elle est utilisée lors de défauts ne permettant pas de continuer la bonne exécution du script.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Constantes&lt;/h5&gt;

&lt;p&gt;La classe définit des constantes de niveau d'erreur, ces niveaux seront reportés en code de réponse HTTP le cas échéant, et sont toutes de niveau supérieur à 500 (Internal server error).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;550&lt;/strong&gt; : &lt;code&gt;UNDEFINED_ISSUE&lt;/code&gt; : Uncoded or undefined error (before as 0)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;555&lt;/strong&gt; : &lt;code&gt;SETUP_ISSUE&lt;/code&gt; : Server configuration issue (before as 0)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;560&lt;/strong&gt; : &lt;code&gt;CONFIG_ISSUE&lt;/code&gt; : Dotclear configuration file issue (before as 10)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;565&lt;/strong&gt; : &lt;code&gt;DATABASE_ISSUE&lt;/code&gt;  :Database connexion issue (before as 20)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;570&lt;/strong&gt; : &lt;code&gt;BLOG_ISSUE&lt;/code&gt; : Blog definition issue (before as 30)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;575&lt;/strong&gt; : &lt;code&gt;TEMPLATE_CREATION_ISSUE&lt;/code&gt; : Template file creation issue (before as 40)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;580&lt;/strong&gt; : &lt;code&gt;THEME_ISSUE&lt;/code&gt; : Theme issue (before as 50)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;585&lt;/strong&gt; : &lt;code&gt;TEMPLATE_PROCESSING_ISSUE&lt;/code&gt; : Template processing issue (before as 60)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;590&lt;/strong&gt; : &lt;code&gt;BLOG_OFFLINE&lt;/code&gt; : Blog is offline (before as 70)&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Lancement&lt;/h5&gt;

&lt;p&gt;Il y a deux façons lancer un défaut, par la création d'une instance en passant en arguments le titre, le message et le niveau, ou de manière statique en passant en arguments le titre et l'exception.&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
use Dotclear\Fault;

// Dynamique
if (!defined(&amp;#039;DC_CONTEXT_ADMIN&amp;#039;)) {
    new Fault(&amp;#039;Server error&amp;#039;, &amp;#039;Site temporarily unavailable&amp;#039;, Fault::SETUP_ISSUE);
}
// Statique
try {
    if ($a &amp;lt; 1) {
        throw new Exception(&amp;#039;a est inferieur à 1&amp;#039;, Fault::CONFIG_ISSUE);
    }
    if ($a &amp;gt; 10) {
        throw new Exception(&amp;#039;a est supérieur à 10&amp;#039;, Fault::CONFIG_ISSUE);
    }
 } catch (Exception $e) {
    Fault::throw(&amp;#039;Mauvaise valeur de a&amp;#039;, $e);
 }&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;Retour&lt;/h5&gt;

&lt;p&gt;La classe permet plusieurs façons de reporter le défaut.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si le script est exécuté en mode CLI (ligne de commande) comme pour une mise à jour depuis une console, la classe répondra par un simple message dans la console.&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Si le script est exécuté normalement, une page web indiquant le niveau d'erreur, son titre et un message explicatif sera retourné avec en code de réponse HTTP le niveau d'erreur.&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Si au moment du lancement de la classe la constante &lt;code&gt;DC_DEBUG&lt;/code&gt; est déjà définie et est à &lt;strong&gt;true&lt;/strong&gt;, l'erreur php sera retournée, comme si la classe n'existait pas.&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Personnalisation&lt;/h5&gt;

&lt;p&gt;Il est possible de personnaliser la page web de défaut. Pour cela il faut renseigner la constante &lt;code&gt;DC_ERRORFILE&lt;/code&gt; en la définissant avec le chemin complet vers un fichier qui sera inclu dans la méthode retournant le défaut. Ce fichier devra rendre à la sortie standard de PHP (echo) du code HTML complet et valide. Les variables &lt;code&gt;$summary&lt;/code&gt;, &lt;code&gt;$message&lt;/code&gt; et &lt;code&gt;$code&lt;/code&gt; lui sont accessibles.&lt;br /&gt;&lt;/p&gt;&lt;figure class=&quot;media-center&quot;&gt;&lt;img src=&quot;https://dotclear.watch/public/2.27/.class_fault_http_m.png&quot; alt=&quot;class_fault_http.png, juil. 2023&quot; title=&quot;class_fault_http.png, juil. 2023&quot; /&gt;&lt;figcaption&gt;Reponse HTML de la classe Fault&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier de désactivation d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-de-d%C3%A9sactivation-d-un-module</link>
        <guid isPermaLink="false">urn:md5:97509a7fdf791a5500dbcca62d002353</guid>
        <pubDate>Fri, 14 Jul 2023 00:39:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>disabled</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>theme</category>
                <description>&lt;p&gt;Le fichier de désactivation en dur d'un module se nomme &lt;strong&gt;_disabled&lt;/strong&gt;, c'est un fichier vide qui est placé à la &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;racine du module&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Normalement ce fichier n'est pas à manipuler, le gestionnaire de modules se charge de l'ajouter suivant des prérequis ou des actions définies.&lt;br /&gt;
Le gestionnaire de module va lire le &lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-module&quot;&gt;fichier de définition du module&lt;/a&gt; et si les prérequis du module ne sont pas remplis, il désactivera le module en ajoutant le fichier &lt;strong&gt;_disabled&lt;/strong&gt; à sa racine.&lt;br /&gt;
Depuis l'interface d'administration du blog, dans la liste des plugins ou des thèmes installés, il est possible de désactiver ou de réactiver des modules.&lt;br /&gt;
Une fois ce fichier présent, seul le fichier de définition du module est lu.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Gestion d'URL d'administration</title>
        <link>https://dotclear.watch/Billet/Gestion-d-URL-d-administration</link>
        <guid isPermaLink="false">urn:md5:5f4e600e6c3a229f9d4d08317752f88a</guid>
        <pubDate>Thu, 13 Jul 2023 23:08:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>backend</category>
                  <category>url</category>
                <description>&lt;p&gt;La &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt; de Dotclear embarque des changements côté URL, dont certains non rétro compatibles.&lt;/p&gt; &lt;h5&gt;Déprécié&lt;/h5&gt;

&lt;p&gt;Avec le passage aux espaces de noms PHP, la classe &lt;strong&gt;dcAdminURL&lt;/strong&gt; devient &lt;code&gt;Dotclear\Core\Backend\Url&lt;/code&gt;.&lt;br /&gt;
Et son instance se déplace également de &lt;strong&gt;dcCore::app()-&amp;gt;adminurl&lt;/strong&gt; vers &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;url&lt;/code&gt;.&lt;br /&gt;
A noter que grâce au plugins dcProxyV1, les anciens noms restent accessibles.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Obsolète&lt;/h5&gt;

&lt;p&gt;Dûe à la mise en place de la &lt;a href=&quot;https://dotclear.watch/Billet/Lancement-de-l-application&quot;&gt;nouvelle structure de l'application&lt;/a&gt;, l'utilisation des URLs écrites directement est proscrite. C'est à dire que partout où un plugin écrivait &lt;code&gt;'plugin.php?p=monPlugin&lt;/code&gt;' le code ne fonctionnera plus. Il faut impérativement utiliser le gestionnaire d'URL &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;url&lt;/code&gt; et ses méthodes.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
// dcCore::app()-&amp;gt;adminurl-&amp;gt;get(&amp;#039;admin.plugin.monPlugin&amp;#039;, [&amp;#039;var&amp;#039; =&amp;gt; 1]);
dcCore::app()-&amp;gt;admin-&amp;gt;url-&amp;gt;get(&amp;#039;admin.plugin.monPlugin&amp;#039;, [&amp;#039;var&amp;#039; =&amp;gt; 1]);
// ou encore mieux
My::manageURL([&amp;#039;var&amp;#039; =&amp;gt; 1]);

// Http::redirect(&amp;#039;plugin.php?p=monPlugin&amp;amp;var=1);
dcCore::app()-&amp;gt;admin-&amp;gt;url-&amp;gt;redirect(&amp;#039;admin.plugin.monPlugin&amp;#039;, [&amp;#039;var&amp;#039; =&amp;gt; 1]);
// ou encore mieux
My::redirect([&amp;#039;var&amp;#039; =&amp;gt; 1]);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pourquoi ? Parce que l'ajout du Process en cours est fait automatiquement par ce biais. Le code ci-dessus renverra l'URL &lt;code&gt;/index.php?process=Plugin&amp;amp;p=monPlugin&amp;amp;var=1&lt;/code&gt;.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Nouveauté&lt;/h5&gt;

&lt;p&gt;Une nouvelle URL débarque dans le gestionnaire, celle de déconnexion, elle permet de se déconnecter de l'interface d'administration même en cas de plantage d'un plugin ou d'un thème. Son identifiant est &lt;code&gt;'admin.logout'&lt;/code&gt;. Si vous souhaitez par exemple déconnecter l'utilisateur depuis votre script il suffit de faire &lt;code&gt;dcCore::app()-&amp;gt;redirect('admin.logout');&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Pour des raisons d'uniformisation, l'identifiant d'URL &lt;strong&gt;'admin.popup_posts'&lt;/strong&gt; sera a terme remplacé par &lt;code&gt;'admin.popup.posts'&lt;/code&gt; et un autre nouvel identifiant &lt;code&gt;'admin.help.charte'&lt;/code&gt; peu utilisé est ajouté.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Attention&lt;/h5&gt;

&lt;p&gt;Ce n'est pas tout, en rapport au gestionnaire d'URL et à la nouvelle structure de l'application, certains formulaires ne fonctionneront pas comme il faut. En effet les formulaires utilisant la method GET ne peuvent embarquer dans l'URL le process, du moins il le perd en chemin ! (Merci monsieur HTML) Il faut donc impérativement ajouter un champ caché contenant &lt;code&gt;process=xxx&lt;/code&gt; ou xxx est l'identifiant de la page qu'il souhaite atteindre enregistré dans le gestionnaire d'URL. Exemple pour la page principale d'un plugin il faudra ajouter dans le formulaire &lt;code&gt;new Form\Hidden('process', 'Plugin');&lt;/code&gt; ou &lt;code&gt;form::hidden('process', 'Plugin');&lt;/code&gt; ou &lt;code&gt;'&amp;lt;input type=&quot;hidden&quot; name=&quot;process&quot; value=&quot;Plugin&quot; /&amp;gt;'&lt;/code&gt;. Dans la majorité des cas, les formulaires utilisant la méthode POST, ainsi que les filtres de listes tiennent compte du process.&lt;br /&gt;
&lt;br /&gt;
A noter que la &lt;a href=&quot;https://dotclear.watch/Billet/Les-classes-de-module-My&quot;&gt;classe My&lt;/a&gt; d'aide des modules propose des méthodes simplifiant l'accès aux URLs du module.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Déplacement de classes</title>
        <link>https://dotclear.watch/Billet/D%C3%A9placement-de-classes</link>
        <guid isPermaLink="false">urn:md5:39816fb224c63c01c4e6fcc0c7b0fea3</guid>
        <pubDate>Wed, 12 Jul 2023 20:10:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>class</category>
                  <category>déplacé</category>
                <description>&lt;p&gt;Pour cette &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt;, continuant la transition vers les espaces de noms PHP, de nombreuses classes dont principalement celles d'administration se sont vues déplacer dans le dossier &lt;code&gt;src&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Voici la liste des classes changeant de nom dans cette version.&lt;br /&gt;
&lt;br /&gt;
Pour la partie administration :&lt;/p&gt;
&lt;pre&gt;
    &amp;#039;adminBlogFilter&amp;#039;      =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\FilterBlogs&amp;#039;,
    &amp;#039;adminBlogList&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\ListingBlogs&amp;#039;,
    &amp;#039;adminCommentFilter&amp;#039;   =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\FilterComments&amp;#039;,
    &amp;#039;adminCommentList&amp;#039;     =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\ListingComments&amp;#039;,
    &amp;#039;adminGenericFilterV2&amp;#039; =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\Filters&amp;#039;,
    &amp;#039;adminGenericListV2&amp;#039;   =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\Listing&amp;#039;,
    &amp;#039;adminMediaFilter&amp;#039;     =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\FilterMedia&amp;#039;,
    &amp;#039;adminMediaList&amp;#039;       =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\ListingMedia&amp;#039;,
    &amp;#039;adminMediaPage&amp;#039;       =&amp;gt; &amp;#039;Dotclear\Core\Backend\MediaPage&amp;#039;,
    &amp;#039;adminModulesList&amp;#039;     =&amp;gt; &amp;#039;Dotclear\Core\Backend\ModulesList&amp;#039;,
    &amp;#039;adminPostFilter&amp;#039;      =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\FilterPosts&amp;#039;,
    &amp;#039;adminPostList&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\ListingPosts&amp;#039;,
    &amp;#039;adminPostMiniList&amp;#039;    =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\ListingPostsMini&amp;#039;,
    &amp;#039;adminUserFilter&amp;#039;      =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\FilterUsers&amp;#039;,
    &amp;#039;adminUserList&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\ListingUsers&amp;#039;,
    &amp;#039;adminThemesList&amp;#039;      =&amp;gt; &amp;#039;Dotclear\Core\Backend\ThemesList&amp;#039;,
    &amp;#039;adminUserPref&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\UserPref&amp;#039;,
    &amp;#039;dcActions&amp;#039;            =&amp;gt; &amp;#039;Dotclear\Core\Backend\Action\Actions&amp;#039;,
    &amp;#039;dcAdmin&amp;#039;              =&amp;gt; &amp;#039;Dotclear\Core\Backend\Utility&amp;#039;,
    &amp;#039;dcAdminBlogPref&amp;#039;      =&amp;gt; &amp;#039;Dotclear\Core\Backend\BlogPref&amp;#039;,
    &amp;#039;dcAdminCombos&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\Combos&amp;#039;,
    &amp;#039;dcAdminFilter&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\Filter&amp;#039;,
    &amp;#039;dcAdminFilters&amp;#039;       =&amp;gt; &amp;#039;Dotclear\Core\Backend\Filter\FiltersLibrary&amp;#039;,
    &amp;#039;dcAdminHelper&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\Helper&amp;#039;,
    &amp;#039;dcAdminNotices&amp;#039;       =&amp;gt; &amp;#039;Dotclear\Core\Backend\Notices&amp;#039;,
    &amp;#039;dcAdminURL&amp;#039;           =&amp;gt; &amp;#039;Dotclear\Core\Backend\Url&amp;#039;,
    &amp;#039;dcBlogsActions&amp;#039;       =&amp;gt; &amp;#039;Dotclear\Core\Backend\Action\ActionsBlogs&amp;#039;,
    &amp;#039;dcCommentsActions&amp;#039;    =&amp;gt; &amp;#039;Dotclear\Core\Backend\Action\ActionsComments&amp;#039;,
    &amp;#039;dcPostsActions&amp;#039;       =&amp;gt; &amp;#039;Dotclear\Core\Backend\Action\ActionsPosts&amp;#039;,
    &amp;#039;dcFavorites&amp;#039;          =&amp;gt; &amp;#039;Dotclear\Core\Backend\Favorites&amp;#039;,
    &amp;#039;dcMenu&amp;#039;               =&amp;gt; &amp;#039;Dotclear\Core\Backend\Menu&amp;#039;,
    &amp;#039;dcPage&amp;#039;               =&amp;gt; &amp;#039;Dotclear\Core\Backend\Page&amp;#039;,
    &amp;#039;dcPager&amp;#039;              =&amp;gt; &amp;#039;Dotclear\Core\Backend\Listing\Pager&amp;#039;,
    &amp;#039;dcThemeConfig&amp;#039;        =&amp;gt; &amp;#039;Dotclear\Core\Backend\ThemeConfig&amp;#039;,
&lt;/pre&gt;

&lt;p&gt;Pour la partie publique :&lt;/p&gt;
&lt;pre&gt;
    &amp;#039;dcPublic&amp;#039; =&amp;gt; &amp;#039;Dotclear\Core\Frontend\Utility&amp;#039;,
&lt;/pre&gt;

&lt;p&gt;Pour la partie Core :&lt;/p&gt;
&lt;pre&gt;
    &amp;#039;dcNsProcess&amp;#039; =&amp;gt; &amp;#039;Dotclear\Core\Process&amp;#039;,
    &amp;#039;dcUpgrade&amp;#039; =&amp;gt; &amp;#039;Dotclear\Core\Upgrade\Upgrade&amp;#039;,
&lt;/pre&gt;

&lt;p&gt;Pour utiliser ces classes il faut ajouter en début de fichier la déclaration &lt;code&gt;use&lt;/code&gt; suivi du  nom &lt;strong&gt;complet&lt;/strong&gt; de la classe.&lt;br /&gt;
Par exemple :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
use Dotclear\Core\Backend\Notices;

// dcAdminNotices::addSuccessNotice(__(&amp;#039;Youhou&amp;#039;));
Notices::addSuccessNotice(__(&amp;#039;Youhou&amp;#039;));&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Les dépréciés</title>
        <link>https://dotclear.watch/Billet/Les-d%C3%A9pr%C3%A9ci%C3%A9s</link>
        <guid isPermaLink="false">urn:md5:1510c60d4fc8db1f1d9671402038ef88</guid>
        <pubDate>Wed, 12 Jul 2023 19:54:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>déprécié</category>
                <description>&lt;p&gt;La &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt; de Dotclear apporte son lot de dépréciés. Et leur nombre augmente par rapport aux dernières versions.&lt;/p&gt; &lt;h5&gt;Autoloader&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;dcCore::autoload()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Autoloader::me()&lt;/code&gt;&lt;br /&gt;
Il faut désormais appeler directement &lt;code&gt;Autoloader::me()&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Erreur&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;_ _error()&lt;/strong&gt; =&amp;gt; &lt;code&gt;new Dotclear\Fault()&lt;/code&gt;&lt;br /&gt;
Il faut utiliser la classe dédiée &lt;strong&gt;Fault&lt;/strong&gt; avec soit le constructeur &lt;code&gt;new Dotclear\Fault()&lt;/code&gt; ou bien la forme statique &lt;code&gt;Dotclear\Fault::throw()&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Déconnection&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;logout=1&lt;/strong&gt; =&amp;gt; &lt;code&gt;process=Logout&lt;/code&gt;&lt;br /&gt;
La déconnection a maintenant une URL dédiée. Pour l'appeler, il faut utiliser le gestionnaire d'URL &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;url-&amp;gt;redirect('admin.logout')&lt;/code&gt; qui donnera dans l'URL &lt;code&gt;&amp;amp;process=Logout&lt;/code&gt;&lt;br /&gt;
&lt;ins&gt;&lt;strong&gt;Astuces :&lt;/strong&gt;&lt;/ins&gt; Si un plugin ou un thème bloque l'accès à l'admin, il est possible de simplement ajouter à la fin de l'URL de votre navigateur &lt;code&gt;?process=Logout&lt;/code&gt; et vous pourrez vous reconnecter en &lt;q&gt;mode sans échec&lt;/q&gt;.&lt;/p&gt;

&lt;h5&gt;Variable $init de process&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;dcNsProcess::$init&lt;/strong&gt; =&amp;gt; &lt;code&gt;Process::status()&lt;/code&gt;&lt;br /&gt;
Introduite en 2.26 cette variable posait des problèmes, elle a été remplacé par la méthode &lt;code&gt;Dotclear\Core\Process::status()&lt;/code&gt; qui sert à la fois en lecture et en écriture.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Ajout de menu&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;dcAdminHelper::addMenuItem()&lt;/strong&gt; =&amp;gt; &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;menus-&amp;gt;addItem()&lt;/code&gt;&lt;br /&gt;
Avec l'arrivée des espaces de noms PHP dans la partie administration, les menus font partie d'un objet nommé &lt;code&gt;Menus&lt;/code&gt; et donc il faut passer par lui pour ajouter des menus avec &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;menus-&amp;gt;addItem()&lt;/code&gt;.&lt;br /&gt;
Pour les plugins il est recommandé d'utiliser la &lt;a href=&quot;https://dotclear.watch/Billet/Les-classes-de-module-My&quot;&gt;classe My&lt;/a&gt; et la méthode  &lt;code&gt;My::addBackendMenuItem()&lt;/code&gt;..&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Constantes de menu&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dcAdmin::MENU_FAVORITES&lt;/strong&gt; =&amp;gt; &lt;code&gt;Menus::MENU_FAVORITES&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcAdmin::MENU_BLOG&lt;/strong&gt; =&amp;gt; &lt;code&gt;Menus::MENU_BLOG&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcAdmin::MENU_SYSTEM&lt;/strong&gt; =&amp;gt; &lt;code&gt;Menus::MENU_SYSTEM&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcAdmin::MENU_PLUGINS&lt;/strong&gt; =&amp;gt; &lt;code&gt;Menus::MENU_PLUGINS&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ici encore suite à l'arrivée du nouvel objet &lt;code&gt;Menus&lt;/code&gt;, les constantes associées sont déplacées dedans. Le nom complet de la classe est &lt;code&gt;Dotclear\Core\Backend\Menus&lt;/code&gt;. Il est possible de les appeler depuis l'instance &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;menus::MENU_XXX&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Les notices&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dcPage::notices()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::getNotices()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::addMessageNotice()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::addMessageNotice()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::addSuccessNotice()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::addSuccessNotice()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::addWarningNotice()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::addWarningNotice()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::addErrorNotice()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::addErrorNotice()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::message()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::message()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::success()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::success()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::warning()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::warning()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::error()&lt;/strong&gt; =&amp;gt; &lt;code&gt;Notices::error()&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Toutes les méthodes de dcPage (nouvellement Page) en rapport aux notices sont dépréciées, il faut désormais utiliser les méthodes de la classe d'origine &lt;code&gt;Dotclear\Core\Backend\Notices&lt;/code&gt; dont les signatures restent les mêmes.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Fichiers de modules&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dcPage::cssModuleLoad()&lt;/strong&gt; =&amp;gt; &lt;code&gt;My::cssLoad()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcPage::jsModuleLoad()&lt;/strong&gt; =&amp;gt; &lt;code&gt;My::jsLoad()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcUtils::cssModuleLoad()&lt;/strong&gt; =&amp;gt; &lt;code&gt;My::cssLoad()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcUtils::jsModuleLoad()&lt;/strong&gt; =&amp;gt; &lt;code&gt;My::jsLoad()&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Encore une fois la &lt;a href=&quot;https://dotclear.watch/Billet/Les-classes-de-module-My&quot;&gt;classe My&lt;/a&gt; dédiée aux modules vient prendre le relai de ces deux méthodes. La différence est que, &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;la structure des modules&lt;/a&gt; devenant plus stricte, ces deux nouvelles méthodes ont uniquement besoin du nom du fichier à charger. Il n'est plus nécessaire de fournir le nom du module ni celui du sous répertoire. Pour les &lt;strong&gt;css&lt;/strong&gt; les fichiers sont rangés dans le dossier &lt;code&gt;css&lt;/code&gt;, pour les &lt;strong&gt;js&lt;/strong&gt;, les fichiers sont rangés dan le dossier &lt;code&gt;js&lt;/code&gt;. Propre.&lt;br /&gt;
Exemple avec un partie de la méthode process de la classe Manage d'un module :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
//...
Page::openModule(
    My::name,
    // charge le fichier MonPlugin/js/backend.js
    My::jsLoad(&amp;#039;backend&amp;#039;) .
    // charge le fichier MonPlugin/css/style.css
    My::cssLoad(&amp;#039;style&amp;#039;)
);&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;De core à admin&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dcCore::app()-&amp;gt;adminurl&lt;/strong&gt; =&amp;gt; &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;url&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcCore::app()-&amp;gt;favs&lt;/strong&gt; =&amp;gt; &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;favs&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dcCore::app()-&amp;gt;menu&lt;/strong&gt; =&amp;gt; &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;menus&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comme annoté dans le code depuis quelques versions certaines instances se trouvant historiquement dans &lt;code&gt;dcCore&lt;/code&gt; auraient dû aller dans &lt;code&gt;dcCore::app()-&amp;gt;admin&lt;/code&gt;, c'est chose faite en 2.27.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Points d'entrées&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dotclear/inc/public/_prepend.php&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dotclear/inc/admin/_prepend.php&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;tous les fichiers &lt;strong&gt;dotclear/admin/xxx.php&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tous les points d'entrée qui étaient représentés par des fichiers sont dépréciés, ils sont remplacés par un seul fichier index.php qui &lt;a href=&quot;https://dotclear.watch/Billet/Lancement-de-l-application&quot;&gt;lance l'application Dotclear&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Coté public, ce sera l'index.php de &lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-blog&quot;&gt;définition du blog&lt;/a&gt; qui lancera l'application.&lt;/li&gt;
&lt;li&gt;Coté admin, ce sera l'index.php de l'URL d'administration qui s'en chargera.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cas particulier, la mise à jour en ligne de commande se déplace de &lt;strong&gt;dotclear/inc/dbschema/upgrade-cli.php&lt;/strong&gt; vers &lt;code&gt;dotclear/admin/upgrade/upgrade-cli.php&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;user@server: /var/www/dotclear$ php admin/upgrade/upgrade-cli.php inc/config.php&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;Propriétés du core&lt;/h5&gt;

&lt;p&gt;Nombre de propriétés de dcCore utilisent en 2.27 &lt;a href=&quot;https://php.watch/versions/7.4/typed-properties#uninitialized&quot; hreflang=&quot;en&quot; title=&quot;The uninitialized state&quot;&gt;l'état 'uninitialized'&lt;/a&gt; c'est à dire qu'il ne faut plus tester leur nullité mais leur présence, cela se traduit par exemple par :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;is_null(dcCore::app()-&amp;gt;auth)&lt;/strong&gt; ou &lt;strong&gt;dcCore::app()-&amp;gt;auth === null&lt;/strong&gt; =&amp;gt; &lt;code&gt;isset(dcCore::app()-&amp;gt;auth)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier de définition d'un blog</title>
        <link>https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-blog</link>
        <guid isPermaLink="false">urn:md5:5dba185a9aa101b892a2c2da2a4c9c2e</guid>
        <pubDate>Tue, 11 Jul 2023 23:45:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>blog</category>
                  <category>definition</category>
                <description>&lt;p&gt;Avec la &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt; de Dotclear le fichier &lt;strong&gt;index.php&lt;/strong&gt; de définition d'un blog évolue.&lt;/p&gt; &lt;p&gt;Là ou le fichier ressemblait à cela :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
define(&amp;#039;DC_BLOG_ID&amp;#039;,&amp;#039;blog&amp;#039;); # identifiant unique du blog
require dirname(__FILE__).&amp;#039;/../dotclear/inc/public/prepend.php&amp;#039;; # chemin vers prepend.php
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Il ressemblera à ceci :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
define(&amp;#039;DC_BLOG_ID&amp;#039;,&amp;#039;blog&amp;#039;); // identifiant unique du blog
require_once implode(DIRECTORY_SEPARATOR, [__DIR__, &amp;#039;..&amp;#039;, &amp;#039;dotclear&amp;#039;, &amp;#039;src&amp;#039;, &amp;#039;App.php&amp;#039;]); // chemin vers l&amp;#039;application dotclear
Dotclear\App::bootstrap(&amp;#039;Frontend&amp;#039;); // lancement de l&amp;#039;application côté public (Frontend)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bien entendu les deux écritures de ce fichier sont valables pour quelques versions encore.&lt;br /&gt;
Les changements ci-dessus sont dû à l'utilisation du &lt;a href=&quot;https://dotclear.watch/Billet/Lancement-de-l-application&quot;&gt;nouveau point d'entrée unique&lt;/a&gt; de Dotclear.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Fichier de définition d'un module</title>
        <link>https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-module</link>
        <guid isPermaLink="false">urn:md5:0deff8c52b8419d8f95fcddee9b92aa4</guid>
        <pubDate>Tue, 11 Jul 2023 21:14:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>define</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>theme</category>
                <description>&lt;p&gt;Le fichier de définition se situe à la &lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;racine du module&lt;/a&gt;, il se nomme &lt;strong&gt;_define.php&lt;/strong&gt; et il va donner à Dotclear toutes les informations indispensables à sa compréhension. Il est en très grande partie commun aux thèmes et aux plugins.&lt;/p&gt; &lt;p&gt;Son contenu peut être le suivant :&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
/**
 * Mettre ici les informations de licence
 */
$this-&amp;gt;registerModule(
    &amp;#039;Le module&amp;#039;, // Nom (requis)
    &amp;#039;Un module qui ne fait rien&amp;#039;, // Description (requis)
    &amp;#039;Jean-Christian Denis and contributors&amp;#039;, // Auteur (requis)
    &amp;#039;1.0&amp;#039;,  // Version (requis)
    [
        &amp;#039;requires&amp;#039; =&amp;gt; [
            [&amp;#039;php&amp;#039;, &amp;#039;8.1&amp;#039;], // Version minimum de PHP (optionnel)
            [&amp;#039;core&amp;#039;, &amp;#039;2.26&amp;#039;], // Version miminum de Dotclear (recommandé)
            [&amp;#039;UnAutreModule&amp;#039;, &amp;#039;1.1&amp;#039;], // Dépendance à un autre module (optionnel)
        ],
        &amp;#039;priority&amp;#039; =&amp;gt; 1000, // priorité, nombre entier positif (optionnel)
        &amp;#039;permissions&amp;#039; =&amp;gt; dcCore::app()-&amp;gt;auth-&amp;gt;makePermissions([
            dcCore::app()-&amp;gt;auth::PERMISSION_CONTENT_ADMIN,
        ]), // Permissions (recommandé)
        &amp;#039;type&amp;#039; =&amp;gt; &amp;#039;plugin&amp;#039;, // type de module, plugin ou theme (requis)
        &amp;#039;settings&amp;#039;    =&amp;gt; [
            &amp;#039;blog&amp;#039; =&amp;gt; &amp;#039;#params.LeModule&amp;#039;, // plugin, sa configuration est sur la page de paramètres du blog
            &amp;#039;self&amp;#039; =&amp;gt; &amp;#039;&amp;#039;, // plugin, sa page de gestion est sa page de configuration
            &amp;#039;pref&amp;#039; =&amp;gt; &amp;#039;#user-options.LeModule&amp;#039;, // plugin, sa configuration est dans les préférences utilisateur
        ],
        &amp;#039;parent&amp;#039; =&amp;gt; &amp;#039;ductile&amp;#039;, // thème, son parent (optionnel)
        &amp;#039;tplset&amp;#039; =&amp;gt; &amp;#039;mustek&amp;#039;, // thème, le jeu de template à utiliser (optionnel)
        &amp;#039;standalone_config&amp;#039; =&amp;gt; true, // thème, utilisation de sa propre configuration (optionnel)
        &amp;#039;support&amp;#039; =&amp;gt; &amp;#039;https://github.com/JcDenis/LeModule&amp;#039;, // Lien vers la page du support (recommandé)
        &amp;#039;details&amp;#039; =&amp;gt; &amp;#039;https://plugins.dotaddict.org/dc2/details/LeModule&amp;#039;, // Lien vers la page de détails (recommandé)
        &amp;#039;repository&amp;#039; =&amp;gt; &amp;#039;https://raw.githubusercontent.com/JcDenis/LeModule/master/dcstore.xml&amp;#039;, // Lien vers la définition du dépôt tiers (optionnel)
        &amp;#039;widgettitleformat&amp;#039;     =&amp;gt; &amp;#039;&amp;#039;, // formatage de widget (optionnel)
        &amp;#039;widgetsubtitleformat&amp;#039;  =&amp;gt; &amp;#039;&amp;#039;, // formatage de widget (optionnel)
        &amp;#039;widgetcontainerformat&amp;#039; =&amp;gt; &amp;#039;&amp;#039;, // formatage de widget (optionnel)
    ]
);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;Attention :&lt;/strong&gt; Ce fichier est appelé très tôt dans le code, à l'intérieur d'une méthode, il peut être appelé plusieurs fois et d'autres script peuvent l'appeler, à cause de tout cela seules les classes dcAuth, dcCore et celles contenues dans les fichiers _init.php des modules peuvent être utilisées dans ce fichier.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;A noter :&lt;/strong&gt; Si la page de configuration du plugin est dans un fichier &lt;code&gt;src/Config.php&lt;/code&gt;, Dotclear l'indiquera de manière automatique, il n'est pas nécessaire de l'indiquer dans la définition des paramètres &lt;em&gt;settings&lt;/em&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;La présence du fichier define.php est obligatoire.&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>Structure d'un module</title>
        <link>https://dotclear.watch/Billet/Structure-d-un-module</link>
        <guid isPermaLink="false">urn:md5:6d0c1344a22a365bd1abddfe6de79f06</guid>
        <pubDate>Tue, 11 Jul 2023 21:09:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>structure</category>
                  <category>theme</category>
                <description>&lt;p&gt;Avec la &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;version 2.27&lt;/a&gt; de Dotclear la structure de plugins et thèmes devient plus rigide. Cette structure deviendra obligatoire assez rapidement.&lt;/p&gt; &lt;p&gt;La structure générale d'un module est quasi commune aux plugins et aux thèmes. Elle se définit comme suit.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Nom&lt;/h5&gt;

&lt;p&gt;Depuis la mise en place des espaces de nom pour les modules, le nom du répertoire racine du module sera son ID et son espace de nom PHP. De ce fait il est proscrit tous caractères autres que des chiffres et lettres et le nom doit commencer par une lettre.&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Invalide&lt;/strong&gt; : mon-plugin, 1to3plugin,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Valide :&lt;/strong&gt; monplugin, MonPlugin2,&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Fichiers à la racine du module :&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-module&quot;&gt;_define.php&lt;/a&gt; : Fichier de définition&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9sactivation-d-un-module&quot;&gt;_disabled&lt;/a&gt; : Fichier de désactivation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-init-d-un-module&quot;&gt;_init.php&lt;/a&gt; : Fichier de définition d'initialisation&lt;/li&gt;
&lt;li&gt;CHANGELOG.md : récapitulatif des modifications/versions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9p%C3%B4t-tiers&quot;&gt;dcstore.xml&lt;/a&gt; : Fichier de définition de dépôt distant&lt;/li&gt;
&lt;li&gt;icon.svg : Icône&lt;/li&gt;
&lt;li&gt;icon-dark.svg : Icône sombre&lt;/li&gt;
&lt;li&gt;LICENSE : Licence&lt;/li&gt;
&lt;li&gt;README.md : Document d'introduction&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Répertoires à la racine du module :&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;css : Feuilles de styles&lt;/li&gt;
&lt;li&gt;default-templates : Templates&lt;/li&gt;
&lt;li&gt;img : Images&lt;/li&gt;
&lt;li&gt;js : Scripts javascript&lt;/li&gt;
&lt;li&gt;locales : Traductions&lt;/li&gt;
&lt;li&gt;src : Espace de nom contenant tous les fichiers .php&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Fichiers du dossier src :&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-Backend-d-un-module&quot;&gt;Backend.php&lt;/a&gt; : ex _admin.php Préparation de la partie admin,&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-Config-d-un-module&quot;&gt;Config.php&lt;/a&gt; : ex _config.php Configurateur,&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-Frontend-d-un-module&quot;&gt;Frontend.php&lt;/a&gt; : ex _public.php Préparation de la partie publique&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-Install-d-un-module&quot;&gt;Install.php&lt;/a&gt; : ex _install.php Processus d'installation&lt;/li&gt;
&lt;li&gt;Manage.php : ex index.php Page de gestion principale&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Les-classes-de-module-My&quot;&gt;My.php&lt;/a&gt; : fonctions prédéfinies d'aides au code&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Fichier-Prepend-d-un-module&quot;&gt;Prepend.php&lt;/a&gt; : ex _prepend.php Préparation générale&lt;/li&gt;
&lt;li&gt;Widgets.php : ex _widgets.php Gestion des widgets par le plugin widgets&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Bonnes pratiques&lt;/h5&gt;

&lt;p&gt;Il est vivement recommandé (possible obligation à l'avenir) d'utiliser l'&lt;strong&gt;ID du module&lt;/strong&gt; pour l'identifiant de ses paramètres dans les espaces de paramètres (blog settings) et les espaces de préférences (user pref).&lt;br /&gt;
Il est recommandé de séparer les behaviors trop volumineux des fichiers &lt;strong&gt;Backend.php&lt;/strong&gt; / &lt;strong&gt;Frontend.php&lt;/strong&gt; et de les mettre dans un fichier &lt;code&gt;BackendBehaviors.php&lt;/code&gt; / &lt;code&gt;FrontendBehaviors.php&lt;/code&gt;.&lt;br /&gt;
De manière générale le nom de fichier et donc de classe doit être en rapport avec sa fonction, par exemple une classe contenant toutes les méthodes en rapport aux &lt;strong&gt;templates coté public&lt;/strong&gt; sera nommé &lt;code&gt;FrontendTemplate&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;Ce document est en cours d'écriture, il est incomplet.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>La class Process</title>
        <link>https://dotclear.watch/Billet/La-class-Process</link>
        <guid isPermaLink="false">urn:md5:c7e57bde7d87b749d5506bb78759ec9a</guid>
        <pubDate>Tue, 11 Jul 2023 20:41:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.27</category>
                          <category>2.27</category>
                  <category>class</category>
                  <category>module</category>
                  <category>plugin</category>
                  <category>process</category>
                  <category>theme</category>
                <description>&lt;p&gt;La classe &lt;strong&gt;Process&lt;/strong&gt; introduite dans les dernières versions de Dotclear devient la norme et est requise quasi partout depuis &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot; hreflang=&quot;fr&quot; title=&quot;Note de release 2.27&quot;&gt;Dotclear 2.27&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;La plupart des classes de plugins et thèmes doivent étendre la classe Process, pour cela il suffit de déclarer son utilisation en début de fichier puis d'étendre votre classe.&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
use Dotclear\Core\Process;

class Manage extends Process
{
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette classe est pour l'instant très succincte mais permet de découper le déroulement du script en trois parties.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Première partie&lt;/h5&gt;

&lt;p&gt;Elle utilise la méthode &lt;code&gt;Process::init()&lt;/code&gt; elle permet de vérifier les droits à utiliser votre classe. Elle utilise un mécanisme mémorisant le statut de cette initialisation, verrouillant ou non l'utilisation des méthodes suivantes.&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function init(): bool
{
    // On enregistre la permissions d&amp;#039;utiliser la classe et on renvoie le résultat
    return self::status(My::checkContext(My::MANAGE));
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On voit ici l'utilisation de la &lt;a href=&quot;https://dotclear.watch/Billet/Les-classes-de-module-My&quot;&gt;classe My&lt;/a&gt; qui est un outil d'aide à l'écriture des modules simplifiant l'utilisation de certains mécanismes.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Seconde partie&lt;/h5&gt;

&lt;p&gt;Elle utilise la méthode &lt;code&gt;Process::process()&lt;/code&gt; qui est consacrée à la préparation et au traitement des données, telles que celles des formulaires par exemple.&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function process(): bool
{
    // On vérifie le droit d&amp;#039;effectuer cette partie
    if (!self::status()) {
        return false;
    }

    if (!empty($_POST[&amp;#039;id&amp;#039;])) {
        // traitement de mon formulaire

        // On a réussi, on ajoute un message
        Notices::addSuccessNotice(__(&amp;#039;Victory&amp;#039;));
        // On redirige vers la page du plugin
        dcCore::-&amp;gt;admin-&amp;gt;url-&amp;gt;redirect(&amp;#039;admin.plugin.&amp;#039; . My::id());
    }

    // Cette méthode doit retourner true si on veut exécuter la troisième partie
    return true;
}&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;La troisième partie&lt;/h5&gt;

&lt;p&gt;Elle utilise la méthode &lt;code&gt;Process::render()&lt;/code&gt; qui est consacré au rendu. C'est à dire à l'affichage dans le navigateur.&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;public static function render(): void
{
    // On vérifie le droit d&amp;#039;effectuer cette partie
    if (!self::status()) {
        return;
    }

    // On prépare l&amp;#039;affichage du haut de page
    Page::openModule(My::name());

    // On ajoute le menu façon Dotclear
    echo
    Page::breadcrumb(
        [
            __(&amp;#039;Plugin&amp;#039;)  =&amp;gt; &amp;#039;&amp;#039;,
            My::name() =&amp;gt; &amp;#039;&amp;#039;,
        ]
    ) .
    // On affiche d&amp;#039;éventuelle messages
    Notices::getNotices();

    // On ajoute le contenu de la page
    echo __(&amp;#039;yeah!&amp;#039;);

    // On ajoute l&amp;#039;aide de la page
    Page::helpBlock(My::id());

    // On ferme la page
    Page::closeModule();
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ici on voit l'utilisation des classes d'outils My et Page qui vont grandement faciliter l'écriture des plugins et thèmes.&lt;br /&gt;
&lt;br /&gt;
A noter que seule la première méthode &lt;strong&gt;init()&lt;/strong&gt; est obligatoire. Si elle renvoie &lt;strong&gt;true&lt;/strong&gt;, c'est que la classe ne contient pas de méthode &lt;strong&gt;process()&lt;/strong&gt;, la méthode &lt;strong&gt;render()&lt;/strong&gt; sera exécuté.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.27 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
          <item>
        <title>2.27</title>
        <link>https://dotclear.watch/Billet/Release-2.27</link>
        <guid isPermaLink="false">urn:md5:72ade80918360fdffe7ef013f0d6eb83</guid>
        <pubDate>Tue, 11 Jul 2023 20:28:00 +0100</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>Versions</category>
                          <category>2.27</category>
                  <category>release</category>
                <description>&lt;p&gt;Sortie prévue le 13 Aout 2023, &lt;a href=&quot;https://fr.dotclear.org/blog/post/2023/08/13/Dotclear-2.27&quot; hreflang=&quot;fr&quot; title=&quot;Annonce officielle Dotclear 2.27&quot;&gt;cette version&lt;/a&gt; est l'occasion de fêter les 20 ans de Dotclear !&lt;/p&gt; &lt;h5&gt;Résumé&lt;/h5&gt;

&lt;p&gt;Cette version comprend un nombre très important de changements coté code, elle accélère sa transition vers les espaces de noms PHP avec toute la partie administration qui les utilise désormais. (Tout comme les plugins et les thèmes) Le moteur lui même a entamé sa transition et maintenant il n'y a plus qu'un unique point d'entrée dans le code pour tout !&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Nouveautés :&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Nouvelle gestion du moteur suivant &lt;a href=&quot;https://dotclear.watch/Billet/Lancement-de-l-application&quot;&gt;le schéma App =&amp;gt; Utility =&amp;gt; Process&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Quasi obligation d'utilisation de &lt;a href=&quot;https://dotclear.watch/Billet/La-class-Process&quot;&gt;la classe Process&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Nouvelle &lt;a href=&quot;https://dotclear.watch/Billet/Gestion-d-URL-d-administration&quot;&gt;gestion des URLs d'administration&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Nouvelle &lt;a href=&quot;https://dotclear.watch/Billet/La-classe-d-erreur&quot;&gt;gestion d'erreur du core&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Nouveau &lt;a href=&quot;https://dotclear.watch/Billet/Fichier-release-de-Dotclear&quot;&gt;fichier de release&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Modification du &lt;a href=&quot;https://dotclear.watch/Billet/Fichier-de-d%C3%A9finition-d-un-blog&quot;&gt;fichier de définition de blog&lt;/a&gt; index.php,&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/D%C3%A9placement-de-classes&quot;&gt;Déplacement&lt;/a&gt; de nombreuses classes, principalement liées à d'administration,&lt;/li&gt;
&lt;li&gt;Nombreuses variables, fonctions, méthodes et classes &lt;a href=&quot;https://dotclear.watch/Billet/Les-d%C3%A9pr%C3%A9ci%C3%A9s&quot;&gt;dépréciés&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Structure-d-un-module&quot;&gt;La structure des plugins et thèmes&lt;/a&gt; qui a pas mal bougé depuis quelques versions,&lt;/li&gt;
&lt;li&gt;Nouvelle &lt;a href=&quot;https://dotclear.watch/Billet/Les-classes-de-module-My&quot;&gt;classe outils My&lt;/a&gt; pour les modules,&lt;/li&gt;
&lt;li&gt;Nouvelles classes outils Form qui ajoutent de nombreuses balises HTML,&lt;/li&gt;
&lt;li&gt;Nouvelle fonction JS pour le service Rest.&lt;/li&gt;
&lt;li&gt;Prévisualisation de thèmes dans l'admin.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Définitions :&lt;/h5&gt;

&lt;p&gt;Le langage autour de Dotclear a également évolué en même temps que son code. De quoi parle-t-on ?&lt;br /&gt;
Désormais on peut parler d'App, de Process, d'Utility, de Backend, Frontend, etc. Traduction:&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;App&lt;/strong&gt; : L'application dotclear dans son ensemble, c'est également le nom de la classe qui est désormais le &lt;a href=&quot;https://dotclear.watch/Billet/Lancement-de-l-application&quot;&gt;point de départ&lt;/a&gt; du script PHP,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Utility&lt;/strong&gt; : Ce sont les classes maitresses, chaque Utility gère une partie de Dotclear, admin, public, cli, install,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Process&lt;/strong&gt; : Alors là ça va se compliquer, du coté Dotclear ce sont les sous parties d'un Utility, par exemple pour faire simple, coté admin, un Process correspondra à une page (Preferences, Blogs, Posts...). Mais un process est également ajouté à un grand nombre de classes dans le Core de Dotclear et aussi dans les thèmes, les plugins, il permet de séquencer le script. En savoir plus sur &lt;a href=&quot;https://dotclear.watch/Billet/La-class-Process&quot;&gt;la classe Process&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backend&lt;/strong&gt; : La partie admin,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frontend&lt;/strong&gt; : La partie public.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Incompatibilités :&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Les plugins et thèmes n'utilisant pas le gestionnaire d'URL &lt;code&gt;dcCore::app()-&amp;gt;admin-&amp;gt;url&lt;/code&gt; (ou le déprécié &lt;code&gt;dcCore::app()-&amp;gt;adminurl&lt;/code&gt;) pour les redirections et formulaires, risquent de ne pas envoyer vers la page souhaitée.&lt;/li&gt;
&lt;li&gt;Les formulaires utilisant la méthode GET doivent ajouter un champ caché contenant &lt;code&gt;process=xxx&lt;/code&gt; où xxx est l'identifiant la page qu'il souhaite atteindre enregistré dans le gestionnaire d'URL. Exemple pour la page générale d'un plugin il faudra ajouter dans le formulaire &lt;code&gt;new Form\Hidden('process', 'Plugin');&lt;/code&gt; ou encore &lt;code&gt;form::hidden('process', 'Plugin');&lt;/code&gt;.&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;&lt;ins&gt;Information importante pour les développeurs :&lt;/ins&gt;&lt;/strong&gt;&lt;br /&gt;
C'est la dernière version compatible avec PHP 7.4 ! La prochaine version majeure de Dotclear prévue pour novembre .2023 nécessitera PHP 8.1.&lt;br /&gt;
&lt;br /&gt;
Les informations distillées ici sont non exhaustives et pourront être compléter à l'avenir.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;</description>
        
              </item>
      </channel>
</rss>
