diff options
| author | 2019-12-03 22:37:40 +0100 | |
|---|---|---|
| committer | 2019-12-03 22:37:40 +0100 | |
| commit | 705318aa39a605a4d869db588f6cffb12019a611 (patch) | |
| tree | 36383dfee24999f9928957621b655e67b20714b7 /docs/fr/developers | |
| parent | 0de7e84380dff5222e6728aacbbb42abaac51dd9 (diff) | |
Translate docs with po4a (#2590)
* [i18n] Add docs po4a script
* Add proof of concept
* Add a few more translations
* Hush ShellCheck and shfmt
* Make that list po4a-friendly
* drat, this document could've probably been auto-generated
* Definitive proof that it's translated from French ;-)
* Add some brand spanking new French translation
* More translation
* Mostly finish that config page
* Fix up FAQ
* More contributing
* Dev first steps
* Let's ignore that admin stuff at the very least for now
* Translate release new version, make French the source first and copy all translations
Then replace French with English in the source.
Much quicker than any alternative route.
* And add the English translation
* Minor stylistic leftover from French
* Most of first steps
* Forgot the extensions
* Use po4a 0.56 to get rid of way too many newlines
* Fix up those newlines
* No point linking to Firefox integration anymore from the new user guide
* Start on main view
* A bunch of main view stuff
* More main view
* And some subscriptions before going to bed
* First steps for devs
* More dev first steps
* Incomplete French → English dev/GH translation
Because I need to ask about that mailing list thing
* Fix typo in docs/en/developers/02_Github.md
* Translate & complete devs/github to English
* Fix up most of extensions
* Is that supposed to be a non-breaking space? Let's see
* Match up some users/mobile access
* More users/mobile access
* Add fresh French translation to Fever API
* Fix typo
* Match frontend todo thingies
* Fix a typo
* Some extensions strings
* Remove Fx subscription service from the docs
Cf. https://github.com/FreshRSS/FreshRSS/pull/2606
* Add translation for https://github.com/FreshRSS/FreshRSS/pull/2643
* fix typo as per https://github.com/FreshRSS/FreshRSS/pull/2643#discussion_r345433009
* Add some more French translations
* Update French translation as per @aledeg comment https://github.com/FreshRSS/FreshRSS/pull/2590#discussion_r345465909
* Translate some of the meaningless stuff
* Translate the rest of contributing.md to French
* Fix conflicts
* Translate Docker first steps to French
* Update with change from #2665
* Add @aledeg corrections
* Overlooked a couple @aledeg corrections thanks to GitHub autohide
* Latest @aledeg suggestions
Diffstat (limited to 'docs/fr/developers')
| -rw-r--r-- | docs/fr/developers/01_First_steps.md | 147 | ||||
| -rw-r--r-- | docs/fr/developers/02_Github.md | 170 | ||||
| -rw-r--r-- | docs/fr/developers/03_Backend/02_Minz.md | 14 | ||||
| -rw-r--r-- | docs/fr/developers/03_Backend/04_Changing_source_code.md | 8 | ||||
| -rw-r--r-- | docs/fr/developers/03_Backend/05_Extensions.md | 472 | ||||
| -rw-r--r-- | docs/fr/developers/04_Frontend/01_View_files.md | 8 | ||||
| -rw-r--r-- | docs/fr/developers/04_Frontend/02_Design.md | 6 | ||||
| -rw-r--r-- | docs/fr/developers/05_Release_new_version.md | 105 |
8 files changed, 697 insertions, 233 deletions
diff --git a/docs/fr/developers/01_First_steps.md b/docs/fr/developers/01_First_steps.md index df3fa65f2..2efa65991 100644 --- a/docs/fr/developers/01_First_steps.md +++ b/docs/fr/developers/01_First_steps.md @@ -1,20 +1,105 @@ -# Configurer son environnement +# Configurer son environnement (Docker) + +FreshRSS est construit en PHP et utilise le framework Minz. Les +dépendancessont directement incluses dans le code source, donc vous n'avez +pas besoin d'utiliser Composer. + +Il existe plusieurs façons de configurer votre environnement +dedéveloppement. La méthode la plus simple et la plus supportée est basée +surDocker. C'est la solution qui est documentée ci-dessous. Si vous avez +déjà unenvironnement PHP fonctionnel, vous n'en avez probablement pas +besoin. + +Nous supposons ici que vous utilisez une distribution GNU/Linux, capable +d'exécuter Docker. Sinon, vous devrez adapter les commandes en conséquence. + +Les commandes qui suivent doivent être exécutées dans une console. Ils +commencent par `$` quand les commandes doivent être exécutées en tant +qu'utilisateur normal, et par `#` quand elles doivent être exécutées en tant +qu'utilisateur root. Vous n'avez pas besoin de taper ces caractères. Un +chemin d'accès peut être indiqué devant ces caractères pour vous aider à +identifier où ils doivent être exécutés. Par exemple, `app$ echo 'Hello +World'` indique que vous devez exécuter la commande `echo` dans le +répertoire `app/`. + +Tout d'abord, vous devez installer +[Docker](https://docs.docker.com/install/linux/docker-ce/ubuntu/). + +Une fois que c'est fait, clonez le dépôt de code de la manière suivante : + +```console +$ git clone https://github.com/FreshRSS/FreshRSS.git +$ cd FreshRSS +``` + +Notez que, pour contribuer, vous devrez d'abord « forker » ce dépôt de code +(ou dépôt de code référent) et cloner votre « fork » à la place de ce +dépôt. Adaptez les commandes en conséquence. + +Ensuite, la seule commande que vous devez connaître est la suivante : + +```console +$ make start +``` + +Cela peut prendre un certain temps pour que Docker télécharge l'image +utilisée. Dans le cas où la commande échoue pour un problème de droit, il +faudra soit ajouter votre utilisateur au groupe `docker`, soit relancer la +commande en la préfixant par `sudo`. + +**Vous pouvez maintenant accéder à FreshRSS à [http://localhost:8080](http://localhost:8080).** Suivez simplement le processus d'installation et sélectionnez la base de données SQLite. + +Vous pouvez arrêter les conteneurs en tapant <kbd>Control</kbd> + <kbd>c</kbd> ou avec la commande suivante, dans un autre terminal: + +```console +$ make stop +``` -**TODO** +Si la configuration vous intéresse, les commandes `make' sont définies dans +le fichier [`Makefile`](/Makefile). -## Docker +Si vous avez besoin d'utiliser une image Docker identifiée par un tag +différent (par défaut `dev-alpine`), vous pouvez surcharger de la manière +suivante la variable d'environnement `TAG` au moment de l'exécution de la +commande : -Le développement et le deploiement de FreshRSS peuvent se faire [via Docker](https://github.com/FreshRSS/FreshRSS/tree/dev/Docker). +```console +$ TAG=dev-arm make start +``` + +Vous pouvez trouver la liste complète des tags disponibles [sur le hub +Docker](https://hub.docker.com/r/freshrss/freshrss/tags). + +Si vous voulez construire l'image Docker, vous pouvez lancer la commande +suivante : + +```console +$ make build +$ # ou +$ TAG=dev-arm make build +``` + +La valeur de la variable `TAG` peut contenir n'importe quelle valeur (par +exemple `dev-local`). Vous pouvez cibler une architecture spécifique en +ajoutant `-alpine` ou `-arm` à la fin du tag (par exemple `dev-local-arm`). # Architecture du projet -**TODO** +**À FAIRE** + +# Extensions + +Si vous souhaitez créer votre propre extension FreshRSS, consultez la +[documentation de l'extension](03_Backend/05_Extensions.md). # Style de codage -Si vous désirez contribuer au code, il est important de respecter le style de codage suivant. Le code actuel ne le respecte pas entièrement mais il est de notre devoir à tous de le changer dès que l'occasion se présente. +Si vous désirez contribuer au code, il est important de respecter le style +de codage suivant. Le code actuel ne le respecte pas entièrement mais il est +de notre devoir à tous de le changer dès que l'occasion se présente. -Aucune nouvelle contribution ne respectant pas ces règles ne sera acceptée tant que les corrections nécessaires ne sont pas appliquées. +Aucune nouvelle contribution ne respectant pas ces règles ne sera acceptée +tant que les corrections nécessaires ne sont pas appliquées. ## Espaces, tabulations et autres caractères blancs @@ -23,7 +108,8 @@ L'indentation du code doit être faite impérativement avec des tabulations. ### Alignement -Une fois l'indentation faite, il peut être nécessaire de faire un alignement pour simplifier la lecture. Dans ce cas, il faut utiliser les espaces. +Une fois l'indentation faite, il peut être nécessaire de faire un alignement +pour simplifier la lecture. Dans ce cas, il faut utiliser les espaces. ```php $resultat = une_fonction_avec_un_nom_long($param1, $param2, @@ -32,9 +118,12 @@ $resultat = une_fonction_avec_un_nom_long($param1, $param2, ### Fin de ligne -Le caractère de fin de ligne doit être un saut de ligne (LF) qui est le caractère de fin de ligne des systèmes *NIX. Ce caractère ne doit pas être précédé par des caractères blanc. +Le caractère de fin de ligne doit être un saut de ligne (LF) qui est le +caractère de fin de ligne des systèmes *NIX. Ce caractère ne doit pas être +précédé par des caractères blanc. -Il est possible de vérifier la présence de caractères blancs en fin de ligne grâce à Git avec la commande suivante : +Il est possible de vérifier la présence de caractères blancs en fin de ligne +grâce à Git avec la commande suivante : ```bash # commande à lancer avant l'ajout des fichiers dans l'index @@ -65,7 +154,10 @@ echo $a ? 1 : 0; ### Le cas des parenthèses -Il n'y a pas d'espaces entre des parenthèses. Il n'y a pas d'espaces avant une parenthèse ouvrante sauf si elle est précédée d'un mot-clé. Il n'y a pas d'espaces après une parenthèse fermante sauf si elle est suivie d'une accolade ouvrante. +Il n'y a pas d'espaces entre des parenthèses. Il n'y a pas d'espaces avant +une parenthèse ouvrante sauf si elle est précédée d'un mot-clé. Il n'y a pas +d'espaces après une parenthèse fermante sauf si elle est suivie d'une +accolade ouvrante. ```php if ($a == 10) { @@ -79,7 +171,11 @@ if ((int)$a == 10) { ### Le cas des fonctions chainées -Ce cas se présente le plus souvent en Javascript. Quand on a des fonctions chainées, des fonctions anonymes ainsi que des fonctions de rappels, il est très facile de se perdre. Dans ce cas là, on ajoute une indentation supplémentaire pour toute l'instruction et on revient au même niveau pour une instruction de même niveau. +Ce cas se présente le plus souvent en Javascript. Quand on a des fonctions +chainées, des fonctions anonymes ainsi que des fonctions de rappels, il est +très facile de se perdre. Dans ce cas là, on ajoute une indentation +supplémentaire pour toute l'instruction et on revient au même niveau pour +une instruction de même niveau. ```javascript // Première instruction @@ -98,9 +194,13 @@ shortcut.add("shift+" + shortcuts.mark_read, function () { ## Longueur des lignes -Les lignes ne doivent pas dépasser 80 caractères. Il est cependant autorisé exceptionnellement de dépasser cette limite s'il n'est pas possible de la respecter mais en aucun cas, les lignes ne doivent dépasser les 100 caractères. +Les lignes ne doivent pas dépasser 80 caractères. Il est cependant autorisé +exceptionnellement de dépasser cette limite s'il n'est pas possible de la +respecter mais en aucun cas, les lignes ne doivent dépasser les 100 +caractères. -Dans le cas des fonctions, les paramètres peuvent être déclarés sur plusieurs lignes. +Dans le cas des fonctions, les paramètres peuvent être déclarés sur +plusieurs lignes. ```php function ma_fonction($param_1, $param_2, @@ -111,7 +211,8 @@ function ma_fonction($param_1, $param_2, ## Nommage -L'ensemble des éléments du code (fonctions, classes, méthodes et variables) doivent être nommés de manière à décrire leur usage de façon concise. +L'ensemble des éléments du code (fonctions, classes, méthodes et variables) +doivent être nommés de manière à décrire leur usage de façon concise. ### Fonctions et variables @@ -150,12 +251,14 @@ Les fichiers doivent être encodés en UTF-8. ## Compatibilité PHP -Assurez-vous que votre code fonctionne avec une version de PHP aussi ancienne que celle que FreshRSS supporte officiellement. +Assurez-vous que votre code fonctionne avec une version de PHP aussi +ancienne que celle que FreshRSS supporte officiellement. ## Divers -### Opérateurs -Les opérateurs doivent être en fin de ligne dans le cas de conditions sur plusieurs lignes. +### Le cas des opérateurs +Les opérateurs doivent être en fin de ligne dans le cas de conditions sur +plusieurs lignes. ```php if ($a == 10 || @@ -164,13 +267,15 @@ if ($a == 10 || } ``` -### Fin des fichiers +### Fin de fichier -Si le fichier ne contient que du PHP, il ne doit pas comporter de balise fermante +Si le fichier ne contient que du PHP, il ne doit pas comporter de balise +fermante. ### Tableaux -Lors de l'écriture de tableaux sur plusieurs lignes, tous les éléments doivent être suivis d'une virgule (même le dernier). +Lors de l'écriture de tableaux sur plusieurs lignes, tous les éléments +doivent être suivis d'une virgule (même le dernier). ```php $variable = [ diff --git a/docs/fr/developers/02_Github.md b/docs/fr/developers/02_Github.md index 686b69ec4..439c70933 100644 --- a/docs/fr/developers/02_Github.md +++ b/docs/fr/developers/02_Github.md @@ -1,77 +1,169 @@ # Remonter un problème ou une suggestion -Malgré le soin apporté à FreshRSS, il se peut que des bugs apparaissent encore. Le projet est jeune et le développement dynamique, aussi celui-ci pourra être corrigé rapidement. Il se peut aussi que vous ayez en tête une fonctionnalité qui n'existe pas encore. Que celle-ci vous paraisse idiote, farfelue, inutile ou trop spécifique, il ne faut surtout pas hésiter à nous la proposer ! Très souvent des "idées en l'air" ont trouvé une oreille attentive. Ce sont les regards externes qui font le plus évoluer le projet. +Malgré le soin apporté à FreshRSS, il se peut que des bugs apparaissent +encore. Le projet est jeune et le développement dynamique, aussi celui-ci +pourra être corrigé rapidement. Il se peut aussi que vous ayez en tête une +fonctionnalité qui n'existe pas encore. Que celle-ci vous paraisse idiote, +farfelue, inutile ou trop spécifique, il ne faut surtout pas hésiter à nous +la proposer ! Très souvent des "idées en l'air" ont trouvé une oreille +attentive. Ce sont les regards externes qui font le plus évoluer le projet. -Si vous êtes convaincus qu'il faut vous faire entendre, voici la marche à suivre. +Si vous êtes convaincus qu'il faut vous faire entendre, voici la marche à +suivre. ## Sur GitHub -GitHub est la plate-forme à privilégier pour vos demandes. En effet, cela nous permet de pouvoir discuter à plusieurs sur un problème ou une suggestion et de faire émerger, souvent, des idées nouvelles. Ne négligeons pas cet aspect "social" ! - - 1. [Rendez-vous sur le gestionnaire de tickets de bugs](https://github.com/FreshRSS/FreshRSS/issues) - 2. Commencez par rechercher si une demande similaire n'a pas déjà été faite. Si oui, n'hésitez pas à ajouter votre voix à la demande. - 3. Si votre demande est nouvelle, [ouvrez un nouveau ticket de bug](https://github.com/FreshRSS/FreshRSS/issues/new) - 4. Rédigez enfin votre demande. Si vous maitrisez l'anglais, c'est la langue à privilégier car cela permet d'ouvrir la discussion à un plus grand nombre de personnes. Sinon, ce n'est pas grave, continuez en français :) - 5. Merci de bien vouloir suivre les quelques conseils donnés plus bas pour faciliter la prise en compte de votre ticket. - +GitHub est la plate-forme à privilégier pour vos demandes. En effet, cela +nous permet de pouvoir discuter à plusieurs sur un problème ou une +suggestion et de faire émerger, souvent, des idées nouvelles. Ne négligeons +pas cet aspect "social" ! + + 1. [Rendez-vous sur le gestionnaire de tickets de + bugs](https://github.com/FreshRSS/FreshRSS/issues) + 2. Commencez par rechercher si une demande similaire n'a pas déjà été + faite. Si oui, n'hésitez pas à ajouter votre voix à la demande. + 3. Si votre demande est nouvelle, [ouvrez un nouveau ticket de + bug](https://github.com/FreshRSS/FreshRSS/issues/new) + 4. Rédigez enfin votre demande. Si vous maitrisez l'anglais, c'est la + langue à privilégier car cela permet d'ouvrir la discussion à un plus + grand nombre de personnes. Sinon, ce n'est pas grave, continuez en + français :) + 5. Merci de bien vouloir suivre les quelques conseils donnés plus bas pour + faciliter la prise en compte de votre ticket. + ## De façon informelle -Tout le monde n'aime pas ou n'utilise pas GitHub pour des raisons aussi diverses que légitimes. C'est pourquoi vous pouvez aussi nous contacter de façon plus informelle. +Tout le monde n'aime pas ou n'utilise pas GitHub pour des raisons aussi +diverses que légitimes. C'est pourquoi vous pouvez aussi nous contacter de +façon plus informelle. -* Sur [les listes de diffusion](https://freshrss.org/announce-of-the-mailing-lists.html) +* Sur [notre chat + Mattermost](https://framateam.org/signup_user_complete/?id=e2680d3e3128b9fac8fdb3003b0024ee) +* Sur [les listes de + diffusion](https://freshrss.org/announce-of-the-mailing-lists.html) * À des évènements / rencontres autour du Logiciel Libre * Autour d'une bière dans un bar * Etc. ## Conseils -Voici quelques conseils pour bien présenter votre remontée de bug ou votre suggestion : - - -* **Faites attention à l'orthographe.** même si ce n'est pas toujours facile, faites votre maximum ;) -* **Donnez un titre explicite à votre demande**, quitte à ce qu'il soit un peu long. Cela nous aide non seulement à comprendre votre demande, mais aussi à retrouver votre ticket plus tard. -* **Une demande = un ticket.** Vous pouvez avoir des tas d'idées mais vous avez peur de spammer le gestionnaire de bugs : ça ne fait rien. Il vaut mieux avoir un peu trop de tickets que trop de demandes dans un seul. On s'occupera de fermer et regrouper les demandes qui le peuvent. -* Si vous remontez un bug, pensez à nous **fournir les logs de FreshRSS** (accessibles dans les dossier ''data/log/'' de FreshRSS) **et PHP** (l'emplacement peut varier selon les distributions, mais pensez à chercher dans ''/var/log/httpd'' ou ''/var/log/apache''). -* Si vous ne trouvez pas les fichiers de logs, précisez-le dans votre ticket afin que nous sachions que vous avez déjà cherché. -* Tous les bugs ne nécessitent pas les logs, mais si vous doutez, mieux vaut nous les fournir. Les logs sont importants et très utiles pour débugguer ! -* Il se peut que les logs puissent révéler des informations plus ou moins confidentielles, **faites attention à ne rien divulguer de sensible.** - -De plus, face à un bug, je ne peux que vous encourager à suivre le format de message suivant (tiré du [site de Max & Sam](http://sametmax.com/template-de-demande-daide-en-informatique/)) : - ----- - -**Quel est mon objectif ?** +Voici quelques conseils pour bien présenter votre remontée de bug ou votre +suggestion : + + +* **Faites attention à l'orthographe.** même si ce n'est pas toujours + facile, faites votre maximum. ;) +* **Donnez un titre explicite à votre demande**, quitte à ce qu'il soit un + peu long. Cela nous aide non seulement à comprendre votre demande, mais + aussi à retrouver votre ticket plus tard. +* **Une demande = un ticket.** Vous pouvez avoir des tas d'idées mais vous + avez peur de spammer le gestionnaire de bugs : ça ne fait rien. Il vaut + mieux avoir un peu trop de tickets que trop de demandes dans un seul. On + s'occupera de fermer et regrouper les demandes qui le peuvent. +* Si vous remontez un bug, pensez à nous **fournir les logs de FreshRSS** + (accessibles dans les dossier ''data/log/'' de FreshRSS) **et PHP** + (l'emplacement peut varier selon les distributions, mais pensez à chercher + dans ''/var/log/httpd'' ou ''/var/log/apache''). +* Si vous ne trouvez pas les fichiers de logs, précisez-le dans votre ticket + afin que nous sachions que vous avez déjà cherché. +* Tous les bugs ne nécessitent pas les logs, mais si vous doutez, mieux vaut + nous les fournir. Les logs sont importants et très utiles pour débugguer ! +* Il se peut que les logs puissent révéler des informations plus ou moins + confidentielles, **faites attention à ne rien divulguer de sensible.** + +De plus, face à un bug, je ne peux que vous encourager à suivre le format de +message suivant (tiré du [site de Sam & +Max](http://sametmax.com/template-de-demande-daide-en-informatique/)) : + +### Quel est mon objectif ? Donnez le contexte général de ce que vous essayiez de faire. -**Qu’est-ce que j’ai essayé de faire ?** +### Qu’est-ce que j’ai essayé de faire ? -Expliquez pas à pas ce que vous avez fait afin que nous puissions reproduire le bug. +Expliquez pas à pas ce que vous avez fait afin que nous puissions reproduire +le bug. -**Quels résultats ai-je obtenus ?** +### Quels résultats ai-je obtenus ? -Le bug : ce que vous voyez qui n'aurez pas dû se passer. Ici vous pouvez fournir les logs. +Le bug : ce que vous voyez qui n'aurez pas dû se passer. Ici vous pouvez +fournir les logs. -**Quel était le résultat attendu ?** +### Quel était le résultat attendu ? Afin que nous comprenions bien où est le problème... au moins selon vous :p -**Quelle est ma situation ?** +### Quelle est ma situation ? Pensez à donner les informations suivantes si vous les connaissez : 1. Quel navigateur ? Quelle version ? 2. Quel serveur : Apache, Nginx ? Quelle version ? 3. Quelle version de PHP ? - 4. Quelle base de données : SQLite, MySQL, MariaDB, PostgreSQL ? Quelle version ? + 4. Quelle base de données : SQLite, MySQL, MariaDB, PostgreSQL ? Quelle + version ? 5. Quelle distribution sur le serveur ? Et… quelle version ? ----- - # Système de branches -**TODO** +## Élémentaire +Si vous êtes novice dans Git, voici quelques ressources qui pourraient vous +être utiles : + +* [Article du blog de GitHub](https://github.com/blog/120-new-to-git) +* <http://try.github.com/> +* <http://sixrevisions.com/resources/git-tutorials-beginners/> +* <http://rogerdudler.github.io/git-guide/> + +## Obtenir le dernier code du répertoire FreshRSS +Vous devez avant tout ajouter le repo officiel à votre liste de repo remote +: +```bash +git remote add upstream git@github.com:FreshRSS/FreshRSS.git +``` + +Vous pouvez vérifier que le repo remote a été ajouté avec succès en +utilisant : +```bash +git remote -v show +``` + +Vous pouvez maintenant pull le dernier code de développement : +```bash +git checkout dev +git pull upstream dev +``` + +## Lancer une nouvelle branche de développement +```bash +git checkout -b mon-branch-developpement +``` # Proposer un patch -**TODO**
\ No newline at end of file +```bash +# Ajoutez le fichier modifié, ici actualize_script.php +git add app/actualize_script.php +# Commitez le changement et écrivez un message de commit approprié. +git commit +# Vérifiez deux fois que tout a l'air d'aller bien +git show +# Poussez les changements sur ton fork +git push +``` + +Vous pouvez maintenant créer un PR en fonction de votre branche. S'il vous +plaît, assurez-vous de le soumettre contre la branche `dev` ! + +## Comment écrire un message de commit + +Un message de commit devrait décrire succinctement les changements sur la +première ligne. Par exemple : + +> Fixe une icône cassée + +Si nécessaire, une ligne blanche et une explication plus longue peuvent le +suivre. + +Pour d'autres conseils, voir +[ici](https://chris.beams.io/posts/git-commit/). diff --git a/docs/fr/developers/03_Backend/02_Minz.md b/docs/fr/developers/03_Backend/02_Minz.md index 7699f9390..754e23ea9 100644 --- a/docs/fr/developers/03_Backend/02_Minz.md +++ b/docs/fr/developers/03_Backend/02_Minz.md @@ -1,27 +1,27 @@ # Modèles -**TODO** +**À FAIRE** # Contrôleurs et actions -**TODO** +**À FAIRE** # Vues -**TODO** +**À FAIRE** # Routage -**TODO** +**À FAIRE** # Écriture des URL -**TODO** +**À FAIRE** # Internationalisation -**TODO** +**À FAIRE** # Comprendres les mécanismes internes -**TODO** +**À FAIRE** diff --git a/docs/fr/developers/03_Backend/04_Changing_source_code.md b/docs/fr/developers/03_Backend/04_Changing_source_code.md index 0282dd9d2..fd4a354d1 100644 --- a/docs/fr/developers/03_Backend/04_Changing_source_code.md +++ b/docs/fr/developers/03_Backend/04_Changing_source_code.md @@ -1,15 +1,15 @@ # Accès à la base de données -**TODO** +**À FAIRE** # Écrire une action et sa vue associée -**TODO** +**À FAIRE** # Gestion de l'authentification -**TODO** +**À FAIRE** # Gestion des logs -**TODO** +**À FAIRE** diff --git a/docs/fr/developers/03_Backend/05_Extensions.md b/docs/fr/developers/03_Backend/05_Extensions.md index 37a4340af..1b340505f 100644 --- a/docs/fr/developers/03_Backend/05_Extensions.md +++ b/docs/fr/developers/03_Backend/05_Extensions.md @@ -1,47 +1,88 @@ -# Fiche technique 0001 — Écriture d'extensions pour FreshRSS +# Écriture d'extensions pour FreshRSS ## Présentation de FreshRSS -FreshRSS est un agrégateur de flux RSS / Atom écrit en PHP depuis octobre 2012. Le site officiel est situé à l'adresse [freshrss.org](https://freshrss.org) et son dépot Git est hébergé par Github : [github.com/FreshRSS/FreshRSS](https://github.com/FreshRSS/FreshRSS). +FreshRSS est un agrégateur de flux RSS / Atom écrit en PHP depuis octobre +2012. Le site officiel est situé à l'adresse +[freshrss.org](https://freshrss.org) et son dépot Git est hébergé par Github +: [github.com/FreshRSS/FreshRSS](https://github.com/FreshRSS/FreshRSS). ## Problème à résoudre -FreshRSS est limité dans ses possibilités techniques par différents facteurs : +FreshRSS est limité dans ses possibilités techniques par différents facteurs +: -- La disponibilité des développeurs principaux ; -- La volonté d'intégrer certains changements ; -- Le niveau de « hack » nécessaire pour intégrer des fonctionnalités à la marge. +* La disponibilité des développeurs principaux ; +* La volonté d'intégrer certains changements ; +* Le niveau de « hack » nécessaire pour intégrer des fonctionnalités à la + marge. -Si la première limitation peut, en théorie, être levée par la participation de nouveaux contributeurs au projet, elle est en réalité conditionnée par la volonté des contributeurs à s'intéresser au code source du projet en entier. Afin de lever les deux autres limitations quant à elles, il faudra la plupart du temps passer par un « à-coté » souvent synonyme de « fork ». +Si la première limitation peut, en théorie, être levée par la participation +de nouveaux contributeurs au projet, elle est en réalité conditionnée par la +volonté des contributeurs à s'intéresser au code source du projet en +entier. Afin de lever les deux autres limitations quant à elles, il faudra +la plupart du temps passer par un « à-coté » souvent synonyme de « fork ». -Une autre solution consiste à passer par un système d'extensions. En permettant à des utilisateurs d'écrire leur propre extension sans avoir à s'intéresser au cœur même du logiciel de base, on permet : +Une autre solution consiste à passer par un système d'extensions. En +permettant à des utilisateurs d'écrire leur propre extension sans avoir à +s'intéresser au cœur même du logiciel de base, on permet : -1. De réduire la quantité de code source à assimiler pour un nouveau contributeur ; -2. De permettre d'intégrer des nouveautés de façon non-officielles ; -3. De se passer des développeurs principaux pour d'éventuelles améliorations sans passer par la case « fork ». - -Note : il est tout à fait imaginable que les fonctionnalités d'une extension puissent par la suite être intégrées dans le code initial de FreshRSS de façon officielle. Cela permet de proposer un « proof of concept » assez facilement. +1. De réduire la quantité de code source à assimiler pour un nouveau + contributeur ; +2. De permettre d'intégrer des nouveautés de façon non-officielles ; +3. De se passer des développeurs principaux pour d'éventuelles améliorations + sans passer par la case « fork ». +Note : il est tout à fait imaginable que les fonctionnalités d'une extension +puissent par la suite être intégrées dans le code initial de FreshRSS de +façon officielle. Cela permet de proposer un « proof of concept » assez +facilement. ## Comprendre les mécaniques de base (Minz et MVC) **TODO** : bouger dans 02_Minz.md -Cette fiche technique devrait renvoyer vers la documentation officielle de FreshRSS et de Minz (le framework PHP sur lequel repose FreshRSS). Malheureusement cette documentation n'existe pas encore. Voici donc en quelques mots les principaux éléments à connaître. Il n'est pas nécessaire de lire l'ensemble des chapitres de cette section si vous n'avez pas à utiliser une fonctionnalité dans votre extension (si vous n'avez pas besoin de traduire votre extension, pas besoin d'en savoir plus sur le module `Minz_Translate` par exemple). +Cette fiche technique devrait renvoyer vers la documentation officielle de +FreshRSS et de Minz (le framework PHP sur lequel repose +FreshRSS). Malheureusement cette documentation n'existe pas encore. Voici +donc en quelques mots les principaux éléments à connaître. Il n'est pas +nécessaire de lire l'ensemble des chapitres de cette section si vous n'avez +pas à utiliser une fonctionnalité dans votre extension (si vous n'avez pas +besoin de traduire votre extension, pas besoin d'en savoir plus sur le +module `Minz_Translate` par exemple). ### Architecture MVC -Minz repose et impose une architecture MVC pour les projets l'utilisant. On distingue dans cette architecture trois composants principaux : - -- Le Modèle : c'est l'objet de base que l'on va manipuler. Dans FreshRSS, les catégories, les flux et les articles sont des modèles. La partie du code qui permet de les manipuler en base de données fait aussi partie du modèle mais est séparée du modèle de base : on parle de DAO (pour « Data Access Object »). Les modèles sont stockés dans un répertoire `Models`. -- La Vue : c'est ce qui représente ce que verra l'utilisateur. La vue est donc simplement du code HTML que l'on mixe avec du PHP pour afficher les informations dynamiques. Les vues sont stockées dans un répertoire `views`. -- Le Contrôleur : c'est ce qui permet de lier modèles et vues entre eux. Typiquement, un contrôleur va charger des modèles à partir de la base de données (une liste d'articles par exemple) pour les « passer » à une vue afin qu'elle les affiche. Les contrôleurs sont stockés dans un répertoire `Controllers`. - -### Le routage - -Afin de lier une URL à un contrôleur, on doit passer par une phase dite de « routage ». Dans FreshRSS, cela est particulièrement simple car il suffit d'indiquer le nom du contrôleur à charger dans l'URL à l'aide d'un paramètre `c`. Par exemple, l'adresse http://exemple.com?c=hello va exécuter le code contenu dans le contrôleur `hello`. - -Une notion qui n'a pas encore été évoquée est le système d'« actions ». Une action est exécutée *sur* un contrôleur. Concrètement, un contrôleur va être représenté par une classe et ses actions par des méthodes. Pour exécuter une action, il est nécessaire d'indiquer un paramètre `a` dans l'URL. +Minz repose et impose une architecture MVC pour les projets l'utilisant. On +distingue dans cette architecture trois composants principaux : + +* Le Modèle : c'est l'objet de base que l'on va manipuler. Dans FreshRSS, + les catégories, les flux et les articles sont des modèles. La partie du + code qui permet de les manipuler en base de données fait aussi partie du + modèle mais est séparée du modèle de base : on parle de DAO (pour « Data + Access Object »). Les modèles sont stockés dans un répertoire `Models`. +* La Vue : c'est ce qui représente ce que verra l'utilisateur. La vue est + donc simplement du code HTML que l'on mixe avec du PHP pour afficher les + informations dynamiques. Les vues sont stockées dans un répertoire + `views`. +* Le Contrôleur : c'est ce qui permet de lier modèles et vues entre + eux. Typiquement, un contrôleur va charger des modèles à partir de la base + de données (une liste d'articles par exemple) pour les « passer » à une + vue afin qu'elle les affiche. Les contrôleurs sont stockés dans un + répertoire `Controllers`. + +### Routage + +Afin de lier une URL à un contrôleur, on doit passer par une phase dite de « +routage ». Dans FreshRSS, cela est particulièrement simple car il suffit +d'indiquer le nom du contrôleur à charger dans l'URL à l'aide d'un paramètre +`c`. Par exemple, l'adresse http://exemple.com?c=hello va exécuter le code +contenu dans le contrôleur `hello`. + +Une notion qui n'a pas encore été évoquée est le système d'« actions ». Une +action est exécutée *sur* un contrôleur. Concrètement, un contrôleur va être +représenté par une classe et ses actions par des méthodes. Pour exécuter une +action, il est nécessaire d'indiquer un paramètre `a` dans l'URL. Exemple de code : @@ -61,17 +102,24 @@ class FreshRSS_hello_Controller extends Minz_ActionController { ?> ``` -Si l'on charge l'adresse http://exemple.com?c=hello&a=world, l'action `world` va donc être exécutée sur le contrôleur `hello`. +Si l'on charge l'adresse http://exemple.com?c=hello&a=world, l'action +`world` va donc être exécutée sur le contrôleur `hello`. -Note : si `c` ou `a` n'est pas précisée, la valeur par défaut de chacune de ces variables est `index`. Ainsi l'adresse http://exemple.com?c=hello va exécuter l'action `index` du contrôleur `hello`. +Note : si `c` ou `a` n'est pas précisée, la valeur par défaut de chacune de +ces variables est `index`. Ainsi l'adresse http://exemple.com?c=hello va +exécuter l'action `index` du contrôleur `hello`. -Plus loin, sera utilisée la convention `hello/world` pour évoquer un couple contrôleur/action. +Plus loin, sera utilisée la convention `hello/world` pour évoquer un couple +contrôleur/action. -### Gestion des vues +### Vues -Chaque vue est associée à un contrôleur et à une action. La vue associée à `hello/world` va être stockée dans un fichier bien spécifique : `views/hello/world.phtml`. Cette convention est imposée par Minz. +Chaque vue est associée à un contrôleur et à une action. La vue associée à +`hello/world` va être stockée dans un fichier bien spécifique : +`views/hello/world.phtml`. Cette convention est imposée par Minz. -Comme expliqué plus haut, les vues sont du code HTML mixé à du PHP. Exemple de code : +Comme expliqué plus haut, les vues sont du code HTML mixé à du PHP. Exemple +de code : ```html <p> @@ -83,7 +131,9 @@ La variable `$this->a_variable` a été passée précédemment par le contrôleu ### Accéder aux paramètres GET / POST -Il est souvent nécessaire de profiter des paramètres passés par GET ou par POST. Dans Minz, ces paramètres sont accessibles de façon indistincts à l'aide de la classe `Minz_Request`. Exemple de code : +Il est souvent nécessaire de profiter des paramètres passés par GET ou par +POST. Dans Minz, ces paramètres sont accessibles de façon indistincts à +l'aide de la classe `Minz_Request`. Exemple de code : ```php <?php @@ -105,17 +155,26 @@ echo Minz_Request::param('bar'); ?> ``` -La méthode `Minz_Request::isPost()` peut être utile pour n'exécuter un morceau de code que s'il s'agit d'une requête POST. +La méthode `Minz_Request::isPost()` peut être utile pour n'exécuter un +morceau de code que s'il s'agit d'une requête POST. -Note : il est préférable de n'utiliser `Minz_Request` que dans les contrôleurs. Il est probable que vous rencontriez cette méthode dans les vues de FreshRSS, voire dans les modèles, mais sachez qu'il ne s'agit **pas** d'une bonne pratique. +Note : il est préférable de n'utiliser `Minz_Request` que dans les +contrôleurs. Il est probable que vous rencontriez cette méthode dans les +vues de FreshRSS, voire dans les modèles, mais sachez qu'il ne s'agit +**pas** d'une bonne pratique. ### Accéder aux paramètres de session -L'accès aux paramètres de session est étrangement similaire aux paramètres GET / POST mais passe par la classe `Minz_Session` cette fois-ci ! Il n'y a pas d'exemple ici car vous pouvez reprendre le précédent en changeant tous les `Minz_Request` par des `Minz_Session`. +L'accès aux paramètres de session est étrangement similaire aux paramètres +GET / POST mais passe par la classe `Minz_Session` cette fois-ci ! Il n'y a +pas d'exemple ici car vous pouvez reprendre le précédent en changeant tous +les `Minz_Request` par des `Minz_Session`. ### Gestion des URL -Pour profiter pleinement du système de routage de Minz, il est fortement déconseillé d'écrire les URL en dur dans votre code. Par exemple, la vue suivante doit être évitée : +Pour profiter pleinement du système de routage de Minz, il est fortement +déconseillé d'écrire les URL en dur dans votre code. Par exemple, la vue +suivante doit être évitée : ```html <p> @@ -123,9 +182,13 @@ Pour profiter pleinement du système de routage de Minz, il est fortement décon </p> ``` -Si un jour il est décidé d'utiliser un système d'« url rewriting » pour avoir des adresses au format http://exemple.com/controller/action, toutes les adresses précédentes deviendraient ineffectives ! +Si un jour il est décidé d'utiliser un système d'« url rewriting » pour +avoir des adresses au format http://exemple.com/controller/action, toutes +les adresses précédentes deviendraient ineffectives ! -Préférez donc l'utilisation de la classe `Minz_Url` et de sa méthode `display()`. `Minz_Url::display()` prend en paramètre un tableau de la forme suivante : +Préférez donc l'utilisation de la classe `Minz_Url` et de sa méthode +`display()`. `Minz_Url::display()` prend en paramètre un tableau de la forme +suivante : ```php <?php @@ -144,7 +207,8 @@ echo Minz_Url::display($url_array); ?> ``` -Comme cela peut devenir un peu pénible à utiliser à la longue, surtout dans les vues, il est préférable d'utiliser le raccourci `_url()` : +Comme cela peut devenir un peu pénible à utiliser à la longue, surtout dans +les vues, il est préférable d'utiliser le raccourci `_url()` : ```php <?php @@ -155,11 +219,16 @@ echo _url('hello', 'world', 'foo', 'bar'); ?> ``` -Note : en règle générale, la forme raccourcie (`_url()`) doit être utilisée dans les vues tandis que la forme longue (`Minz_Url::display()`) doit être utilisée dans les contrôleurs. +Note : en règle générale, la forme raccourcie (`_url()`) doit être utilisée +dans les vues tandis que la forme longue (`Minz_Url::display()`) doit être +utilisée dans les contrôleurs. ### Redirections -Il est souvent nécessaire de rediriger un utilisateur vers une autre page. Pour cela, la classe `Minz_Request` dispose d'une autre méthode utile : `forward()`. Cette méthode prend en argument le même format d'URL que celui vu juste avant. +Il est souvent nécessaire de rediriger un utilisateur vers une autre +page. Pour cela, la classe `Minz_Request` dispose d'une autre méthode utile +: `forward()`. Cette méthode prend en argument le même format d'URL que +celui vu juste avant. Exemple de code : @@ -173,7 +242,7 @@ $url_array = [ // Indique à Minz de rediriger l'utilisateur vers la page hello/world. // Notez qu'il s'agit d'une redirection au sens Minz du terme, pas d'une redirection que le navigateur va avoir à gérer (code HTTP 301 ou 302) -// Le code qui suit forward() va ainsi être exécuté ! +// Le code qui suit forward() va ainsi être exécuté ! Minz_Request::forward($url_array); // Pour effectuer une redirection type 302, ajoutez "true". @@ -183,7 +252,14 @@ Minz_Request::forward($url_array, true); ?> ``` -Il est très fréquent de vouloir effectuer une redirection tout en affichant un message à l'utilisateur pour lui indiquer comment s'est déroulée l'action effectuée juste avant (validation d'un formulaire par exemple). Un tel message est passé par une variable de session `notification` (note : nous parlerons plutôt de « feedback » désormais pour éviter la confusion avec une notification qui peut survenir à tout moment). Pour faciliter ce genre d'action très fréquente, il existe deux raccourcis qui effectuent tout deux une redirection type 302 en affectant un message de feedback : +Il est très fréquent de vouloir effectuer une redirection tout en affichant +un message à l'utilisateur pour lui indiquer comment s'est déroulée l'action +effectuée juste avant (validation d'un formulaire par exemple). Un tel +message est passé par une variable de session `notification` (note : nous +parlerons plutôt de « feedback » désormais pour éviter la confusion avec une +notification qui peut survenir à tout moment). Pour faciliter ce genre +d'action très fréquente, il existe deux raccourcis qui effectuent tout deux +une redirection type 302 en affectant un message de feedback : ```php <?php @@ -206,43 +282,62 @@ Minz_Request::bad($feedback_bad, $url_array); ### Gestion de la traduction -Il est fréquent (et c'est un euphémisme) de vouloir afficher des phrases à l'utilisateur. Dans l'exemple précédent par exemple, nous affichions un feedback à l'utilisateur en fonction du résultat d'une validation de formulaire. Le problème est que FreshRSS possède des utilisateurs de différentes nationalités. Il est donc nécessaire de pouvoir gérer différentes langues pour ne pas rester cantonné à l'Anglais ou au Français. - -La solution consiste à utiliser la classe `Minz_Translate` qui permet de traduire dynamiquement FreshRSS (ou toute application basée sur Minz). Avant d'utiliser ce module, il est nécessaire de savoir où trouver les chaînes de caractères à traduire. Chaque langue possède son propre sous-répertoire dans un répertoire parent nommé `i18n`. Par exemple, les fichiers de langue en Français sont situés dans `i18n/fr/`. Il existe sept fichiers différents : - -- `admin.php` pour tout ce qui est relatif à l'administration de FreshRSS ; -- `conf.php` pour l'aspect configuration ; -- `feedback.php` contient les traductions des messages de feedback ; -- `gen.php` stocke ce qui est global à FreshRSS (gen pour « general ») ; -- `index.php` pour la page principale qui liste les flux et la page « À propos » ; -- `install.php` contient les phrases relatives à l'installation de FreshRSS ; -- `sub.php` pour l'aspect gestion des abonnements (sub pour « subscription »). - -Cette organisation permet de ne pas avoir un unique énorme fichier de traduction. - -Les fichiers de traduction sont assez simples : il s'agit seulement de retourner un tableau PHP contenant les traductions. Extrait du fichier `app/i18n/fr/gen.php` : +Il est fréquent (et c'est un euphémisme) de vouloir afficher des phrases à +l'utilisateur. Dans l'exemple précédent par exemple, nous affichions un +feedback à l'utilisateur en fonction du résultat d'une validation de +formulaire. Le problème est que FreshRSS possède des utilisateurs de +différentes nationalités. Il est donc nécessaire de pouvoir gérer +différentes langues pour ne pas rester cantonné à l'Anglais ou au Français. + +La solution consiste à utiliser la classe `Minz_Translate` qui permet de +traduire dynamiquement FreshRSS (ou toute application basée sur Minz). Avant +d'utiliser ce module, il est nécessaire de savoir où trouver les chaînes de +caractères à traduire. Chaque langue possède son propre sous-répertoire dans +un répertoire parent nommé `i18n`. Par exemple, les fichiers de langue en +Français sont situés dans `i18n/fr/`. Il existe sept fichiers différents : + +* `admin.php` pour tout ce qui est relatif à l'administration de FreshRSS ; +* `conf.php` pour l'aspect configuration ; +* `feedback.php` contient les traductions des messages de feedback ; +* `gen.php` stocke ce qui est global à FreshRSS (gen pour « general ») ; +* `index.php` pour la page principale qui liste les flux et la page « À + propos » ; +* `install.php` contient les phrases relatives à l'installation de FreshRSS + ; +* `sub.php` pour l'aspect gestion des abonnements (sub pour « subscription + »). + +Cette organisation permet de ne pas avoir un unique énorme fichier de +traduction. + +Les fichiers de traduction sont assez simples : il s'agit seulement de +retourner un tableau PHP contenant les traductions. Extrait du fichier +`app/i18n/fr/gen.php` : ```php <?php -return [ +return array( 'action' => [ 'actualize' => 'Actualiser', 'back_to_rss_feeds' => '← Retour à vos flux RSS', 'cancel' => 'Annuler', 'create' => 'Créer', 'disable' => 'Désactiver', - ], - 'freshrss' => [ + ), + 'freshrss' => array( '_' => 'FreshRSS', 'about' => 'À propos de FreshRSS', - ], + ), ]; ?> ``` -Pour accéder à ces traductions, `Minz_Translate` va nous aider à l'aide de sa méthode `Minz_Translate::t()`. Comme cela peut être un peu long à taper, il a été introduit un raccourci qui **doit** être utilisé en toutes circonstances : `_t()`. Exemple de code : +Pour accéder à ces traductions, `Minz_Translate` va nous aider à l'aide de +sa méthode `Minz_Translate::t()`. Comme cela peut être un peu long à taper, +il a été introduit un raccourci qui **doit** être utilisé en toutes +circonstances : `_t()`. Exemple de code : ```html <p> @@ -252,85 +347,212 @@ Pour accéder à ces traductions, `Minz_Translate` va nous aider à l'aide de sa </p> ``` -La chaîne à passer à la fonction `_t()` consiste en une série d'identifiants séparés par des points. Le premier identifiant indique de quel fichier on veut extraire la traduction (dans notre cas présent, de `gen.php`), tandis que les suivantes indiquent des entrées de tableaux. Ainsi `action` est une entrée du tableau principal et `back_to_rss_feeds` est une entrée du tableau `action`. Cela permet d'organiser encore un peu plus nos fichiers de traduction. - -Il existe un petit cas particulier qui permet parfois de se simplifier la vie : le cas de l'identifiant `_`. Celui-ci doit nécessairement être présent en bout de chaîne et permet de donner une valeur à l'identifiant de niveau supérieur. C'est assez dur à expliquer mais très simple à comprendre. Dans l'exemple donné plus haut, un `_` est associé à la valeur `FreshRSS` : cela signifie qu'il n'y a pas besoin d'écrire `_t('gen.freshrss._')` mais `_t('gen.freshrss')` suffit. +La chaîne à passer à la fonction `_t()` consiste en une série d'identifiants +séparés par des points. Le premier identifiant indique de quel fichier on +veut extraire la traduction (dans notre cas présent, de `gen.php`), tandis +que les suivantes indiquent des entrées de tableaux. Ainsi `action` est une +entrée du tableau principal et `back_to_rss_feeds` est une entrée du tableau +`action`. Cela permet d'organiser encore un peu plus nos fichiers de +traduction. + +Il existe un petit cas particulier qui permet parfois de se simplifier la +vie : le cas de l'identifiant `_`. Celui-ci doit nécessairement être présent +en bout de chaîne et permet de donner une valeur à l'identifiant de niveau +supérieur. C'est assez dur à expliquer mais très simple à comprendre. Dans +l'exemple donné plus haut, un `_` est associé à la valeur `FreshRSS` : cela +signifie qu'il n'y a pas besoin d'écrire `_t('gen.freshrss._')` mais +`_t('gen.freshrss')` suffit. ### Gestion de la configuration ## Écrire une extension pour FreshRSS -Nous y voilà ! Nous avons abordé les fonctionnalités les plus utiles de Minz et qui permettent de faire tourner FreshRSS correctement et il est plus que temps d'aborder les extensions en elles-même. +Nous y voilà ! Nous avons abordé les fonctionnalités les plus utiles de Minz +et qui permettent de faire tourner FreshRSS correctement et il est plus que +temps d'aborder les extensions en elles-même. -Une extension permet donc d'ajouter des fonctionnalités facilement à FreshRSS sans avoir à toucher au cœur du projet directement. +Une extension permet donc d'ajouter des fonctionnalités facilement à +FreshRSS sans avoir à toucher au cœur du projet directement. ### Les fichiers et répertoires de base -La première chose à noter est que **toutes** les extensions **doivent** se situer dans le répertoire `extensions`, à la base de l'arborescence de FreshRSS. Une extension est un répertoire contenant un ensemble de fichiers et sous-répertoires obligatoires ou facultatifs. La convention veut que l'on précède le nom du répertoire principal par un « x » pour indiquer qu'il ne s'agit pas d'une extension incluse par défaut dans FreshRSS. - -Le répertoire principal d'une extension doit comporter au moins deux fichiers **obligatoire** : - -- Un fichier `metadata.json` qui contient une description de l'extension. Ce fichier est écrit en JSON ; -- Un fichier `extension.php` contenant le point d'entrée de l'extension. +La première chose à noter est que **toutes** les extensions **doivent** se +situer dans le répertoire `extensions`, à la base de l'arborescence de +FreshRSS. Une extension est un répertoire contenant un ensemble de fichiers +et sous-répertoires obligatoires ou facultatifs. La convention veut que l'on +précède le nom du répertoire principal par un « x » pour indiquer qu'il ne +s'agit pas d'une extension incluse par défaut dans FreshRSS. -Il est possible aussi que vous ayez besoin de fichiers ou sous-répertoires additionnels selon vos besoins : +Le répertoire principal d'une extension doit comporter au moins deux +fichiers **obligatoire** : -- `configure.phtml` est le fichier contenant le formulaire permettant de paramétrer votre extension ; -- Un répertoire `static/` contenant fichiers CSS et JavaScript dont vous aurez besoin pour votre extension. Notez que si vous devez écrire beaucoup de CSS il est peut-être plus intéressant d'écrire un thème complet (mais ce n'est pas le sujet de cette fiche technique) ; -- Un répertoire `Controllers` contenant des contrôleurs additionnels ; -- Un répertoire `i18n` contenant des traductions supplémentaires ; -- Des répertoires `layout` et `views` permettant de définir de nouvelles vues ou d'écraser les vues actuelles. +* Un fichier `metadata.json` qui contient une description de l'extension. Ce + fichier est écrit en JSON ; +* Un fichier `extension.php` contenant le point d'entrée de l'extension. -De plus, il est de bon ton d'avoir un fichier `LICENSE` indiquant la licence sous laquelle est distribuée votre extension et un fichier `README` donnant une description détaillée de celle-ci. +Please note that there is a not a required link between the directory name +of the extension and the name of the class inside `extension.php`, but you +should follow our best practice: If you want to write a `HelloWorld` +extension, the directory name should be `xExtension-HelloWorld` and the base +class name `HelloWorldExtension`. -### Écrire le fichier metadata.json - -Le fichier `metadata.json` définit votre extension à travers un certain nombre d'éléments importants. Il doit contenir un tableau JSON valide contenant les entrées suivantes : - -- `name` : le nom de votre extension ; -- `author` : votre nom, éventuellement votre adresse mail mais il n'y a pas de format spécifique à adopter ; -- `description` : une description de votre extension ; -- `version` : le numéro de version actuel de l'extension ; -- `entrypoint` : indique le point d'entrée de votre extension. Il doit correspondre au nom de la classe contenue dans le fichier `extension.php` sans le suffixe `Extension` (donc si le point d'entrée est `HelloWorld`, votre classe s'appellera `HelloWorldExtension`) ; -- `type` : définit le type de votre extension. Il existe deux types : `system` et `user`. Nous étudierons cette différence juste après. +In the file `freshrss/extensions/xExtension-HelloWorld/extension.php` you +need the structure: +```html +class HelloWorldExtension extends Minz_Extension { + public function init() { + // your code here + } +} +``` +There is an example HelloWorld extension that you can download from [our +GitHub repo](https://github.com/FreshRSS/xExtension-HelloWorld). + +You may also need additional files or subdirectories depending on your +needs: + +* `configure.phtml` est le fichier contenant le formulaire pour paramétrer + votre extension +* A `static/` directory containing CSS and JavaScript files that you will + need for your extension (note that if you need to write a lot of CSS it + may be more interesting to write a complete theme) +* A `Controllers` directory containing additional controllers +* An `i18n` directory containing additional translations +* `layout` and` views` directories to define new views or to overwrite the + current views + +In addition, it is good to have a `LICENSE` file indicating the license +under which your extension is distributed and a` README` file giving a +detailed description of it. + +### The metadata.json file + +The `metadata.json` file defines your extension through a number of +important elements. It must contain a valid JSON array containing the +following entries: + +* `name` : le nom de votre extension ; +* `author` : votre nom, éventuellement votre adresse mail mais il n'y a pas + de format spécifique à adopter ; +* `description` : une description de votre extension ; +* `version` : le numéro de version actuel de l'extension ; +* `entrypoint` : indique le point d'entrée de votre extension. Il doit + correspondre au nom de la classe contenue dans le fichier `extension.php` + sans le suffixe `Extension` (donc si le point d'entrée est `HelloWorld`, + votre classe s'appellera `HelloWorldExtension`) ; +* `type` : définit le type de votre extension. Il existe deux types : + `system` et `user`. Nous étudierons cette différence juste après. Seuls les champs `name` et `entrypoint` sont requis. ### Choisir entre extension « system » ou « user » -### Écrire le fichier extension.php - -Ce fichier est le point d'entrée de votre extension. Il doit contenir une classe bien spécifique pour fonctionner. Comme évoqué plus haut, le nom de la classe doit être votre `entrypoint` suffixé par `Extension` (`HelloWorldExtension` par exemple). De plus, cette classe doit héritée de la classe `Minz_Extension` pour bénéficier des méthodes propres aux extensions. - -Votre classe va bénéficier de quatre méthodes à redéfinir : - -- `install()` est appelée lorsqu'un utilisateur va cliquer sur le bouton pour activer votre extension. Elle permet par exemple de mettre à jour la base de données d'un utilisateur afin de la rendre compatible avec l'extension. Elle retourne `true` si tout s'est bien passé ou, dans le cas contraire, une chaîne de caractères expliquant le problème ; -- `uninstall()` est appelée lorsqu'un utilisateur va cliquer sur le bouton pour désactiver votre extension. Ainsi, vous pourrez annuler les changements en base de données que vous avez potentiellement faits dans `install()`. Elle retourne `true` si tout s'est bien passé ou, dans le cas contraire, une chaîne de caractères expliquant le problème ; -- `init()` est appelée à chaque chargement de page *si l'extension est activée*. Elle va donc initialiser le comportement de l'extension. C'est la méthode la plus importante ; -- `handleConfigureAction()` est appelée lorsqu'un utilisateur charge le panneau de gestion de l'extension. Plus précisément, elle est appelée lorsque l'URL `?c=extension&a=configure&e=le-nom-de-votre-extension` est chargée. Vous devriez aussi écrire ici le comportement voulu lors de la validation du formulaire contenu dans votre fichier `configure.phtml`. - -De plus, vous disposerez d'un certain nombre de méthodes directement héritées de `Minz_Extension` que vous ne devriez pas redéfinir : - -- Les « getters » tout d'abord. La plupart sont suffisamment explicites pour ne pas les détailler : `getName()`, `getEntrypoint()`, `getPath()` (permet de récupérer le chemin vers votre extension), `getAuthor()`, `getDescription()`, `getVersion()`, `getType()` ; -- `getFileUrl($filename, $type)` va vous retourner l'URL vers un fichier du répertoire `static`. Le premier paramètre est le nom du fichier (sans `static/`), le deuxième est le type de fichier à servir (`css` ou `js`) ; -- `registerController($base_name)` va indiquer à Minz de prendre en compte le contrôleur donné dans le système de routage. Le contrôleur doit se situer dans votre répertoire `Controllers`, le nom du fichier doit être `<base_name>Controller.php` et le nom de la classe `FreshExtension_<base_name>_Controller`. - -TODO : - -- `registerViews()` -- `registerTranslates()` -- `registerHook($hook_name, $hook_function)` +A __user__ extension can be enabled by some users and not by others +(typically for user preferences). + +A __system__ extension in comparison is enabled for every account. + +### Writing your own extension.php + +This file is the entry point of your extension. It must contain a specific +class to function. As mentioned above, the name of the class must be your +`entrypoint` suffixed by` Extension` (`HelloWorldExtension` for example). +In addition, this class must be inherited from the `Minz_Extension` class to +benefit from extensions-specific methods. + +Your class will benefit from four methods to redefine: + +* `install()` is called when a user clicks the button to activate your + extension. It allows, for example, to update the database of a user in + order to make it compatible with the extension. It returns `true` if + everything went well or, if not, a string explaining the problem. +* `uninstall()` is called when a user clicks the button to disable your + extension. This will allow you to undo the database changes you + potentially made in `install ()`. It returns `true` if everything went + well or, if not, a string explaining the problem. +* `init()` is called for every page load *if the extension is enabled*. It + will therefore initialize the behavior of the extension. This is the most + important method. +* `handleConfigureAction()` is called when a user loads the extension + management panel. Specifically, it is called when the + `?c=extension&a=configured&e=name-of-your-extension` URL is loaded. You + should also write here the behavior you want when validating the form in + your `configure.phtml` file. + +In addition, you will have a number of methods directly inherited from +`Minz_Extension` that you should not redefine: + +* The "getters" first: most are explicit enough not to detail them here - + `getName()`, `getEntrypoint()`, `getPath()` (allows you to retrieve the + path to your extension), `getAuthor()`, `getDescription()`, + `getVersion()`, `getType()`. +* `getFileUrl($filename, $type)` will return the URL to a file in the + `static` directory. The first parameter is the name of the file (without + `static /`), the second is the type of file to be used (`css` or` js`). +* `registerController($base_name)` will tell Minz to take into account the + given controller in the routing system. The controller must be located in + your `Controllers` directory, the name of the file must be` + <base_name>Controller.php` and the name of the + `FreshExtension_<base_name>_Controller` class. + +**À FAIRE** + +* `registerViews()` +* `registerTranslates()` +* `registerHook($hook_name, $hook_function)` + +### Le système « hooks » + +You can register at the FreshRSS event system in an extensions `init()` +method, to manipulate data when some of the core functions are executed. -### Système de « hooks » - -TODO : - -- `entry_before_display` (`function($entry) -> Entry | null`) -- `entry_before_insert` (`function($entry) -> Entry | null`) -- `feed_before_insert` (`function($feed) -> Feed | null`) -- `post_update` (`function(none) -> none`) -- `simplepie_before_init` (`function($simplePie, $feed) -> none`) - -### Écrire le fichier configure.phtml +```html +class HelloWorldExtension extends Minz_Extension +{ + public function init() { + $this->registerHook('entry_before_display', array($this, 'renderEntry')); + } + public function renderEntry($entry) { + $entry->_content('<h1>Hello World</h1>' . $entry->content()); + return $entry; + } +} +``` -Lorsque vous voulez ajouter de la configuration à votre extension ou afficher ses informations, vous devez créer le fichier `configure.phtml`. +The following events are available: + +* `entry_before_display` (`function($entry) -> Entry | null`): will be + executed every time an entry is rendered. The entry itself (instance of + FreshRSS\_Entry) will be passed as parameter. +* `entry_before_insert` (`function($entry) -> Entry | null`): will be + executed when a feed is refreshed and new entries will be imported into + the database. The new entry (instance of FreshRSS\_Entry) will be passed + as parameter. +* `feed_before_insert` (`function($feed) -> Feed | null`): will be executed + when a new feed is imported into the database. The new feed (instance of + FreshRSS\_Feed) will be passed as parameter. +* `freshrss_init` (`function() -> none`): will be executed at the end of the + initialization of FreshRSS, useful to initialize components or to do + additional access checks +* `menu_admin_entry` (`function() -> string`): add an entry at the end of + the "Administration" menu, the returned string must be valid HTML + (e.g. `<li class="item active"><a href="url">New entry</a></li>`) +* `menu_configuration_entry` (`function() -> string`): add an entry at the + end of the "Configuration" menu, the returned string must be valid HTML + (e.g. `<li class="item active"><a href="url">New entry</a></li>`) +* `menu_other_entry` (`function() -> string`): add an entry at the end of + the header dropdown menu (i.e. after the "About" entry), the returned + string must be valid HTML (e.g. `<li class="item active"><a href="url">New + entry</a></li>`) +* `nav_reading_modes` (`function($reading_modes) -> array | null`): **TODO** + add documentation +* `post_update` (`function(none) -> none`): **TODO** add documentation +* `simplepie_before_init` (`function($simplePie, $feed) -> none`): **TODO** + add documentation + +### Writing your own configure.phtml + +When you want to support user configurations for your extension or simply +display some information, you have to create the `configure.phtml` file. + +**À FAIRE** diff --git a/docs/fr/developers/04_Frontend/01_View_files.md b/docs/fr/developers/04_Frontend/01_View_files.md index 45174bf58..e35b48809 100644 --- a/docs/fr/developers/04_Frontend/01_View_files.md +++ b/docs/fr/developers/04_Frontend/01_View_files.md @@ -1,15 +1,15 @@ # Les fichiers .phtml -**TODO** +**À FAIRE** # Écrire une URL -**TODO** +**À FAIRE** # Afficher une icône -**TODO** +**À FAIRE** # Internationalisation -**TODO** +**À FAIRE** diff --git a/docs/fr/developers/04_Frontend/02_Design.md b/docs/fr/developers/04_Frontend/02_Design.md index d05a4c44c..03d7ea862 100644 --- a/docs/fr/developers/04_Frontend/02_Design.md +++ b/docs/fr/developers/04_Frontend/02_Design.md @@ -1,11 +1,11 @@ # Fichier modèle -**TODO** +**À FAIRE** # Écrire un nouveau thème -**TODO** +**À FAIRE** # Surcharger les icônes -**TODO** +**À FAIRE** diff --git a/docs/fr/developers/05_Release_new_version.md b/docs/fr/developers/05_Release_new_version.md index 731dc0c76..ae80dfa23 100644 --- a/docs/fr/developers/05_Release_new_version.md +++ b/docs/fr/developers/05_Release_new_version.md @@ -1,14 +1,21 @@ # Préparer la sortie -Afin d'avoir le plus de retour possible avant une sortie, il est préférable de l'annoncer sur GitHub en créant un ticket dédié ([voir les exemples](https://github.com/FreshRSS/FreshRSS/search?utf8=%E2%9C%93&q=Call+for+testing&type=Issues)). Ceci est à faire **au moins une semaine à l'avance**. +Afin d'avoir le plus de retour possible avant une sortie, il est préférable +de l'annoncer sur GitHub en créant un ticket dédié ([voir les +exemples](https://github.com/FreshRSS/FreshRSS/search?utf8=%E2%9C%93&q=Call+for+testing&type=Issues)). +Ceci est à faire **au moins une semaine à l'avance**. Il est aussi recommandé de faire l'annonce sur mailing@freshrss.org. # S'assurer de l'état de dev -Avant de sortir une nouvelle version de FreshRSS, il faut vous assurer que le code est stable et ne présente pas de bugs majeurs. Idéalement, il faudrait que nos tests soient automatisés et exécutés avant toute publication. +Avant de sortir une nouvelle version de FreshRSS, il faut vous assurer que +le code est stable et ne présente pas de bugs majeurs. Idéalement, il +faudrait que nos tests soient automatisés et exécutés avant toute +publication. -Il faut aussi **vous assurer que le fichier CHANGELOG est à jour** dans la branche de dev avec les mises à jour de la ou les version(s) à sortir. +Il faut aussi **vous assurer que le fichier CHANGELOG est à jour** dans la +branche de dev avec les mises à jour de la ou les version(s) à sortir. # Processus Git @@ -27,33 +34,56 @@ $ git push && git push --tags # Mise à jour de update.freshrss.org -Il est important de mettre à jour update.freshrss.org puisqu'il s'agit du service par défaut gérant les mises à jour automatiques de FreshRSS. +Il est important de mettre à jour update.freshrss.org puisqu'il s'agit du +service par défaut gérant les mises à jour automatiques de FreshRSS. -Le dépot gérant le code se trouve sur GitHub : [FreshRSS/update.freshrss.org](https://github.com/FreshRSS/update.freshrss.org/). +Le dépot gérant le code se trouve sur GitHub : +[FreshRSS/update.freshrss.org](https://github.com/FreshRSS/update.freshrss.org/). ## Écriture du script de mise à jour -Les scripts se trouvent dans le répertoire `./scripts/` et doivent être de la forme `update_to_x.y.z.php`. On trouve aussi dans ce répertoire `update_to_dev.php` destiné aux mises à jour de la branche de dev (ce script ne doit pas inclure de code spécifique à une version particulière !) et `update_util.php` contenant une liste de fonctions utiles à tous les scripts. +Les scripts se trouvent dans le répertoire `./scripts/` et doivent être de +la forme `update_to_x.y.z.php`. On trouve aussi dans ce répertoire +`update_to_dev.php` destiné aux mises à jour de la branche de dev (ce script +ne doit pas inclure de code spécifique à une version particulière !) et +`update_util.php` contenant une liste de fonctions utiles à tous les +scripts. -Afin d'écrire un nouveau script, il est préférable de copier / coller celui de la dernière version ou de partir de `update_to_dev.php`. La première chose à faire est de définir l'URL à partir de laquelle sera téléchargée le package FreshRSS (`PACKAGE_URL`). L'URL est de la forme `https://codeload.github.com/FreshRSS/FreshRSS/zip/x.y.z`. +Afin d'écrire un nouveau script, il est préférable de copier / coller celui +de la dernière version ou de partir de `update_to_dev.php`. La première +chose à faire est de définir l'URL à partir de laquelle sera téléchargée le +package FreshRSS (`PACKAGE_URL`). L'URL est de la forme +`https://codeload.github.com/FreshRSS/FreshRSS/zip/x.y.z`. Il existe ensuite 5 fonctions à remplir : -- `apply_update()` qui se charge de sauvegarder le répertoire contenant les données, de vérifier sa structure, de télécharger le package FreshRSS, de le déployer et de tout nettoyer. Cette fonction est pré-remplie mais des ajustements peuvent être faits si besoin est (ex. réorganisation de la structure de `./data`). Elle retourne `true` si aucun problème n'est survenu ou une chaîne de caractères indiquant un soucis ; -- `need_info_update()` retourne `true` si l'utilisateur doit intervenir durant la mise à jour ou `false` sinon ; -- `ask_info_update()` affiche un formulaire à l'utilisateur si `need_info_update()` a retourné `true` ; -- `save_info_update()` est chargée de sauvegarder les informations renseignées par l'utilisateur (issues du formulaire de `ask_info_update()`) ; -- `do_post_update()` est exécutée à la fin de la mise à jour et prend en compte le code de la nouvelle version (ex. si la nouvelle version modifie l'objet `Minz_Configuration`, vous bénéficierez de ces améliorations). +* `apply_update()` qui se charge de sauvegarder le répertoire contenant les + données, de vérifier sa structure, de télécharger le package FreshRSS, de + le déployer et de tout nettoyer. Cette fonction est pré-remplie mais des + ajustements peuvent être faits si besoin est (ex. réorganisation de la + structure de `./data`). Elle retourne `true` si aucun problème n'est + survenu ou une chaîne de caractères indiquant un soucis ; +* `need_info_update()` retourne `true` si l'utilisateur doit intervenir + durant la mise à jour ou `false` sinon ; +* `ask_info_update()` affiche un formulaire à l'utilisateur si + `need_info_update()` a retourné `true` ; +* `save_info_update()` est chargée de sauvegarder les informations + renseignées par l'utilisateur (issues du formulaire de + `ask_info_update()`) ; +* `do_post_update()` est exécutée à la fin de la mise à jour et prend en + compte le code de la nouvelle version (ex. si la nouvelle version modifie + l'objet `Minz_Configuration`, vous bénéficierez de ces améliorations). ## Mise à jour du fichier de versions -Lorsque le script a été écrit et versionné, il est nécessaire de mettre à jour le fichier `./versions.php` qui contient une table de correspondances indiquant quelles versions sont mises à jour vers quelles autres versions. +Lorsque le script a été écrit et versionné, il est nécessaire de mettre à +jour le fichier `./versions.php` qui contient une table de correspondances +indiquant quelles versions sont mises à jour vers quelles autres versions. Voici un exemple de fichier `versions.php` : ```php <?php - return array( // STABLE '0.8.0' => '1.0.0', @@ -68,35 +98,49 @@ return array( Et voici comment fonctionne cette table : -- à gauche se trouve la version N, à droite la version N+1 ; -- les versions `x.y.z-dev` sont **toutes** mises à jour vers `dev` ; -- les versions stables sont mises à jour vers des versions stables ; -- il est possible de sauter plusieurs versions d'un coup à condition que les scripts de mise à jour le prennent en charge ; -- il est conseillé d'indiquer la correspondance de la version courante vers sa potentielle future version en précisant que cette version n'existe pas encore. Tant que le script correspondant n'existera pas, rien ne se passera. +* à gauche se trouve la version N, à droite la version N+1 ; +* les versions `x.y.z-dev` sont **toutes** mises à jour vers `dev` ; +* les versions stables sont mises à jour vers des versions stables ; +* il est possible de sauter plusieurs versions d'un coup à condition que les + scripts de mise à jour le prennent en charge ; +* il est conseillé d'indiquer la correspondance de la version courante vers + sa potentielle future version en précisant que cette version n'existe pas + encore. Tant que le script correspondant n'existera pas, rien ne se + passera. -Il est **très fortement** indiqué de garder ce fichier rangé selon les numéros de versions en séparant les versions stables et de dev. +Il est **très fortement** indiqué de garder ce fichier rangé selon les +numéros de versions en séparant les versions stables et de dev. ## Déploiement -Avant de mettre à jour update.freshrss.org, il est préférable de tester avec dev.update.freshrss.org qui correspond à la pré-production. Mettez donc à jour dev.update.freshrss.org et changez l'URL `FRESHRSS_UPDATE_WEBSITE` de votre instance FreshRSS. Lancez la mise à jour et vérifiez que celle-ci se déroule correctement. +Avant de mettre à jour update.freshrss.org, il est préférable de tester avec +dev.update.freshrss.org qui correspond à la pré-production. Mettez donc à +jour dev.update.freshrss.org et changez l'URL `FRESHRSS_UPDATE_WEBSITE` de +votre instance FreshRSS. Lancez la mise à jour et vérifiez que celle-ci se +déroule correctement. -Lorsque vous serez satisfait, mettez à jour update.freshrss.org avec le nouveau script et en testant de nouveau puis passez à la suite. +Lorsque vous serez satisfait, mettez à jour update.freshrss.org avec le +nouveau script et en testant de nouveau puis passez à la suite. # Mise à jour des services FreshRSS -Deux services sont à mettre à jour immédiatement après la mise à jour de update.freshrss.org : +Deux services sont à mettre à jour immédiatement après la mise à jour de +update.freshrss.org : -- rss.freshrss.org ; -- demo.freshrss.org (identifiants publics : `demo` / `demodemo`). +* rss.freshrss.org ; +* demo.freshrss.org (identifiants publics : `demo` / `demodemo`). # Annoncer publiquement la sortie Lorsque tout fonctionne, il est temps d'annoncer la sortie au monde entier ! -- sur GitHub en créant [une nouvelle release](https://github.com/FreshRSS/FreshRSS/releases/new) ; -- sur le blog de freshrss.org au minimum pour les versions stables (écrire l'article sur [FreshRSS/freshrss.org](https://github.com/FreshRSS/freshrss.org)). -- sur Twitter (compte [@FreshRSS](https://twitter.com/FreshRSS)) ; -- et sur mailing@freshrss.org ; +* sur GitHub en créant [une nouvelle + release](https://github.com/FreshRSS/FreshRSS/releases/new) ; +* sur le blog de freshrss.org au minimum pour les versions stables (écrire + l'article sur + [FreshRSS/freshrss.org](https://github.com/FreshRSS/freshrss.org)). +* sur Twitter (compte [@FreshRSS](https://twitter.com/FreshRSS)) ; +* et sur mailing@freshrss.org ; # Lancer la prochaine version de développement @@ -109,4 +153,5 @@ $ vim CHANGELOG.md $ git add CHANGELOG.md && git commit && git push ``` -Pensez aussi à mettre à jour update.freshrss.org pour qu'il prenne en compte la version de développement actuelle. +Pensez aussi à mettre à jour update.freshrss.org pour qu'il prenne en compte +la version de développement actuelle. |
