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 | |
parent | c3e17abcf02664ecfca1d82068ef441a6338c18a (diff) | |
download | freshrss-afc38e43ec724c79b73e1a9fa68f33c56eb1add9.tar.gz freshrss-afc38e43ec724c79b73e1a9fa68f33c56eb1add9.zip |
Provide documentation under ./docs
Diffstat (limited to 'docs/en/developers')
-rw-r--r-- | docs/en/developers/01_First_steps.md | 194 | ||||
-rw-r--r-- | docs/en/developers/02_Github.md | 11 | ||||
-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 | ||||
-rw-r--r-- | docs/en/developers/04_Frontend/01_View_files.md | 15 | ||||
-rw-r--r-- | docs/en/developers/04_Frontend/02_Design.md | 11 | ||||
-rw-r--r-- | docs/en/developers/05_Release_new_version.md | 1 |
10 files changed, 608 insertions, 0 deletions
diff --git a/docs/en/developers/01_First_steps.md b/docs/en/developers/01_First_steps.md new file mode 100644 index 000000000..e35dbda12 --- /dev/null +++ b/docs/en/developers/01_First_steps.md @@ -0,0 +1,194 @@ +# Environment configuration + +**TODO** + +# Project architecture + +**TODO** + +# Coding style + +If you want to contribute to the source code, it is important to follow the project coding style. The actual code does not follow it throughout the project, but every time we have an opportunity, we should fix it. + +Contributions which do not follow the coding style will be rejected as long as the coding style is not fixed. + +## Spaces, tabs and white spaces + +### Indent +Code indent must use tabs. + +### Alignment + +Once the code is indented, it might be useful to align it to ease the reading. In that case, use spaces. + +```php +$result = a_function_with_a_really_long_name($param1, $param2, + $param3, $param4); +``` + +### End of line + +The end of line character must be a line feed (LF) which is a default end of line on *NIX systems. This character must not follow other white spaces. + +It is possible to verify if there is white spaces before the end of line, with the following Git command: + +```bash +# command to check files before adding them in the Git index +git diff --check +# command to check files after adding them in the Git index +git diff --check --cached +``` + +### End of file + +Every file must end by an empty line. + +### With commas, dots and semi-columns + +There is no space before those characters but there is one after. + +### With operators + +There is a space before and after every operator. + +```php +if ($a == 10) { + // do something +} + +echo $a ? 1 : 0; +``` + +### With brackets + +There is no spaces in the brackets. There is no space before the opening bracket except if it is after a keyword. There is no space after the closing bracket except if it is followed by a curly bracket. + +```php +if ($a == 10) { + // do something +} + +if ((int)$a == 10) { + // do something +} +``` + +### With chained functions + +It happens most of the time in Javascript files. When there is chained functions, closures and callback functions, it is hard to understand the code if not properly formatted. In those cases, we add a new indent level for the complete instruction and reset the indent for a new instruction on the same level. + +```javascript +// First instruction +shortcut.add(shortcuts.mark_read, function () { + //... + }, { + 'disable_in_input': true + }); +// Second instruction +shortcut.add("shift+" + shortcuts.mark_read, function () { + //... + }, { + 'disable_in_input': true + }); +``` + +## Line length + +Lines should be shorter than 80 characters. However, in some case, it is possible to extend that limit to 100 characters. + +With functions, parameters can be declared on different lines. + +```php +function my_function($param_1, $param_2, + $param_3, $param_4) { + // do something +} +``` + +## Naming + +All the code elements (functions, classes, methods and variables) must describe their usage in concise way. + +### Functions and variables + +They must follow the "snake case" convention. + +```php +// a function +function function_name() { + // do something +} +// a variable +$variable_name; +``` + +### Methods + +They must follow the "lower camel case" convention. + +```php +private function methodName() { + // do something +} +``` + +### Classes + +They must follow the "upper camel case" convention. + +```php +abstract class ClassName {} +``` + +## Encoding + +Files must be encoded with UTF-8 character set. + +## PHP 5.3 compatibility + +Do not get an array item directly from a function or a method. Use a variable. + +```php +// code with PHP 5.3 compatibility +$my_variable = function_returning_an_array(); +echo $my_variable[0]; +// code without PHP 5.3 compatibility +echo function_returning_an_array()[0]; +``` + +Do not use short array declaration. + +```php +// code with PHP 5.3 compatibility +$variable = array(); +// code without PHP 5.3 compatibility +$variable = []; +``` + +## Miscellaneous + +### Operators +They must be at the end of the line if a condition runs on more than one line. + +```php +if ($a == 10 || + $a == 20) { + // do something +} +``` + +### End of file + +If the file contains only PHP code, the PHP closing tag must be omitted. + +### Arrays + +If an array declaration runs on more than one line, each element must be followed by a comma even the last one. + +```php +$variable = array( + "value 1", + "value 2", + "value 3", +); +``` diff --git a/docs/en/developers/02_Github.md b/docs/en/developers/02_Github.md new file mode 100644 index 000000000..c16a6d040 --- /dev/null +++ b/docs/en/developers/02_Github.md @@ -0,0 +1,11 @@ +# Reporting a bug or a suggestion + +**TODO** + +# Branching + +**TODO** + +# Sending a patch + +**TODO** 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) diff --git a/docs/en/developers/04_Frontend/01_View_files.md b/docs/en/developers/04_Frontend/01_View_files.md new file mode 100644 index 000000000..5eb284dde --- /dev/null +++ b/docs/en/developers/04_Frontend/01_View_files.md @@ -0,0 +1,15 @@ +# The .phtml files + +**TODO** + +# Writing a URL + +**TODO** + +# Displaying an icon + +**TODO** + +# Internationalisation + +**TODO** diff --git a/docs/en/developers/04_Frontend/02_Design.md b/docs/en/developers/04_Frontend/02_Design.md new file mode 100644 index 000000000..c2e622a08 --- /dev/null +++ b/docs/en/developers/04_Frontend/02_Design.md @@ -0,0 +1,11 @@ +# Template file + +**TODO** + +# Writing a new theme + +**TODO** + +# Overriding icons + +**TODO** diff --git a/docs/en/developers/05_Release_new_version.md b/docs/en/developers/05_Release_new_version.md new file mode 100644 index 000000000..e1a23c8ba --- /dev/null +++ b/docs/en/developers/05_Release_new_version.md @@ -0,0 +1 @@ +**TODO** |