diff options
author | Marien Fressinaud <dev@marienfressinaud.fr> | 2017-04-23 09:36:05 +0200 |
---|---|---|
committer | Marien Fressinaud <dev@marienfressinaud.fr> | 2017-04-24 23:08:43 +0200 |
commit | afc38e43ec724c79b73e1a9fa68f33c56eb1add9 (patch) | |
tree | a90fbc79ce6bdd26b5c3304677770aa75ea5cda9 /docs/en/developers/03_Backend | |
parent | c3e17abcf02664ecfca1d82068ef441a6338c18a (diff) | |
download | freshrss-afc38e43ec724c79b73e1a9fa68f33c56eb1add9.tar.gz freshrss-afc38e43ec724c79b73e1a9fa68f33c56eb1add9.zip |
Provide documentation under ./docs
Diffstat (limited to 'docs/en/developers/03_Backend')
-rw-r--r-- | docs/en/developers/03_Backend/01_Database_schema.md | 0 | ||||
-rw-r--r-- | docs/en/developers/03_Backend/02_Minz.md | 27 | ||||
-rw-r--r-- | docs/en/developers/03_Backend/03_External_libraries.md | 0 | ||||
-rw-r--r-- | docs/en/developers/03_Backend/04_Changing_source_code.md | 15 | ||||
-rw-r--r-- | docs/en/developers/03_Backend/05_Extensions.md | 334 |
5 files changed, 376 insertions, 0 deletions
diff --git a/docs/en/developers/03_Backend/01_Database_schema.md b/docs/en/developers/03_Backend/01_Database_schema.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/en/developers/03_Backend/01_Database_schema.md diff --git a/docs/en/developers/03_Backend/02_Minz.md b/docs/en/developers/03_Backend/02_Minz.md new file mode 100644 index 000000000..cfbea15fe --- /dev/null +++ b/docs/en/developers/03_Backend/02_Minz.md @@ -0,0 +1,27 @@ +# Models + +**TODO** + +# Controllers and actions + +**TODO** + +# Views + +**TODO** + +# Routing + +**TODO** + +# Writing URL + +**TODO** + +# Internationalisation + +**TODO** + +# Understanding internals + +**TODO** diff --git a/docs/en/developers/03_Backend/03_External_libraries.md b/docs/en/developers/03_Backend/03_External_libraries.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/en/developers/03_Backend/03_External_libraries.md diff --git a/docs/en/developers/03_Backend/04_Changing_source_code.md b/docs/en/developers/03_Backend/04_Changing_source_code.md new file mode 100644 index 000000000..e8a5958e4 --- /dev/null +++ b/docs/en/developers/03_Backend/04_Changing_source_code.md @@ -0,0 +1,15 @@ +# Accessing the database + +**TODO** + +# Writing an action and its related view + +**TODO** + +# Authentication + +**TODO** + +# Logs + +**TODO**
\ No newline at end of file diff --git a/docs/en/developers/03_Backend/05_Extensions.md b/docs/en/developers/03_Backend/05_Extensions.md new file mode 100644 index 000000000..c5c00ff08 --- /dev/null +++ b/docs/en/developers/03_Backend/05_Extensions.md @@ -0,0 +1,334 @@ +# Writing extensions for FreshRSS + +## About FreshRSS + +FreshRSS is an RSS / Atom feeds aggregator written in PHP since October 2012. The official site is located at [freshrss.org](http://freshrss.org) and its repository is hosted by Github: [github.com/FreshRSS/FreshRSS](https://github.com/FreshRSS/FreshRSS). + +## Problem to solve + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +## Understanding basic mechanics (Minz and MVC) + +**TODO** : move to 02_Minz.md + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### MVC Architecture + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### Routing + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +Code example: + +```php +<?php + +class FreshRSS_hello_Controller extends Minz_ActionController { + public function indexAction() { + $this->view->a_variable = 'FooBar'; + } + + public function worldAction() { + $this->view->a_variable = 'Hello World!'; + } +} + +?> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### Views + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +Code example: + +```html +<p> + This is a parameter passed from the controller: <?php echo $this->a_variable; ?> +</p> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### Working with GET / POST + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +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'); + +?> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### Access session settings + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### Working with URLs + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +```html +<p> + Go to page <a href="http://example.com?c=hello&a=world">Hello world</a>! +</p> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +```php +<?php + +$url_array = array( + 'c' => 'hello', + 'a' => 'world', + 'params' => array( + 'foo' => 'bar', + ) +); + +// Show something like .?c=hello&a=world&foo=bar +echo Minz_Url::display($url_array); + +?> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +```php +<?php + +// Displays the same as above +echo _url('hello', 'world', 'foo', 'bar'); + +?> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### Redirections + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +Code example: + +```php +<?php + +$url_array = 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); + +?> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +```php +<?php + +$url_array = 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); + +// or + +Minz_Request::bad($feedback_bad, $url_array); + +?> +``` + +### Translation Management + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +```php +<?php + +return array( + 'action' => array( + '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', + ), +); + +?> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +Code example: + +```html +<p> + <a href="<?php echo _url('index', 'index'); ?>"> + <?php echo _t('gen.action.back_to_rss_feeds'); ?> + </a> +</p> +``` + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +### Configuration management + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +## Write an extension for FreshRSS + +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. + +### Basic files and folders + +The first thing to note is that **all** extensions **must** be located in the `extensions` directory, at the base of the FreshRSS tree. +An extension is a directory containing a set of mandatory (and optional) files and subdirectories. +The convention requires that the main directory name be preceded by an "x" to indicate that it is not an extension included by default in FreshRSS. + +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). + +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`. + +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` 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. + +### 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` : 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 » + +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. + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) + +- `registerViews()` +- `registerTranslates()` +- `registerHook($hook_name, $hook_function)` + +### 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. + +```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; + } +} +``` +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. +- `post_update` (`function(none) -> 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. + +**TODO** translate from [french version](https://github.com/FreshRSS/documentation/blob/master/fr/docs/developers/03_Backend/05_Extensions.md) |