30

Alors si on veut permettre des plugins pour yAronet, je vois principalement deux points à résoudre :

La structure des fichiers
Je pense que ça change pas mal de choses sur la façon dont le code est structuré aujourd'hui. Chaque fonctionnalité est composée d'un à quatre morceaux : le code exécutable (PHP), les fichiers de ressource (ex. chaînes dans plusieurs langues, templates), les fichiers statiques (ex. CSS et JS) et les fichiers de sortie (ex. logs et images uploadées). Chacune de ces trois parties est placée dans un dossier à part parce que ça permet de les héberger avec des règles différentes sur le serveur web : les fichiers PHP doivent être exécutables tandis que tout le reste ne l'est pas, les fichiers statiques doivent être accessibles par HTTP tandis que les fichiers de ressource ne devraient pas l'être, etc. L'arborescence ressemble aujourd'hui à ça :
yaronet/
    resource/
    src/
    static/
    storage/

Si on envisage des plugins pour yAronet, il faudrait pouvoir les distribuer sous la forme d'archives autonomes qu'il suffit de décompresser quelque part pour que ça fonctionne. S'il faut mettre des fichiers par-ci et des fichiers par-là, ça devient rapidement compliqué de s'y retrouver et d'ajouter/supprimer des plugins sans oublier d'en déployer la moitié ou de nettoyer des fichiers inutiles.

Mais du coup ça veut dire que le site doit pouvoir servir des fichiers statiques depuis plusieurs endroits, exécuter du code PHP stocké dans plusieurs dossiers, etc. L'arborescence deviendrait quelque chose comme ça :
yaronet/
    plugin1/
        resource/
        src/
        static/
        storage/
    plugin2/
        ...

Il faudrait déterminer comment rendre ça possible sans que tout le dossier ne soit accessible par HTTP. Peut-être que faire proxy via le code PHP y compris pour les fichiers statiques pourrait être une option, mais ça reste assez dommage : un serveur HTTP est bien plus performant pour cette tâche, et peut utiliser plein de techniques auxquelles PHP n'a pas accès (cache & co).

Les hooks
Plus simple à expliquer : pour s'interfacer dans le site il faudra un système de hook qui permettrait d'intercaler facilement des morceaux de code. Même chose au niveau des templates, où on voudrait pouvoir ajouter ou modifier des élément visuels dans les pages existantes. Il faut trouver un bon compromis entre proposer suffisamment de points d'ancrage pour que ça reste permissif sans que le code n'en souffre trop.

Pour l'intégration visuelles, une solution alternative serait de dire "il n'y a aucune possibilité d'insérer du code dans les pages, toutes les modifications doivent se faire en post-processing à l'aide de code JS". Mais d'une part ça va un peu à l'encontre d'un des choix du site de fonctionner correctement même sans JS, d'autre part ça repousse le problème un peu plus loin et ça risque d'être très difficile de maintenir une rétro-compatibilité avec ce genre de solution, donc je ne pense pas que ce soit une bonne idée.

Est-ce que vous avez d'autres choses en tête ?
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

31

voila ce que j'avais fais à l'époque pour ce framework web,

pour les hook, le système de template fonctionnait simplement avec des §mots§ clefs,
le système était récursif et les mots clefs agrégés formaient alors un path pour rechercher les bout de template enfants

un bout de template était simplement un .php classique, sa sortie texte allait alors remplacer son §appel§ et mise en cache si nécessaire

une api donnaient des infos (nom, path, url du site/plugin, ..) et permettait d’interagir avec le système de template pour remplacer/ajouter au head, meta, titre, js, css, body, .. déclarer un fichier js/css à insérer dans la page, appeler des plugins, ou n'importe quoi d'autre (c'est juste du php, pas un pseudo langage dédié :- )

si le mot clef fournis avait un pipe | il s'agissait alors d'un plugin

par exemple §hello|world|:- )§ exécutait le plugin hello avec 'world' et ':- )' comme arguments

plugins similaires à un bout de template, du php classique, avec aussi la gestion du cache et la même api pour toucher la page et ajouter ses dépendances

(la seule vrai != est qu'il fallait déclarer une fonction "maître", appelé par le framework à la demande, à l'inverse du bout de template exécuté lui directement)

également des scripts php propres aux plugins peuvent êtres appelés directement depuis des url, pour recevoir des formulaires, envoyer des mails ... sans passer par le framework mais le laissant accessible

chaque plugin avait un répertoire dédié, avec des sous répertoires pour ses .php et ses fichiers statiques, la séparation était effectuée au niveau du serveur web, via le rewriting d'url :

conf nginx
location /p/ { # plugins # plugin php scripts /p/$plugin/$file => /fastIce/plugins/$plugin/php/$file.php location ~ ^/p/([^/\.]+)/([^/\.]+)$ { alias $root/fastIce/plugins/$1/php; set $file /$2.php; try_files $file =404; fastcgi_pass fpmphp; fastcgi_intercept_errors on; include fastcgi_params; fastcgi_param FST $root/fastIce/fastIce.php; fastcgi_param SCRIPT_FILENAME $document_root$file; } # plugin static files => /p/$plugin/$filePath location ~ ^/p/([^/\.]+)/(.+)$ { alias $root/fastIce/plugins/$1/http/$2; gzip_static on;expires max;access_log off;log_not_found off; } # ajax plugin caller => /p/$plugin location ~ ^/p/([^/\.]+)$ { fastcgi_pass fpmphp; fastcgi_intercept_errors on; include fastcgi_params; fastcgi_param QUERY_STRING plg=$1; fastcgi_param FST $root/fastIce/fastIce.php; fastcgi_param SCRIPT_FILENAME $root/fastIce/plugins/ajax_plg/php/ajax.php; }
premier bloc pour appeler directement un script php propre à un plugin
second bloc, pour servir un fichier statique du plugin
troisième bloc pour lancer la fonction maître d'un plugin depuis l'extérieur (le php lié chargeant le framework et appelant le plugin demandé avec $_POST comme arguments

techniquement je me servais des plugins pour tout, un bon exemple est un éditeur de contenus inline, dans mes template je foutais simplement un §editable|§ la ou je voulais une zone custom,
en non admin il affichais alors le contenu tandis qu' en admin insère plutôt un éditeur en content éditable avec les js/css nécessaires à celui ci dans le head

32

D'accord, donc pour gérer correctement les différents types de fichier à servir tu imposes une hiérarchie standard pour tous les plugins et tu prépares ta configuration du serveur HTTP pour adopter le bon comportement en fonction du nom du dossier, genre fichiers statiques pour "/plugin/*/static/" et exécution de PHP pour "/plugin/*/src/" ?
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

33

oui, exactement comme ici avec ta séparation en quatre sous dossiers

et cela permet aussi de toucher la conf au besoin pour limiter certaines choses fastcgi_param PHP_VALUE "disable_functions=exec";
ou ajouter des variables globales à php pour simplifier les choses, exemple ici pour inclure facilement le framework : fastcgi_param FST $root/fastIce/fastIce.php;, j'utilise ensuite include $_SERVER['FST'];


voila ma structure exacte (le code du git n'avait pas encore eu cette séparation effective, mais je peux mettre à jour si besoin) :

/plugins # tous les plugins dans ce répertoire
/plugins/myplugin/ # répertoire d'un plugin
/plugins/myplugin/myplugin.php # fichier principal du plugin, contenant sa fonction "maître" fn_myplugin(), non accessible de manière directe depuis l'extérieur ( appelé directement par le moteur de template ou implicitement par le 3eme bloc de la conf nginx )
/plugins/myplugin/http/ # éventuels fichiers statiques dédiés, accessibles depuis l'extérieur via rewriting
/plugins/myplugin/php/ # éventuels scripts php dédiés, accessibles depuis l'extérieur via rewriting

et si besoin de ressources particulières je les mettaient sur la racine du plugin

après le plus important est la remonté et bonne insertion des différentes parties nécessaires au fonctionnement du plugin dans la page, code js d'init, fichiers à inclure ect ..

34

OK c'est pas con et ça règle la question des fichiers, reste celui des hooks smile (je trouve ta solution très permissive, j'aimerais quelque chose d'un peu plus cadré sinon la rétro-compatibilité va être un enfer)
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

35

Pour les hooks, il faut voir ce qui est accepté comme type de plugin, ou s'il n'y a aucune restriction.
J'aime bien l'idée que tout ce qui est ajouté au rendu dans le client le soit en modifiant proprement le DOM une fois la page chargée, mais tu n'as pas des situations dans les requêtes Ajax de base de yN qui modifient déjà le DOM et pourraient du coup poser problème ?
Ça oblige aussi à avoir tout un tas de contrôles pour s'assurer que le plugin ne fasse pas planter l'exécution du JS suite à une erreur bête (modifier un élément qui n'existe pas à tout hasard). Voir si c'est au plugin de gérer ces contrôles ou au moteur de plugins ? (mais la seconde solution est sacrément lourde à mettre en place, sauf à aimer le Javascript cheeky).
Ou alors ne sont proposées que des typologies spécifiques de plugins, par zones (plugin qui impacte le menu d'en haut, ou l'élément "post", ou le module de création de message...). Mais c'est rigide (et probablement pénible à maintenir).
avatar

36

Nil (./35) :
J'aime bien l'idée que tout ce qui est ajouté au rendu dans le client le soit en modifiant proprement le DOM une fois la page chargée
"tout ce qui est ajouté" tu veux dire par des plugins ? Si oui ça veut dire qu'il faut obligatoirement avoir JavaScript pour que les plugins fonctionnent, ce qui est une régression par rapport au reste du site. Et puis surtout, si l'API c'est "n'importe quoi dans la page parce qu'un plugin peut modifier absolument ce qu'il veut", soit ça verrouille les développements futurs soit ça t'oblige à casser la compatibilité chaque fois que tu touches au DOM. Je ne pense pas que ce soit une approche viable.

Nil (./35) :
Ou alors ne sont proposées que des typologies spécifiques de plugins, par zones (plugin qui impacte le menu d'en haut, ou l'élément "post", ou le module de création de message...). Mais c'est rigide (et probablement pénible à maintenir).
C'est un peu ce que j'avais en tête en effet. C'est beaucoup plus pénible à mettre en place, beaucoup plus strict et limité également puisqu'on ne peut s'intégrer que là où c'était prévu à l'avance, mais avec une maintenance plus facile et une compatibilité bien mieux contrôlée à mon avis.
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)