summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorGravatar maTh <math-home@web.de> 2023-02-23 22:20:36 +0100
committerGravatar GitHub <noreply@github.com> 2023-02-23 22:20:36 +0100
commit859c48383a229db43cf50ca64b09149bab0e3da4 (patch)
tree92eecf35a15f287a8a103ccbac8e9bd3d37344f5 /docs
parent67647586581c9e706013a4b7692261dc6bcf0831 (diff)
docs: Minz Framwork (#5102)
* done * Update docs/fr/developers/Minz/index.md Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Diffstat (limited to 'docs')
-rw-r--r--docs/en/developers/03_Backend/05_Extensions.md190
-rw-r--r--docs/en/developers/Minz/index.md198
-rw-r--r--docs/fr/developers/03_Backend/02_Minz.md29
-rw-r--r--docs/fr/developers/03_Backend/05_Extensions.md324
-rw-r--r--docs/fr/developers/Minz/index.md249
-rw-r--r--docs/fr/developers/Minz/migration.md3
-rw-r--r--docs/fr/internationalization.md79
7 files changed, 521 insertions, 551 deletions
diff --git a/docs/en/developers/03_Backend/05_Extensions.md b/docs/en/developers/03_Backend/05_Extensions.md
index aa707d2e4..e86d73bfa 100644
--- a/docs/en/developers/03_Backend/05_Extensions.md
+++ b/docs/en/developers/03_Backend/05_Extensions.md
@@ -22,195 +22,9 @@ Another solution consists of an extension system. By allowing users to write the
Note: it is quite conceivable that the functionalities of an extension can later be officially integrated into the FreshRSS code. Extensions make it easy to propose a proof of concept.
-## Understanding basic mechanics (Minz and MVC)
+## Minz Framework
-**TODO** : move to 02_Minz.md
-
-This data sheet should refer to the official FreshRSS and Minz documentation (the PHP framework on which FreshRSS is based). Unfortunately, this documentation does not yet exist. In a few words, here are the main things you should know. It is not necessary to read all the chapters in this section if you don’t need to use a feature in your extension (if you don’t need to translate your extension, no need to know more about the `Minz_Translate` module for example).
-
-### MVC Architecture
-
-Minz relies on and imposes an MVC architecture on projects using it. This architecture consists of three main components:
-
-* The model: this is the base object that we will manipulate. In FreshRSS, categories, flows and articles are templates. The part of the code that makes it possible to manipulate them in a database is also part of the model but is separated from the base model: we speak of DAO (for "Data Access Object"). The templates are stored in a `Models` folder.
-* The view: this is what the user sees. The view is therefore simply HTML code mixed with PHP to display dynamic information. The views are stored in a `views` folder.
-* The controller: this is what makes it possible to link models and views. Typically, a controller will load templates from the database (like a list of items) to "pass" them to a view for display. Controllers are stored in a `Controllers` directory.
-
-### Routing
-
-In order to link a URL to a controller, first you have to go through a "routing" phase. In FreshRSS, this is particularly simple because it suffices to specify the name of the controller to load into the URL using a `c` parameter.
-For example, the address <http://example.com?c=hello> will execute the code contained in the `hello` controller.
-
-One concept that has not yet been discussed is the "actions" system. An action is executed *on* a controller. Concretely, a controller is represented by a class and its actions by methods. To execute an action, it is necessary to specify an `a` parameter in the URL.
-
-Code example:
-
-```php
-<?php
-
-class FreshRSS_hello_Controller extends FreshRSS_ActionController {
- public function indexAction() {
- $this->view->a_variable = 'FooBar';
- }
-
- public function worldAction() {
- $this->view->a_variable = 'Hello World!';
- }
-}
-
-?>
-```
-
-When loading the address <http://example.com?c=hello&a=world>, the `world` action is executed on the `hello` controller.
-
-Note: if `c` or `a` is not specified, the default value for each of these variables is `index`.
-So the address <http://example.com?c=hello> will execute the `index` action of the `hello` controller.
-
-From now on, the `hello/world` naming convention will be used to refer to a controller/action pair.
-
-### Views
-
-Each view is associated with a controller and an action. The view associated with `hello/world` will be stored in a very specific file: `views/hello/world. phtml`. This convention is imposed by Minz.
-
-As explained above, the views consist of HTML mixed with PHP. Code example:
-
-```html
-<p>
- This is a parameter passed from the controller: <?= $this->a_variable ?>
-</p>
-```
-
-The variable `$this->a_variable` is passed by the controller (see previous example). The difference is that in the controller it is necessary to pass `$this->view`, while in the view `$this` suffices.
-
-### Working with GET / POST
-
-It is often necessary to take advantage of parameters passed by GET or POST. In Minz, these parameters are accessible using the `Minz_Request` class.
-Code example:
-
-```php
-<?php
-
-$default_value = 'foo';
-$param = Minz_Request::param('bar', $default_value);
-
-// Display the value of the parameter `bar` (passed via GET or POST)
-// or "foo" if the parameter does not exist.
-echo $param;
-
-// Sets the value of the `bar` parameter
-Minz_Request::_param('bar', 'baz');
-
-// Will necessarily display "baz" since we have just forced its value.
-// Note that the second parameter (default) is optional.
-echo Minz_Request::param('bar');
-
-?>
-```
-
-The `Minz_Request::isPost()` method can be used to execute a piece of code only if it is a POST request.
-
-Note: it is preferable to use `Minz_Request` only in controllers. It is likely that you will encounter this method in FreshRSS views, or even in templates, but be aware that this is **not** good practice.
-
-### Access session settings
-
-The access to session parameters is strangely similar to the GET / POST parameters but passes through the `Minz_Session` class this time! There is no example here because you can repeat the previous example by changing all `Minz_Request` to `Minz_Session`.
-
-### Working with URLs
-
-To take full advantage of the Minz routing system, it is strongly discouraged to write hard URLs in your code. For example, the following view should be avoided:
-
-```html
-<p>
- Go to page <a href="http://example.com?c=hello&amp;a=world">Hello world</a>!
-</p>
-```
-
-If one day it was decided to use a "url rewriting" system to have addresses in a <http://example.com/controller/action> format, all previous addresses would become ineffective!
-
-So use the `Minz_Url` class and its `display()` method instead. `Minz_Url::display()` takes an array of the following form as its argument:
-
-```php
-<?php
-
-$url_array = [
- 'c' => 'hello',
- 'a' => 'world',
- 'params' => [
- 'foo' => 'bar',
- ],
-];
-
-// Show something like .?c=hello&amp;a=world&amp;foo=bar
-echo Minz_Url::display($url_array);
-
-?>
-```
-
-Since this can become a bit tedious to use in the long run, especially in views, it is preferable to use the `_url()` shortcut:
-
-```php
-<?php
-
-// Displays the same as above
-echo _url('hello', 'world', 'foo', 'bar');
-
-?>
-```
-
-Note: as a general rule, the shortened form (`_url()`) should be used in views, while the long form (`Minz_Url::display()`) should be used in controllers.
-
-### Redirections
-
-It is often necessary to redirect a user to another page. To do so, the `Minz_Request` class offers another useful method: `forward()`. This method takes the same URL format as the one seen just before as its argument.
-
-Code example:
-
-```php
-<?php
-
-$url_array = [
- 'c' => 'hello',
- 'a' => 'world',
-];
-
-// Tells Minz to redirect the user to the hello / world page.
-// Note that this is a redirection in the Minz sense of the term, not a redirection that the browser will have to manage (HTTP code 301 or 302)
-// The code that follows forward() will thus be executed!
-Minz_Request::forward($url_array);
-
-// To perform a type 302 redirect, add "true".
-// The code that follows will never be executed.
-Minz_Request::forward($url_array, true);
-
-?>
-```
-
-It is very common to want display a message to the user while performing a redirect, to tell the user how the action was carried out (validation of a form for example). Such a message is passed through a `notification` session variable (note: we will talk about feedback from now on to avoid confusion with a notification that can occur at any time). To facilitate this kind of very frequent action, there are two shortcuts that both perform a 302 redirect by assigning a feedback message:
-
-```php
-<?php
-
-$url_array = [
- 'c' => 'hello',
- 'a' => 'world',
-];
-$feedback_good = 'All went well!';
-$feedback_bad = 'Oops, something went wrong.';
-
-Minz_Request::good($feedback_good, $url_array);
-
-// or
-
-Minz_Request::bad($feedback_bad, $url_array);
-
-?>
-```
-
-### Translation Management
-
-This part [is explained here](/docs/en/internationalization.md).
-
-### Configuration management
+see [Minz documentation](/docs/en/developers/Minz/index.md)
## Write an extension for FreshRSS
diff --git a/docs/en/developers/Minz/index.md b/docs/en/developers/Minz/index.md
index 9b6d46f17..ed5bc0482 100644
--- a/docs/en/developers/Minz/index.md
+++ b/docs/en/developers/Minz/index.md
@@ -1,19 +1,193 @@
-# Minz
+# Minz Framework
Minz is the homemade PHP framework used by FreshRSS.
-The documentation is still incomplete and it would be great to explain:
+This data sheet should refer to the official FreshRSS and Minz documentation (the PHP framework on which FreshRSS is based). Unfortunately, this documentation does not yet exist. In a few words, here are the main things you should know. It is not necessary to read all the chapters in this section if you don’t need to use a feature in your extension (if you don’t need to translate your extension, no need to know more about the `Minz_Translate` module for example).
-- routing, controllers and actions
-- configuration
-- models and database
-- views
-- URLs management
-- sessions
-- internationalisation
-- extensions
-- mailer
+## MVC Architecture
+
+Minz relies on and imposes an MVC architecture on projects using it. This architecture consists of three main components:
+
+* The model: this is the base object that we will manipulate. In FreshRSS, categories, flows and articles are templates. The part of the code that makes it possible to manipulate them in a database is also part of the model but is separated from the base model: we speak of DAO (for "Data Access Object"). The templates are stored in a `Models` folder.
+* The view: this is what the user sees. The view is therefore simply HTML code mixed with PHP to display dynamic information. The views are stored in a `views` folder.
+* The controller: this is what makes it possible to link models and views. Typically, a controller will load templates from the database (like a list of items) to "pass" them to a view for display. Controllers are stored in a `Controllers` directory.
+
+## Routing
+
+In order to link a URL to a controller, first you have to go through a "routing" phase. In FreshRSS, this is particularly simple because it suffices to specify the name of the controller to load into the URL using a `c` parameter.
+For example, the address <http://example.com?c=hello> will execute the code contained in the `hello` controller.
+
+One concept that has not yet been discussed is the "actions" system. An action is executed *on* a controller. Concretely, a controller is represented by a class and its actions by methods. To execute an action, it is necessary to specify an `a` parameter in the URL.
+
+Code example:
+
+```php
+<?php
+
+class FreshRSS_hello_Controller extends FreshRSS_ActionController {
+ public function indexAction() {
+ $this->view->a_variable = 'FooBar';
+ }
+
+ public function worldAction() {
+ $this->view->a_variable = 'Hello World!';
+ }
+}
+
+?>
+```
+
+When loading the address <http://example.com?c=hello&a=world>, the `world` action is executed on the `hello` controller.
+
+Note: if `c` or `a` is not specified, the default value for each of these variables is `index`.
+So the address <http://example.com?c=hello> will execute the `index` action of the `hello` controller.
+
+From now on, the `hello/world` naming convention will be used to refer to a controller/action pair.
+
+## Views
+
+Each view is associated with a controller and an action. The view associated with `hello/world` will be stored in a very specific file: `views/hello/world. phtml`. This convention is imposed by Minz.
+
+As explained above, the views consist of HTML mixed with PHP. Code example:
+
+```html
+<p>
+ This is a parameter passed from the controller: <?= $this->a_variable ?>
+</p>
+```
+
+The variable `$this->a_variable` is passed by the controller (see previous example). The difference is that in the controller it is necessary to pass `$this->view`, while in the view `$this` suffices.
+
+## Working with GET / POST
+
+It is often necessary to take advantage of parameters passed by GET or POST. In Minz, these parameters are accessible using the `Minz_Request` class.
+Code example:
+
+```php
+<?php
+
+$default_value = 'foo';
+$param = Minz_Request::param('bar', $default_value);
+
+// Display the value of the parameter `bar` (passed via GET or POST)
+// or "foo" if the parameter does not exist.
+echo $param;
+
+// Sets the value of the `bar` parameter
+Minz_Request::_param('bar', 'baz');
+
+// Will necessarily display "baz" since we have just forced its value.
+// Note that the second parameter (default) is optional.
+echo Minz_Request::param('bar');
+
+?>
+```
+
+The `Minz_Request::isPost()` method can be used to execute a piece of code only if it is a POST request.
+
+Note: it is preferable to use `Minz_Request` only in controllers. It is likely that you will encounter this method in FreshRSS views, or even in templates, but be aware that this is **not** good practice.
+
+## Access session settings
+
+The access to session parameters is strangely similar to the GET / POST parameters but passes through the `Minz_Session` class this time! There is no example here because you can repeat the previous example by changing all `Minz_Request` to `Minz_Session`.
+
+## Working with URLs
+
+To take full advantage of the Minz routing system, it is strongly discouraged to write hard URLs in your code. For example, the following view should be avoided:
+
+```html
+<p>
+ Go to page <a href="http://example.com?c=hello&amp;a=world">Hello world</a>!
+</p>
+```
+
+If one day it was decided to use a "url rewriting" system to have addresses in a <http://example.com/controller/action> format, all previous addresses would become ineffective!
+
+So use the `Minz_Url` class and its `display()` method instead. `Minz_Url::display()` takes an array of the following form as its argument:
+
+```php
+<?php
+
+$url_array = [
+ 'c' => 'hello',
+ 'a' => 'world',
+ 'params' => [
+ 'foo' => 'bar',
+ ],
+];
+
+// Show something like .?c=hello&amp;a=world&amp;foo=bar
+echo Minz_Url::display($url_array);
+
+?>
+```
+
+Since this can become a bit tedious to use in the long run, especially in views, it is preferable to use the `_url()` shortcut:
+
+```php
+<?php
+
+// Displays the same as above
+echo _url('hello', 'world', 'foo', 'bar');
+
+?>
+```
+
+Note: as a general rule, the shortened form (`_url()`) should be used in views, while the long form (`Minz_Url::display()`) should be used in controllers.
+
+## Redirections
+
+It is often necessary to redirect a user to another page. To do so, the `Minz_Request` class offers another useful method: `forward()`. This method takes the same URL format as the one seen just before as its argument.
+
+Code example:
+
+```php
+<?php
+
+$url_array = [
+ 'c' => 'hello',
+ 'a' => 'world',
+];
+
+// Tells Minz to redirect the user to the hello / world page.
+// Note that this is a redirection in the Minz sense of the term, not a redirection that the browser will have to manage (HTTP code 301 or 302)
+// The code that follows forward() will thus be executed!
+Minz_Request::forward($url_array);
+
+// To perform a type 302 redirect, add "true".
+// The code that follows will never be executed.
+Minz_Request::forward($url_array, true);
+
+?>
+```
+
+It is very common to want display a message to the user while performing a redirect, to tell the user how the action was carried out (validation of a form for example). Such a message is passed through a `notification` session variable (note: we will talk about feedback from now on to avoid confusion with a notification that can occur at any time). To facilitate this kind of very frequent action, there are two shortcuts that both perform a 302 redirect by assigning a feedback message:
+
+```php
+<?php
+
+$url_array = [
+ 'c' => 'hello',
+ 'a' => 'world',
+];
+$feedback_good = 'All went well!';
+$feedback_bad = 'Oops, something went wrong.';
+
+Minz_Request::good($feedback_good, $url_array);
+
+// or
+
+Minz_Request::bad($feedback_bad, $url_array);
+
+?>
+```
+
+## Translation Management
+
+This part [is explained here](/docs/en/internationalization.md).
+
+## Migration
Existing documentation includes:
-- [How to manage migrations](migrations.md)
+* [How to manage migrations](migrations.md)
diff --git a/docs/fr/developers/03_Backend/02_Minz.md b/docs/fr/developers/03_Backend/02_Minz.md
deleted file mode 100644
index 5daf684f0..000000000
--- a/docs/fr/developers/03_Backend/02_Minz.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Minz
-
-## Modèles
-
-> **À FAIRE**
-
-## Contrôleurs et actions
-
-> **À FAIRE**
-
-## Vues
-
-> **À FAIRE**
-
-## Routage
-
-> **À FAIRE**
-
-## Écriture des URL
-
-> **À FAIRE**
-
-## Internationalisation
-
-> **À FAIRE**
-
-## Comprendres les mécanismes internes
-
-> **À FAIRE**
diff --git a/docs/fr/developers/03_Backend/05_Extensions.md b/docs/fr/developers/03_Backend/05_Extensions.md
index a715c40b3..548aebf4f 100644
--- a/docs/fr/developers/03_Backend/05_Extensions.md
+++ b/docs/fr/developers/03_Backend/05_Extensions.md
@@ -36,329 +36,9 @@ 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).
-
-### 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`.
-
-### 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 :
-
-```php
-<?php
-
-class FreshRSS_hello_Controller extends FreshRSS_ActionController {
- public function indexAction() {
- $this->view->a_variable = 'FooBar';
- }
-
- public function worldAction() {
- $this->view->a_variable = 'Hello World!';
- }
-}
-
-?>
-```
-
-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`.
-
-Plus loin, sera utilisée la convention `hello/world` pour évoquer un couple
-contrôleur/action.
-
-### 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.
-
-Comme expliqué plus haut, les vues sont du code HTML mixé à du PHP. Exemple
-de code :
-
-```html
-<p>
- Phrase passée en paramètre : <?= $this->a_variable ?>
-</p>
-```
-
-La variable `$this->a_variable` a été passée précédemment par le contrôleur (voir exemple précédent). La différence est que dans le contrôleur il est nécessaire de passer par `$this->view` et que dans la vue `$this` suffit.
-
-### 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 :
-
-```php
-<?php
-
-$default_value = 'foo';
-$param = Minz_Request::param('bar', $default_value);
-
-// Affichera la valeur du paramètre `bar` (passé via GET ou POST)
-// ou "foo" si le paramètre n’existe pas.
-echo $param;
-
-// Force la valeur du paramètre `bar`
-Minz_Request::_param('bar', 'baz');
-
-// Affichera forcément "baz" puisque nous venons de forcer sa valeur.
-// Notez que le second paramètre (valeur par défaut) est facultatif.
-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.
-
-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`.
-
-### 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 :
-
-```html
-<p>
- Accéder à la page <a href="http://exemple.com?c=hello&amp;a=world">Hello world</a>!
-</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 !
-
-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
-
-$url_array = [
- 'c' => 'hello',
- 'a' => 'world',
- 'params' => [
- 'foo' => 'bar',
- ],
-];
-
-// Affichera quelque chose comme .?c=hello&amp;a=world&amp;foo=bar
-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()` :
-
-```php
-<?php
-
-// Affichera la même chose que précédemment
-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.
-
-### 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.
-
-Exemple de code :
-
-```php
-<?php
-
-$url_array = [
- 'c' => 'hello',
- 'a' => 'world',
-];
-
-// 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é !
-Minz_Request::forward($url_array);
-
-// Pour effectuer une redirection type 302, ajoutez "true".
-// Le code qui suivra ne sera alors jamais exécuté.
-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 :
-
-```php
-<?php
-
-$url_array = [
- 'c' => 'hello',
- 'a' => 'world',
-];
-$feedback_good = 'Tout s’est bien passé !';
-$feedback_bad = 'Oups, quelque chose n’a pas marché.';
-
-Minz_Request::good($feedback_good, $url_array);
-
-// ou
-
-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` :
-
-```php
-<?php
-
-return array(
- 'action' => [
- 'actualize' => 'Actualiser',
- 'back_to_rss_feeds' => '← Retour à vos flux RSS',
- 'cancel' => 'Annuler',
- 'create' => 'Créer',
- 'disable' => 'Désactiver',
- ),
- '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 :
-
-```html
-<p>
- <a href="<?= _url('index', 'index') ?>">
- <?= _t('gen.action.back_to_rss_feeds') ?>
- </a>
-</p>
-```
+## Minz Framework
-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
+see [Minz documentation](/docs/fr/developers/Minz/index.md)
## Écrire une extension pour FreshRSS
diff --git a/docs/fr/developers/Minz/index.md b/docs/fr/developers/Minz/index.md
new file mode 100644
index 000000000..0d1d2124a
--- /dev/null
+++ b/docs/fr/developers/Minz/index.md
@@ -0,0 +1,249 @@
+# Minz
+
+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`.
+
+## 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 :
+
+```php
+<?php
+
+class FreshRSS_hello_Controller extends FreshRSS_ActionController {
+ public function indexAction() {
+ $this->view->a_variable = 'FooBar';
+ }
+
+ public function worldAction() {
+ $this->view->a_variable = 'Hello World!';
+ }
+}
+
+?>
+```
+
+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`.
+
+Plus loin, sera utilisée la convention `hello/world` pour évoquer un couple
+contrôleur/action.
+
+## 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.
+
+Comme expliqué plus haut, les vues sont du code HTML mixé à du PHP. Exemple
+de code :
+
+```html
+<p>
+ Phrase passée en paramètre : <?= $this->a_variable ?>
+</p>
+```
+
+La variable `$this->a_variable` a été passée précédemment par le contrôleur (voir exemple précédent). La différence est que dans le contrôleur il est nécessaire de passer par `$this->view` et que dans la vue `$this` suffit.
+
+## 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 :
+
+```php
+<?php
+
+$default_value = 'foo';
+$param = Minz_Request::param('bar', $default_value);
+
+// Affichera la valeur du paramètre `bar` (passé via GET ou POST)
+// ou "foo" si le paramètre n’existe pas.
+echo $param;
+
+// Force la valeur du paramètre `bar`
+Minz_Request::_param('bar', 'baz');
+
+// Affichera forcément "baz" puisque nous venons de forcer sa valeur.
+// Notez que le second paramètre (valeur par défaut) est facultatif.
+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.
+
+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`.
+
+## 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 :
+
+```html
+<p>
+ Accéder à la page <a href="http://exemple.com?c=hello&amp;a=world">Hello world</a>!
+</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 !
+
+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
+
+$url_array = [
+ 'c' => 'hello',
+ 'a' => 'world',
+ 'params' => [
+ 'foo' => 'bar',
+ ],
+];
+
+// Affichera quelque chose comme .?c=hello&amp;a=world&amp;foo=bar
+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()` :
+
+```php
+<?php
+
+// Affichera la même chose que précédemment
+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.
+
+## 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.
+
+Exemple de code :
+
+```php
+<?php
+
+$url_array = [
+ 'c' => 'hello',
+ 'a' => 'world',
+];
+
+// 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é !
+Minz_Request::forward($url_array);
+
+// Pour effectuer une redirection type 302, ajoutez "true".
+// Le code qui suivra ne sera alors jamais exécuté.
+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 :
+
+```php
+<?php
+
+$url_array = [
+ 'c' => 'hello',
+ 'a' => 'world',
+];
+$feedback_good = 'Tout s’est bien passé !';
+$feedback_bad = 'Oups, quelque chose n’a pas marché.';
+
+Minz_Request::good($feedback_good, $url_array);
+
+// ou
+
+Minz_Request::bad($feedback_bad, $url_array);
+
+?>
+```
+
+## Gestion de la traduction
+
+Cette partie est [expliquée dans la page dédiée](/docs/fr/internationalization.md).
+
+## Migration
+
+Existing documentation includes:
+
+* [How to manage migrations](migrations.md)
diff --git a/docs/fr/developers/Minz/migration.md b/docs/fr/developers/Minz/migration.md
new file mode 100644
index 000000000..ad2eef949
--- /dev/null
+++ b/docs/fr/developers/Minz/migration.md
@@ -0,0 +1,3 @@
+# Migration
+
+see [English documentation](/docs/en/developers/Minz/migrations.md)
diff --git a/docs/fr/internationalization.md b/docs/fr/internationalization.md
new file mode 100644
index 000000000..532ed457d
--- /dev/null
+++ b/docs/fr/internationalization.md
@@ -0,0 +1,79 @@
+# 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` :
+
+```php
+<?php
+
+return array(
+ 'action' => [
+ 'actualize' => 'Actualiser',
+ 'back_to_rss_feeds' => '← Retour à vos flux RSS',
+ 'cancel' => 'Annuler',
+ 'create' => 'Créer',
+ 'disable' => 'Désactiver',
+ ),
+ '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 :
+
+```html
+<p>
+ <a href="<?= _url('index', 'index') ?>">
+ <?= _t('gen.action.back_to_rss_feeds') ?>
+ </a>
+</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.