web-dev-qa-db-fra.com

Champs dynamiques dans les paramètres du module

J'ai créé un module Joomla qui restitue un ensemble de titres dans un widget, avec des liens vers l'élément principal. Il charge ces titres à partir d'une catégorie Joomla ou d'un flux RSS. Il est extensible et permet d'ajouter d'autres sources de données.

Dans le fichier XML de configuration, j'ai un champ select pour sélectionner la source de données et les champs suivants qui utilisent showon pour en activer un ou plusieurs, en fonction de la source sélectionnée. Ça marche bien.

Maintenant, je souhaite déplacer le code des sources de données dans des plug-ins distincts, afin de le rendre plus facilement extensible. Mais je me heurte à la difficulté d'afficher les champs de ces plugins dans la configuration du module.

Je peux voir comment créer un plugin champ dans le module, ce qui me permettra d’offrir une liste des plugins pertinents, mais je dois aussi pouvoir extraire des champs de configuration de le plugin sélectionné.

Je sais que je pourrais simplement avoir la config pour les plugins dans les plugins eux-mêmes, mais je préférerais l'avoir au niveau du module parce que vous voudrez peut-être plus d'un widget sur votre site avec une config différente mais en utilisant le même plugin.

Je cherche actuellement à créer un type de champ personnalisé , conformément à cette question sur SO ou à utiliser un subform.

Cependant, à ma connaissance, cela ne me permet que de créer un seul champ. Ce dont j'ai besoin, c'est de créer un nombre arbitraire de champs et de les lier de nouveau au champ de liste des plug-ins afin qu'ils puissent être affichés ou masqués, selon le cas.

Quelqu'un peut-il me donner des conseils sur la manière d'y parvenir?

Merci!

1
Simba

Pas de réponse ici, mais j'ai réussi à le résoudre moi-même. La solution consiste en fait à utiliser les deux solutions que j'avais déjà à l'esprit: un type de champ personnalisé et un subform.

Ma solution fonctionne comme suit: j'ai créé un type de champ personnalisé qui remplace le type de champ subform, en remplaçant spécifiquement le comportement formsource.

Le type de champ standard subform prend un attribut formsource, qui contient le chemin d'accès à un autre fichier XML avec la définition de formulaire à inclure.

Ma classe annule cela et au lieu de charger un fichier XML externe, elle en génère un pour lui-même en déclenchant un événement et en lisant les données renvoyées par les plug-ins. Chaque plugin répond avec sa propre liste de paramètres de configuration, qui sont ensuite combinés dans une chaîne XML de formulaire.

jimport('joomla.form.helper');
JFormHelper::loadFieldClass('subform');

class JFormFieldFieldsFromPlugins extends JFormFieldSubform {
    protected $type = 'FieldsFromPlugins';

    public function getInput() {
        //override $this->formsource that the main Subform class uses.
        $this->formsource = $this->buildSubformFromPlugins();
        return parent::getInput();
    }

    private function buildSubformFromPlugins()
    {
        JPluginHelper::importPlugin('myPluginType');
        $dispatcher = JEventDispatcher::getInstance();
        $results = $dispatcher->trigger('onGetPluginFields', []);
        // .... now build XML string from $results ....
        return $xml;
    }
}

C'est ça en quelques mots.

Cependant, il y a quelques autres choses qui méritent d’être mentionnées, pour être complètes.

  • Les champs du sous-formulaire sont gérés indépendamment des champs du formulaire principal. Je voulais avoir un champ principal offrant une liste de sélection de plug-ins, et pour que seuls les champs de plug-in pertinents soient affichés. Ceci est fait en utilisant un attribut showon dans le XML. Cependant, showon ne fonctionne pas entre le sous-formulaire et le formulaire principal. La solution pour cela consistait à déplacer la liste de sélection dans le sous-formulaire. Ce n'est pas idéal car cela signifie qu'il y a maintenant un bloc XML dans mon code PHP qui serait mieux dans le fichier XML du module, mais cela fonctionne au moins de cette façon.

  • La disposition par défaut d'un sous-formulaire comporte tous les champs en retrait de quelques centaines de pixels. Je ne voulais pas de ça, mais il a fallu pas mal d'efforts pour s'en débarrasser. En théorie, vous pouvez remplacer la mise en page en écrivant une méthode getLayoutPaths() dans la classe, mais cela ne fonctionne pas bien pour les sous-formulaires car le chemin de mise en page de substitution est également hérité par tous les sous-champs. J'ai résolu ce problème en chargeant les chemins par défaut ainsi que le chemin de substitution dans ma méthode getLayoutPaths(). Cela fonctionne, bien que cela ressemble à un fudge. J'envisage d'offrir un correctif à Joomla pour éviter une partie de la laideur.

Cela a été une bonne expérience d'apprentissage pour moi. Je suis content d'avoir eu un peu de temps libre pour expérimenter avec, cependant, parce que ce n'était pas évident et pas bien documenté. J'espère qu'une partie de cet article est utile à quiconque essaie de faire quelque chose de similaire.

3
Simba