web-dev-qa-db-fra.com

Comment faire pour que mon plugin Editor (type: editors-xtd) survive après les mises à jour?

J'ai un projet pour lequel j'écris un composant, un module et un plugin d'éditeur.

J'ai réussi à rassembler un plugin rudimentaire qui fonctionne avec TinyMCE (au moins) et qui:

  1. Affiche un bouton personnalisé
  2. Déclenche une fenêtre modale contextuelle contenant un tableau dynamique de boutons utilisant des données de base de données.
  3. Insère un espace réservé personnalisé à accolade frisée dans un article.

La partie qui me préoccupe est de rendre ma solution "preuve de mise à niveau".

J'ai suivi https://mrgott.com/13-joomla/17-how-to-create-joomla-editors-xtd-plugin-button-and-open-modal-popup autant que moi pourrait, jusqu'à ce que je devais rompre et construire au-delà de ce qui est mentionné. Cette ressource met en garde:

REMARQUE: Oui, la première question qui se pose est la suivante: qu’en est-il si, après chaque mise à jour, votre fichier sera supprimé car il ne fait pas partie du composant com_content de Joomla. Oui, c’est vrai, mais en fait, je vais bien en conservant ce fichier et en le téléchargeant après chaque mise à jour du système, plutôt que de faire le développement de plug-ins de manière incorrecte.

Si vous construisez ce plugin pour votre client, vous devriez mieux construire un composant, ou peut-être avez-vous déjà construit un composant et ajoutez-vous simplement un nouveau fichier de vue pour votre plugin editors-xtd.

Je pense que mon composant nécessitera plus qu'un nouveau fichier dans views. Je préférerais apprendre "de la bonne façon". Je ne veux pas "abandonner" comme Philippe . Quels fichiers dois-je créer (copier et modifier dans mon composant) pour rendre mon plug-in durable? Je pourrais aussi utiliser une astuce pour ajouter une petite icône à mon bouton personnalisé dans l'éditeur; pour le moment, je n'ai que du texte avec un espace vide à gauche.

La fonction onDisplay() dans /plugins/editors-xtd/picturelinkcode/picturelinkcode.php:

public function onDisplay($name)
{       
    $query_string = [
        "option" => "com_content",      // I want this to be "com_picture",
        "view"   => "article",
        "layout" => "picturelinkcode",  // some examples use "modal" here
        "tmpl"   => "component",
        "editor" => $name
    ];

    $link = 'index.php?' . http_build_query($query_string);

    $button = new JObject;
    $button->modal = true;
    $button->class = 'btn';
    $button->link  = $link;
    $button->text  = JText::_('Linkcode');
    $button->name  = 'picturelinkcode';
    $button->options = "{handler: 'iframe', size: {x: 600, y: 400}}";

    return $button;
}

Le /administrator/components/com_content/views/article/tmpl/picturelinkcode.php fichier:

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

$document     = JFactory::getDocument();
$this->editor = JFactory::getApplication()->input->getCmd('editor', '');
$this->editor = preg_replace('~[^\w[\]-]+~', '', $this->editor);  // sanitize

/**
 * ...better coding practice would probably be
 * to store the js and the data processing
 * outside of this tmpl file
 *   --apologies while sprinting
 */
$script  = 'function insertPictureLinkcode(linkcode) {' . "\n";
$script .= '  var tag = "{loadpicture " + linkcode + "}";' . "\n";
$script .= '  window.parent.jInsertEditorText(tag, ' . json_encode($this->editor) . ');' . "\n"; // "jform_articletext"
$script .= '  window.parent.jModalClose();' . "\n";
$script .= '  return false;' . "\n";
$script .= '}' . "\n";

JFactory::getDocument()->addScriptDeclaration($script);

?><h3>Picture Linkcodes</h3><?php

// Retrieve all linkcodes and their associated counts
$db = JFactory::getDBO();
$subquery = $db->getQuery(true)
               ->select("id")
               ->from("#__fields")
               ->where([
                   "context = 'com_picture.picture'",
                   "name = 'linkcode'"
                 ]);
$query = $db->getQuery(true)
            ->select("value AS linkcode, COUNT(*) AS picturecount")
            ->from("#__fields_values")
            ->where("field_id = ($subquery)")
            ->group("value");
$db->setQuery($query);

try
{
    $resultset = $db->loadObjectList();
    if (!$resultset)
    {
        echo "No Linkcodes Available Yet<br>";
    }
    else
    {
        ?>
        <form class="form">
            <table>
                <?php
                foreach ($resultset as $row)
                {
                    ?>
                    <tr>
                        <td>
                            <button onclick="insertPictureLinkcode('<?php echo $row->linkcode; ?>');" class="btn btn-primary">
                                <?php echo $row->linkcode; ?>
                            </button>
                        </td>
                        <td>
                            (<?php echo $row->picturecount; ?>)
                        </td>
                    </tr>
                    <?php
                }
                ?>
            </table>
        </form>
        <?php
    }
} catch (Exception $e) {
    echo "<div class='bg-danger'>Picture Linkcode Query Error - Contact Developer</div>";
    //echo "<div class='bg-danger'>" , $query->dump() , "<br>" , $e->getMessage() , "</div>";
}

Captures d'écran de ma tentative de codage actuellement fonctionnelle: https://imgur.com/a/kP2WGKo (Je devrais demander à @Eoin quelle technologie il utilise pour créer ces gifs animés géniaux )

Au cas où cela serait important, mon composant est presque identique à celui du noyau adminstistrator/components/com_contact et mon module n'aura qu'un travail - remplacer les espaces réservés dans les articles à contenu dynamique. Mon plugin aura éventuellement plus de fonctionnalités que ce que je montre dans cette question.

4
mickmackusa

Normalement, le plugin ouvrirait une liste d'éléments. Dans ce cas, le composant n'a pas le modèle/vue pour les éléments. Donc, vous devez les créer.

Au minimum, le modèle doit contenir la méthode getListQuery() qui renvoie la requête utilisée pour extraire les éléments.

administrateur/composants/com_picture/models/items.php:

defined('_JEXEC') or die;

class PictureModelItems extends JModelList
{
    protected function getListQuery()
    {
        // Retrieve all linkcodes and their associated counts
        $db = $this->_db;
        $subQuery = $db->getQuery(true)
            ->select($db->quoteName('id'))
            ->from($db->quoteName('#__fields'))
            ->where(
                [
                    $db->quoteName('context') . ' = ' . $db->quote('com_picture.picture'),
                    $db->quoteName('name') . ' = ' . $db->quote('linkcode'),
                ]
            );

        $query = $db->getQuery(true)
            ->select([$db->quoteName('value', 'linkcode'), 'COUNT(*) AS picturecount'])
            ->from($db->quoteName('#__fields_values'))
            ->where($db->quoteName('field_id') . ' = (' . $subQuery . ')')
            ->group($db->quoteName('value'));

        return $query;
    }
}

La vue, au minimum, doit récupérer les éléments.

administrateur/composants/com_picture/views/items/view.html.php:

defined('_JEXEC') or die;

class PictureViewItems extends JViewLegacy
{
    protected $items;

    public function display($tpl = null)
    {
        $this->items = $this->get('Items');

        return parent::display($tpl);
    }
}

Ensuite, dans la présentation de la vue, affichez la liste des éléments d'un tableau ou de tout autre format de votre choix.

Dans le plugin bouton, changez la propriété link pour qu'elle pointe vers votre nouvelle vue:

$button->link = 'index.php?option=com_picture&amp;view=items&amp;layout=modal&amp;tmpl=component&amp;editor=' . $name . '&amp;' . JSession::getFormToken() . '=1';

Je pourrais aussi utiliser une astuce pour ajouter une petite icône à mon bouton personnalisé dans l'éditeur

L'icône provient de la propriété name du bouton. Il obtient icon- ajouté devant pour former une classe d’icônes IcoMoon. Par exemple. si vous le définissez sur joomla, la classe résultante sera icon-joomla. Voir toutes les icônes ici .

2
Sharky