aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/docs/en/developers/03_Backend/05_Extensions.md
diff options
context:
space:
mode:
authorFrans de Jonge <fransdejonge@gmail.com>2019-12-03 22:37:40 +0100
committerAlexandre Alapetite <alexandre@alapetite.fr>2019-12-03 22:37:40 +0100
commit705318aa39a605a4d869db588f6cffb12019a611 (patch)
tree36383dfee24999f9928957621b655e67b20714b7 /docs/en/developers/03_Backend/05_Extensions.md
parent0de7e84380dff5222e6728aacbbb42abaac51dd9 (diff)
downloadfreshrss-705318aa39a605a4d869db588f6cffb12019a611.tar.gz
freshrss-705318aa39a605a4d869db588f6cffb12019a611.zip
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/en/developers/03_Backend/05_Extensions.md')
-rw-r--r--docs/en/developers/03_Backend/05_Extensions.md108
1 files changed, 54 insertions, 54 deletions
diff --git a/docs/en/developers/03_Backend/05_Extensions.md b/docs/en/developers/03_Backend/05_Extensions.md
index 4610e4b90..3977faae6 100644
--- a/docs/en/developers/03_Backend/05_Extensions.md
+++ b/docs/en/developers/03_Backend/05_Extensions.md
@@ -2,9 +2,9 @@
## About FreshRSS
-FreshRSS is an RSS / Atom feeds aggregator written in PHP since October 2012. The official site is located at [freshrss.org](https://freshrss.org) and its repository is hosted by Github: [github.com/FreshRSS/FreshRSS](https://github.com/FreshRSS/FreshRSS).
+FreshRSS is an RSS / Atom feed aggregator written in PHP dating back to October 2012. The official site is located at [freshrss.org](https://freshrss.org) and the official repository is hosted on Github: [github.com/FreshRSS/FreshRSS](https://github.com/FreshRSS/FreshRSS).
-## Problem to solve
+## The problem
FreshRSS is limited in its technical possibilities by various factors:
@@ -18,7 +18,7 @@ Another solution consists of an extension system. By allowing users to write the
1. Reducing the amount of source code a new contributor has to take in
2. Unofficial integration of novelties
-3. No necessity of forking or main developer approvement.
+3. No forking or main developer approval required.
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.
@@ -30,10 +30,10 @@ This data sheet should refer to the official FreshRSS and Minz documentation (th
### MVC Architecture
-Minz relies on and imposes an MVC architecture for projects using it. This architecture consists of three main components:
+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 an `views` 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
@@ -64,7 +64,7 @@ When loading the address http://exemple.com?c=hello&a=world, the `world` action
Note: if `c` or `a` is not specified, the default value for each of these variables is `index`. So the address http://exemple.com?c=hello will execute the `index` action of the `hello` controller.
-Later, the `hello/world` convention will be used to refer to a controller/action pair.
+From now on, the `hello/world` naming convention will be used to refer to a controller/action pair.
### Views
@@ -123,7 +123,7 @@ To take full advantage of the Minz routing system, it is strongly discouraged to
</p>
```
-Should it be decided one day to use a "url rewriting" system to have addresses in a http://exemple.com/controller/action format, all previous addresses would become ineffective!
+If one day it was decided to use a "url rewriting" system to have addresses in a http://exemple.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:
@@ -144,7 +144,7 @@ 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:
+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
@@ -192,8 +192,8 @@ $url_array = [
'c' => 'hello',
'a' => 'world',
];
-$feedback_good = 'Tout s\'est bien passé !';
-$feedback_bad = 'Oups, quelque chose n\'a pas marché.';
+$feedback_good = 'All went well!';
+$feedback_bad = 'Oops, something went wrong.';
Minz_Request::good($feedback_good, $url_array);
@@ -210,17 +210,17 @@ It is common (and that's an understatement) to want to show some text to the use
The solution is to use the `Minz_Translate` class, which allows dynamic translation of FreshRSS (or any Minz-based application). Before using this module, it is necessary to know where to find the strings to be translated. Each language has its own subdirectory in a parent directory named `i18n`. For example, English language files are located in `i18n/fr/`. There are seven different files:
-- `admin.php` for anything related to FreshRSS administration
-- `conf.php` for configuration
-- `feedback.php` contains translations of feedback messages
-- `gen.php` stores what is global to FreshRSS (gen for "general")
-- `index.php` for the main page that lists feeds and the About page
-- `install.php` contains strings related FreshRSS installation
-- `sub.php` for subscription management (sub for "subscription")
+* `admin.php` for anything related to FreshRSS administration
+* `conf.php` for configuration
+* `feedback.php` contains translations of feedback messages
+* `gen.php` stores what is global to FreshRSS (gen for "general")
+* `index.php` for the main page that lists feeds and the About page
+* `install.php` contains strings related FreshRSS installation
+* `sub.php` for subscription management (sub for "subscription")
This organization makes it possible to avoid a single huge translation file.
-The translation files are quite simple: it is only a matter of returning a PHP table containing the translations. Extract from `app/i18n/en/gen.php`:
+The translation files are quite simple: it's only a matter of returning a PHP table containing the translations. As an example, here's an extract from `app/i18n/fr/gen.php`:
```php
<?php
@@ -263,7 +263,7 @@ There is a small special case that sometimes makes life easier: the `_` identifi
Here we are! We've talked about the most useful features of Minz and how to run FreshRSS correctly and it's about time to address the extensions themselves.
-An extension allows you to add functionality easily to FreshRSS without having to touch the core of the project directly.
+An extension allows you to easily add functionality to FreshRSS without having to touch the core of the project directly.
### Basic files and folders
@@ -273,8 +273,8 @@ The convention requires that the main directory name be preceded by an "x" to in
The main directory of an extension must contain at least two **mandatory** files:
-- A `metadata.json` file that contains a description of the extension. This file is written in JSON.
-- An `extension.php` file containing the entry point of the extension (which is a class that inherits Minz_Extension).
+* A `metadata.json` file that contains a description of the extension. This file is written in JSON.
+* An `extension.php` file containing the entry point of the extension (which is a class that inherits Minz_Extension).
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:
@@ -292,11 +292,11 @@ There is an example HelloWorld extension that you can download from [our GitHub
You may also need additional files or subdirectories depending on your needs:
-- `configure.phtml` is the file containing the form to parameterize your 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
+* `configure.phtml` is the file containing the form to parameterize your 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.
@@ -304,16 +304,16 @@ In addition, it is good to have a `LICENSE` file indicating the license under wh
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` : the name of your extension
-- `author` : your name, your e-mail address ... but there is no specific format to adopt
-- `description` : a description of your extension
-- `version` : the current version number of the extension
-- `entrypoint` : Indicates the entry point of your extension. It must match the name of the class contained in the file `extension.php` without the suffix` Extension` (so if the entry point is `HelloWorld`, your class will be called` HelloWorldExtension`)
-- `type` : Defines the type of your extension. There are two types: `system` and` user`. We will study this difference right after.
+* `name`: the name of your extension
+* `author`: your name, your e-mail address ... but there is no specific format to adopt
+* `description`: a description of your extension
+* `version`: the current version number of the extension
+* `entrypoint`: Indicates the entry point of your extension. It must match the name of the class contained in the file `extension.php` without the suffix` Extension` (so if the entry point is `HelloWorld`, your class will be called` HelloWorldExtension`)
+* `type`: Defines the type of your extension. There are two types: `system` and` user`. We will study this difference right after.
Only the `name` and` entrypoint` fields are required.
-### Choose between « system » or « user »
+### Choosing between `system` and `user`
A __user__ extension can be enabled by some users and not by others (typically for user preferences).
@@ -327,24 +327,24 @@ In addition, this class must be inherited from the `Minz_Extension` class to ben
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.
+* `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.
+* 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.
**TODO**
-- `registerViews()`
-- `registerTranslates()`
-- `registerHook($hook_name, $hook_function)`
+* `registerViews()`
+* `registerTranslates()`
+* `registerHook($hook_name, $hook_function)`
-### The « hooks » system
+### The "hooks" system
You can register at the FreshRSS event system in an extensions `init()` method, to manipulate data when some of the core functions are executed.
@@ -363,16 +363,16 @@ class HelloWorldExtension extends Minz_Extension
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
+* `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