aboutsummaryrefslogtreecommitdiff
path: root/docs/i18n/templates
diff options
context:
space:
mode:
authorGravatar maTh <math-home@web.de> 2023-05-11 08:32:19 +0200
committerGravatar GitHub <noreply@github.com> 2023-05-11 08:32:19 +0200
commit2343f0ded14ac6970575c23e4de34e536241b623 (patch)
treec53d5c3f08d45b05d1866f0155b2cdf6f37d74a1 /docs/i18n/templates
parent97226dc8a6bc561b817e4d9a5e51328deba09c61 (diff)
Docs: delete 04_Changing_source_code.md (#5391)
* delete 04_Changing_source_code.md * make pot --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Diffstat (limited to 'docs/i18n/templates')
-rw-r--r--docs/i18n/templates/freshrss.pot8566
1 files changed, 6018 insertions, 2548 deletions
diff --git a/docs/i18n/templates/freshrss.pot b/docs/i18n/templates/freshrss.pot
index 69ecee8f2..16bc2bfa7 100644
--- a/docs/i18n/templates/freshrss.pot
+++ b/docs/i18n/templates/freshrss.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://github.com/FreshRSS/FreshRSS/issues\n"
-"POT-Creation-Date: 2020-02-29 18:49+0100\n"
+"POT-Creation-Date: 2023-05-11 00:12+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,47 +19,21 @@ msgstr ""
#. type: Title ##
#: en/./contributing.md:1
-#, no-wrap
-msgid "Join us on the mailing lists"
-msgstr ""
-
-#. type: Plain text
-#: en/./contributing.md:4
-msgid ""
-"Do you want to ask us some questions? Do you want to discuss with us? Don’t "
-"hesitate to subscribe to our mailing lists!"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./contributing.md:7
-msgid ""
-"The first mailing is destined to generic information, it should be adapted "
-"to users. [Join "
-"mailing@freshrss.org](https://freshrss.org/mailman/listinfo/mailing)."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./contributing.md:7
-msgid ""
-"The second mailing is mainly for developers. [Join "
-"dev@freshrss.org](https://freshrss.org/mailman/listinfo/dev)"
-msgstr ""
-
-#. type: Title ##
-#: en/./contributing.md:8
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Report a bug"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:11
+#: en/./contributing.md:4
+#, markdown-text
msgid ""
"Have you found a bug? Don’t panic, here are some steps to report it with "
"ease:"
msgstr ""
#. type: Bullet: '1. '
-#: en/./contributing.md:15
+#: en/./contributing.md:8
+#, markdown-text
msgid ""
"Search for it on [the bug "
"tracker](https://github.com/FreshRSS/FreshRSS/issues) (don’t forget to use "
@@ -67,94 +41,116 @@ msgid ""
msgstr ""
#. type: Bullet: '2. '
-#: en/./contributing.md:15
+#: en/./contributing.md:8
+#, markdown-text
msgid ""
"If you find a similar bug, don’t hesitate to post a comment to add more "
"importance to the related ticket."
msgstr ""
#. type: Bullet: '3. '
-#: en/./contributing.md:15
+#: en/./contributing.md:8
+#, markdown-text
msgid ""
"If you didn’t find it, [open a new "
"ticket](https://github.com/FreshRSS/FreshRSS/issues/new)."
msgstr ""
#. type: Plain text
-#: en/./contributing.md:17
+#: en/./contributing.md:10
+#, markdown-text
msgid ""
"If you have to create a new ticket, please try to keep in mind the following "
"advice:"
msgstr ""
#. type: Bullet: '* '
-#: en/./contributing.md:20
+#: en/./contributing.md:13
+#, markdown-text
msgid "Give an explicit title to the ticket so it will be easier to find it later."
msgstr ""
#. type: Bullet: '* '
-#: en/./contributing.md:20
+#: en/./contributing.md:13
+#, markdown-text
msgid ""
"Be as exhaustive as possible in the description: what did you do? What is "
"the bug? What are the steps to reproduce the bug?"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:22
+#: en/./contributing.md:15
+#, markdown-text
msgid "We also need some information:"
msgstr ""
#. type: Bullet: '* '
-#: en/./contributing.md:27
+#: en/./contributing.md:20
+#, markdown-text
msgid "Your FreshRSS version (on the about page or in the `constants.php` file)"
msgstr ""
#. type: Bullet: '* '
-#: en/./contributing.md:27
+#: en/./contributing.md:20
+#, markdown-text
msgid "Your server configuration: the type of hosting and the PHP version"
msgstr ""
#. type: Bullet: '* '
-#: en/./contributing.md:27
+#: en/./contributing.md:20
+#, markdown-text
msgid "Your storage system (SQLite, MySQL, MariaDB, PostgreSQL)"
msgstr ""
#. type: Bullet: '* '
-#: en/./contributing.md:27
+#: en/./contributing.md:20
+#, markdown-text
msgid ""
"If possible, the related logs (PHP logs and FreshRSS logs under "
"`data/users/your_user/log.txt`)"
msgstr ""
+#. type: Plain text
+#: en/./contributing.md:22
+#, markdown-text
+msgid ""
+"For a more detailed guide on writing bug reports, please refer to [the "
+"in-depth guide on reporting bugs](developers/06_Reporting_Bugs)."
+msgstr ""
+
#. type: Title ##
-#: en/./contributing.md:28
-#, no-wrap
+#: en/./contributing.md:23
+#, markdown-text, no-wrap
msgid "Fix a bug"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:31
+#: en/./contributing.md:26
+#, markdown-text
msgid ""
"Would you like to fix a bug? For optimum coordination between collaborators, "
"you should follow these indications:"
msgstr ""
#. type: Bullet: '1. '
-#: en/./contributing.md:36
+#: en/./contributing.md:31
+#, markdown-text
msgid ""
"Be sure the bug is associated with a ticket and indicate that you’ll work on "
"it."
msgstr ""
#. type: Bullet: '2. '
-#: en/./contributing.md:36
+#: en/./contributing.md:31
+#, markdown-text
msgid ""
"[Fork the project "
"repository](https://help.github.com/articles/fork-a-repo/)."
msgstr ""
#. type: Bullet: '3. '
-#: en/./contributing.md:36
+#: en/./contributing.md:31
+#, markdown-text
msgid ""
"[Create a new "
"branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/). "
@@ -164,37 +160,40 @@ msgid ""
msgstr ""
#. type: Bullet: '4. '
-#: en/./contributing.md:36
+#: en/./contributing.md:31
+#, markdown-text
msgid ""
"Make your changes to your fork and [send a pull "
"request](https://help.github.com/articles/using-pull-requests/)."
msgstr ""
#. type: Plain text
-#: en/./contributing.md:38
+#: en/./contributing.md:33
+#, markdown-text
msgid ""
"If you have to write code, please follow [our coding style "
-"recommendations](developers/01_First_steps.md)."
+"recommendations](developers/02_First_steps.md)."
msgstr ""
#. type: Plain text
-#: en/./contributing.md:40
-#, no-wrap
+#: en/./contributing.md:35
+#, markdown-text, no-wrap
msgid ""
"**Tip:** if you’re searching for easy-to-fix bugs, please have a look at the "
-"\"[good first "
-"issue](https://github.com/FreshRSS/FreshRSS/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\" "
+"“[good first "
+"issue](https://github.com/FreshRSS/FreshRSS/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)” "
"ticket label.\n"
msgstr ""
#. type: Title ##
-#: en/./contributing.md:41
-#, no-wrap
+#: en/./contributing.md:36
+#, markdown-text, no-wrap
msgid "Submit an idea"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:44
+#: en/./contributing.md:39
+#, markdown-text
msgid ""
"You have great ideas, yes! Don’t be shy and open [a new "
"ticket](https://github.com/FreshRSS/FreshRSS/issues/new) on our bug tracker "
@@ -203,58 +202,187 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./contributing.md:46
+#: en/./contributing.md:41
+#, markdown-text
msgid "If your idea is nice, we’ll have a look at it."
msgstr ""
#. type: Title ##
-#: en/./contributing.md:47
-#, no-wrap
+#: en/./contributing.md:42
+#, markdown-text, no-wrap
msgid "Contribute to internationalization (i18n)"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:50
+#: en/./contributing.md:45
+#, markdown-text
msgid ""
-"If you want to improve internationalization, please open a new ticket first "
-"and follow the advice from the *Fix a bug* section."
+"Learn how to contribute to translations in [the dedicated "
+"documentation](./internationalization.md)."
+msgstr ""
+
+#. type: Title ##
+#: en/./contributing.md:46
+#, markdown-text, no-wrap
+msgid "Contribute to documentation"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:52
-msgid "Translations are present in the subdirectories of `./app/i18n/`."
+#: en/./contributing.md:49
+#, markdown-text
+msgid ""
+"The documentation needs a lot of improvements in order to be more useful to "
+"new contributors and we are working on it. If you want to give some help, "
+"meet us in the main repositories [docs "
+"directory](https://github.com/FreshRSS/FreshRSS/tree/edge/docs)!"
+msgstr ""
+
+#. type: Title #
+#: en/./developers/01_Index.md:1
+#, markdown-text, no-wrap
+msgid "FreshRSS Development"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/01_Index.md:3
+#, markdown-text, no-wrap
+msgid "First Steps"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:54
+#: en/./developers/01_Index.md:6
+#, markdown-text
msgid ""
-"We’re working on a better way to handle internationalization, but don’t "
-"hesitate to suggest any ideas!"
+"Start by creating your development environment. A guide to setting up "
+"FreshRSS’s development environment can be found on [the appropriate "
+"page](02_First_steps.md)."
msgstr ""
#. type: Title ##
-#: en/./contributing.md:55
-#, no-wrap
-msgid "Contribute to documentation"
+#: en/./developers/01_Index.md:7
+#, markdown-text, no-wrap
+msgid "After That"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:16
+#, markdown-text
+msgid "[Github Branching and Pushing](02_Github.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:16
+#, markdown-text
+msgid "[Running tests](03_Running_tests.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:16
+#, markdown-text
+msgid "[Creating a pull request](04_Pull_requests.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:16
+#, markdown-text
+msgid "[Releasing a new version](05_Release_new_version.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:16
+#, markdown-text
+msgid "[Reporting bugs](06_Reporting_Bugs.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:16
+#, markdown-text
+msgid "[Fever API](06_Fever_API.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:16
+#, markdown-text
+msgid "[GoogleReader API](06_GoogleReader_API.md)"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/01_Index.md:17
+#, markdown-text, no-wrap
+msgid "Backend Development"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:22
+#, markdown-text
+msgid "[Making extensions for FreshRSS](03_Backend/05_Extensions.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:22
+#, markdown-text
+msgid "[Database Schema](03_Backend/01_Database_schema.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:22
+#, markdown-text
+msgid "[External libraries](03_Backend/03_External_libraries.md)"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/01_Index.md:23
+#, markdown-text, no-wrap
+msgid "Frontend Development"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:27
+#, markdown-text
+msgid "[View files](04_Frontend/01_View_files.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:27
+#, markdown-text
+msgid "[Design (Themes/Theming)](04_Frontend/02_Design.md)"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/01_Index.md:28
+#, markdown-text, no-wrap
+msgid "Namespaces"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/01_Index.md:31
+#, markdown-text
+msgid "[OPML FreshRSS namespace](OPML.md)"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/01_Index.md:32
+#, markdown-text, no-wrap
+msgid "Minz"
msgstr ""
#. type: Plain text
-#: en/./contributing.md:58
+#: en/./developers/01_Index.md:34
+#, markdown-text
msgid ""
-"The documentation needs a lot of improvements in order to be more useful to "
-"new contributors and we are working on it. If you want to give some help, "
-"meet us in the main repositories [docs "
-"directory](https://github.com/FreshRSS/FreshRSS/tree/edge/docs)!"
+"Minz is the homemade PHP framework used by FreshRSS. More information can be "
+"found [here](Minz/index.md)."
msgstr ""
#. type: Title #
-#: en/./developers/01_First_steps.md:1
-#, no-wrap
+#: en/./developers/02_First_steps.md:1
+#, markdown-text, no-wrap
msgid "Environment configuration (Docker)"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:4
+#: en/./developers/02_First_steps.md:4
+#, markdown-text
msgid ""
"FreshRSS is built with PHP and uses a homemade framework, Minz. The "
"dependencies are directly included in the source code, so you don’t need "
@@ -262,7 +390,8 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:6
+#: en/./developers/02_First_steps.md:6
+#, markdown-text
msgid ""
"There are various ways to configure your development environment. The "
"easiest and most supported method is based on Docker, which is the solution "
@@ -271,14 +400,16 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:8
+#: en/./developers/02_First_steps.md:8
+#, markdown-text
msgid ""
"We assume here that you use a GNU/Linux distribution, capable of running "
"Docker. Otherwise, you’ll have to adapt the commands accordingly."
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:10
+#: en/./developers/02_First_steps.md:10
+#, markdown-text
msgid ""
"The commands that follow have to be executed in a console. They start by `$` "
"when commands need to be executed as normal user, and by `#` when they need "
@@ -289,33 +420,30 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:12
+#: en/./developers/02_First_steps.md:12
+#, markdown-text
msgid ""
"First, you need to install "
"[Docker](https://docs.docker.com/install/linux/docker-ce/ubuntu/)."
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:14
+#: en/./developers/02_First_steps.md:14
+#, markdown-text
msgid "Once you’re done, clone the repository with:"
msgstr ""
-#. type: Code fence info string
-#: en/./developers/01_First_steps.md:15 en/./developers/01_First_steps.md:24 en/./developers/01_First_steps.md:34 en/./developers/01_First_steps.md:42 en/./developers/01_First_steps.md:50 en/./developers/03_Running_tests.md:9 en/./developers/03_Running_tests.md:17 en/./developers/04_Pull_requests.md:23 en/./developers/04_Pull_requests.md:38
-#, no-wrap
-msgid "console"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/01_First_steps.md:15
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:15
#, no-wrap
msgid ""
-"$ git clone https://github.com/FreshRSS/FreshRSS.git\n"
-"$ cd FreshRSS\n"
+"git clone https://github.com/FreshRSS/FreshRSS.git\n"
+"cd FreshRSS\n"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:21
+#: en/./developers/02_First_steps.md:21
+#, markdown-text
msgid ""
"Note that, if you want to contribute, you have to fork the repository first "
"and clone your fork instead of the \"root\" one. Adapt the commands in "
@@ -323,26 +451,28 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:23
+#: en/./developers/02_First_steps.md:23
+#, markdown-text
msgid "Then, the only command you need to know is the following:"
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:24
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:24
#, no-wrap
-msgid "$ make start\n"
+msgid "make start\n"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:29
+#: en/./developers/02_First_steps.md:29
+#, markdown-text
msgid ""
"This might take some time while Docker downloads the image. If your user "
"isn’t in the `docker` group, you’ll need to prepend the command with `sudo`."
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:31
-#, no-wrap
+#: en/./developers/02_First_steps.md:31
+#, markdown-text, no-wrap
msgid ""
"**You can now access FreshRSS at "
"[http://localhost:8080](http://localhost:8080).** Just follow the install "
@@ -350,103 +480,110 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:33
-#, no-wrap
+#: en/./developers/02_First_steps.md:33
+#, markdown-text, no-wrap
msgid ""
"You can stop the containers by typing <kbd>Control</kbd> + <kbd>c</kbd> or "
"with the following command, in another terminal:\n"
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:34
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:34
#, no-wrap
-msgid "$ make stop\n"
+msgid "make stop\n"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:39
+#: en/./developers/02_First_steps.md:39
+#, markdown-text
msgid ""
"If you’re interested in the configuration, the `make` commands are defined "
"in the [`Makefile`](/Makefile)."
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:41
+#: en/./developers/02_First_steps.md:41
+#, markdown-text
msgid ""
"If you need to use a different tag image (default is `alpine`), you can set "
"the `TAG` environment variable:"
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:42
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:42
#, no-wrap
-msgid "$ TAG=arm make start\n"
+msgid "TAG=arm make start\n"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:47
+#: en/./developers/02_First_steps.md:47
+#, markdown-text
msgid ""
"You can find the full list of available tags [on the Docker "
"hub](https://hub.docker.com/r/freshrss/freshrss/tags)."
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:49
+#: en/./developers/02_First_steps.md:49
+#, markdown-text
msgid ""
"If you want to build the Docker image yourself, you can use the following "
"command:"
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:50
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:50
#, no-wrap
msgid ""
-"$ make build\n"
-"$ # or\n"
-"$ TAG=arm make build\n"
+"make build\n"
+"# or\n"
+"TAG=arm make build\n"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:57
+#: en/./developers/02_First_steps.md:57
+#, markdown-text
msgid ""
"The `TAG` variable can be anything (e.g. `local`). You can target a specific "
"architecture by adding `-alpine` or `-arm` at the end of the tag "
"(e.g. `local-arm`)."
msgstr ""
-#. type: Title #
-#: en/./developers/01_First_steps.md:58
-#, no-wrap
+#. type: Title ##
+#: en/./developers/02_First_steps.md:58
+#, markdown-text, no-wrap
msgid "Project architecture"
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:61 en/./developers/03_Backend/02_Minz.md:4 en/./developers/03_Backend/02_Minz.md:8 en/./developers/03_Backend/02_Minz.md:12 en/./developers/03_Backend/02_Minz.md:16 en/./developers/03_Backend/02_Minz.md:20 en/./developers/03_Backend/02_Minz.md:24 en/./developers/03_Backend/02_Minz.md:27 en/./developers/03_Backend/04_Changing_source_code.md:4 en/./developers/03_Backend/04_Changing_source_code.md:8 en/./developers/03_Backend/04_Changing_source_code.md:12 en/./developers/03_Backend/04_Changing_source_code.md:15 en/./developers/03_Backend/05_Extensions.md:342 en/./developers/03_Backend/05_Extensions.md:383 en/./developers/04_Frontend/01_View_files.md:4 en/./developers/04_Frontend/01_View_files.md:8 en/./developers/04_Frontend/01_View_files.md:12 en/./developers/04_Frontend/01_View_files.md:15 en/./developers/04_Frontend/02_Design.md:4 en/./developers/04_Frontend/02_Design.md:8 en/./developers/04_Frontend/02_Design.md:11 en/./users/03_Main_view.md:4 en/./users/03_Main_view.md:8 en/./users/03_Main_view.md:12 en/./users/04_Subscriptions.md:4 en/./users/04_Subscriptions.md:8 en/./users/04_Subscriptions.md:19 en/./users/05_Configuration.md:70 en/./users/05_Configuration.md:74 en/./users/05_Configuration.md:128 en/./users/05_Configuration.md:153 en/./users/05_Configuration.md:157 en/./users/05_Configuration.md:161
-#, no-wrap
-msgid "**TODO**\n"
+#. type: Bullet: '- '
+#: en/./developers/02_First_steps.md:61
+#, markdown-text
+msgid "the PHP framework: [Minz](Minz/index.md)"
msgstr ""
#. type: Title #
-#: en/./developers/01_First_steps.md:62
-#, no-wrap
+#: en/./developers/02_First_steps.md:62 en/./users/05_Configuration.md:178
+#, markdown-text, no-wrap
msgid "Extensions"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:65
+#: en/./developers/02_First_steps.md:65
+#, markdown-text
msgid ""
"If you want to create your own FreshRSS extension, take a look at the "
"[extension documentation](03_Backend/05_Extensions.md)."
msgstr ""
-#. type: Title #
-#: en/./developers/01_First_steps.md:66
-#, no-wrap
+#. type: Title ##
+#: en/./developers/02_First_steps.md:66
+#, markdown-text, no-wrap
msgid "Coding style"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:69
+#: en/./developers/02_First_steps.md:69
+#, markdown-text
msgid ""
"If you want to contribute to the source code, it’s important to follow the "
"project’s coding style. The actual code doesn’t always follow it throughout "
@@ -454,50 +591,277 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:71
+#: en/./developers/02_First_steps.md:71
+#, markdown-text
msgid ""
"Contributions which don’t follow the coding style will be rejected as long "
"as the coding style is not fixed."
msgstr ""
#. type: Title ##
-#: en/./developers/01_First_steps.md:72
+#: en/./developers/02_First_steps.md:72
+#, markdown-text, no-wrap
+msgid "GitHub Actions"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/02_First_steps.md:76
+#, markdown-text
+msgid ""
+"The code will be checked for every pull request commit on GitHub via [GitHub "
+"Actions](https://github.com/FreshRSS/FreshRSS/actions). See the "
+"configuration file [`tests.yml`](../../../.github/workflows/tests.yml)."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/02_First_steps.md:77
+#, markdown-text, no-wrap
+msgid "Running fixes & tests"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/02_First_steps.md:80
+#, markdown-text
+msgid ""
+"Tests can be run locally, e.g. by running `make test-all`, and several "
+"problems can be automatically fixed by running `make fix-all`."
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:81
#, no-wrap
-msgid "Spaces, tabs and other whitespace characters"
+msgid ""
+"make fix-all\n"
+"make test-all\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/02_First_steps.md:87
+#, markdown-text
+msgid ""
+"This requires `make` and `npm` in addition to the FreshRSS requirements. See "
+"below for the precise requirements for a few platforms."
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:88
+#, markdown-text, no-wrap
+msgid "Debian / Ubuntu"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/02_First_steps.md:91
+#, markdown-text, no-wrap
+msgid ""
+"> ℹ️ Also applies to [Microsoft "
+"Windows](https://docs.microsoft.com/windows/wsl/install-win10) thanks to "
+"[WSL](https://ubuntu.com/wsl).\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/02_First_steps.md:93
+#, markdown-text
+msgid ""
+"Here are the dependencies that need to be manually installed prior to "
+"running the fixes & tests."
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:94
+#, no-wrap
+msgid ""
+"sudo apt update && sudo apt install --no-install-recommends -y make npm "
+"php-cli php-curl php-mbstring php-xml unzip wget\n"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:98
+#, markdown-text, no-wrap
+msgid "Fedora / Red Hat"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:100
+#, no-wrap
+msgid ""
+"yum install -y git make npm php-cli php-curl php-mbstring php-xml php-pdo "
+"unzip wget\n"
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:74
+#: en/./developers/02_First_steps.md:104
+#, markdown-text, no-wrap
+msgid "Alpine Linux"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:106
#, no-wrap
+msgid ""
+"apk add git make npm php-cli php-curl php-ctype php-dom php-mbstring "
+"php-openssl php-phar php-simplexml php-xml php-pdo php-tokenizer "
+"php-xmlreader php-xmlwriter unzip wget\n"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:110
+#, markdown-text, no-wrap
+msgid "Partial fixes & tests"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/02_First_steps.md:114
+#, markdown-text
+msgid ""
+"composer-based: `npm run fix && npm test` or see the [`scripts` section of "
+"`composer.json`](../../../composer.json) for individual tests or fixes such "
+"as `composer phpstan`"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/02_First_steps.md:114
+#, markdown-text
+msgid ""
+"npm-based: `npm run fix && npm test` or see the [`scripts` section of "
+"`package.json`](../../../package.json) for individual tests or fixes such as "
+"`npm run rtlcss`"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:115
+#, markdown-text, no-wrap
+msgid "Tests summary"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/02_First_steps.md:118
+#, markdown-text
+msgid "A short (not complete) summary:"
+msgstr ""
+
+#. type: Title ####
+#: en/./developers/02_First_steps.md:119
+#, markdown-text, no-wrap
+msgid "PHP"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/02_First_steps.md:127
+#, markdown-text
+msgid "Syntax of `php` and `phtml` files is checked."
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/02_First_steps.md:127
+#, markdown-text
+msgid ""
+"translation files (`i18n`) are checked ([more information about i18n "
+"files](internationalization.html))."
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/02_First_steps.md:127
+#, markdown-text
+msgid "unit test (`tests`) are run by [PHPunit](https://phpunit.de/)."
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/02_First_steps.md:127 en/./developers/02_First_steps.md:134
+#: en/./developers/02_First_steps.md:139 en/./developers/02_First_steps.md:144
+#, markdown-text
+msgid "Linter:"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./developers/02_First_steps.md:127 en/./developers/02_First_steps.md:134
+#, markdown-text
+msgid "[PHP_Codesniffer (phpcs)](https://github.com/squizlabs/PHP_CodeSniffer)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./developers/02_First_steps.md:127
+#, markdown-text
+msgid "[PHPstan](https://github.com/phpstan/phpstan)"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:128
+#, markdown-text, no-wrap
+msgid "CSS"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./developers/02_First_steps.md:134
+#, markdown-text
+msgid "via npm `.styleintrc.json`"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./developers/02_First_steps.md:134
+#, markdown-text
+msgid "check that RTL (right-to-left) CSS files match to standard CSS files"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:135
+#, markdown-text, no-wrap
+msgid "JavaScript"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./developers/02_First_steps.md:139
+#, markdown-text
+msgid ""
+"via npm `.styleintrc.json` ([ECMAScript "
+"2017](https://en.wikipedia.org/wiki/ECMAScript#8th_Edition_%E2%80%93_ECMAScript_2017))"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:140
+#, markdown-text, no-wrap
+msgid "Markdown"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./developers/02_First_steps.md:144
+#, markdown-text
+msgid "via npm `.markdownlint.json`"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/02_First_steps.md:145
+#, markdown-text, no-wrap
+msgid "Spaces, tabs and other whitespace characters"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/02_First_steps.md:147
+#, markdown-text, no-wrap
msgid "Indentation"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:76
+#: en/./developers/02_First_steps.md:150
+#, markdown-text
msgid "Code indentation must use tabs."
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:77
-#, no-wrap
+#: en/./developers/02_First_steps.md:151
+#, markdown-text, no-wrap
msgid "Alignment"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:80
+#: en/./developers/02_First_steps.md:154
+#, markdown-text
msgid ""
"Once the code has been correctly indented, it might be useful to align it "
"for ease of reading. In that case, please use spaces."
msgstr ""
-#. type: Code fence info string
-#: en/./developers/01_First_steps.md:81 en/./developers/01_First_steps.md:111 en/./developers/01_First_steps.md:123 en/./developers/01_First_steps.md:158 en/./developers/01_First_steps.md:173 en/./developers/01_First_steps.md:186 en/./developers/01_First_steps.md:196 en/./developers/01_First_steps.md:213 en/./developers/01_First_steps.md:228 en/./developers/03_Backend/05_Extensions.md:47 en/./developers/03_Backend/05_Extensions.md:88 en/./developers/03_Backend/05_Extensions.md:130 en/./developers/03_Backend/05_Extensions.md:149 en/./developers/03_Backend/05_Extensions.md:166 en/./developers/03_Backend/05_Extensions.md:188 en/./developers/03_Backend/05_Extensions.md:225 en/./developers/05_Release_new_version.md:53 en/./users/06_Fever_API.md:107
-#, no-wrap
-msgid "php"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/01_First_steps.md:81
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:155
#, no-wrap
msgid ""
"$result = a_function_with_a_really_long_name($param1, $param2,\n"
@@ -505,33 +869,29 @@ msgid ""
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:86
-#, no-wrap
+#: en/./developers/02_First_steps.md:160
+#, markdown-text, no-wrap
msgid "End of line"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:89
+#: en/./developers/02_First_steps.md:163
+#, markdown-text
msgid ""
"The newline character must be a line feed (LF), which is the default line "
"ending on *NIX systems. This character must not follow other white space."
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:91
+#: en/./developers/02_First_steps.md:165
+#, markdown-text
msgid ""
"You can verify if there is any unintended white space at the end of line "
"with the following Git command:"
msgstr ""
-#. type: Code fence info string
-#: en/./developers/01_First_steps.md:92 en/./developers/02_Github.md:80 en/./developers/02_Github.md:85 en/./developers/02_Github.md:90 en/./developers/02_Github.md:96 en/./developers/02_Github.md:102 en/./developers/05_Release_new_version.md:15 en/./developers/05_Release_new_version.md:101
-#, no-wrap
-msgid "bash"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/01_First_steps.md:92
+#. type: Fenced code block (sh)
+#: en/./developers/02_First_steps.md:166
#, no-wrap
msgid ""
"# command to check files before adding them in the Git index\n"
@@ -541,42 +901,45 @@ msgid ""
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:99 en/./developers/01_First_steps.md:220
-#, no-wrap
+#: en/./developers/02_First_steps.md:173
+#, markdown-text, no-wrap
msgid "End of file"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:102
+#: en/./developers/02_First_steps.md:176
+#, markdown-text
msgid "Every file must end by an empty line."
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:103
-#, no-wrap
+#: en/./developers/02_First_steps.md:177
+#, markdown-text, no-wrap
msgid "Commas, dots and semi-columns"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:106
+#: en/./developers/02_First_steps.md:180
+#, markdown-text
msgid ""
"There should no space before those characters, but there should be one "
"after."
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:107 en/./developers/01_First_steps.md:210
-#, no-wrap
+#: en/./developers/02_First_steps.md:181
+#, markdown-text, no-wrap
msgid "Operators"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:110
+#: en/./developers/02_First_steps.md:184
+#, markdown-text
msgid "There should be a space before and after every operator."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:111
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:185
#, no-wrap
msgid ""
"if ($a == 10) {\n"
@@ -587,13 +950,14 @@ msgid ""
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:119
-#, no-wrap
+#: en/./developers/02_First_steps.md:193
+#, markdown-text, no-wrap
msgid "Parentheses"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:122
+#: en/./developers/02_First_steps.md:196
+#, markdown-text
msgid ""
"There should be no spaces in between brackets. There should be no spaces "
"before the opening bracket, except if it’s after a keyword. There shouldn’t "
@@ -601,8 +965,8 @@ msgid ""
"bracket."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:123
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:197
#, no-wrap
msgid ""
"if ($a == 10) {\n"
@@ -615,29 +979,24 @@ msgid ""
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:133
-#, no-wrap
+#: en/./developers/02_First_steps.md:207
+#, markdown-text, no-wrap
msgid "With chained functions"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:136
+#: en/./developers/02_First_steps.md:210
+#, markdown-text
msgid ""
-"It happens most of the time in Javascript files. When there are chained "
-"functions with closures and callback functions, it’s hard to understand the "
+"It happens most of the time in JavaScript files. When there are chained "
+"functions with closures and call-back functions, it’s 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."
msgstr ""
-#. type: Code fence info string
-#: en/./developers/01_First_steps.md:137
-#, no-wrap
-msgid "javascript"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/01_First_steps.md:137
+#. type: Fenced code block (javascript)
+#: en/./developers/02_First_steps.md:211
#, no-wrap
msgid ""
"// First instruction\n"
@@ -655,25 +1014,27 @@ msgid ""
msgstr ""
#. type: Title ##
-#: en/./developers/01_First_steps.md:152
-#, no-wrap
+#: en/./developers/02_First_steps.md:226
+#, markdown-text, no-wrap
msgid "Line length"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:155
+#: en/./developers/02_First_steps.md:229
+#, markdown-text
msgid ""
"Lines should strive to be shorter than 80 characters. However, this limit "
"may be extended to 100 characters when strictly necessary."
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:157
+#: en/./developers/02_First_steps.md:231
+#, markdown-text
msgid "With functions, parameters can be declared on multiple lines."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:158
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:232
#, no-wrap
msgid ""
"function my_function($param_1, $param_2,\n"
@@ -683,31 +1044,33 @@ msgid ""
msgstr ""
#. type: Title ##
-#: en/./developers/01_First_steps.md:165
-#, no-wrap
+#: en/./developers/02_First_steps.md:239
+#, markdown-text, no-wrap
msgid "Naming"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:168
+#: en/./developers/02_First_steps.md:242
+#, markdown-text
msgid ""
"All code elements (functions, classes, methods and variables) must describe "
"their usage succinctly."
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:169
-#, no-wrap
+#: en/./developers/02_First_steps.md:243
+#, markdown-text, no-wrap
msgid "Functions and variables"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:172
+#: en/./developers/02_First_steps.md:246
+#, markdown-text
msgid "Functions and variables must follow the \"snake case\" naming convention."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:173
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:247
#, no-wrap
msgid ""
"// a function\n"
@@ -719,18 +1082,19 @@ msgid ""
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:182
-#, no-wrap
+#: en/./developers/02_First_steps.md:256
+#, markdown-text, no-wrap
msgid "Methods"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:185
+#: en/./developers/02_First_steps.md:259
+#, markdown-text
msgid "Methods must follow the \"lower camel case\" naming convention."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:186
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:260
#, no-wrap
msgid ""
"private function methodName() {\n"
@@ -739,61 +1103,71 @@ msgid ""
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:192
-#, no-wrap
+#: en/./developers/02_First_steps.md:266
+#, markdown-text, no-wrap
msgid "Classes"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:195
+#: en/./developers/02_First_steps.md:269
+#, markdown-text
msgid "Classes must follow the \"upper camel case\" naming convention."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:196
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:270
#, no-wrap
msgid "abstract class ClassName {}\n"
msgstr ""
#. type: Title ##
-#: en/./developers/01_First_steps.md:200
-#, no-wrap
+#: en/./developers/02_First_steps.md:274
+#, markdown-text, no-wrap
msgid "Encoding"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:203
+#: en/./developers/02_First_steps.md:277
+#, markdown-text
msgid "Files must be encoded with the UTF-8 character set."
msgstr ""
#. type: Title ##
-#: en/./developers/01_First_steps.md:204
-#, no-wrap
+#: en/./developers/02_First_steps.md:278
+#, markdown-text, no-wrap
msgid "PHP compatibility"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:207
+#: en/./developers/02_First_steps.md:281
+#, markdown-text
msgid ""
"Please ensure that your code works with the oldest PHP version officially "
"supported by FreshRSS."
msgstr ""
-#. type: Title ##
-#: en/./developers/01_First_steps.md:208
-#, no-wrap
+#. type: Title ###
+#: en/./developers/02_First_steps.md:282 en/./developers/OPML.md:47
+#, markdown-text, no-wrap
msgid "Miscellaneous"
msgstr ""
+#. type: Title ###
+#: en/./developers/02_First_steps.md:284
+#, markdown-text, no-wrap
+msgid "Operators on multiple lines"
+msgstr ""
+
#. type: Plain text
-#: en/./developers/01_First_steps.md:212
+#: en/./developers/02_First_steps.md:287
+#, markdown-text
msgid ""
"Operators must be at the end of the line if a condition is split over more "
"than one line."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:213
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:288
#, no-wrap
msgid ""
"if ($a == 10 ||\n"
@@ -802,26 +1176,34 @@ msgid ""
"}\n"
msgstr ""
+#. type: Title ###
+#: en/./developers/02_First_steps.md:295
+#, markdown-text, no-wrap
+msgid "End of PHP file"
+msgstr ""
+
#. type: Plain text
-#: en/./developers/01_First_steps.md:223
+#: en/./developers/02_First_steps.md:298
+#, markdown-text
msgid "If the file contains only PHP code, the PHP closing tag must be omitted."
msgstr ""
#. type: Title ###
-#: en/./developers/01_First_steps.md:224
-#, no-wrap
+#: en/./developers/02_First_steps.md:299
+#, markdown-text, no-wrap
msgid "Arrays"
msgstr ""
#. type: Plain text
-#: en/./developers/01_First_steps.md:227
+#: en/./developers/02_First_steps.md:302
+#, markdown-text
msgid ""
"If an array declaration runs on more than one line, each element must be "
"followed by a comma, including the last one."
msgstr ""
-#. type: Plain text
-#: en/./developers/01_First_steps.md:228
+#. type: Fenced code block (php)
+#: en/./developers/02_First_steps.md:303
#, no-wrap
msgid ""
"$variable = [\n"
@@ -833,341 +1215,84 @@ msgstr ""
#. type: Title #
#: en/./developers/02_Github.md:1
-#, no-wrap
-msgid "Reporting a bug or a suggestion"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:4
-msgid ""
-"Despite the care given to FreshRSS, it’s still possible that bugs occur. The "
-"project is young and development is dynamic, so it can be corrected "
-"quickly. You might also have a feature in mind that does not yet "
-"exist. Regardless whether your idea seems silly, far-fetched, useless or too "
-"specific, please don’t hesitate to propose it to us! \"Ideas in the air\" "
-"often find an attentive ear. It’s new external perspectives that make the "
-"project evolve the most."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:6
-msgid ""
-"If you’re convinced that you should be heard, here’s how you can go about "
-"it."
-msgstr ""
-
-#. type: Title ##
-#: en/./developers/02_Github.md:7
-#, no-wrap
-msgid "On GitHub"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:10
-msgid ""
-"GitHub is the ideal platform to submit your requests. It allows us to "
-"discuss a problem or suggestion with others and it often generates new "
-"ideas. Let’s not neglect this \"social\" aspect!"
-msgstr ""
-
-#. type: Bullet: ' 1. '
-#: en/./developers/02_Github.md:16
-msgid "[Go to the bug ticket manager](https://github.com/FreshRSS/FreshRSS/issues)"
-msgstr ""
-
-#. type: Bullet: ' 2. '
-#: en/./developers/02_Github.md:16
-msgid ""
-"Start by checking if a similar request hasn’t already been made. If so, "
-"please feel free to add your voice to the request."
-msgstr ""
-
-#. type: Bullet: ' 3. '
-#: en/./developers/02_Github.md:16
-msgid ""
-"If your request is new, [open a new bug "
-"ticket](https://github.com/FreshRSS/FreshRSS/issues/new)"
-msgstr ""
-
-#. type: Bullet: ' 4. '
-#: en/./developers/02_Github.md:16
-msgid ""
-"Finally, write your request. If you’re fluent in English, it’s the preferred "
-"language because it allows for discussion with the largest number of people."
-msgstr ""
-
-#. type: Bullet: ' 5. '
-#: en/./developers/02_Github.md:16
-msgid "Please follow the tips below to make it easier to let your ticket be heard."
-msgstr ""
-
-#. type: Title ##
-#: en/./developers/02_Github.md:17
-#, no-wrap
-msgid "Informal"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:20
-msgid ""
-"Not everyone likes or uses GitHub for a variety of legitimate reasons. That "
-"is why you can also contact us in a more informal way."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:26
-msgid ""
-"On [our Mattermost "
-"chat](https://framateam.org/signup_user_complete/?id=e2680d3e3128b9fac8fdb3003b0024ee)"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:26
-msgid ""
-"On [the mailing "
-"lists](https://freshrss.org/announce-of-the-mailing-lists.html)"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:26
-msgid "At events / meetings around Free Software"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:26
-msgid "Over a beer in a bar"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:26
-msgid "Etc."
-msgstr ""
-
-#. type: Title ##
-#: en/./developers/02_Github.md:27
-#, no-wrap
-msgid "Tips"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:30
-msgid "Here are some tips to help you present your bug report or suggestion:"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:39
-msgid "**Pay attention to spelling**. Even if it’s not always easy, try your best!"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:39
-msgid ""
-"**Give an explicit title to your request**, even if it’s a bit long. This "
-"not only helps us understand your request, but also to find your ticket "
-"later."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:39
-msgid ""
-"**One request = one ticket.** You may have lots of ideas while being afraid "
-"to spam the bug manager: it does’nt matter. It’s better to have a few too "
-"many tickets than too many requests in one. We’ll close and consolidate "
-"requests when possible."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:39
-msgid ""
-"If you report a bug, think about **providing us with the FreshRSS logs** "
-"(accessible in the FreshRSS `data/log/` folder) and the **PHP logs** (the "
-"location may vary by distribution, but consider searching in "
-"`/var/log/httpd` or `/var/log/apache`)."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:39
-msgid ""
-"If you can’t find the log files, specify it in your ticket so we know you’ve "
-"already searched."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:39
-msgid ""
-"Not all bugs require logs, but if you have any doubts, it is better to "
-"provide them to us. Logs are important and very useful for debugging!"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/02_Github.md:39
-msgid ""
-"The logs may reveal confidential information, so **be careful not to "
-"disclose anything sensitive.**"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:41
-msgid ""
-"In addition, when facing a bug, you’re encouraged to follow this message "
-"format (from the [Sam & Max "
-"website](http://sametmax.com/template-de-demande-daide-en-informatique/):"
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/02_Github.md:42
-#, no-wrap
-msgid "What’s my goal?"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:45
-msgid "Give the general context of what you were trying to do."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/02_Github.md:46
-#, no-wrap
-msgid "What have I been trying to do?"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:49
-msgid "Explain step by step what you have done so that we can reproduce the bug."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/02_Github.md:50
-#, no-wrap
-msgid "What results have I achieved?"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:53
-msgid ""
-"The bug: what you see that shouldn’t have happened. Here you can provide the "
-"logs."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/02_Github.md:54
-#, no-wrap
-msgid "What was the expected result?"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:57
-msgid "So that we understand what you consider to be the problem."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/02_Github.md:58
-#, no-wrap
-msgid "What are my circumstances?"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/02_Github.md:61
-msgid "Remember to give the following information if you know it:"
-msgstr ""
-
-#. type: Bullet: ' 1. '
-#: en/./developers/02_Github.md:67
-msgid "Which browser? Which version?"
-msgstr ""
-
-#. type: Bullet: ' 2. '
-#: en/./developers/02_Github.md:67
-msgid "Which server: Apache, Nginx? Which version?"
-msgstr ""
-
-#. type: Bullet: ' 3. '
-#: en/./developers/02_Github.md:67
-msgid "Which version of PHP?"
-msgstr ""
-
-#. type: Bullet: ' 4. '
-#: en/./developers/02_Github.md:67
-msgid "Which database: SQLite, MySQL, MariaDB, PostgreSQL? Which version?"
-msgstr ""
-
-#. type: Bullet: ' 5. '
-#: en/./developers/02_Github.md:67
-msgid "Which distribution runs on the server? And… which version?"
-msgstr ""
-
-#. type: Title #
-#: en/./developers/02_Github.md:68
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Branching"
msgstr ""
#. type: Title ##
-#: en/./developers/02_Github.md:70
-#, no-wrap
+#: en/./developers/02_Github.md:3
+#, markdown-text, no-wrap
msgid "Basic"
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:72
+#: en/./developers/02_Github.md:6
+#, markdown-text
msgid "If you are new to Git, here are some of the resources you might find useful:"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/02_Github.md:77
+#: en/./developers/02_Github.md:11
+#, markdown-text
msgid "[GitHub’s blog post](https://github.com/blog/120-new-to-git)"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/02_Github.md:77
+#: en/./developers/02_Github.md:11
+#, markdown-text
msgid "<http://try.github.com/>"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/02_Github.md:77
+#: en/./developers/02_Github.md:11
+#, markdown-text
msgid "<http://sixrevisions.com/resources/git-tutorials-beginners/>"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/02_Github.md:77
+#: en/./developers/02_Github.md:11
+#, markdown-text
msgid "<http://rogerdudler.github.io/git-guide/>"
msgstr ""
#. type: Title ##
-#: en/./developers/02_Github.md:78
-#, no-wrap
+#: en/./developers/02_Github.md:12
+#, markdown-text, no-wrap
msgid "Getting the latest code from the FreshRSS repository"
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:80
+#: en/./developers/02_Github.md:15
+#, markdown-text
msgid "First you need to add the official repo to your remote repo list:"
msgstr ""
-#. type: Plain text
-#: en/./developers/02_Github.md:80
+#. type: Fenced code block (sh)
+#: en/./developers/02_Github.md:16
#, no-wrap
msgid "git remote add upstream git@github.com:FreshRSS/FreshRSS.git\n"
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:85
+#: en/./developers/02_Github.md:21
+#, markdown-text
msgid "You can verify the remote repo is successfully added by using:"
msgstr ""
-#. type: Plain text
-#: en/./developers/02_Github.md:85
+#. type: Fenced code block (sh)
+#: en/./developers/02_Github.md:22
#, no-wrap
msgid "git remote -v show\n"
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:90
+#: en/./developers/02_Github.md:27
+#, markdown-text
msgid "Now you can pull the latest development code:"
msgstr ""
-#. type: Plain text
-#: en/./developers/02_Github.md:90
+#. type: Fenced code block (sh)
+#: en/./developers/02_Github.md:28
#, no-wrap
msgid ""
"git checkout edge\n"
@@ -1175,25 +1300,25 @@ msgid ""
msgstr ""
#. type: Title ##
-#: en/./developers/02_Github.md:95
-#, no-wrap
+#: en/./developers/02_Github.md:33
+#, markdown-text, no-wrap
msgid "Starting a new development branch"
msgstr ""
-#. type: Plain text
-#: en/./developers/02_Github.md:96
+#. type: Fenced code block (sh)
+#: en/./developers/02_Github.md:35
#, no-wrap
msgid "git checkout -b my-development-branch\n"
msgstr ""
-#. type: Title #
-#: en/./developers/02_Github.md:100
-#, no-wrap
+#. type: Title ##
+#: en/./developers/02_Github.md:39
+#, markdown-text, no-wrap
msgid "Sending a patch"
msgstr ""
-#. type: Plain text
-#: en/./developers/02_Github.md:102
+#. type: Fenced code block (sh)
+#: en/./developers/02_Github.md:41
#, no-wrap
msgid ""
"# Add the changed file, here actualize_script.php\n"
@@ -1207,119 +1332,94 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:114
+#: en/./developers/02_Github.md:53
+#, markdown-text
msgid "Now you can create a PR based on your branch."
msgstr ""
#. type: Title ##
-#: en/./developers/02_Github.md:115
-#, no-wrap
+#: en/./developers/02_Github.md:54
+#, markdown-text, no-wrap
msgid "How to write a commit message"
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:118
+#: en/./developers/02_Github.md:57
+#, markdown-text
msgid ""
-"A commit message should succintly describe the changes on the first "
+"A commit message should succinctly describe the changes on the first "
"line. For example:"
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:120
-#, no-wrap
+#: en/./developers/02_Github.md:59
+#, markdown-text, no-wrap
msgid "> Fix broken icon\n"
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:122
+#: en/./developers/02_Github.md:61
+#, markdown-text
msgid "If necessary, this can be followed by a blank line and a longer explanation."
msgstr ""
#. type: Plain text
-#: en/./developers/02_Github.md:123
+#: en/./developers/02_Github.md:62
+#, markdown-text
msgid "For further tips, see [here](https://chris.beams.io/posts/git-commit/)."
msgstr ""
#. type: Title #
-#: en/./developers/03_Backend/02_Minz.md:1
-#, no-wrap
-msgid "Models"
-msgstr ""
-
-#. type: Title #
-#: en/./developers/03_Backend/02_Minz.md:5
-#, no-wrap
-msgid "Controllers and actions"
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/02_Minz.md:9 en/./developers/03_Backend/05_Extensions.md:69
-#, no-wrap
-msgid "Views"
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/02_Minz.md:13 en/./developers/03_Backend/05_Extensions.md:39
-#, no-wrap
-msgid "Routing"
-msgstr ""
-
-#. type: Title #
-#: en/./developers/03_Backend/02_Minz.md:17
-#, no-wrap
-msgid "Writing URL"
-msgstr ""
-
-#. type: Title #
-#: en/./developers/03_Backend/02_Minz.md:21 en/./developers/04_Frontend/01_View_files.md:13
-#, no-wrap
-msgid "Internationalisation"
+#: en/./developers/03_Backend/01_Database_schema.md:1
+#, markdown-text, no-wrap
+msgid "Database Schema"
msgstr ""
-#. type: Title #
-#: en/./developers/03_Backend/02_Minz.md:25
-#, no-wrap
-msgid "Understanding internals"
-msgstr ""
-
-#. type: Title #
-#: en/./developers/03_Backend/04_Changing_source_code.md:1
-#, no-wrap
-msgid "Accessing the database"
+#. type: Plain text
+#: en/./developers/03_Backend/01_Database_schema.md:4
+#: en/./developers/03_Backend/05_Extensions.md:169
+#: en/./developers/04_Frontend/01_View_files.md:6
+#: en/./developers/04_Frontend/01_View_files.md:10
+#: en/./developers/04_Frontend/01_View_files.md:14
+#: en/./developers/04_Frontend/01_View_files.md:17
+#: en/./users/05_Configuration.md:185
+#, markdown-text, no-wrap
+msgid "> **TODO**\n"
msgstr ""
-#. type: Title #
-#: en/./developers/03_Backend/04_Changing_source_code.md:5
-#, no-wrap
-msgid "Writing an action and its related view"
+#. type: Title ##
+#: en/./developers/03_Backend/01_Database_schema.md:5
+#, markdown-text, no-wrap
+msgid "See also"
msgstr ""
-#. type: Title #
-#: en/./developers/03_Backend/04_Changing_source_code.md:9
-#, no-wrap
-msgid "Authentication"
+#. type: Bullet: '* '
+#: en/./developers/03_Backend/01_Database_schema.md:7
+#, markdown-text
+msgid "[Database configuration](../../admins/DatabaseConfig.md)"
msgstr ""
#. type: Title #
-#: en/./developers/03_Backend/04_Changing_source_code.md:13
-#, no-wrap
-msgid "Logs"
+#: en/./developers/03_Backend/03_External_libraries.md:1
+#, markdown-text, no-wrap
+msgid "External Libraries"
msgstr ""
#. type: Title #
#: en/./developers/03_Backend/05_Extensions.md:1
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Writing extensions for FreshRSS"
msgstr ""
#. type: Title ##
#: en/./developers/03_Backend/05_Extensions.md:3
-#, no-wrap
+#, markdown-text, no-wrap
msgid "About FreshRSS"
msgstr ""
#. type: Plain text
#: en/./developers/03_Backend/05_Extensions.md:6
+#, markdown-text
msgid ""
"FreshRSS is an RSS / Atom feed aggregator written in PHP dating back to "
"October 2012. The official site is located at "
@@ -1330,32 +1430,37 @@ msgstr ""
#. type: Title ##
#: en/./developers/03_Backend/05_Extensions.md:7
-#, no-wrap
+#, markdown-text, no-wrap
msgid "The problem"
msgstr ""
#. type: Plain text
#: en/./developers/03_Backend/05_Extensions.md:10
+#, markdown-text
msgid "FreshRSS is limited in its technical possibilities by various factors:"
msgstr ""
#. type: Bullet: '* '
#: en/./developers/03_Backend/05_Extensions.md:14
+#, markdown-text
msgid "The number of developers"
msgstr ""
#. type: Bullet: '* '
#: en/./developers/03_Backend/05_Extensions.md:14
+#, markdown-text
msgid "The will to integrate certain changes"
msgstr ""
#. type: Bullet: '* '
#: en/./developers/03_Backend/05_Extensions.md:14
+#, markdown-text
msgid "The level of \"hacking\" required to integrate marginal features"
msgstr ""
#. type: Plain text
#: en/./developers/03_Backend/05_Extensions.md:16
+#, markdown-text
msgid ""
"While the first limitation can, in theory, be lifted by the participation of "
"new contributors to the project, it depends on the willingness of "
@@ -1366,6 +1471,7 @@ msgstr ""
#. type: Plain text
#: en/./developers/03_Backend/05_Extensions.md:18
+#, markdown-text
msgid ""
"Another solution consists of an extension system. By allowing users to write "
"their own extension without taking an interest in the core of the basic "
@@ -1374,595 +1480,100 @@ msgstr ""
#. type: Bullet: '1. '
#: en/./developers/03_Backend/05_Extensions.md:22
+#, markdown-text
msgid "Reducing the amount of source code a new contributor has to take in"
msgstr ""
#. type: Bullet: '2. '
#: en/./developers/03_Backend/05_Extensions.md:22
+#, markdown-text
msgid "Unofficial integration of novelties"
msgstr ""
#. type: Bullet: '3. '
#: en/./developers/03_Backend/05_Extensions.md:22
+#, markdown-text
msgid "No forking or main developer approval required."
msgstr ""
#. type: Plain text
#: en/./developers/03_Backend/05_Extensions.md:24
+#, markdown-text
msgid ""
"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."
msgstr ""
-#. type: Title ##
+#. type: Title #
#: en/./developers/03_Backend/05_Extensions.md:25
-#, no-wrap
-msgid "Understanding basic mechanics (Minz and MVC)"
+#: en/./developers/Minz/index.md:1
+#, markdown-text, no-wrap
+msgid "Minz Framework"
msgstr ""
#. type: Plain text
#: en/./developers/03_Backend/05_Extensions.md:28
-#, no-wrap
-msgid "**TODO** : move to 02_Minz.md\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:30
-msgid ""
-"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)."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:31
-#, no-wrap
-msgid "MVC Architecture"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:34
-msgid ""
-"Minz relies on and imposes an MVC architecture on projects using it. This "
-"architecture consists of three main components:"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:38
-msgid ""
-"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."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:38
-msgid ""
-"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."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:38
-msgid ""
-"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."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:42
-msgid ""
-"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://exemple.com?c=hello will "
-"execute the code contained in the `hello` controller."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:44
-msgid ""
-"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."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:46 en/./developers/03_Backend/05_Extensions.md:165
-msgid "Code example:"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:47
-#, no-wrap
-msgid ""
-"<?php\n"
-"\n"
-"class FreshRSS_hello_Controller extends FreshRSS_ActionController {\n"
-"\tpublic function indexAction() {\n"
-"\t\t$this->view->a_variable = 'FooBar';\n"
-"\t}\n"
-"\n"
-"\tpublic function worldAction() {\n"
-"\t\t$this->view->a_variable = 'Hello World!';\n"
-"\t}\n"
-"}\n"
-"\n"
-"?>\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:64
-msgid ""
-"When loading the address http://exemple.com?c=hello&a=world, the `world` "
-"action is executed on the `hello` controller."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:66
-msgid ""
-"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."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:68
-msgid ""
-"From now on, the `hello/world` naming convention will be used to refer to a "
-"controller/action pair."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:72
-msgid ""
-"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."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:74
-msgid "As explained above, the views consist of HTML mixed with PHP. Code example:"
-msgstr ""
-
-#. type: Code fence info string
-#: en/./developers/03_Backend/05_Extensions.md:75 en/./developers/03_Backend/05_Extensions.md:120 en/./developers/03_Backend/05_Extensions.md:248 en/./developers/03_Backend/05_Extensions.md:284 en/./developers/03_Backend/05_Extensions.md:351
-#, no-wrap
-msgid "html"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:75
-#, no-wrap
-msgid ""
-"<p>\n"
-"\tThis is a parameter passed from the controller: <?= $this->a_variable ?>\n"
-"</p>\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:82
-#, no-wrap
-msgid ""
-"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.\n"
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:83
-#, no-wrap
-msgid "Working with GET / POST"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:87
-msgid ""
-"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:"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:88
-#, no-wrap
-msgid ""
-"<?php\n"
-"\n"
-"$default_value = 'foo';\n"
-"$param = Minz_Request::param('bar', $default_value);\n"
-"\n"
-"// Display the value of the parameter `bar` (passed via GET or POST)\n"
-"// or \"foo\" if the parameter does not exist.\n"
-"echo $param;\n"
-"\n"
-"// Sets the value of the `bar` parameter\n"
-"Minz_Request::_param('bar', 'baz');\n"
-"\n"
-"// Will necessarily display \"baz\" since we have just forced its value.\n"
-"// Note that the second parameter (default) is optional.\n"
-"echo Minz_Request::param('bar');\n"
-"\n"
-"?>\n"
+#, markdown-text
+msgid "see [Minz documentation](/docs/en/developers/Minz/index.md)"
msgstr ""
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:109
-msgid ""
-"The `Minz_Request::isPost()` method can be used to execute a piece of code "
-"only if it is a POST request."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:111
-msgid ""
-"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."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:112
-#, no-wrap
-msgid "Access session settings"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:115
-msgid ""
-"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`."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:116
-#, no-wrap
-msgid "Working with URLs"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:119
-msgid ""
-"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:"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:120
-#, no-wrap
-msgid ""
-"<p>\n"
-"\tGo to page <a href=\"http://example.com?c=hello&amp;a=world\">Hello "
-"world</a>!\n"
-"</p>\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:127
-msgid ""
-"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!"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:129
-msgid ""
-"So use the `Minz_Url` class and its `display()` method "
-"instead. `Minz_Url::display()` takes an array of the following form as its "
-"argument:"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:130
-#, no-wrap
-msgid ""
-"<?php\n"
-"\n"
-"$url_array = [\n"
-"\t'c' => 'hello',\n"
-"\t'a' => 'world',\n"
-"\t'params' => [\n"
-"\t\t'foo' => 'bar',\n"
-"\t],\n"
-"];\n"
-"\n"
-"// Show something like .?c=hello&amp;a=world&amp;foo=bar\n"
-"echo Minz_Url::display($url_array);\n"
-"\n"
-"?>\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:148
-msgid ""
-"Since this can become a bit tedious to use in the long run, especially in "
-"views, it is preferable to use the `_url()` shortcut:"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:149
-#, no-wrap
-msgid ""
-"<?php\n"
-"\n"
-"// Displays the same as above\n"
-"echo _url('hello', 'world', 'foo', 'bar');\n"
-"\n"
-"?>\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:159
-msgid ""
-"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."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:160
-#, no-wrap
-msgid "Redirections"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:163
-msgid ""
-"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."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:166
-#, no-wrap
-msgid ""
-"<?php\n"
-"\n"
-"$url_array = [\n"
-"\t'c' => 'hello',\n"
-"\t'a' => 'world',\n"
-"];\n"
-"\n"
-"// Tells Minz to redirect the user to the hello / world page.\n"
-"// 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)\n"
-"// The code that follows forward() will thus be executed!\n"
-"Minz_Request::forward($url_array);\n"
-"\n"
-"// To perform a type 302 redirect, add \"true\".\n"
-"// The code that follows will never be executed.\n"
-"Minz_Request::forward($url_array, true);\n"
-"\n"
-"?>\n"
+#. type: Title ##
+#: en/./developers/03_Backend/05_Extensions.md:29
+#, markdown-text, no-wrap
+msgid "Write an extension for FreshRSS"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:187
+#: en/./developers/03_Backend/05_Extensions.md:32
+#, markdown-text
msgid ""
-"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:"
+"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."
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:188
-#, no-wrap
+#: en/./developers/03_Backend/05_Extensions.md:34
+#, markdown-text
msgid ""
-"<?php\n"
-"\n"
-"$url_array = [\n"
-"\t'c' => 'hello',\n"
-"\t'a' => 'world',\n"
-"];\n"
-"$feedback_good = 'All went well!';\n"
-"$feedback_bad = 'Oops, something went wrong.';\n"
-"\n"
-"Minz_Request::good($feedback_good, $url_array);\n"
-"\n"
-"// or\n"
-"\n"
-"Minz_Request::bad($feedback_bad, $url_array);\n"
-"\n"
-"?>\n"
+"An extension allows you to easily add functionality to FreshRSS without "
+"having to touch the core of the project directly."
msgstr ""
#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:207
-#, no-wrap
-msgid "Translation Management"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:210
-msgid ""
-"It is common (and that’s an understatement) to want to show some text to the "
-"user. In the previous example, for example, we display feedback to the user "
-"based on the result of form validation. The problem is that FreshRSS has "
-"users of different nationalities. It is therefore necessary to be able to "
-"manage different languages in order not to remain confined to English or "
-"French."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:212
-msgid ""
-"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:"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:220
-msgid "`admin.php` for anything related to FreshRSS administration"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:220
-msgid "`conf.php` for configuration"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:220
-msgid "`feedback.php` contains translations of feedback messages"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:220
-msgid "`gen.php` stores what is global to FreshRSS (gen for \"general\")"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:220
-msgid "`index.php` for the main page that lists feeds and the About page"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:220
-msgid "`install.php` contains strings related FreshRSS installation"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:220
-msgid "`sub.php` for subscription management (sub for \"subscription\")"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:222
-msgid "This organization makes it possible to avoid a single huge translation file."
+#: en/./developers/03_Backend/05_Extensions.md:35
+#, markdown-text, no-wrap
+msgid "Make it work in Docker"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:224
-msgid ""
-"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`:"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:225
-#, no-wrap
-msgid ""
-"<?php\n"
-"\n"
-"return array(\n"
-"\t'action' => [\n"
-"\t\t'actualize' => 'Actualiser',\n"
-"\t\t'back_to_rss_feeds' => '← Retour à vos flux RSS',\n"
-"\t\t'cancel' => 'Annuler',\n"
-"\t\t'create' => 'Créer',\n"
-"\t\t'disable' => 'Désactiver',\n"
-"\t),\n"
-"\t'freshrss' => array(\n"
-"\t\t'_' => 'FreshRSS',\n"
-"\t\t'about' => 'À propos de FreshRSS',\n"
-"\t),\n"
-"];\n"
-"\n"
-"?>\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:247
-msgid ""
-"To access these translations, `Minz_Translate` will help us with its "
-"`Minz_Translate::t()` method. As this can be a bit long to type, a shortcut "
-"has been introduced that **must** be used in all circumstances: `_t()`. "
-"Code example:"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:248
-#, no-wrap
-msgid ""
-"<p>\n"
-"\t<a href=\"<?= _url('index', 'index') ?>\">\n"
-"\t\t<?= _t('gen.action.back_to_rss_feeds') ?>\n"
-"\t</a>\n"
-"</p>\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:257
-msgid ""
-"The string to pass to the `_t()` function consists of a series of "
-"identifiers separated by dots. The first identifier indicates from which "
-"file to extract the translation (in this case, `gen.php`), while the "
-"following ones indicate table entries. Thus `action` is an entry of the main "
-"array and `back_to_rss_feeds` is an entry of the `action` array. This allows "
-"us to further organize our translation files."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:259
+#: en/./developers/03_Backend/05_Extensions.md:38
+#, markdown-text
msgid ""
-"There is a small special case that sometimes makes life easier: the `_` "
-"identifier. This must necessarily be present at the end of the chain and "
-"gives a value to the higher-level identifier. It’s pretty hard to explain "
-"but very simple to understand. In the example given above, a `_` is "
-"associated with the value `FreshRSS`: this means that there is no need to "
-"write `_t('gen.freshrss._')` but `_t('gen.freshrss')` suffices."
-msgstr ""
-
-#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:260
-#, no-wrap
-msgid "Configuration management"
+"When working on an extension, it’s easier to see it working directly in its "
+"environment. With Docker, you can leverage the use of the ```volume``` "
+"option when starting the container. Hopefully, you can use it without "
+"Docker-related knowledge by using the Makefile rule:"
msgstr ""
-#. type: Title ##
-#: en/./developers/03_Backend/05_Extensions.md:262
+#. type: Fenced code block (sh)
+#: en/./developers/03_Backend/05_Extensions.md:38
#, no-wrap
-msgid "Write an extension for FreshRSS"
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:265
-msgid ""
-"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."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:267
msgid ""
-"An extension allows you to easily add functionality to FreshRSS without "
-"having to touch the core of the project directly."
+"make start extensions=\"/full/path/to/extension/1 "
+"/full/path/to/extension/2\"\n"
msgstr ""
#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:268
-#, no-wrap
+#: en/./developers/03_Backend/05_Extensions.md:42
+#, markdown-text, no-wrap
msgid "Basic files and folders"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:273
+#: en/./developers/03_Backend/05_Extensions.md:47
+#, markdown-text
msgid ""
"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 "
@@ -1973,28 +1584,32 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:275
+#: en/./developers/03_Backend/05_Extensions.md:49
+#, markdown-text
msgid ""
"The main directory of an extension must contain at least two **mandatory** "
"files:"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:278
+#: en/./developers/03_Backend/05_Extensions.md:52
+#, markdown-text
msgid ""
"A `metadata.json` file that contains a description of the extension. This "
"file is written in JSON."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:278
+#: en/./developers/03_Backend/05_Extensions.md:52
+#, markdown-text
msgid ""
"An `extension.php` file containing the entry point of the extension (which "
"is a class that inherits Minz_Extension)."
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:282
+#: en/./developers/03_Backend/05_Extensions.md:56
+#, markdown-text
msgid ""
"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 "
@@ -2004,14 +1619,15 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:284
+#: en/./developers/03_Backend/05_Extensions.md:58
+#, markdown-text
msgid ""
"In the file `freshrss/extensions/xExtension-HelloWorld/extension.php` you "
"need the structure:"
msgstr ""
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:284
+#. type: Fenced code block (php)
+#: en/./developers/03_Backend/05_Extensions.md:58
#, no-wrap
msgid ""
"class HelloWorldExtension extends Minz_Extension {\n"
@@ -2022,28 +1638,32 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:292
+#: en/./developers/03_Backend/05_Extensions.md:67
+#, markdown-text
msgid ""
"There is an example HelloWorld extension that you can download from [our "
"GitHub repo](https://github.com/FreshRSS/xExtension-HelloWorld)."
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:294
+#: en/./developers/03_Backend/05_Extensions.md:69
+#, markdown-text
msgid ""
"You may also need additional files or subdirectories depending on your "
"needs:"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:300
+#: en/./developers/03_Backend/05_Extensions.md:75
+#, markdown-text
msgid ""
"`configure.phtml` is the file containing the form to parameterize your "
"extension"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:300
+#: en/./developers/03_Backend/05_Extensions.md:75
+#, markdown-text
msgid ""
"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 "
@@ -2051,38 +1671,43 @@ msgid ""
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:300
+#: en/./developers/03_Backend/05_Extensions.md:75
+#, markdown-text
msgid "A `Controllers` directory containing additional controllers"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:300
+#: en/./developers/03_Backend/05_Extensions.md:75
+#, markdown-text
msgid "An `i18n` directory containing additional translations"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:300
+#: en/./developers/03_Backend/05_Extensions.md:75
+#, markdown-text
msgid ""
-"`layout` and` views` directories to define new views or to overwrite the "
+"`layout` and `views` directories to define new views or to overwrite the "
"current views"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:302
+#: en/./developers/03_Backend/05_Extensions.md:77
+#, markdown-text
msgid ""
"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 "
+"under which your extension is distributed and a `README` file giving a "
"detailed description of it."
msgstr ""
#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:303
-#, no-wrap
+#: en/./developers/03_Backend/05_Extensions.md:78
+#, markdown-text, no-wrap
msgid "The metadata.json file"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:306
+#: en/./developers/03_Backend/05_Extensions.md:81
+#, markdown-text
msgid ""
"The `metadata.json` file defines your extension through a number of "
"important elements. It must contain a valid JSON array containing the "
@@ -2090,187 +1715,200 @@ msgid ""
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:313
+#: en/./developers/03_Backend/05_Extensions.md:89
+#, markdown-text
msgid "`name`: the name of your extension"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:313
+#: en/./developers/03_Backend/05_Extensions.md:89
+#, markdown-text
msgid ""
"`author`: your name, your e-mail address … but there is no specific format "
"to adopt"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:313
+#: en/./developers/03_Backend/05_Extensions.md:89
+#, markdown-text
msgid "`description`: a description of your extension"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:313
+#: en/./developers/03_Backend/05_Extensions.md:89
+#, markdown-text
msgid "`version`: the current version number of the extension"
msgstr ""
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:313
-msgid ""
-"`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`)"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:313
+#. type: Plain text
+#: en/./developers/03_Backend/05_Extensions.md:89
+#, markdown-text, no-wrap
msgid ""
-"`type`: Defines the type of your extension. There are two types: `system` "
-"and` user`. We will study this difference right after."
+"* `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`\n"
+"(so if the entry point is `HelloWorld`, your class will be called "
+"`HelloWorldExtension`)\n"
+"* `type`: Defines the type of your extension. There are two types: `system` "
+"and `user`. We will study this difference right after.\n"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:315
-msgid "Only the `name` and` entrypoint` fields are required."
+#: en/./developers/03_Backend/05_Extensions.md:91
+#, markdown-text
+msgid "Only the `name` and `entrypoint` fields are required."
msgstr ""
#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:316
-#, no-wrap
+#: en/./developers/03_Backend/05_Extensions.md:92
+#, markdown-text, no-wrap
msgid "Choosing between `system` and `user`"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:319
+#: en/./developers/03_Backend/05_Extensions.md:95
+#, markdown-text
msgid ""
-"A __user__ extension can be enabled by some users and not by others "
-"(typically for user preferences)."
+"A *user* extension can be enabled by some users and not by others (typically "
+"for user preferences)."
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:321
-msgid "A __system__ extension in comparison is enabled for every account."
+#: en/./developers/03_Backend/05_Extensions.md:97
+#, markdown-text
+msgid "A *system* extension in comparison is enabled for every account."
msgstr ""
#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:322
-#, no-wrap
+#: en/./developers/03_Backend/05_Extensions.md:98
+#, markdown-text, no-wrap
msgid "Writing your own extension.php"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:327
-msgid ""
-"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."
-msgstr ""
-
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:329
-msgid "Your class will benefit from four methods to redefine:"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:334
+#: en/./developers/03_Backend/05_Extensions.md:102
+#, markdown-text
msgid ""
-"`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."
+"This file is the core of your extension. It must define some key elements "
+"to be loaded by the extension system:"
msgstr ""
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:334
+#. type: Bullet: '1. '
+#: en/./developers/03_Backend/05_Extensions.md:106
+#, markdown-text
msgid ""
-"`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."
+"The class name must be the `entrypoint` value defined in the `metadata.json` "
+"file suffixed by `Extension` (if your `entrypoint` value is `HelloWorld`, "
+"your class name will be `HelloWorldExtension`)."
msgstr ""
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:334
+#. type: Bullet: '1. '
+#: en/./developers/03_Backend/05_Extensions.md:106
+#, markdown-text
msgid ""
-"`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."
+"The class must extend the `Minz_Extension` abstract class which defines the "
+"core methods and properties of a FreshRSS extension."
msgstr ""
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:334
+#. type: Bullet: '1. '
+#: en/./developers/03_Backend/05_Extensions.md:106
+#, markdown-text
msgid ""
-"`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."
+"The class must define the `init` method. This method is called **only** if "
+"the extension is loaded. Its purpose is to initialize the extension and its "
+"behavior during every page load."
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:336
+#: en/./developers/03_Backend/05_Extensions.md:111
+#, markdown-text
msgid ""
-"In addition, you will have a number of methods directly inherited from "
-"`Minz_Extension` that you should not redefine:"
+"The `Minz_Extension` abstract class defines a set of methods that can be "
+"overridden to fit your needs: * the `install` method is called when the user "
+"enables the extension in the configuration page. It must return `true` when "
+"successful and a string containing an error message when not. Its purpose is "
+"to prepare FreshRSS for the extension (adding a table to the database, "
+"creating a folder tree, …). * the `uninstall` method is called when the "
+"user disables the extension in the configuration page. It must return `true` "
+"when successful and a string containing an error message when not. Its "
+"purpose is to clean FreshRSS (removing a table from the database, deleting a "
+"folder tree, …). Usually it reverts changes introduced by the `install` "
+"method. * the `handleConfigureAction` method is called when a user loads "
+"the extension configuration panel. It contains the logic to validate and "
+"store the submitted values defined in the `configure.phtml` file."
msgstr ""
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:340
+#. type: Plain text
+#: en/./developers/03_Backend/05_Extensions.md:113
+#, markdown-text, no-wrap
msgid ""
-"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()`."
+"> If your extension code is scattered in different classes, you need to load "
+"their source before using them. Of course you could include the files "
+"manually, but it’s more efficient to load them automatically. To do so, you "
+"just need to define the `autoload` method which will include them when "
+"needed. This method will be registered automatically when the extension is "
+"enabled.\n"
msgstr ""
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:340
-msgid ""
-"`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`)."
+#. type: Plain text
+#: en/./developers/03_Backend/05_Extensions.md:127
+#, markdown-text, no-wrap
+msgid ""
+"The `Minz_Extension` abstract class defines another set of methods that "
+"should not be overridden:\n"
+"* the `getName`, `getEntrypoint`, `getPath`, `getAuthor`, `getDescription`, "
+"`getVersion`, and `getType` methods return the extension internal "
+"properties. Those properties are extracted from the `metadata.json` file.\n"
+"* the `getFileUrl` returns the URL of the selected file. The file must exist "
+"in the `static` folder of the extension.\n"
+"* the `registerController` method register an extension controller in "
+"FreshRSS. The selected controller must be defined in the extension "
+"*Controllers* folder, its file name must be `\\<name\\>Controller.php`, and "
+"its class name must be `FreshExtension_\\<name\\>_Controller`.\n"
+"* the `registerViews` method registers the extension views in FreshRSS.\n"
+"* the `registerTranslates` method registers the extension translation files "
+"in FreshRSS.\n"
+"* the `registerHook` method registers hook actions in different part of the "
+"application.\n"
+"* the `getSystemConfiguration` method retrieves the extension configuration "
+"for the system.\n"
+"* the `setSystemConfiguration` method stores the extension configuration for "
+"the system.\n"
+"* the `removeSystemConfiguration` method removes the extension configuration "
+"for the system.\n"
+"* the `getUserConfiguration` method retrieves the extension configuration "
+"for the current user.\n"
+"* the `setUserConfiguration` method stores the extension configuration for "
+"the current user.\n"
+"* the `removeUserConfiguration` method removes the extension configuration "
+"for the current user.\n"
msgstr ""
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:340
+#. type: Plain text
+#: en/./developers/03_Backend/05_Extensions.md:129
+#, markdown-text, no-wrap
msgid ""
-"`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."
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:346
-msgid "`registerViews()`"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:346
-msgid "`registerTranslates()`"
-msgstr ""
-
-#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:346
-msgid "`registerHook($hook_name, $hook_function)`"
+"> Note that if you modify the later set of methods, you might break the "
+"extension system. Thus making FreshRSS unusable. So it’s highly recommended "
+"to let those unmodified.\n"
msgstr ""
#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:347
-#, no-wrap
+#: en/./developers/03_Backend/05_Extensions.md:130
+#, markdown-text, no-wrap
msgid "The \"hooks\" system"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:350
+#: en/./developers/03_Backend/05_Extensions.md:133
+#, markdown-text
msgid ""
"You can register at the FreshRSS event system in an extensions `init()` "
"method, to manipulate data when some of the core functions are executed."
msgstr ""
-#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:351
+#. type: Fenced code block (html)
+#: en/./developers/03_Backend/05_Extensions.md:134
#, no-wrap
msgid ""
"class HelloWorldExtension extends Minz_Extension\n"
@@ -2287,21 +1925,24 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:365
+#: en/./developers/03_Backend/05_Extensions.md:148
+#, markdown-text
msgid "The following events are available:"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`check_url_before_add` (`function($url) -> Url | null`): will be executed "
"every time a URL is added. The URL itself will be passed as parameter. This "
-"way a website known to have feeds which does not advertise it in the header "
+"way a website known to have feeds which doesn’t advertise it in the header "
"can still be automatically supported."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`entry_before_display` (`function($entry) -> Entry | null`): will be "
"executed every time an entry is rendered. The entry itself (instance of "
@@ -2309,7 +1950,8 @@ msgid ""
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`entry_before_insert` (`function($entry) -> Entry | null`): will be executed "
"when a feed is refreshed and new entries will be imported into the "
@@ -2318,7 +1960,8 @@ msgid ""
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`feed_before_actualize` (`function($feed) -> Feed | null`): will be executed "
"when a feed is updated. The feed (instance of FreshRSS\\_Feed) will be "
@@ -2326,7 +1969,8 @@ msgid ""
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`feed_before_insert` (`function($feed) -> Feed | null`): will be executed "
"when a new feed is imported into the database. The new feed (instance of "
@@ -2334,65 +1978,98 @@ msgid ""
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`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"
+"additional access checks."
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
+msgid ""
+"`freshrss_user_maintenance` (`function() -> none`): will be executed for "
+"each user during the `actualize_script`, useful to run some maintenance "
+"tasks on the user."
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
+msgid ""
+"`js_vars` (`function($vars = array) -> array | null`): will be executed if "
+"the `jsonVars` in the header will be generated."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`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>`)"
+"class=\"item active\"><a href=\"url\">New entry</a></li>`)."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`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>`)"
+"(e.g. `<li class=\"item active\"><a href=\"url\">New entry</a></li>`)."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`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>`)"
+"entry</a></li>`)."
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
+msgid ""
+"`nav_menu` (`function() -> string`): will be executed if the navigation was "
+"built."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`nav_reading_modes` (`function($reading_modes) -> array | null`): **TODO** "
-"add documentation"
+"add documentation."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
-msgid "`post_update` (`function(none) -> none`): **TODO** add documentation"
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
+msgid "`post_update` (`function(none) -> none`): **TODO** add documentation."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/03_Backend/05_Extensions.md:378
+#: en/./developers/03_Backend/05_Extensions.md:164
+#, markdown-text
msgid ""
"`simplepie_before_init` (`function($simplePie, $feed) -> none`): **TODO** "
-"add documentation"
+"add documentation."
msgstr ""
#. type: Title ###
-#: en/./developers/03_Backend/05_Extensions.md:379
-#, no-wrap
+#: en/./developers/03_Backend/05_Extensions.md:165
+#, markdown-text, no-wrap
msgid "Writing your own configure.phtml"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Backend/05_Extensions.md:382
+#: en/./developers/03_Backend/05_Extensions.md:168
+#, markdown-text
msgid ""
"When you want to support user configurations for your extension or simply "
"display some information, you have to create the `configure.phtml` file."
@@ -2400,12 +2077,13 @@ msgstr ""
#. type: Title #
#: en/./developers/03_Running_tests.md:1
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Running tests"
msgstr ""
#. type: Plain text
#: en/./developers/03_Running_tests.md:4
+#, markdown-text
msgid ""
"FreshRSS is tested with [PHPUnit](https://phpunit.de/). No code should be "
"merged in `edge` if the tests don’t pass."
@@ -2413,25 +2091,27 @@ msgstr ""
#. type: Title ##
#: en/./developers/03_Running_tests.md:5
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Locally"
msgstr ""
#. type: Plain text
#: en/./developers/03_Running_tests.md:8
+#, markdown-text
msgid ""
"As a developer, you can run the test suite on your PC easily with `make` "
"commands. You can run the test suite with:"
msgstr ""
-#. type: Plain text
+#. type: Fenced code block (sh)
#: en/./developers/03_Running_tests.md:9
#, no-wrap
-msgid "$ make test\n"
+msgid "make test\n"
msgstr ""
#. type: Plain text
#: en/./developers/03_Running_tests.md:14
+#, markdown-text
msgid ""
"This command downloads the PHPUnit binary and verifies its checksum. If the "
"verification fails, the file is deleted. In this case, you should [open an "
@@ -2441,83 +2121,309 @@ msgstr ""
#. type: Plain text
#: en/./developers/03_Running_tests.md:16
+#, markdown-text
msgid ""
"Then, it executes PHPUnit in a Docker container. If you don’t use Docker, "
"you can run the command directly with:"
msgstr ""
-#. type: Plain text
+#. type: Fenced code block (sh)
#: en/./developers/03_Running_tests.md:17
#, no-wrap
-msgid "$ NO_DOCKER=true make test\n"
+msgid "NO_DOCKER=true make test\n"
msgstr ""
-#. type: Title ##
-#: en/./developers/03_Running_tests.md:21
+#. type: Plain text
+#: en/./developers/03_Running_tests.md:22
+#, markdown-text
+msgid "The linter can be run with a `make` command as well:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/03_Running_tests.md:23
#, no-wrap
-msgid "Travis"
+msgid ""
+"make lint # to execute the linter on the PHP files\n"
+"make lint-fix # or, to fix the errors detected by the linter\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/03_Running_tests.md:29
+#, markdown-text
+msgid ""
+"Similarly to PHPUnit, it downloads a "
+"[PHP\\_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) binary "
+"(i.e. `phpcs` or `phpcbf` depending on the command) and verifies its "
+"checksum."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/03_Running_tests.md:30
+#, markdown-text, no-wrap
+msgid "GitHub Actions for Continuous Integration"
msgstr ""
#. type: Plain text
-#: en/./developers/03_Running_tests.md:24
+#: en/./developers/03_Running_tests.md:35
+#, markdown-text
msgid ""
-"Tests are automatically run when you open a pull request on GitHub. It is "
-"done with [Travis CI](https://travis-ci.org/FreshRSS/FreshRSS/). This is "
-"done to ensure there is no regressions in your code. We cannot merge a PR if "
-"the tests fail so we will ask you to fix bugs before to review your code."
+"Tests are automatically run when you open a pull request on GitHub. They "
+"are performed with [GitHub "
+"Actions](https://github.com/FreshRSS/FreshRSS/actions). This ensures your "
+"code will not introduce some kind of regression. We will not merge a PR if "
+"tests fail so we will ask you to fix any bugs before reviewing your code."
msgstr ""
#. type: Plain text
-#: en/./developers/03_Running_tests.md:25
+#: en/./developers/03_Running_tests.md:37
+#, markdown-text
msgid ""
-"If you’re interested in, you can take a look at [the configuration "
-"file](https://github.com/FreshRSS/FreshRSS/blob/edge/.travis.yml)."
+"If you are interested, you can take a look at [the configuration "
+"file](https://github.com/FreshRSS/FreshRSS/blob/edge/.github/workflows/tests.yml)."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/03_Running_tests.md:38
+#, markdown-text, no-wrap
+msgid "Using feed snapshots"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/03_Running_tests.md:42
+#, markdown-text
+msgid ""
+"As feed data is volatile, it’s better to work with snapshots when debugging "
+"some issues. You can find the description to retrieve a snapshot "
+"[here](06_Reporting_Bugs.md#how-to-provide-feed-data)."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/03_Running_tests.md:46
+#, markdown-text
+msgid ""
+"To serve those snapshots, you can use a mock server. Here we will "
+"demonstrate how to work with [WireMock](https://wiremock.org/) but other "
+"solutions exist. Here are the steps to start using the WireMock mock "
+"server:"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/03_Running_tests.md:76
+#, markdown-text, no-wrap
+msgid ""
+"1. Go to the mock server home folder.\n"
+"If you do not have one, you need to create one.\n"
+"1. Inside the mock server home folder, create the ___file_ and _mappings_ "
+"folders.\n"
+"1. Copy or move your snapshots in the ___file_ folder.\n"
+"1. Create the _feed.json_ file in the _mappings_ folder with the following "
+"content:\n"
+"\t```js\n"
+"\t{\n"
+"\t\t\"request\": {\n"
+"\t\t\t\"method\": \"GET\",\n"
+"\t\t\t\"urlPathPattern\": \"/.*\"\n"
+"\t\t},\n"
+"\t\t\"response\": {\n"
+"\t\t\t\"status\": 200,\n"
+"\t\t\t\"bodyFileName\": \"{{request.pathSegments.[0]}}\",\n"
+"\t\t\t\"transformers\": [\"response-template\"],\n"
+"\t\t\t\"headers\": {\n"
+"\t\t\t\t\"Content-Type\": \"application/rss+xml\"\n"
+"\t\t\t}\n"
+"\t\t}\n"
+"\t}\n"
+"\t```\n"
+"1. Launch the containerized server with the following command:\n"
+"\t```bash\n"
+"\t# <PORT> is the port used on the host to communicate with the server\n"
+"\t# <NETWORK> is the name of the docker network used (by default, it’s "
+"freshrss-network)\n"
+"\tdocker run -it --rm -p <PORT>:8080 --name wiremock --network <NETWORK> -v "
+"$PWD:/home/wiremock wiremock/wiremock:latest-alpine "
+"--local-response-templating\n"
+"\t```\n"
+"1. You can access the `<RSS>` mock file directly:\n"
+" * from the host by sending a GET request to "
+"`http://localhost:<PORT>/<RSS>`,\n"
+" * from any container connected on the same network by sending a GET "
+"request to `http://wiremock:8080/<RSS>`.\n"
msgstr ""
#. type: Title #
#: en/./developers/04_Frontend/01_View_files.md:1
-#, no-wrap
+#, markdown-text, no-wrap
+msgid "View files"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/04_Frontend/01_View_files.md:3
+#, markdown-text, no-wrap
msgid "The .phtml files"
msgstr ""
-#. type: Title #
-#: en/./developers/04_Frontend/01_View_files.md:5
-#, no-wrap
+#. type: Title ##
+#: en/./developers/04_Frontend/01_View_files.md:7
+#, markdown-text, no-wrap
msgid "Writing a URL"
msgstr ""
-#. type: Title #
-#: en/./developers/04_Frontend/01_View_files.md:9
-#, no-wrap
+#. type: Title ##
+#: en/./developers/04_Frontend/01_View_files.md:11
+#, markdown-text, no-wrap
msgid "Displaying an icon"
msgstr ""
+#. type: Title ##
+#: en/./developers/04_Frontend/01_View_files.md:15
+#, markdown-text, no-wrap
+msgid "Internationalisation"
+msgstr ""
+
#. type: Title #
#: en/./developers/04_Frontend/02_Design.md:1
-#, no-wrap
+#, markdown-text, no-wrap
+msgid "Writing a new theme"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:4
+#, markdown-text, no-wrap
+msgid ""
+"**Note: Currently personal themes are not officially supported and may be "
+"overwritten when updating. Be sure to keep backups!**\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:6
+#, markdown-text, no-wrap
+msgid ""
+"**As of writing (02-02-2021), support for themes as extensions is under "
+"development.**\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:8
+#, markdown-text
+msgid ""
+"The easiest way to create a theme is by copying and modifying the base theme "
+"(or another of the pre-installed themes). The base theme can be found in "
+"[/p/themes/base-theme](https://github.com/FreshRSS/FreshRSS/tree/edge/p/themes/base-theme). "
+"Themes require:"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/04_Frontend/02_Design.md:13
+#, markdown-text
+msgid "a **metadata.json** file to describe the theme."
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/04_Frontend/02_Design.md:13
+#, markdown-text
+msgid ""
+"a **loader.gif** file to use as a loading icon (assuming .loading’s "
+"background has not been overridden)"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/04_Frontend/02_Design.md:13
+#, markdown-text
+msgid ""
+"an **icons** folder containing .svg, .ico, and .png files to override "
+"existing icons"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./developers/04_Frontend/02_Design.md:13
+#, markdown-text
+msgid ""
+"a **thumbs** folder containing a file, **original.png** that will be used as "
+"the preview for the theme"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:15
+#, markdown-text
+msgid ""
+"\"_frss.css\" is normally added to the metadata file as a fallback for "
+"missing aspects. The file is taken from the base theme. If submitting a pull "
+"request for a theme, please know that [pull request themes must include this "
+"file.](https://github.com/FreshRSS/FreshRSS/pull/2938#issuecomment-624085450)"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/04_Frontend/02_Design.md:16
+#, markdown-text, no-wrap
+msgid "RTL Support"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:19
+#, markdown-text
+msgid ""
+"RTL (right-to-left) support for languages such as Hebrew and Arabic is "
+"handled through CSSJanus. To generate an RTL CSS file from your standard "
+"file, use `make rtl`. Be sure to commit the resulting file "
+"(filename.rtl.css)."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/04_Frontend/02_Design.md:20
+#, markdown-text, no-wrap
+msgid "Overriding icons"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:23
+#, markdown-text
+msgid ""
+"To replace the default icons, add an \"icons\" folder to your theme’s "
+"folder. Use files with the same name as the default icon to override them."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/04_Frontend/02_Design.md:24
+#, markdown-text, no-wrap
msgid "Template file"
msgstr ""
-#. type: Title #
-#: en/./developers/04_Frontend/02_Design.md:5
-#, no-wrap
-msgid "Writing a new theme"
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:27
+#, markdown-text
+msgid "`metadata.json`"
msgstr ""
-#. type: Title #
-#: en/./developers/04_Frontend/02_Design.md:9
+#. type: Fenced code block (json)
+#: en/./developers/04_Frontend/02_Design.md:28
#, no-wrap
-msgid "Overriding icons"
+msgid ""
+"{\n"
+"\t\"name\": \"Theme name\",\n"
+"\t\"author\": \"Theme author\",\n"
+"\t\"description\": \"Theme description\",\n"
+"\t\"version\": 0.1,\n"
+"\t\"files\": [\"_frss.css\", \"file1.css\", \"file2.css\"]\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Frontend/02_Design.md:38
+#, markdown-text
+msgid ""
+"An example of a css theme file can be found at "
+"[/p/themes/base-theme/base.css](https://github.com/FreshRSS/FreshRSS/blob/edge/p/themes/base-theme/base.css)"
msgstr ""
#. type: Title #
#: en/./developers/04_Pull_requests.md:1
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Opening a pull request"
msgstr ""
#. type: Plain text
#: en/./developers/04_Pull_requests.md:4
+#, markdown-text
msgid ""
"So you want to propose a patch to the community? It’s time to open a [pull "
"request](https://github.com/FreshRSS/FreshRSS/pulls)!"
@@ -2525,6 +2431,7 @@ msgstr ""
#. type: Plain text
#: en/./developers/04_Pull_requests.md:6
+#, markdown-text
msgid ""
"When you open a PR, your message will be prefilled with a message based on "
"[a "
@@ -2536,17 +2443,28 @@ msgstr ""
#. type: Plain text
#: en/./developers/04_Pull_requests.md:8
+#, markdown-text
msgid "The rest of this document explains specific points."
msgstr ""
#. type: Title ##
#: en/./developers/04_Pull_requests.md:9
-#, no-wrap
+#, markdown-text, no-wrap
msgid "How to rebase your branch on `edge`"
msgstr ""
#. type: Plain text
#: en/./developers/04_Pull_requests.md:12
+#, markdown-text, no-wrap
+msgid ""
+"**TODO:** Update this section. With GitHub’s *squash and merge*, rebasing "
+"(and other forms of history rewriting) is more dangerous and annoying "
+"(e.g. breaking review mechanism) than useful.\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/04_Pull_requests.md:14
+#, markdown-text
msgid ""
"Rebasing a branch is useful to make sure your code is based on the most "
"recent version of FreshRSS and there are no conflicts. You have two ways to "
@@ -2554,20 +2472,22 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:14
+#: en/./developers/04_Pull_requests.md:16
+#, markdown-text
msgid ""
"If you have any doubt, please let us know and we’ll help you! We all began "
"with Git one day and it’s not an easy thing to work with."
msgstr ""
#. type: Title ###
-#: en/./developers/04_Pull_requests.md:15
-#, no-wrap
+#: en/./developers/04_Pull_requests.md:17
+#, markdown-text, no-wrap
msgid "Rebasing"
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:18
+#: en/./developers/04_Pull_requests.md:20
+#, markdown-text
msgid ""
"Rebasing is the cleanest method because the Git history will be completely "
"linear and consequently easier to read and navigate. It might also be more "
@@ -2576,7 +2496,8 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:20
+#: en/./developers/04_Pull_requests.md:22
+#, markdown-text
msgid ""
"Note that you should never rebase a branch if someone else is working on "
"it. Otherwise, since it rewrites the history, it can be a real mess to sort "
@@ -2584,35 +2505,38 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:22
+#: en/./developers/04_Pull_requests.md:24
+#, markdown-text
msgid "To rebase a branch:"
msgstr ""
-#. type: Plain text
-#: en/./developers/04_Pull_requests.md:23
+#. type: Fenced code block (sh)
+#: en/./developers/04_Pull_requests.md:25
#, no-wrap
msgid ""
-"$ git checkout edge # go on edge branch\n"
-"$ git pull upstream edge # pull the last version of edge\n"
-"$ git checkout - # go back to your branch\n"
-"$ git rebase edge # rebase your branch on edge\n"
+"git checkout edge # go on edge branch\n"
+"git pull upstream edge # pull the last version of edge\n"
+"git checkout - # go back to your branch\n"
+"git rebase edge # rebase your branch on edge\n"
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:31
+#: en/./developers/04_Pull_requests.md:33
+#, markdown-text
msgid ""
"If you feel confident, you can use `git rebase -i edge` to rewrite your "
"history and make it clearer."
msgstr ""
#. type: Title ###
-#: en/./developers/04_Pull_requests.md:32
-#, no-wrap
+#: en/./developers/04_Pull_requests.md:34
+#, markdown-text, no-wrap
msgid "Merging"
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:35
+#: en/./developers/04_Pull_requests.md:37
+#, markdown-text
msgid ""
"If you prefer, you can simply merge `edge` into your own branch. Conflicts "
"might be easier to resolve, but your Git history will be less "
@@ -2621,28 +2545,30 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:37
+#: en/./developers/04_Pull_requests.md:39
+#, markdown-text
msgid "To merge `edge`:"
msgstr ""
-#. type: Plain text
-#: en/./developers/04_Pull_requests.md:38
+#. type: Fenced code block (sh)
+#: en/./developers/04_Pull_requests.md:40
#, no-wrap
msgid ""
-"$ git checkout edge # go on edge branch\n"
-"$ git pull upstream edge # pull the last version of edge\n"
-"$ git checkout - # go back to your branch\n"
-"$ git merge edge # merge edge into your branch\n"
+"git checkout edge # go on edge branch\n"
+"git pull upstream edge # pull the last version of edge\n"
+"git checkout - # go back to your branch\n"
+"git merge edge # merge edge into your branch\n"
msgstr ""
#. type: Title ##
-#: en/./developers/04_Pull_requests.md:45
-#, no-wrap
+#: en/./developers/04_Pull_requests.md:47
+#, markdown-text, no-wrap
msgid "How to write a Git commit message"
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:48
+#: en/./developers/04_Pull_requests.md:50
+#, markdown-text
msgid ""
"It’s important to have proper commit messages in order to facilitate later "
"debugging, so please read the following advice. Commit messages should "
@@ -2650,22 +2576,25 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:50
+#: en/./developers/04_Pull_requests.md:52
+#, markdown-text
msgid ""
-"The first line should start with a verb (e.g., \"Add\") and explain the "
+"The first line should start with a verb (e.g., “Add”) and explain the "
"objective of the commit in few words. It’s usually less than 50 characters "
"so it remains concise. You can consider this line the subject of your "
"commit. Think of it as the second part of a sentence that starts with the "
-"words \"This commit will.\""
+"words “This commit will.”"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/04_Pull_requests.md:52
+#: en/./developers/04_Pull_requests.md:54
+#, markdown-text
msgid "This commit will *add feature X*"
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:54
+#: en/./developers/04_Pull_requests.md:56
+#, markdown-text
msgid ""
"Then, insert a blank line, and start to write the body. It’s usually wrapped "
"at 72 characters, but you are pretty free in the tone of the message. The "
@@ -2677,27 +2606,30 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:56
+#: en/./developers/04_Pull_requests.md:58
+#, markdown-text
msgid ""
"You also can add references (e.g., the URL to the initial ticket in the bug "
"tracker, or a reference to some forum explaining a point)."
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:58
+#: en/./developers/04_Pull_requests.md:60
+#, markdown-text
msgid ""
"You can find more information about commit messages [on this blog "
"post](https://chris.beams.io/posts/git-commit/)."
msgstr ""
#. type: Title ##
-#: en/./developers/04_Pull_requests.md:59
-#, no-wrap
+#: en/./developers/04_Pull_requests.md:61
+#, markdown-text, no-wrap
msgid "How to write tests"
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:62
+#: en/./developers/04_Pull_requests.md:64
+#, markdown-text
msgid ""
"FreshRSS has few tests for now, but we’re working on it. We added this point "
"to the checklist to help us to write more tests, and we would really "
@@ -2705,34 +2637,38 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:64
+#: en/./developers/04_Pull_requests.md:66
+#, markdown-text
msgid ""
"We use [PHPUnit](https://phpunit.de/) version 7.5 "
"([documentation](https://phpunit.readthedocs.io/en/7.5/))."
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:66
+#: en/./developers/04_Pull_requests.md:68
+#, markdown-text
msgid ""
"You’ll find more information on how to run tests [in this "
"document](03_Running_tests.md)."
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:68
+#: en/./developers/04_Pull_requests.md:70
+#, markdown-text
msgid ""
"Feel free to ask us for assistance. Not everything will be easy to test, so "
"don’t spend too much time on this."
msgstr ""
#. type: Title ##
-#: en/./developers/04_Pull_requests.md:69
-#, no-wrap
+#: en/./developers/04_Pull_requests.md:71
+#, markdown-text, no-wrap
msgid "Why you should write documentation"
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:72
+#: en/./developers/04_Pull_requests.md:74
+#, markdown-text
msgid ""
"A friendly project should have correct and complete documentation, so "
"newcomers don’t have to ask too many questions, and users can find answers "
@@ -2741,7 +2677,8 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/04_Pull_requests.md:73
+#: en/./developers/04_Pull_requests.md:75
+#, markdown-text
msgid ""
"Our documentation can still be improved quite a bit, so you’re very welcome "
"if you want to help."
@@ -2749,33 +2686,35 @@ msgstr ""
#. type: Title #
#: en/./developers/05_Release_new_version.md:1
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Preparing the release"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:4
+#: en/./developers/05_Release_new_version.md:5
+#, markdown-text
msgid ""
"In order to get as much feedback as possible before a release, it’s "
"preferable to announce it on GitHub by creating a dedicated ticket ([see "
-"examples] "
-"(https://github.com/FreshRSS/FreshRSS/search?utf8=%E2%9C%93&q=Call+for+testing&type=Issues)). "
+"examples](https://github.com/FreshRSS/FreshRSS/search?utf8=%E2%9C%93&q=Call+for+testing&type=Issues)). "
"This should be done **at least one week in advance**."
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:6
+#: en/./developers/05_Release_new_version.md:7
+#, markdown-text
msgid "It’s also recommended to make the announcement on mailing@freshrss.org."
msgstr ""
-#. type: Title #
-#: en/./developers/05_Release_new_version.md:7
-#, no-wrap
+#. type: Title ##
+#: en/./developers/05_Release_new_version.md:8
+#, markdown-text, no-wrap
msgid "Check the dev status"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:10
+#: en/./developers/05_Release_new_version.md:11
+#, markdown-text
msgid ""
"Before releasing a new version of FreshRSS, you must ensure that the code is "
"stable and free of major bugs. Ideally, our tests should be automated and "
@@ -2783,20 +2722,21 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:12
+#: en/./developers/05_Release_new_version.md:13
+#, markdown-text
msgid ""
"You must also **make sure that the CHANGELOG file is up to date** with the "
"updates of the version to be released."
msgstr ""
-#. type: Title #
-#: en/./developers/05_Release_new_version.md:13
-#, no-wrap
+#. type: Title ##
+#: en/./developers/05_Release_new_version.md:14
+#, markdown-text, no-wrap
msgid "Git process"
msgstr ""
-#. type: Plain text
-#: en/./developers/05_Release_new_version.md:15
+#. type: Fenced code block (console)
+#: en/./developers/05_Release_new_version.md:16
#, no-wrap
msgid ""
"$ git checkout edge\n"
@@ -2810,45 +2750,48 @@ msgid ""
"$ git push && git push --tags\n"
msgstr ""
-#. type: Title #
-#: en/./developers/05_Release_new_version.md:27
-#, no-wrap
+#. type: Title ##
+#: en/./developers/05_Release_new_version.md:28
+#, markdown-text, no-wrap
msgid "Updating `update.freshrss.org`"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:30
+#: en/./developers/05_Release_new_version.md:31
+#, markdown-text
msgid ""
"It’s important to update update.freshrss.org since this is the default "
"service for automatic FreshRSS updates."
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:32
+#: en/./developers/05_Release_new_version.md:33
+#, markdown-text
msgid ""
"The repository managing the code is located on GitHub: "
-"[FreshRSS/update.freshrss.org] "
-"(https://github.com/FreshRSS/update.freshrss.org/)."
+"[FreshRSS/update.freshrss.org](https://github.com/FreshRSS/update.freshrss.org/)."
msgstr ""
#. type: Title ##
-#: en/./developers/05_Release_new_version.md:33
-#, no-wrap
+#: en/./developers/05_Release_new_version.md:34
+#, markdown-text, no-wrap
msgid "Writing the update script"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:36
+#: en/./developers/05_Release_new_version.md:37
+#, markdown-text
msgid ""
"The scripts are located in the `./scripts/` directory and must take the form "
"`update_to_x.y.z.z.php`. This directory also contains `update_to_dev.php` "
-"intended for updates of the `edge` branch (this script must not include "
-"code specific to a particular version!) and `update_util.php`, which "
-"contains a list of functions useful for all scripts."
+"intended for updates of the `edge` branch (this script must not include code "
+"specific to a particular version!) and `update_util.php`, which contains a "
+"list of functions useful for all scripts."
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:38
+#: en/./developers/05_Release_new_version.md:39
+#, markdown-text
msgid ""
"In order to write a new script, it’s better to copy/paste the last version "
"or to start from `update_to_dev.php`. The first thing to do is to define the "
@@ -2858,12 +2801,14 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:40
+#: en/./developers/05_Release_new_version.md:41
+#, markdown-text
msgid "There are then 5 functions that have to be executed:"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:46
+#: en/./developers/05_Release_new_version.md:47
+#, markdown-text
msgid ""
"`apply_update()` takes care of saving the directory containing the data, "
"checking its structure, downloading the FreshRSS package, deploying it and "
@@ -2873,28 +2818,32 @@ msgid ""
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:46
+#: en/./developers/05_Release_new_version.md:47
+#, markdown-text
msgid ""
"`need_info_update()` returns `true` if the user must intervene during the "
"update or `false` if not;"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:46
+#: en/./developers/05_Release_new_version.md:47
+#, markdown-text
msgid ""
"`ask_info_update()` displays a form to the user if `need_info_update()` has "
"returned `true`;"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:46
+#: en/./developers/05_Release_new_version.md:47
+#, markdown-text
msgid ""
"`save_info_update()` is responsible for saving the information filled out by "
"the user (from the `ask_info_update()` form);"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:46
+#: en/./developers/05_Release_new_version.md:47
+#, markdown-text
msgid ""
"`do_post_update()` is executed at the end of the update and takes into "
"account the code of the new version (e.g., if the new version changes the "
@@ -2902,13 +2851,14 @@ msgid ""
msgstr ""
#. type: Title ##
-#: en/./developers/05_Release_new_version.md:47
-#, no-wrap
+#: en/./developers/05_Release_new_version.md:48
+#, markdown-text, no-wrap
msgid "Updating the versions file"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:50
+#: en/./developers/05_Release_new_version.md:51
+#, markdown-text
msgid ""
"Once the script has been written and versioned, it’s necessary to update the "
"`./versions.php' file which contains a mapping table indicating which "
@@ -2916,12 +2866,13 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:52
+#: en/./developers/05_Release_new_version.md:53
+#, markdown-text
msgid "Here’s an example of a `versions.php` file:"
msgstr ""
-#. type: Plain text
-#: en/./developers/05_Release_new_version.md:53
+#. type: Fenced code block (php)
+#: en/./developers/05_Release_new_version.md:54
#, no-wrap
msgid ""
"<?php\n"
@@ -2929,7 +2880,7 @@ msgid ""
"\t// STABLE\n"
"\t'0.8.0' => '1.0.0',\n"
"\t'0.8.1' => '1.0.0',\n"
-"\t'1.0.0' => '1.0.1', // does not exist (yet)\n"
+"\t'1.0.0' => '1.0.1', // doesn’t exist (yet)\n"
"\t// DEV\n"
"\t'1.1.2-dev' => 'dev',\n"
"\t'1.1.3-dev' => 'dev',\n"
@@ -2938,34 +2889,40 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:68
+#: en/./developers/05_Release_new_version.md:69
+#, markdown-text
msgid "And here’s how this table works:"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:74
+#: en/./developers/05_Release_new_version.md:75
+#, markdown-text
msgid "on the left you can find the N version, on the right the N+1 version;"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:74
+#: en/./developers/05_Release_new_version.md:75
+#, markdown-text
msgid "the `x.y.z.z-dev` versions are **all** updated to `edge`;"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:74
+#: en/./developers/05_Release_new_version.md:75
+#, markdown-text
msgid "stable versions are updated to stable versions;"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:74
+#: en/./developers/05_Release_new_version.md:75
+#, markdown-text
msgid ""
"it’s possible to skip several versions at once, provided that the update "
"scripts support it;"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:74
+#: en/./developers/05_Release_new_version.md:75
+#, markdown-text
msgid ""
"it’s advisable to indicate the correspondence of the current version to its "
"potential future version by specifying that this version does not yet "
@@ -2974,20 +2931,22 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:76
+#: en/./developers/05_Release_new_version.md:77
+#, markdown-text
msgid ""
-"It’s **very strongly** recommended to keep this file organized according to "
+"It’s**very strongly** recommended to keep this file organized according to "
"version numbers by separating stable and dev versions."
msgstr ""
#. type: Title ##
-#: en/./developers/05_Release_new_version.md:77
-#, no-wrap
+#: en/./developers/05_Release_new_version.md:78
+#, markdown-text, no-wrap
msgid "Deployment"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:80
+#: en/./developers/05_Release_new_version.md:81
+#, markdown-text
msgid ""
"Before updating update.freshrss.org, it’s better to test with "
"dev.update.freshrss.org, which corresponds to pre-production. So update "
@@ -2996,76 +2955,85 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:82
+#: en/./developers/05_Release_new_version.md:83
+#, markdown-text
msgid ""
"When you’re satisfied, update update.freshrss.org with the new script, test "
"it again, and then move on."
msgstr ""
-#. type: Title #
-#: en/./developers/05_Release_new_version.md:83
-#, no-wrap
+#. type: Title ##
+#: en/./developers/05_Release_new_version.md:84
+#, markdown-text, no-wrap
msgid "Updating the FreshRSS services"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:86
+#: en/./developers/05_Release_new_version.md:87
+#, markdown-text
msgid "Two services need to be updated immediately after the update."
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:89
+#: en/./developers/05_Release_new_version.md:90
+#, markdown-text
msgid "rss.freshrss.org;"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:89
+#: en/./developers/05_Release_new_version.md:90
+#, markdown-text
msgid "demo.freshrss.org (public login: `demo` / `demodemo`)."
msgstr ""
-#. type: Title #
-#: en/./developers/05_Release_new_version.md:90
-#, no-wrap
+#. type: Title ##
+#: en/./developers/05_Release_new_version.md:91
+#, markdown-text, no-wrap
msgid "Publicly announce the release"
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:93
+#: en/./developers/05_Release_new_version.md:94
+#, markdown-text
msgid "When everything’s working, it’s time to announce the release to the world!"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:98
+#: en/./developers/05_Release_new_version.md:99
+#, markdown-text
msgid ""
"on GitHub by creating[a new "
"release](https://github.com/FreshRSS/FreshRSS/releases/new)"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:98
+#: en/./developers/05_Release_new_version.md:99
+#, markdown-text
msgid ""
"on the freshrss.org blog, at least for stable versions (write the article "
"on[FreshRSS/freshrss.org](https://github.com/FreshRSS/freshrss.org))"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:98
+#: en/./developers/05_Release_new_version.md:99
+#, markdown-text
msgid "on Twitter ([@FreshRSS](https://twitter.com/FreshRSS) account)"
msgstr ""
#. type: Bullet: '* '
-#: en/./developers/05_Release_new_version.md:98
+#: en/./developers/05_Release_new_version.md:99
+#, markdown-text
msgid "and on mailing@freshrss.org"
msgstr ""
-#. type: Title #
-#: en/./developers/05_Release_new_version.md:99
-#, no-wrap
+#. type: Title ##
+#: en/./developers/05_Release_new_version.md:100
+#, markdown-text, no-wrap
msgid "Starting the next development version"
msgstr ""
-#. type: Plain text
-#: en/./developers/05_Release_new_version.md:101
+#. type: Fenced code block (console)
+#: en/./developers/05_Release_new_version.md:102
#, no-wrap
msgid ""
"$ git checkout edge\n"
@@ -3077,1337 +3045,2947 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./developers/05_Release_new_version.md:110
+#: en/./developers/05_Release_new_version.md:111
+#, markdown-text
msgid ""
"Also remember to update update.freshrss.org so that it takes the current "
"development version into account."
msgstr ""
+#. type: Title #
+#: en/./developers/06_Fever_API.md:1
+#, markdown-text, no-wrap
+msgid "FreshRSS - Fever API implementation"
+msgstr ""
+
#. type: Plain text
-#: en/./index.md:2
-msgid "![FreshRSS logo](img/logo_freshrss.png)"
+#: en/./developers/06_Fever_API.md:5
+#, markdown-text
+msgid ""
+"See [Mobile access](../users/06_Mobile_access.md) for general aspects of API "
+"access. Additionally [page about our Google Reader compatible "
+"API](06_GoogleReader_API.md) for another possibility."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Fever_API.md:7 en/./developers/06_GoogleReader_API.md:7
+#, markdown-text, no-wrap
+msgid "RSS clients"
msgstr ""
#. type: Plain text
-#: en/./index.md:4
+#: en/./developers/06_Fever_API.md:12
+#, markdown-text
msgid ""
-"FreshRSS is an RSS aggregator and reader. It allows you to read and follow "
-"several news websites at a glance without the need to browse from one "
-"website to another."
+"There are many RSS clients that support the Fever API, but they seem to "
+"understand the Fever API a bit differently. If your favourite client "
+"doesn’t work properly with this API, please create an issue and we’ll have a "
+"look. But we can **only** do that for free clients."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Fever_API.md:13 en/./developers/06_GoogleReader_API.md:13
+#, markdown-text, no-wrap
+msgid "Usage & Authentication"
msgstr ""
#. type: Plain text
-#: en/./index.md:6
-msgid "FreshRSS has a lot of features including:"
+#: en/./developers/06_Fever_API.md:17 en/./developers/06_GoogleReader_API.md:17
+#, markdown-text
+msgid ""
+"Before you can start using this API, you have to enable and setup API "
+"access, which is [documented here](../users/06_Mobile_access.md), and then "
+"reset the user’s API password."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:19
+#, markdown-text
+msgid ""
+"Then point your mobile application to the `fever.php` address "
+"(e.g. `https://freshrss.example.net/api/fever.php`)."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Fever_API.md:20 en/./developers/06_GoogleReader_API.md:20
+#, markdown-text, no-wrap
+msgid "Compatible clients"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:31
+#, markdown-text, no-wrap
+msgid ""
+"| App "
+"| Platform | License "
+"|\n"
+"|:----------------------------------------------------------------------------------:|:-------------------:|:--------------------------------------------------------:|\n"
+"|[Fluent Reader](https://hyliu.me/fluent-reader/) "
+"|Windows, Linux, "
+"macOS|[BSD-3-Clause](https://github.com/yang991178/fluent-reader/blob/master/LICENSE)|\n"
+"|[Fluent Reader lite](https://hyliu.me/fluent-reader-lite/) "
+"|Android, iOS "
+"|[BSD-3-Clause](https://github.com/yang991178/fluent-reader-lite)|\n"
+"|[Fiery "
+"Feeds](https://apps.apple.com/app/fiery-feeds-rss-reader/id1158763303) "
+"|iOS |Closed Source "
+"|\n"
+"|[Newsflash](https://gitlab.com/news-flash/news_flash_gtk/) "
+"|Linux "
+"|[GPLv3](https://gitlab.com/news-flash/news_flash_gtk/)|\n"
+"|[Unread](https://apps.apple.com/app/unread-rss-reader/id1252376153) "
+"|iOS |Closed Source "
+"|\n"
+"|[Reeder](https://www.reederapp.com/) "
+"|iOS |Closed Source "
+"|\n"
+"|[ReadKit](https://apps.apple.com/app/readkit/id588726889) "
+"|macOS |Closed Source "
+"|\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Fever_API.md:32 en/./index.md:7
+#, markdown-text, no-wrap
+msgid "Features"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:35
+#, markdown-text
+msgid "The following features are implemented:"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "RSS and Atom aggregation"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "fetching categories"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "Mark article as favorite if you liked it or if you want to read it later"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "fetching feeds"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "Filter and search functionality helps to easily find articles"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid ""
+"fetching RSS items (new, favorites, unread, by_id, by_feed, by_category, "
+"since)"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "Statistics to show you the publishing frequency all the websites you follow"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "fetching favicons"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "Import/export of your feeds into OPML format"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "setting read marker for item(s)"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "Several themes created by the community"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "setting starred marker for item(s)"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "\"Google Reader\"-like API to connect Android applications"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "setting read marker for feed"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid ""
-"The application is \"responsive,\" which means it adapts to small screens so "
-"you can bring articles in your pocket"
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "setting read marker for category"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Fever_API.md:45
+#, markdown-text
+msgid "supports FreshRSS extensions, which use the `entry_before_display` hook"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:47
+#, markdown-text
+msgid "The following features are not supported:"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
+#: en/./developers/06_Fever_API.md:49
+#, markdown-text
msgid ""
-"Self-hosted: the code is free (under AGPL3 licence), so you can host your "
-"own instance of FreshRSS"
+"**Hot Links** aka **hot** as there is nothing in FreshRSS yet that is "
+"similar or could be used to simulate it."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Fever_API.md:50
+#, markdown-text, no-wrap
+msgid "Testing and debugging"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:53
+#, markdown-text
+msgid ""
+"If this API does not work as expected in your RSS reader, you can test it "
+"manually with a tool like [Postman](https://www.getpostman.com/)."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:55
+#, markdown-text
+msgid ""
+"Configure a POST request to the URL "
+"<https://freshrss.example.net/api/fever.php?api> which should give you the "
+"result:"
+msgstr ""
+
+#. type: Fenced code block (json)
+#: en/./developers/06_Fever_API.md:55
+#, no-wrap
+msgid ""
+"{\n"
+"\t\"api_version\": 3,\n"
+"\t\"auth\": 0\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:62
+#, markdown-text
+msgid "Great, the base setup seems to work!"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:65
+#, markdown-text
+msgid ""
+"Now lets try an authenticated call. Fever uses an `api_key`, which is the "
+"MD5 hash of `\"$username:$apiPassword\"`. Assuming the user is `kevin` and "
+"the password `freshrss`, here is a command-line example to compute the "
+"resulting `api_key`"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/06_Fever_API.md:66
+#, no-wrap
+msgid "api_key=`echo -n \"kevin:freshrss\" | md5sum | cut -d' ' -f1`\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:71
+#, markdown-text
+msgid ""
+"Add a body to your POST request encoded as `form-data` and one key named "
+"`api_key` with the value `your-password-hash`:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/06_Fever_API.md:72
+#, no-wrap
+msgid ""
+"curl -s -F \"api_key=$api_key\" "
+"'https://freshrss.example.net/api/fever.php?api'\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:77
+#, markdown-text
+msgid "This should give:"
+msgstr ""
+
+#. type: Fenced code block (json)
+#: en/./developers/06_Fever_API.md:77
+#, no-wrap
+msgid ""
+"{\n"
+"\t\"api_version\": 3,\n"
+"\t\"auth\": 1,\n"
+"\t\"last_refreshed_on_time\": \"1520013061\"\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:85
+#, markdown-text
+msgid ""
+"Perfect, you’re now authenticated and you can start testing the more "
+"advanced features. To do so, change the URL and append the possible API "
+"actions to your request parameters. Please refer to the [original Fever "
+"documentation](https://feedafever.com/api) for more information."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:87
+#, markdown-text
+msgid "Some basic calls are:"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "Multi-user, so you can also host for your friends and family"
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&items>"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:18
-msgid "And a lot more!"
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&feeds>"
msgstr ""
-#. type: Plain text
-#: en/./index.md:20
-msgid "This documentation is split into different sections:"
+#. type: Bullet: '* '
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&groups>"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:24
-msgid ""
-"[User documentation](./users/02_First_steps.html), where you can discover "
-"all the possibilities offered by FreshRSS"
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&unread_item_ids>"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:24
-msgid ""
-"[Administrator documentation](./admins/01_Index.html) for detailed "
-"installation and maintenance related tasks"
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&saved_item_ids>"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:24
-msgid ""
-"[Developer documentation](./developers/01_First_steps.html) to guide you in "
-"the source code of FreshRSS and to help you if you want to contribute"
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&items&since_id=some_id>"
msgstr ""
#. type: Bullet: '* '
-#: en/./index.md:24
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&items&max_id=some_id>"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&mark=item&as=read&id=some_id>"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Fever_API.md:97
+#, markdown-text
+msgid "<https://freshrss.example.net/api/fever.php?api&mark=item&as=unread&id=some_id>"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Fever_API.md:99
+#, markdown-text
msgid ""
-"[Contributor guidelines](./contributing.md) for those who want to help "
-"improve FreshRSS"
+"Replace `some_id` with a real ID from your `freshrss_username_entry` "
+"database."
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/06_Fever_API.md:100
+#, markdown-text, no-wrap
+msgid "Debugging"
msgstr ""
#. type: Plain text
-#: en/./users/02_First_steps.md:2
+#: en/./developers/06_Fever_API.md:103
+#, markdown-text
msgid ""
-"Learning how to handle a new application is not always easy. We’ve tried to "
-"make FreshRSS as intuitive as possible, but you might still need a little "
-"help to master the program."
+"If nothing helps and your client is still misbehaving, you can add the "
+"following lines to the beginning of the `fever.api` file to determine the "
+"cause of the problems:"
+msgstr ""
+
+#. type: Fenced code block (php)
+#: en/./developers/06_Fever_API.md:104
+#, no-wrap
+msgid ""
+"file_put_contents(__DIR__ . '/fever.log', $_SERVER['HTTP_USER_AGENT'] . ': ' "
+". json_encode($_REQUEST) . PHP_EOL, FILE_APPEND);\n"
msgstr ""
#. type: Plain text
-#: en/./users/02_First_steps.md:4
+#: en/./developers/06_Fever_API.md:109
+#, markdown-text
msgid ""
-"This section will guide you to the pages you need to get started. The order "
-"is tailored to newcomers."
+"Then use your RSS client to query the API and afterwards check the file "
+"`fever.log`."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Fever_API.md:110
+#, markdown-text, no-wrap
+msgid "Credits"
msgstr ""
#. type: Plain text
-#: en/./users/02_First_steps.md:6
+#: en/./developers/06_Fever_API.md:112
+#, markdown-text
msgid ""
-"[After installing the application](../admins/03_Installation.md), the first "
-"step is to add some feeds. You have a few options:"
+"This plugin was inspired by the "
+"[tinytinyrss-fever-plugin](https://github.com/dasmurphy/tinytinyrss-fever-plugin)."
msgstr ""
-#. type: Bullet: '1. '
-#: en/./users/02_First_steps.md:10
-msgid "[Add a feed manually](04_Subscriptions.md#adding-a-feed)"
+#. type: Title #
+#: en/./developers/06_GoogleReader_API.md:1
+#, markdown-text, no-wrap
+msgid "FreshRSS - Google Reader compatible API implementation"
msgstr ""
-#. type: Bullet: '2. '
-#: en/./users/02_First_steps.md:10
-msgid "[Import an OPML or JSON file](04_Subscriptions.md#import-and-export)"
+#. type: Plain text
+#: en/./developers/06_GoogleReader_API.md:4
+#, markdown-text
+msgid ""
+"See [Mobile access](../users/06_Mobile_access.md) for general aspects of API "
+"access."
msgstr ""
-#. type: Bullet: '3. '
-#: en/./users/02_First_steps.md:10
-msgid "[Use the bookmarklet](04_Subscriptions.md#use-bookmarklet)"
+#. type: Plain text
+#: en/./developers/06_GoogleReader_API.md:6
+#, markdown-text
+msgid ""
+"See also the [page about our Fever compatible API](06_Fever_API.md) for "
+"another possibility (less powerful)."
msgstr ""
#. type: Plain text
-#: en/./users/02_First_steps.md:12
+#: en/./developers/06_GoogleReader_API.md:12
+#, markdown-text
msgid ""
-"Once you have added your feeds to FreshRSS, it is time to read them. There "
-"are three availalbe reading modes:"
+"There are many RSS clients that support the Fever API, but they might "
+"understand the API a bit differently. If your favourite client doesn’t work "
+"properly with this API, please create an issue and we’ll have a look. But "
+"we can **only** do that for free clients."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_GoogleReader_API.md:19
+#, markdown-text
+msgid ""
+"Then point your mobile application to the `greader.php` address "
+"(e.g. `https://freshrss.example.net/api/greader.php`)."
msgstr ""
#. type: Bullet: '1. '
-#: en/./users/02_First_steps.md:16
+#: en/./developers/06_GoogleReader_API.md:24
+#, markdown-text
msgid ""
-"[The normal view](03_Main_view.md#normal-view) enables you to quickly read "
-"new articles"
+"On the same FreshRSS API page, note the address given under “Your API "
+"address”, like `https://freshrss.example.net/api/greader.php`"
msgstr ""
#. type: Bullet: '2. '
-#: en/./users/02_First_steps.md:16
+#: en/./developers/06_GoogleReader_API.md:24
+#, markdown-text
msgid ""
-"[The global view](03_Main_view.md#global-view) shows you an overview of the "
-"status of your feeds in one glance"
+"Type the API address in a client, together with your FreshRSS username, and "
+"the corresponding special API password."
msgstr ""
-#. type: Bullet: '3. '
-#: en/./users/02_First_steps.md:16
+#. type: Plain text
+#: en/./developers/06_GoogleReader_API.md:39
+#, markdown-text, no-wrap
msgid ""
-"[The reader view](03_Main_view.md#reader-view) offers you a comfortable "
-"reading experience"
+"| App "
+"| Platform | License "
+"|\n"
+"|:----------------------------------------------------------------------------------:|:-------------------:|:--------------------------------------------------------:|\n"
+"|[News+](https://github.com/noinnion/newsplus/blob/master/apk/NewsPlus_202.apk) "
+"with [News+ Google Reader "
+"extension](https://github.com/noinnion/newsplus/blob/master/apk/GoogleReaderCloneExtension_101.apk) "
+"|Android|Closed Source (Free), [partially open "
+"source](https://github.com/noinnion/newsplus/blob/master/extensions/GoogleReaderCloneExtension/src/com/noinnion/android/newsplus/extension/google_reader/GoogleReaderClient.java)|\n"
+"|[FeedMe "
+"3.5.3+](https://play.google.com/store/apps/details?id=com.seazon.feedme) "
+"|Android |Closed Source (Free) "
+"|\n"
+"|[EasyRSS](https://github.com/Alkarex/EasyRSS) "
+"|Android "
+"|[GPLv3](https://github.com/Alkarex/EasyRSS/blob/master/license.txt) "
+"([F-Droid](https://f-droid.org/packages/org.freshrss.easyrss/))|\n"
+"|[Readrops](https://github.com/readrops/Readrops) |Android "
+"|[GPLv3](https://github.com/readrops/Readrops/blob/develop/LICENSE) "
+"|\n"
+"|[Fluent Reader Lite](https://hyliu.me/fluent-reader-lite/) |Android, iOS "
+"|[BSD-3](https://github.com/yang991178/fluent-reader-lite) "
+"|\n"
+"|[FocusReader](https://play.google.com/store/apps/details?id=allen.town.focus.reader) "
+"|Android |Closed Source(Free) "
+"|\n"
+"|[Newsflash](https://gitlab.com/news-flash/news_flash_gtk/) "
+"|Linux "
+"|[GPLv3](https://gitlab.com/news-flash/news_flash_gtk/) |\n"
+"|[lire](https://lireapp.com/) "
+"|iOS, macOS |Closed Source "
+"|\n"
+"|[Newsboat 2.24+](https://newsboat.org/) |Linux "
+"|[MIT](https://github.com/newsboat/newsboat/blob/master/LICENSE) "
+"|\n"
+"|[Vienna RSS](http://www.vienna-rss.com/) |macOS "
+"|[Apache-2.0](https://github.com/ViennaRSS/vienna-rss/blob/master/LICENCE.md) "
+"|\n"
+"|[Reeder](https://www.reederapp.com/) |macOS, iOS "
+"|Closed Source |\n"
+"|[FreshRSS-Notify](https://addons.mozilla.org/firefox/addon/freshrss-notify-webextension/) "
+"|Firefox |Open Source "
+"|\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_GoogleReader_API.md:41
+#, markdown-text, no-wrap
+msgid ""
+"> ℹ️ See a [better table of compatible clients in our main "
+"Readme](https://github.com/FreshRSS/FreshRSS/blob/edge/README.md#apis--native-apps).\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_GoogleReader_API.md:42
+#, markdown-text, no-wrap
+msgid "Google Reader compatible API"
msgstr ""
#. type: Plain text
-#: en/./users/02_First_steps.md:18
+#: en/./developers/06_GoogleReader_API.md:45
+#, markdown-text
+msgid "Examples of basic queries:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./developers/06_GoogleReader_API.md:46
+#, no-wrap
msgid ""
-"Now that you’ve mastered basic use, it’s time to configure FreshRSS to "
-"improve your reading experience. It’s highly configurable, so it’s "
-"recommended to play around with them to find a configuration that suits you "
-"well. Here are a few resources to help you improve your daily FreshRSS "
-"experience:"
+"# Initial login, using API password (Email and Passwd can be given either as "
+"GET, or POST - better)\n"
+"curl "
+"'https://freshrss.example.net/api/greader.php/accounts/ClientLogin?Email=alice&Passwd=Abcdef123456'\n"
+"SID=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\n"
+"Auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\n"
+"\n"
+"# Examples of read-only requests\n"
+"curl -s -H \"Authorization:GoogleLogin "
+"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
+" "
+"'https://freshrss.example.net/api/greader.php/reader/api/0/subscription/list?output=json'\n"
+"\n"
+"curl -s -H \"Authorization:GoogleLogin "
+"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
+" "
+"'https://freshrss.example.net/api/greader.php/reader/api/0/unread-count?output=json'\n"
+"\n"
+"curl -s -H \"Authorization:GoogleLogin "
+"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
+" "
+"'https://freshrss.example.net/api/greader.php/reader/api/0/tag/list?output=json'\n"
+"\n"
+"# Retrieve a token for requests making modifications\n"
+"curl -H \"Authorization:GoogleLogin "
+"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
+" 'https://freshrss.example.net/api/greader.php/reader/api/0/token'\n"
+"8e6845e089457af25303abc6f53356eb60bdb5f8ZZZZZZZZZZZZZZZZZ\n"
+"\n"
+"# Get articles, piped to jq for easier JSON reading\n"
+"curl -s -H \"Authorization:GoogleLogin "
+"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
+" "
+"'https://freshrss.example.net/api/greader.php/reader/api/0/stream/contents/reading-list' "
+"| jq .\n"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
-msgid "[Organize your feeds in categories](04_Subscriptions.md#feed-management)"
+#: en/./developers/06_GoogleReader_API.md:73
+#, markdown-text
+msgid ""
+"[Source code of our API "
+"implementation](https://github.com/FreshRSS/FreshRSS/blob/edge/p/api/greader.php)"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/06_GoogleReader_API.md:74
+#, markdown-text, no-wrap
+msgid "API documentation from the original Google Reader"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
-msgid "[Change the home page](05_Configuration.md#changing-the-view)"
+#: en/./developers/06_GoogleReader_API.md:81
+#, markdown-text
+msgid ""
+"[By Daniel "
+"Arowser](https://web.archive.org/web/20130710044440/http://undoc.in/api.html) "
+"([source](https://github.com/arowser/google-reader-api))"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
-msgid "[Choose the reading options](05_Configuration.md#reading-options)"
+#: en/./developers/06_GoogleReader_API.md:81
+#, markdown-text
+msgid ""
+"[By Martin "
+"Doms](https://web.archive.org/web/20210126115837/https://blog.martindoms.com/2009/10/16/using-the-google-reader-api-part-2/)"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
-msgid "[Refresh feeds](03_Main_view.md#refreshing-feeds)"
+#: en/./developers/06_GoogleReader_API.md:81
+#, markdown-text
+msgid ""
+"[By Nick "
+"Bradbury](https://inessential.com/2013/03/14/google_reader_api_documentation)"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
+#: en/./developers/06_GoogleReader_API.md:81
+#, markdown-text
msgid ""
-"[Filter articles](03_Main_view.md#filtering-articles) for a fast access to a "
-"selection"
+"[By Niall "
+"Kennedy](https://web.archive.org/web/20170426184845/http://www.niallkennedy.com/blog/2005/12/google-reader-api.html)"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
+#: en/./developers/06_GoogleReader_API.md:81
+#, markdown-text
msgid ""
-"[search for an article](03_Main_view.md#with-the-search-field) published some time "
-"ago"
+"[By Mihai "
+"Parparita](https://web.archive.org/web/20140919042419/http://code.google.com/p/google-reader-api/w/list) "
+"([source](https://github.com/mihaip/google-reader-api))"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/06_GoogleReader_API.md:82
+#, markdown-text, no-wrap
+msgid "API documentation from other compatible clients"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
-msgid "[Access your feeds on a mobile device](06_Mobile_access.md)"
+#: en/./developers/06_GoogleReader_API.md:89
+#, markdown-text
+msgid "[FeedHQ](https://feedhq.readthedocs.io/en/latest/api/index.html)"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
-msgid "[Add some extensions](https://github.com/FreshRSS/Extensions)"
+#: en/./developers/06_GoogleReader_API.md:89
+#, markdown-text
+msgid "[Inoreader](https://www.inoreader.com/developers/)"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/02_First_steps.md:27
-msgid "[Frequently asked questions](07_Frequently_Asked_Questions.md)"
+#: en/./developers/06_GoogleReader_API.md:89
+#, markdown-text
+msgid "[The Old Reader](https://github.com/theoldreader/api)"
msgstr ""
-#. type: Title #
-#: en/./users/03_Main_view.md:1
-#, no-wrap
-msgid "Normal view"
+#. type: Bullet: '* '
+#: en/./developers/06_GoogleReader_API.md:89
+#, markdown-text
+msgid "[pyrfeed](http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI)"
msgstr ""
-#. type: Title #
-#: en/./users/03_Main_view.md:5
-#, no-wrap
-msgid "Global view"
+#. type: Bullet: '* '
+#: en/./developers/06_GoogleReader_API.md:89
+#, markdown-text
+msgid "[BazQux](https://github.com/bazqux/bazqux-api)"
msgstr ""
-#. type: Title #
-#: en/./users/03_Main_view.md:9
-#, no-wrap
-msgid "Reader view"
+#. type: Title ###
+#: en/./developers/06_GoogleReader_API.md:90
+#, markdown-text, no-wrap
+msgid "Synchronisation strategy"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_GoogleReader_API.md:94
+#, markdown-text, no-wrap
+msgid ""
+"> ℹ️ If you are maintaining a client or planning to develop a new one, "
+"please read carefully the following pieces of advice,\n"
+"as many clients start by having a very inneficient synchronisation "
+"strategy.\n"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_GoogleReader_API.md:96
+#, markdown-text
+msgid ""
+"[*Synchronisation recommendation* by "
+"Alkarex](https://github.com/FreshRSS/FreshRSS/issues/2566#issuecomment-541317776)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_GoogleReader_API.md:96
+#, markdown-text
+msgid ""
+"[*The Right Way to Sync* by "
+"BazQux](https://github.com/bazqux/bazqux-api#user-content-the-right-way-to-sync)"
msgstr ""
#. type: Title #
-#: en/./users/03_Main_view.md:13
-#, no-wrap
-msgid "Refreshing feeds"
+#: en/./developers/06_Reporting_Bugs.md:1
+#, markdown-text, no-wrap
+msgid "Reporting a bug or a suggestion"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:16
+#: en/./developers/06_Reporting_Bugs.md:4
+#, markdown-text
msgid ""
-"To take full advantage of FreshRSS, it needs to retrieve new items from the "
-"feeds you have subscribed to. There are several ways to do this."
+"Despite the care given to FreshRSS, it’s still possible that bugs "
+"occur. Development is dynamic, so issues can be corrected quickly. You might "
+"also have a feature in mind that doesn’t yet exist. Regardless whether your "
+"idea seems silly, far-fetched, useless or too specific, please don’t "
+"hesitate to propose it to us! “Ideas in the air” often find an attentive "
+"ear. It’s new external perspectives that make the project evolve the most."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Reporting_Bugs.md:6
+#, markdown-text
+msgid ""
+"If you’re convinced that you should be heard, here’s how you can go about "
+"it."
msgstr ""
#. type: Title ##
-#: en/./users/03_Main_view.md:17
-#, no-wrap
-msgid "Automatic update"
+#: en/./developers/06_Reporting_Bugs.md:7
+#, markdown-text, no-wrap
+msgid "On GitHub"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:20
+#: en/./developers/06_Reporting_Bugs.md:10
+#, markdown-text
msgid ""
-"This is the recommended method since you can forget about it once it is "
-"configured."
+"GitHub is the ideal platform to submit your requests. It allows us to "
+"discuss a problem or suggestion with others and it often generates new "
+"ideas. Let’s not neglect this “social” aspect!"
msgstr ""
-#. type: Title ###
-#: en/./users/03_Main_view.md:21
-#, no-wrap
-msgid "With the actualize_script.php script"
+#. type: Bullet: '1. '
+#: en/./developers/06_Reporting_Bugs.md:16
+#, markdown-text
+msgid "[Go to the bug ticket manager](https://github.com/FreshRSS/FreshRSS/issues)"
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:24
+#. type: Bullet: '2. '
+#: en/./developers/06_Reporting_Bugs.md:16
+#, markdown-text
msgid ""
-"This method is only available if you have access to the scheduled tasks of "
-"the machine on which your FreshRSS instance is installed."
+"Start by checking if a similar request hasn’t already been made. If so, "
+"please feel free to add your voice to the request."
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:26
+#. type: Bullet: '3. '
+#: en/./developers/06_Reporting_Bugs.md:16
+#, markdown-text
msgid ""
-"The script is named *actualize_script.php* and is located in the *app* "
-"folder. The scheduled task syntax will not be explained here. However, here "
-"is [a quick introduction to "
-"crontab](http://www.adminschoice.com/crontab-quick-reference/) that might "
-"help you."
+"If your request is new, [open a new bug "
+"ticket](https://github.com/FreshRSS/FreshRSS/issues/new)"
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:28
-msgid "Here is an example to trigger article update every hour."
+#. type: Bullet: '4. '
+#: en/./developers/06_Reporting_Bugs.md:16
+#, markdown-text
+msgid ""
+"Finally, write your request. If you’re fluent in English, it’s the preferred "
+"language because it allows for discussion with the largest number of people."
msgstr ""
-#. type: Code fence info string
-#: en/./users/03_Main_view.md:29 en/./users/03_Main_view.md:61 en/./users/03_Main_view.md:79 en/./users/03_Main_view.md:85 en/./users/03_Main_view.md:93
-#, no-wrap
-msgid "cron"
+#. type: Bullet: '5. '
+#: en/./developers/06_Reporting_Bugs.md:16
+#, markdown-text
+msgid "Please follow the tips below to make it easier to let your ticket be heard."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Reporting_Bugs.md:17
+#, markdown-text, no-wrap
+msgid "Informal"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:29
-#, no-wrap
+#: en/./developers/06_Reporting_Bugs.md:20
+#, markdown-text
msgid ""
-"0 * * * * php /path/to/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log "
-"2>&1\n"
+"Not everyone likes or uses GitHub for a variety of legitimate reasons. That "
+"is why you can also contact us in a more informal way."
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:34
-msgid "Special parameters to configure the script - all parameters can be combined:"
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:26
+#, markdown-text
+msgid ""
+"On [our Mattermost "
+"chat](https://framateam.org/signup_user_complete/?id=e2680d3e3128b9fac8fdb3003b0024ee)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:26
+#, markdown-text
+msgid "On [our subreddit](https://www.reddit.com/r/freshrss/)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:26
+#, markdown-text
+msgid "At events / meetings around Free Software"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:26
+#, markdown-text
+msgid "Over a beer in a bar"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:26
+#, markdown-text
+msgid "Etc."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Reporting_Bugs.md:27
+#, markdown-text, no-wrap
+msgid "Tips"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:38
+#: en/./developers/06_Reporting_Bugs.md:30
+#, markdown-text
+msgid "Here are some tips to help you present your bug report or suggestion:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text
+msgid "**Pay attention to spelling**. Even if it’s not always easy, try your best!"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text
msgid ""
-"- Parameter \"force\" "
-"https://freshrss.example.net/i/?c=feed&a=actualize&force=1 If *force* is set "
-"to 1 all feeds will be refreshed at once."
+"**Give an explicit title to your request**, even if it’s a bit long. This "
+"not only helps us understand your request, but also to find your ticket "
+"later."
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:42
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text
msgid ""
-"- Parameter \"ajax\" "
-"https://freshrss.example.net/i/?c=feed&a=actualize&ajax=1 Only a status site "
-"is returned and not a complete website. Example: \"OK\""
+"**One request = one ticket.** You may have lots of ideas while being afraid "
+"to spam the bug manager: it doesn’t matter. It’s better to have a few too "
+"many tickets than too many requests in one. We’ll close and consolidate "
+"requests when possible."
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text
+msgid ""
+"If you report a bug, think about **providing us with the FreshRSS logs** "
+"(accessible in the FreshRSS `data/log/` folder) and the **PHP logs** (the "
+"location may vary by distribution, but consider searching in "
+"`/var/log/httpd` or `/var/log/apache`)."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text
+msgid ""
+"If you can’t find the log files, specify it in your ticket so we know you’ve "
+"already searched."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text
+msgid ""
+"Not all bugs require logs, but if you have any doubts, it is better to "
+"provide them to us. Logs are important and very useful for debugging!"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text
+msgid ""
+"The logs may reveal confidential information, so **be careful not to "
+"disclose anything sensitive.**"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:46
+#: en/./developers/06_Reporting_Bugs.md:41
+#, markdown-text, no-wrap
msgid ""
-"- Parameter \"maxFeeds\" "
-"https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=30 If *maxFeeds* "
-"is set the configured amount of feeds is refreshed at once. The default "
-"setting is \"10\"."
+"* If you report a feed problem, it will be easier if you could provide a "
+"snapshot of its content in a text file.\n"
+"See [here](#how-to-provide-feed-data) for more information.\n"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:50
+#: en/./developers/06_Reporting_Bugs.md:43
+#, markdown-text
msgid ""
-"- Parameter \"token\" "
-"https://freshrss.example.net/i/?c=feed&a=actualize&token=542345872345734 "
-"Security parameter to prevent unauthorized refreshes. For detailed "
-"Documentation see \"Form authentication\"."
+"In addition, when facing a bug, you’re encouraged to follow this message "
+"format (from the [Sam & Max "
+"website](http://sametmax.com/template-de-demande-daide-en-informatique/):"
msgstr ""
#. type: Title ###
-#: en/./users/03_Main_view.md:51
-#, no-wrap
-msgid "Online cron"
+#: en/./developers/06_Reporting_Bugs.md:44
+#, markdown-text, no-wrap
+msgid "What’s my goal?"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:54
-msgid ""
-"If you do not have access to the installation server scheduled task, you can "
-"still automate the update process."
+#: en/./developers/06_Reporting_Bugs.md:47
+#, markdown-text
+msgid "Give the general context of what you were trying to do."
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/06_Reporting_Bugs.md:48
+#, markdown-text, no-wrap
+msgid "What have I been trying to do?"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:56
-msgid ""
-"To do so, you need to create a scheduled task, which need to call a specific "
-"URL: https://freshrss.example.net/i/?c=feed&a=actualize (it could be "
-"different depending on your installation). Depending on your application "
-"authentication method, you need to adapt the scheduled task."
+#: en/./developers/06_Reporting_Bugs.md:51
+#, markdown-text
+msgid "Explain step by step what you have done so that we can reproduce the bug."
msgstr ""
-#. type: Title ####
-#: en/./users/03_Main_view.md:57
-#, no-wrap
-msgid "No authentication"
+#. type: Title ###
+#: en/./developers/06_Reporting_Bugs.md:52
+#, markdown-text, no-wrap
+msgid "What results have I achieved?"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:60
+#: en/./developers/06_Reporting_Bugs.md:55
+#, markdown-text
msgid ""
-"This is the most straightforward since you have a public instance; there is "
-"nothing special to configure:"
+"The bug: what you see that shouldn’t have happened. Here you can provide the "
+"logs."
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/06_Reporting_Bugs.md:56
+#, markdown-text, no-wrap
+msgid "What was the expected result?"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:61
-#, no-wrap
-msgid "0 * * * * curl 'https://freshrss.example.net/i/?c=feed&a=actualize'\n"
+#: en/./developers/06_Reporting_Bugs.md:59
+#, markdown-text
+msgid "So that we understand what you consider to be the problem."
msgstr ""
#. type: Title ###
-#: en/./users/03_Main_view.md:65
-#, no-wrap
-msgid "Form authentication"
+#: en/./developers/06_Reporting_Bugs.md:60
+#, markdown-text, no-wrap
+msgid "What are my circumstances?"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:68
+#: en/./developers/06_Reporting_Bugs.md:63
+#, markdown-text
+msgid "Remember to give the following information if you know it:"
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./developers/06_Reporting_Bugs.md:69
+#, markdown-text
+msgid "Which browser? Which version?"
+msgstr ""
+
+#. type: Bullet: '2. '
+#: en/./developers/06_Reporting_Bugs.md:69
+#, markdown-text
+msgid "Which server: Apache, Nginx? Which version?"
+msgstr ""
+
+#. type: Bullet: '3. '
+#: en/./developers/06_Reporting_Bugs.md:69
+#, markdown-text
+msgid "Which version of PHP?"
+msgstr ""
+
+#. type: Bullet: '4. '
+#: en/./developers/06_Reporting_Bugs.md:69
+#, markdown-text
+msgid "Which database: SQLite, MySQL, MariaDB, PostgreSQL? Which version?"
+msgstr ""
+
+#. type: Bullet: '5. '
+#: en/./developers/06_Reporting_Bugs.md:69
+#, markdown-text
+msgid "Which distribution runs on the server? And… which version?"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/06_Reporting_Bugs.md:70
+#, markdown-text, no-wrap
+msgid "How to provide feed data"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/06_Reporting_Bugs.md:74
+#, markdown-text
msgid ""
-"If you configure the application to allow anonymous reading, you can also "
-"allow anonymous users to update feeds (“Allow anonymous refresh of the "
-"articles”)."
+"If you need us to investigate a feed problem, it will be easier if you "
+"provide a snapshot of the feed data. To do that, you can launch the "
+"following command:"
+msgstr ""
+
+#. type: Fenced code block (bash)
+#: en/./developers/06_Reporting_Bugs.md:75
+#, no-wrap
+msgid "wget <feed url> -O output.rss.txt\n"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:70
-msgid "![Anonymous access configuration](../img/users/anonymous_access.1.png)"
+#: en/./developers/06_Reporting_Bugs.md:78
+#, markdown-text
+msgid "Then you can drag-and-drop the generated file into the issue."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/index.md:4
+#, markdown-text
+msgid "Minz is the homemade PHP framework used by FreshRSS."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:72
+#: en/./developers/Minz/index.md:6
+#, markdown-text
msgid ""
-"The URL used in the previous section will now become accessible to "
-"anyone. Therefore you can use the same syntax for the scheduled task."
+"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)."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/Minz/index.md:7
+#, markdown-text, no-wrap
+msgid "MVC Architecture"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:74
+#: en/./developers/Minz/index.md:10
+#, markdown-text
+msgid ""
+"Minz relies on and imposes an MVC architecture on projects using it. This "
+"architecture consists of three main components:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/Minz/index.md:14
+#, markdown-text
msgid ""
-"You can also configure an authentication token to grant special access on "
-"the server."
+"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."
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/Minz/index.md:14
+#, markdown-text
+msgid ""
+"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."
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/Minz/index.md:14
+#, markdown-text
+msgid ""
+"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."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/Minz/index.md:15
+#, markdown-text, no-wrap
+msgid "Routing"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:76
-msgid "![Token configuration](../img/users/token.1.png)"
+#: en/./developers/Minz/index.md:19
+#, markdown-text
+msgid ""
+"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."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:78
-msgid "The scheduled task syntax should look as follows:"
+#: en/./developers/Minz/index.md:21
+#, markdown-text
+msgid ""
+"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."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:79
+#: en/./developers/Minz/index.md:23 en/./developers/Minz/index.md:143
+#, markdown-text
+msgid "Code example:"
+msgstr ""
+
+#. type: Fenced code block (php)
+#: en/./developers/Minz/index.md:24
#, no-wrap
msgid ""
-"0 * * * * curl "
-"'https://freshrss.example.net/i/?c=feed&a=actualize&token=my-token'\n"
+"<?php\n"
+"\n"
+"class FreshRSS_hello_Controller extends FreshRSS_ActionController {\n"
+"\tpublic function indexAction() {\n"
+"\t\t$this->view->a_variable = 'FooBar';\n"
+"\t}\n"
+"\n"
+"\tpublic function worldAction() {\n"
+"\t\t$this->view->a_variable = 'Hello World!';\n"
+"\t}\n"
+"}\n"
+"\n"
+"?>\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/index.md:41
+#, markdown-text
+msgid ""
+"When loading the address <http://example.com?c=hello&a=world>, the `world` "
+"action is executed on the `hello` controller."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:84
+#: en/./developers/Minz/index.md:44
+#, markdown-text
msgid ""
-"You can also target a different user by adding their username to the query "
-"string, with `&user=insert-username`:"
+"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."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:85
-#, no-wrap
+#: en/./developers/Minz/index.md:46
+#, markdown-text
msgid ""
-"0 * * * * curl "
-"'https://freshrss.example.net/i/?c=feed&a=actualize&user=someone&token=my-token'\n"
+"From now on, the `hello/world` naming convention will be used to refer to a "
+"controller/action pair."
msgstr ""
-#. type: Title ###
-#: en/./users/03_Main_view.md:89
-#, no-wrap
-msgid "HTTP authentication"
+#. type: Title #
+#: en/./developers/Minz/index.md:47 en/./users/03_Main_view.md:1
+#, markdown-text, no-wrap
+msgid "Views"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:92
+#: en/./developers/Minz/index.md:50
+#, markdown-text
msgid ""
-"When using HTTP authentication, the syntax in the two previous sections is "
-"unusable. You’ll need to provide your credentials to the scheduled "
-"task. **Note that this method is highly discouraged since it means that your "
-"credentials will be in plain sight!**"
+"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."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:93
+#: en/./developers/Minz/index.md:52
+#, markdown-text
+msgid "As explained above, the views consist of HTML mixed with PHP. Code example:"
+msgstr ""
+
+#. type: Fenced code block (html)
+#: en/./developers/Minz/index.md:53
#, no-wrap
msgid ""
-"0 * * * * curl -u alice:password123 "
-"'https://freshrss.example.net/i/?c=feed&a=actualize'\n"
+"<p>\n"
+"\tThis is a parameter passed from the controller: <?= $this->a_variable ?>\n"
+"</p>\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/index.md:60
+#, markdown-text, no-wrap
+msgid ""
+"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.\n"
msgstr ""
#. type: Title ##
-#: en/./users/03_Main_view.md:97
-#, no-wrap
-msgid "Manual update"
+#: en/./developers/Minz/index.md:61
+#, markdown-text, no-wrap
+msgid "Working with GET / POST"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:100
+#: en/./developers/Minz/index.md:65
+#, markdown-text
msgid ""
-"If you can’t or don’t want to use the automatic method, you can update "
-"manually. There are two methods for updating all or some of the feeds."
+"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:"
msgstr ""
-#. type: Title ###
-#: en/./users/03_Main_view.md:101
+#. type: Fenced code block (php)
+#: en/./developers/Minz/index.md:66
#, no-wrap
-msgid "Complete update"
+msgid ""
+"<?php\n"
+"\n"
+"$default_value = 'foo';\n"
+"$param = Minz_Request::paramString('bar') ?: $default_value;\n"
+"\n"
+"// Display the value of the parameter `bar` (passed via GET or POST)\n"
+"// or \"foo\" if the parameter does not exist.\n"
+"echo $param;\n"
+"\n"
+"// Sets the value of the `bar` parameter\n"
+"Minz_Request::_param('bar', 'baz');\n"
+"\n"
+"// Will necessarily display \"baz\" since we have just forced its value.\n"
+"// Note that the second parameter (default) is optional.\n"
+"echo Minz_Request::paramString('bar');\n"
+"\n"
+"?>\n"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:104
+#: en/./developers/Minz/index.md:87
+#, markdown-text
msgid ""
-"This update occurs on all feeds. To trigger it, simply click on the update "
-"link in the navigation menu."
+"The `Minz_Request::isPost()` method can be used to execute a piece of code "
+"only if it is a POST request."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:106
-msgid "![Navigation menu](../img/users/refresh.1.png)"
+#: en/./developers/Minz/index.md:89
+#, markdown-text
+msgid ""
+"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."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/Minz/index.md:90
+#, markdown-text, no-wrap
+msgid "Access session settings"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:108
+#: en/./developers/Minz/index.md:93
+#, markdown-text
msgid ""
-"When the update starts, a progress bar appears and changes while feeds are "
-"processed."
+"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`."
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/Minz/index.md:94
+#, markdown-text, no-wrap
+msgid "Working with URLs"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:110
-msgid "![Progress bar](../img/users/refresh.5.png)"
+#: en/./developers/Minz/index.md:97
+#, markdown-text
+msgid ""
+"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:"
msgstr ""
-#. type: Title ###
-#: en/./users/03_Main_view.md:111
+#. type: Fenced code block (html)
+#: en/./developers/Minz/index.md:98
#, no-wrap
-msgid "Partial update"
+msgid ""
+"<p>\n"
+"\tGo to page <a href=\"http://example.com?c=hello&amp;a=world\">Hello "
+"world</a>!\n"
+"</p>\n"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:114
+#: en/./developers/Minz/index.md:105
+#, markdown-text
msgid ""
-"This update occurs on the selected feed only. To trigger it, simply click on "
-"the update link in the feed menu."
+"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!"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:116
-msgid "![Feed menu](../img/users/refresh.2.png)"
+#: en/./developers/Minz/index.md:107
+#, markdown-text
+msgid ""
+"So use the `Minz_Url` class and its `display()` method "
+"instead. `Minz_Url::display()` takes an array of the following form as its "
+"argument:"
msgstr ""
-#. type: Title #
-#: en/./users/03_Main_view.md:117
+#. type: Fenced code block (php)
+#: en/./developers/Minz/index.md:108
#, no-wrap
-msgid "Filtering articles"
+msgid ""
+"<?php\n"
+"\n"
+"$url_array = [\n"
+"\t'c' => 'hello',\n"
+"\t'a' => 'world',\n"
+"\t'params' => [\n"
+"\t\t'foo' => 'bar',\n"
+"\t],\n"
+"];\n"
+"\n"
+"// Show something like .?c=hello&amp;a=world&amp;foo=bar\n"
+"echo Minz_Url::display($url_array);\n"
+"\n"
+"?>\n"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:120
+#: en/./developers/Minz/index.md:126
+#, markdown-text
msgid ""
-"When the number of articles stored by FreshRSS inevitably grows larger, it’s "
-"important to use efficient filters to display only a subset of the "
-"articles. There are several methods that filter with different "
-"criteria. Usually those methods can be combined."
+"Since this can become a bit tedious to use in the long run, especially in "
+"views, it is preferable to use the `_url()` shortcut:"
msgstr ""
-#. type: Title ##
-#: en/./users/03_Main_view.md:121
+#. type: Fenced code block (php)
+#: en/./developers/Minz/index.md:127
#, no-wrap
-msgid "By category"
+msgid ""
+"<?php\n"
+"\n"
+"// Displays the same as above\n"
+"echo _url('hello', 'world', 'foo', 'bar');\n"
+"\n"
+"?>\n"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:124
+#: en/./developers/Minz/index.md:137
+#, markdown-text
msgid ""
-"This is the easiest method. You only need to click on the category title in "
-"the side panel. There are two special categories at the top of the panel:"
+"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."
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/03_Main_view.md:127
+#. type: Title ##
+#: en/./developers/Minz/index.md:138
+#, markdown-text, no-wrap
+msgid "Redirections"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/index.md:141
+#, markdown-text
msgid ""
-"*Main feed* displays only articles from feeds marked as available in that "
-"category"
+"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."
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/03_Main_view.md:127
-msgid "*Favourites* displays only articles marked as favourites"
+#. type: Fenced code block (php)
+#: en/./developers/Minz/index.md:144
+#, no-wrap
+msgid ""
+"<?php\n"
+"\n"
+"$url_array = [\n"
+"\t'c' => 'hello',\n"
+"\t'a' => 'world',\n"
+"];\n"
+"\n"
+"// Tells Minz to redirect the user to the hello / world page.\n"
+"// 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)\n"
+"// The code that follows forward() will thus be executed!\n"
+"Minz_Request::forward($url_array);\n"
+"\n"
+"// To perform a type 302 redirect, add \"true\".\n"
+"// The code that follows will never be executed.\n"
+"Minz_Request::forward($url_array, true);\n"
+"\n"
+"?>\n"
msgstr ""
-#. type: Title ##
-#: en/./users/03_Main_view.md:128
+#. type: Plain text
+#: en/./developers/Minz/index.md:165
+#, markdown-text
+msgid ""
+"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:"
+msgstr ""
+
+#. type: Fenced code block (php)
+#: en/./developers/Minz/index.md:166
#, no-wrap
-msgid "By feed"
+msgid ""
+"<?php\n"
+"\n"
+"$url_array = [\n"
+"\t'c' => 'hello',\n"
+"\t'a' => 'world',\n"
+"];\n"
+"$feedback_good = 'All went well!';\n"
+"$feedback_bad = 'Oops, something went wrong.';\n"
+"\n"
+"Minz_Request::good($feedback_good, $url_array);\n"
+"\n"
+"// or\n"
+"\n"
+"Minz_Request::bad($feedback_bad, $url_array);\n"
+"\n"
+"?>\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/Minz/index.md:185
+#, markdown-text, no-wrap
+msgid "Translation Management"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:131
-msgid "There are several methods to filter articles by feed:"
+#: en/./developers/Minz/index.md:188
+#, markdown-text
+msgid "This part [is explained here](/docs/en/internationalization.md)."
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/03_Main_view.md:136
-msgid "by clicking the feed title in the side panel"
+#. type: Title ##
+#: en/./developers/Minz/index.md:189
+#, markdown-text, no-wrap
+msgid "Migration"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/03_Main_view.md:136
-msgid "by clicking the feed title in the article details"
+#. type: Plain text
+#: en/./developers/Minz/index.md:192
+#, markdown-text
+msgid "Existing documentation includes:"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/03_Main_view.md:136
-msgid "by filtering in the feed options from the side panel"
+#. type: Bullet: '* '
+#: en/./developers/Minz/index.md:193
+#, markdown-text
+msgid "[How to manage migrations](migrations.md)"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/03_Main_view.md:136
-msgid "by filtering in the feed configuration"
+#. type: Title #
+#: en/./developers/Minz/migrations.md:1
+#, markdown-text, no-wrap
+msgid "How to manage migrations with Minz"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:138
-msgid "![Feed filter](../img/users/feed.filter.1.png)"
+#: en/./developers/Minz/migrations.md:4
+#, markdown-text
+msgid ""
+"Migrations are the way to modify the database or the structure of files "
+"under the `data/` path."
msgstr ""
#. type: Title ##
-#: en/./users/03_Main_view.md:139
+#: en/./developers/Minz/migrations.md:5
+#, markdown-text, no-wrap
+msgid "How to write a migration?"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/migrations.md:8
+#, markdown-text
+msgid "Migrations are placed under the `app/migrations` folder."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/migrations.md:10
+#, markdown-text
+msgid ""
+"Good practice is to prepend the filename by the current date and explain "
+"what does the migration do in few words "
+"(e.g. `2020_01_11_CreateFooTable.php`)."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/migrations.md:12
+#, markdown-text
+msgid ""
+"The files must contain a class which name starts with `FreshRSS_Migration_`, "
+"followed by the basename of the file "
+"(e.g. `FreshRSS_Migration_2020_01_11_CreateFooTable`)."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/migrations.md:14
+#, markdown-text
+msgid ""
+"The class must declare a `migrate` static function. It must return `true` or "
+"a string to indicate the migration is applied, or `false` otherwise. It can "
+"also raise an exception: the message will be used to detail the error."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/migrations.md:16
+#, markdown-text
+msgid "Example:"
+msgstr ""
+
+#. type: Fenced code block (php)
+#: en/./developers/Minz/migrations.md:17
#, no-wrap
-msgid "By status"
+msgid ""
+"// File: app/migrations/2020_01_11_CreateFooTable.php\n"
+"class FreshRSS_Migration_2020_01_11_CreateFooTable {\n"
+"\tpublic static function migrate() {\n"
+"\t\t$pdo = new Minz_PdoSqlite('sqlite:/some/path/db.sqlite');\n"
+"\t\t$result = $pdo->exec('CREATE TABLE foos (bar TEXT)');\n"
+"\t\tif ($result === false) {\n"
+"\t\t\t$error = $pdo->errorInfo();\n"
+"\t\t\traise Exception('Error in SQL statement: ' . $error[2]);\n"
+"\t\t}\n"
+"\n"
+"\t\treturn true;\n"
+"\t}\n"
+"}\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./developers/Minz/migrations.md:33
+#, markdown-text, no-wrap
+msgid "How to apply migrations?"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:142
+#: en/./developers/Minz/migrations.md:36
+#, markdown-text
+msgid "They are automatically applied one by one when a user accesses FreshRSS."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/Minz/migrations.md:38
+#, markdown-text
msgid ""
-"Each article has two attributes that can be combined. The first attribute "
-"indicates whether or not the article has been read. The second attribute "
-"indicates if the article was marked as favorite or not."
+"Before being applied, migrations are sorted by filenames (see the "
+"[`strnatcmp`](https://php.net/strnatcmp) function). Already applied "
+"migrations are skipped (the list can be found in the "
+"`data/applied_migrations.txt` file)."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:144
+#: en/./developers/Minz/migrations.md:39
+#, markdown-text
msgid ""
-"In version 0.7, attribute filters are available in the article display "
-"dropdown list. With this version, it’s not possible to combine filters. For "
-"instance, it’s not possible to display only read and favorite articles."
+"To ensure migrations are not applied several times if two users access "
+"FreshRSS at the same time, a folder named `data/applied_migrations.txt.lock` "
+"is created, then deleted at the end of the process."
+msgstr ""
+
+#. type: Title #
+#: en/./developers/OPML.md:1
+#, markdown-text, no-wrap
+msgid "OPML in FreshRSS"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:146
-msgid "![Attribute filters in 0.7](../img/users/status.filter.0.7.png)"
+#: en/./developers/OPML.md:4
+#, markdown-text
+msgid ""
+"FreshRSS supports the [OPML](https://en.wikipedia.org/wiki/OPML) format to "
+"export and import lists of RSS/Atom feeds in a standard way, compatible with "
+"several other RSS aggregators."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:148
+#: en/./developers/OPML.md:7
+#, markdown-text
msgid ""
-"Starting with version 0.8, all attribute filters are visible as toggle "
-"icons. They can be combined. As any combination is possible, some have the "
-"same result. For instance, the result for all filters selected is the same "
-"as no filter selected."
+"However, FreshRSS also supports several additional features not covered by "
+"the basic OPML specification. Luckily, the [OPML "
+"specification](http://opml.org/spec2.opml) allows extensions:"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:150
-msgid "![Attribute filters in 0.8](../img/users/status.filter.0.8.png)"
+#: en/./developers/OPML.md:9
+#, markdown-text, no-wrap
+msgid ""
+"> *An OPML file may contain elements and attributes not described on this "
+"page, only if those elements are defined in a namespace.*\n"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:152
-msgid "By default, this filter displays only unread articles"
+#: en/./developers/OPML.md:11
+#, markdown-text
+msgid "and:"
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/OPML.md:13
+#, markdown-text, no-wrap
+msgid ""
+"> *OPML can also be extended by the addition of new values for the type "
+"attribute.*\n"
msgstr ""
#. type: Title ##
-#: en/./users/03_Main_view.md:153
-#, no-wrap
-msgid "By content"
+#: en/./developers/OPML.md:14
+#, markdown-text, no-wrap
+msgid "FreshRSS OPML extension"
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:156
+#: en/./developers/OPML.md:17
+#, markdown-text
msgid ""
-"It is possible to filter articles by their content by inputting a string in "
-"the search field."
+"FreshRSS uses the XML namespace <https://freshrss.org/opml> to export/import "
+"extended information not covered by the basic OPML specification."
msgstr ""
-#. type: Title ##
-#: en/./users/03_Main_view.md:157
-#, no-wrap
-msgid "With the search field"
+#. type: Plain text
+#: en/./developers/OPML.md:19
+#, markdown-text
+msgid ""
+"The list of the custom FreshRSS attributes can be seen in [the source "
+"code](https://github.com/FreshRSS/FreshRSS/blob/edge/app/views/helpers/export/opml.phtml), "
+"and here is an overview:"
+msgstr ""
+
+#. type: Title ###
+#: en/./developers/OPML.md:20
+#, markdown-text, no-wrap
+msgid "HTML+XPath or XML+XPath"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:23
+#, markdown-text
+msgid ""
+"`<outline type=\"HTML+XPath\" ...`: Additional type of source, which is not "
+"RSS/Atom, but HTML Web Scraping using "
+"[XPath](https://www.w3.org/TR/xpath-10/) 1.0."
msgstr ""
#. type: Plain text
-#: en/./users/03_Main_view.md:160
-msgid "You can use the search field to further refine results:"
+#: en/./developers/OPML.md:25
+#, markdown-text, no-wrap
+msgid ""
+"> ℹ️ [XPath 1.0](https://en.wikipedia.org/wiki/XPath) is a standard query "
+"language, which FreshRSS supports to enable [Web "
+"scraping](https://en.wikipedia.org/wiki/Web_scraping).\n"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/03_Main_view.md:199
-msgid "by author: `author:name` or `author:'composed name'`"
+#: en/./developers/OPML.md:27
+#, markdown-text
+msgid ""
+"`<outline type=\"XML+XPath\" ...`: Same than `HTML+XPath` but using an XML "
+"parser."
+msgstr ""
+
+#. type: Plain text
+#: en/./developers/OPML.md:29
+#, markdown-text
+msgid ""
+"The following attributes are using similar naming conventions than "
+"[RSS-Bridge](https://rss-bridge.github.io/rss-bridge/Bridge_API/XPathAbstract.html)."
msgstr ""
#. type: Bullet: '* '
-#: en/./users/03_Main_view.md:199
-msgid "by title: `intitle:keyword` or `intitle:'composed keyword'`"
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid ""
+"`frss:xPathItem`: XPath expression for extracting the feed items from the "
+"source page."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid "Example: `//div[@class=\"news-item\"]`"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/03_Main_view.md:199
-msgid "by URL: `inurl:keyword` or `inurl:'composed keyword'`"
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid ""
+"`frss:xPathItemTitle`: XPath expression for extracting the item’s title from "
+"the item context."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid "Example: `descendant::h2`"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/03_Main_view.md:199
-msgid "by tag: `#tag`"
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid ""
+"`frss:xPathItemContent`: XPath expression for extracting an item’s content "
+"from the item context."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid "Example: `.`"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/03_Main_view.md:199
-msgid "by free-text: `keyword` or `'composed keyword'`"
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid ""
+"`frss:xPathItemUri`: XPath expression for extracting an item link from the "
+"item context."
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:199
-#, no-wrap
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid "Example: `descendant::a/@href`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:46
+#, markdown-text
msgid ""
-"* by date of discovery, using the [ISO 8601 time interval "
-"format](http://en.wikipedia.org/wiki/ISO_8601#Time_intervals): "
-"`date:<date-interval>`\n"
-"\t* From a specific day, or month, or year:\n"
-"\t\t* `date:2014-03-30`\n"
-"\t\t* `date:2014-03` or `date:201403`\n"
-"\t\t* `date:2014`\n"
-"\t* From a specific time of a given day:\n"
-"\t\t* `date:2014-05-30T13`\n"
-"\t\t* `date:2014-05-30T13:30`\n"
-"\t* Between two given dates:\n"
-"\t\t* `date:2014-02/2014-04`\n"
-"\t\t* `date:2014-02--2014-04`\n"
-"\t\t* `date:2014-02/04`\n"
-"\t\t* `date:2014-02-03/05`\n"
-"\t\t* `date:2014-02-03T22:00/22:15`\n"
-"\t\t* `date:2014-02-03T22:00/15`\n"
-"\t* After a given date:\n"
-"\t\t* `date:2014-03/`\n"
-"\t* Before a given date:\n"
-"\t\t* `date:/2014-03`\n"
-"\t* For a specific duration after a given date:\n"
-"\t\t* `date:2014-03/P1W`\n"
-"\t* For a specific duration before a given date:\n"
-"\t\t* `date:P1W/2014-05-25T23:59:59`\n"
-"\t* For the past duration before now (the trailing slash is optional):\n"
-"\t\t* `date:P1Y/` or `date:P1Y` (past year)\n"
-"\t\t* `date:P2M/` (past two months)\n"
-"\t\t* `date:P3W/` (past three weeks)\n"
-"\t\t* `date:P4D/` (past four days)\n"
-"\t\t* `date:PT5H/` (past five hours)\n"
-"\t\t* `date:PT30M/` (past thirty minutes)\n"
-"\t\t* `date:PT90S/` (past ninety seconds)\n"
-"\t\t* `date:P1DT1H/` (past one day and one hour)\n"
-"* by date of publication, using the same format: `pubdate:<date-interval>`\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./users/03_Main_view.md:201
-msgid "Be careful not to enter a space between the operator and the search value."
+"`frss:xPathItemAuthor`: XPath expression for extracting an item author from "
+"the item context."
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:204
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid "Example: `\"Anonymous\"`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:46
+#, markdown-text
msgid ""
-"Some operators can be used negatively, to exclude articles, with the same "
-"syntax as above, but prefixed by a `!` or `-`: `-author:name`, "
-"`-intitle:keyword`, `-inurl:keyword`, `-#tag`, `!keyword`."
+"`frss:xPathItemTimestamp`: XPath expression for extracting an item timestamp "
+"from the item context. The result will be parsed by "
+"[`strtotime()`](https://php.net/strtotime)."
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:206
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:46
+#, markdown-text
msgid ""
-"It is also possible to combine keywords to create a more precise filter. For "
-"example, you can enter multiple instances of `author:`, `intitle:`, "
-"`inurl:`, `#`, and free-text."
+"`frss:xPathItemTimeFormat`: Date/Time format to parse the timestamp, "
+"according to "
+"[`DateTime::createFromFormat()`](https://php.net/datetime.createfromformat)."
msgstr ""
-#. type: Plain text
-#: en/./users/03_Main_view.md:208
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:46
+#, markdown-text
msgid ""
-"Combining several search criteria implies a logical *and*, but the keyword ` "
-"OR ` can be used to combine several search criteria with a logical *or* "
-"instead: `author:Dupont OR author:Dupond`"
+"`frss:xPathItemThumbnail`: XPath expression for extracting an item’s "
+"thumbnail (image) URL from the item context."
msgstr ""
-#. type: Title #
-#: en/./users/04_Subscriptions.md:1
-#, no-wrap
-msgid "Adding a feed"
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid "Example: `descendant::img/@src`"
msgstr ""
-#. type: Title #
-#: en/./users/04_Subscriptions.md:5
-#, no-wrap
-msgid "Import and export"
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid ""
+"`frss:xPathItemCategories`: XPath expression for extracting a list of "
+"categories (tags) from the item context."
msgstr ""
-#. type: Title #
-#: en/./users/04_Subscriptions.md:9
-#, no-wrap
-msgid "Use bookmarklet"
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:46
+#, markdown-text
+msgid ""
+"`frss:xPathItemUid`: XPath expression for extracting an item’s unique ID "
+"from the item context. If left empty, a hash is computed automatically."
msgstr ""
-#. type: Plain text
-#: en/./users/04_Subscriptions.md:12
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:54
+#, markdown-text
msgid ""
-"Bookmarklets are little scripts that you can execute to perform various "
-"tasks. FreshRSS offers a bookmarklet for subscribing to newsfeeds."
+"`frss:cssFullContent`: [CSS "
+"Selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) to "
+"enable the download and extraction of the matching HTML section of each "
+"articles’ Web address."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:54
+#, markdown-text
+msgid "Example: `div.main, .summary`"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/04_Subscriptions.md:16
-msgid "Open \"Subscriptions management\"."
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:54
+#, markdown-text
+msgid ""
+"`frss:cssFullContentFilter`: [CSS "
+"Selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) to "
+"remove the matching HTML elements from the full content retrieved by "
+"`frss:cssFullContent`."
msgstr ""
-#. type: Bullet: ' 2. '
-#: en/./users/04_Subscriptions.md:16
-msgid "Click on \"Subscription tools\"."
+#. type: Bullet: ' * '
+#: en/./developers/OPML.md:54
+#, markdown-text
+msgid "Example: `.footer, .aside`"
msgstr ""
-#. type: Bullet: ' 3. '
-#: en/./users/04_Subscriptions.md:16
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:54
+#, markdown-text
msgid ""
-"Drag the \"Subscribe\" button to your bookmark toolbar or right click and "
-"choose your browser’s \"Bookmark link\" action."
+"`frss:filtersActionRead`: List (separated by a new line) of search queries "
+"to automatically mark a new article as read."
msgstr ""
-#. type: Title #
-#: en/./users/04_Subscriptions.md:17
-#, no-wrap
-msgid "Feed management"
+#. type: Title ###
+#: en/./developers/OPML.md:55
+#, markdown-text, no-wrap
+msgid "Dynamic OPML (reading lists)"
msgstr ""
-#. type: Title #
-#: en/./users/05_Configuration.md:2
-#, no-wrap
-msgid "Display"
+#. type: Bullet: '* '
+#: en/./developers/OPML.md:58
+#, markdown-text
+msgid ""
+"`frss:opmlUrl`: If non-empty, indicates that this outline (category) should "
+"be dynamically populated from a remote OPML at the specified URL."
msgstr ""
-#. type: Title ##
-#: en/./users/05_Configuration.md:4
-#, no-wrap
-msgid "Language"
+#. type: Title ###
+#: en/./developers/OPML.md:59
+#, markdown-text, no-wrap
+msgid "Example"
+msgstr ""
+
+#. type: Fenced code block (xml)
+#: en/./developers/OPML.md:61
+#, no-wrap
+msgid ""
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<opml version=\"2.0\">\n"
+"\t<head>\n"
+"\t\t<title>FreshRSS OPML extension example</title>\n"
+"\t</head>\n"
+"\t<body>\n"
+"\t\t<outline xmlns:frss=\"https://freshrss.org/opml\"\n"
+"\t\t\ttext=\"Example\"\n"
+"\t\t\ttype=\"HTML+XPath\"\n"
+"\t\t\txmlUrl=\"https://www.example.net/page.html\"\n"
+"\t\t\thtmlUrl=\"https://www.example.net/page.html\"\n"
+"\t\t\tdescription=\"Example of Web scraping\"\n"
+"\t\t\tfrss:xPathItem=\"//a[contains(@href, "
+"'/interesting/')]/ancestor::article\"\n"
+"\t\t\tfrss:xPathItemTitle=\"descendant::h2\"\n"
+"\t\t\tfrss:xPathItemContent=\".\"\n"
+"\t\t\tfrss:xPathItemUri=\"descendant::a[string-length(@href)&gt;0]/@href\"\n"
+"\t\t\tfrss:xPathItemThumbnail=\"descendant::img/@src\"\n"
+"\t\t\tfrss:cssFullContent=\"article\"\n"
+"\t\t\tfrss:filtersActionRead=\"intitle:⚡️ OR intitle:🔥&#10;something\"\n"
+"\t\t/>\n"
+"\t</body>\n"
+"</opml>\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:9
-msgid ""
-"FreshRSS is currently available in 14 languages. After confirming your "
-"choice, the interface will be displayed in your preferred language. "
-"Depending on the language chosen, parts of the interface may not be not "
-"translated yet. If you’re willing to help translate the missing bits or "
-"would like to add a new language, please take a look at how you can "
-"[contribute to the "
-"project](../contributing.md#contribute-to-internationalization-i18n)."
+#: en/./index.md:2
+#, markdown-text
+msgid "![FreshRSS logo](img/logo_freshrss.png)"
+msgstr ""
+
+#. type: Title #
+#: en/./index.md:3
+#, markdown-text, no-wrap
+msgid "FreshRSS manual (English)"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:11
+#: en/./index.md:6
+#, markdown-text
msgid ""
-"Some parts of FreshRSS aren’t translated and aren’t intended to be "
-"translated either. For now, this includes the logs visible in the "
-"application as well as the log generated by automatic update scripts."
+"FreshRSS is an RSS aggregator and reader. It allows you to read and follow "
+"several news websites at a glance without the need to browse from one "
+"website to another."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:13
+#: en/./index.md:10
+#, markdown-text
+msgid "FreshRSS has a lot of features including:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "RSS and Atom aggregation"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "Mark article as favorite if you liked it or if you want to read it later"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "Filter and search functionality helps to easily find articles"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "Statistics to show you the publishing frequency all the websites you follow"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "Import/export of your feeds into OPML format"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "Several themes created by the community"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "Several extensions created by the community"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "\"Google Reader\"-like API to connect Android applications"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid ""
+"The application is \"responsive,\" which means it adapts to small screens so "
+"you can bring articles in your pocket"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
msgid ""
-"Available languages are: cz, de, en, es, fr, he, it, ko, nl, oc, pt-br, ru, "
-"tr, zh-cn."
+"Self-hosted: the code is free (under AGPL3 licence), so you can host your "
+"own instance of FreshRSS"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "Multi-user, so you can also host for your friends and family"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "share article links with a bunch of services"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:24
+#, markdown-text
+msgid "And a lot more!"
msgstr ""
#. type: Title ##
-#: en/./users/05_Configuration.md:14
-#, no-wrap
-msgid "Theme"
+#: en/./index.md:25
+#, markdown-text, no-wrap
+msgid "Manual Chapters"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:17
+#: en/./index.md:28
+#, markdown-text
+msgid "This documentation is split into different sections:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./index.md:33
+#, markdown-text
msgid ""
-"There’s no accounting for tastes, which is why FreshRSS offers eight "
-"official themes:"
+"[User documentation](./users/02_First_steps.md), where you can discover all "
+"the possibilities offered by FreshRSS"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Blue Lagoon* by **Mister aiR**"
+#. type: Bullet: '* '
+#: en/./index.md:33
+#, markdown-text
+msgid ""
+"[Administrator documentation](./admins/01_Index.md) for detailed "
+"installation and maintenance related tasks"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Dark* by **AD**"
+#. type: Bullet: '* '
+#: en/./index.md:33
+#, markdown-text
+msgid ""
+"[Developer documentation](./developers/01_Index.md) to guide you in the "
+"source code of FreshRSS and to help you if you want to contribute"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Flat design* by **Marien Fressinaud**"
+#. type: Bullet: '* '
+#: en/./index.md:33
+#, markdown-text
+msgid ""
+"[Contributor guidelines](./contributing.md) for those who want to help "
+"improve FreshRSS"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Origine* by **Marien Fressinaud**"
+#. type: Title ##
+#: en/./index.md:34
+#, markdown-text, no-wrap
+msgid "Demo"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Origine-compact* by **Kevin Papst**"
+#. type: Plain text
+#: en/./index.md:37
+#, markdown-text
+msgid ""
+"The official demo of FreshRSS is available under "
+"[https://demo.freshrss.org/](https://demo.freshrss.org/)."
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Pafat* by **Plopoyop**"
+#. type: Plain text
+#: en/./index.md:39
+#, markdown-text
+msgid "Login credentials:"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Screwdriver* by **Mister aiR**"
+#. type: Bullet: '* '
+#: en/./index.md:42
+#, markdown-text
+msgid "Username: demo"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:26
-msgid "*Swage* by **Patrick Crandol**"
+#. type: Bullet: '* '
+#: en/./index.md:42
+#, markdown-text
+msgid "Password: demodemo"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:28
+#: en/./index.md:44
+#, markdown-text
msgid ""
-"If you can’t find any themes you like, it’s always possible to [create your "
-"own](../developers/04_Frontend/02_Design.md)."
+"Another chance to try out, but not official supported by FreshRSS: The "
+"application is listed on Softaculous "
+"[https://www.softaculous.com/apps/rss/FreshRSS](https://www.softaculous.com/apps/rss/FreshRSS)."
+msgstr ""
+
+#. type: Title ##
+#: en/./index.md:45
+#, markdown-text, no-wrap
+msgid "Licence"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:30
+#: en/./index.md:47
+#, markdown-text
+msgid "FreshRSS is licensed under the GNU Affero General Public License v3.0."
+msgstr ""
+
+#. type: Title #
+#: en/./internationalization.md:1
+#, markdown-text, no-wrap
+msgid "Contributing to internationalization (i18n)"
+msgstr ""
+
+#. type: Plain text
+#: en/./internationalization.md:4
+#, markdown-text
msgid ""
-"To select a theme, simply scroll through the themes and select one that "
-"strikes your fancy. After confirmation, the theme will be applied to the "
-"interface."
+"Thanks to our contributors, FreshRSS is translated into [more than 20 "
+"languages](./users/05_Configuration.md#language). This section will explain "
+"the basics of internationalization in FreshRSS, from translating the "
+"application to your own language to making a specific change."
msgstr ""
#. type: Title ##
-#: en/./users/05_Configuration.md:31
-#, no-wrap
-msgid "Content width"
+#: en/./internationalization.md:5
+#, markdown-text, no-wrap
+msgid "Overview"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:34
+#: en/./internationalization.md:8
+#, markdown-text
msgid ""
-"Some people prefer short lines of text, while others prefer to maximize the "
-"available screen space. To satisfy the maximum number of people, it’s "
-"possible to customize the width of the displayed content. There are four "
-"settings available:"
+"It is common (and that’s an understatement) to want to show some text to the "
+"user. The problem is that FreshRSS has users of different nationalities. It "
+"is therefore necessary to be able to manage different languages in order not "
+"to remain confined to English or French."
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:39
-msgid "**Fine** displays content up to a maximum width of 550 pixels"
+#. type: Plain text
+#: en/./internationalization.md:10
+#, markdown-text
+msgid ""
+"The solution is to use the `Minz_Translate` module, which allows dynamic "
+"translation of FreshRSS. 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 `app/i18n/`. For example, English "
+"language files are located in [`app/i18n/en/`](/app/i18n/en/). There are "
+"seven different files:"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:39
-msgid "**Medium** displays content up to a maximum width of 800 pixels"
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`admin.php` for anything related to FreshRSS administration"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:39
-msgid "**Large** displays content up to a maximum width of 1000 pixels"
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`conf.php` for configuration"
msgstr ""
-#. type: Bullet: ' * '
-#: en/./users/05_Configuration.md:39
-msgid "**No limit** displays the content on 100% of the available space"
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`feedback.php` contains translations of feedback messages"
msgstr ""
-#. type: Title ##
-#: en/./users/05_Configuration.md:40
-#, no-wrap
-msgid "Article icons"
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`gen.php` stores what is global to FreshRSS (`gen` stands for “general”)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`index.php` for the main page that lists feeds and the About page"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`install.php` contains strings related to the installation"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`sub.php` for subscription management (`sub` stands for “subscription”)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./internationalization.md:19
+#, markdown-text
+msgid "`user.php` contains some strings related to the User model"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:43
-msgid "Please note that this section only affects normal view."
+#: en/./internationalization.md:21
+#, markdown-text
+msgid "This organization makes it possible to avoid a single huge translation file."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:45
-msgid "![Article icons configuration](../img/users/configuration.article.icons.png)"
+#: en/./internationalization.md:23
+#, markdown-text
+msgid ""
+"The translation files are quite simple: it’s only a matter of returning a "
+"PHP array containing the translations. As an example, here’s an extract from "
+"[`app/i18n/fr/gen.php`](/app/i18n/fr/gen.php):"
+msgstr ""
+
+#. type: Fenced code block (php)
+#: en/./internationalization.md:24
+#, no-wrap
+msgid ""
+"<?php\n"
+"return array(\n"
+"\t'action' => [\n"
+"\t\t'actualize' => 'Actualiser',\n"
+"\t\t'back_to_rss_feeds' => '← Retour à vos flux RSS',\n"
+"\t\t'cancel' => 'Annuler',\n"
+"\t\t'create' => 'Créer',\n"
+"\t\t'disable' => 'Désactiver',\n"
+"\t),\n"
+"\t'freshrss' => array(\n"
+"\t\t'_' => 'FreshRSS',\n"
+"\t\t'about' => 'À propos de FreshRSS',\n"
+"\t),\n"
+"\t// ...\n"
+");\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:48
+#: en/./internationalization.md:43
+#, markdown-text
msgid ""
-"Each article is rendered with a header (top line) and a footer (bottom "
-"line). In that section, you can choose what will be displayed in those."
+"Each value can be referenced by a key: it consists of a series of "
+"identifiers separated by dots. The first identifier indicates from which "
+"file to extract the translation, while the following ones indicate array "
+"entries. Thus, the `gen.freshrss.about` key is referencing the `about` entry "
+"from the `freshrss` entry which is part of the main array returned by the "
+"`gen.php` file. This allows us to further organize our translation files."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:52
+#: en/./internationalization.md:45
+#, markdown-text
msgid ""
-"If you disable every item in the top line, you’ll still be able to see it "
-"since it contains the feed name and the article title. But if you do the "
-"same thing for the bottom line, it will be empty."
+"You should not have to write the array by yourself and we provide several "
+"commands to ease the manipulation of these files. Let’s see some common use "
+"cases."
msgstr ""
#. type: Title ##
-#: en/./users/05_Configuration.md:53
+#: en/./internationalization.md:46
+#, markdown-text, no-wrap
+msgid "Add support for a new language"
+msgstr ""
+
+#. type: Plain text
+#: en/./internationalization.md:49
+#, markdown-text
+msgid ""
+"If you want to add support for a language which isn’t supported by FreshRSS "
+"yet, you can run this command:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./internationalization.md:50
#, no-wrap
-msgid "HTML5 notification timout"
+msgid "make i18n-add-language lang=[your language code]\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:56
+#: en/./internationalization.md:55
+#, markdown-text
msgid ""
-"After automatically updating the feeds, FreshRSS can pop up a notification "
-"using the HTML5 notification API."
+"You must replace `[your language code]` by the language tag of your "
+"language. It must follow the [IETF BCP 47 "
+"standard](https://en.wikipedia.org/wiki/IETF_language_tag). For instance, "
+"English is `en` and French is `fr`. You can target a specific region with a "
+"subtag, for instance `pt-br` for Brazilian Portuguese. If you’re not sure of "
+"the code, Wikipedia might be a good start to find it or you can ask us for "
+"help too."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:58
-msgid "The duration of this notification can be set. By default, the value is 0."
+#: en/./internationalization.md:57
+#, markdown-text
+msgid ""
+"The command will create a new subfolder under `app/i18n/` and copy the "
+"strings from the reference language (i.e. English). It will also mark all "
+"the translations with a special tag represented by a comment: `// TODO - "
+"Translation`. We’ll see in the next section how to translate the strings."
msgstr ""
#. type: Title ##
-#: en/./users/05_Configuration.md:59
-#, no-wrap
-msgid "Show the navigation button"
+#: en/./internationalization.md:58
+#, markdown-text, no-wrap
+msgid "Translate the interface"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:62
+#: en/./internationalization.md:61
+#, markdown-text
msgid ""
-"By default, FreshRSS displays buttons to ease the article navigation when "
-"browsing on mobile. The drawback is that they eat up some precious space."
+"You might have noticed some strings are not yet translated from English even "
+"though you’ve selected a different language. This is because we mostly speak "
+"English or French and it’s pretty difficult to us to speak all the different "
+"languages!"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:64
+#: en/./internationalization.md:63
+#, markdown-text
msgid ""
-"![navigation button "
-"configuration](../img/users/configuration.navigation.button.png)"
+"To update a string, you just have to open its file, find the string, and "
+"change it (without removing the quotes around it!) You might want to remove "
+"the comment at the end of the line, but you should prefer to use the "
+"following command:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./internationalization.md:64
+#, no-wrap
+msgid "make i18n-format\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:66
+#: en/./internationalization.md:69
+#, markdown-text
msgid ""
-"If you don’t use those buttons because you never browse on mobile or because "
-"you browse with gestures, you can disable them from the interface."
+"It will remove the comments on the lines that you’ve changed, and will "
+"reformat the file correctly. If you’ve made any mistakes, it will fix them "
+"automatically or it will tell you it can’t (well… the command will "
+"dramatically fail without any damage, don’t worry)."
msgstr ""
-#. type: Title #
-#: en/./users/05_Configuration.md:67
+#. type: Plain text
+#: en/./internationalization.md:71
+#, markdown-text
+msgid ""
+"The strings to translate can be easily found in the translations files "
+"thanks to the tag we spoke about at the end of the previous section. Indeed, "
+"it indicates to our tools that the strings are not translated yet. This "
+"means you can find them with Git. For instance for the Greek language:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./internationalization.md:72
#, no-wrap
-msgid "Reading"
+msgid "git grep TODO app/i18n/he\n"
msgstr ""
#. type: Title ##
-#: en/./users/05_Configuration.md:71 en/./users/05_Configuration.md:154
+#: en/./internationalization.md:76
+#, markdown-text, no-wrap
+msgid "Acknowledge a false-positive"
+msgstr ""
+
+#. type: Plain text
+#: en/./internationalization.md:79
+#, markdown-text
+msgid ""
+"Our tool detects if a string needs to be translated if it equals to the "
+"English version. For instance, the word “version” is the same in English and "
+"French. Thus, our tool would mark the French word to be translated. This is, "
+"in fact, the case for the `index.about.version` key. This case is considered "
+"as a false-positive because the word _is_ actually translated. To aknowledge "
+"such translations, you can run:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./internationalization.md:80
#, no-wrap
-msgid "Archival"
+msgid "make i18n-ignore-key lang=fr key=index.about.version\n"
msgstr ""
-#. type: Title #
-#: en/./users/05_Configuration.md:75
+#. type: Plain text
+#: en/./internationalization.md:85
+#, markdown-text
+msgid ""
+"This command adds an IGNORE comment on the translation so the key can be "
+"considered as translated."
+msgstr ""
+
+#. type: Title ##
+#: en/./internationalization.md:86
+#, markdown-text, no-wrap
+msgid "Add/remove/update a key"
+msgstr ""
+
+#. type: Plain text
+#: en/./internationalization.md:89
+#, markdown-text
+msgid ""
+"If you’re developing a new part of the application, you might want to "
+"declare a new translation key. Your first impulse would be to add the key to "
+"each file manually: don’t do that, it’s very painful. We provide another "
+"command:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./internationalization.md:90
#, no-wrap
-msgid "Sharing"
+msgid "make i18n-add-key key=the.key.to.add value='Your string in English'\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:78
-msgid "To make your life easier, you can share articles straight from FreshRSS."
+#: en/./internationalization.md:95
+#, markdown-text
+msgid ""
+"This adds the key to all the files. It’ll be in English, waiting for other "
+"translators."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:80
+#: en/./internationalization.md:97
+#, markdown-text
msgid ""
-"At the moment, FreshRSS supports 18 sharing methods, ranging from "
-"self-hosted services (Shaarli, etc.) to proprietary services (Facebook, "
-"etc.)."
+"Conversely, you may want to remove a key that is no longer used in the "
+"application with:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./internationalization.md:98
+#, no-wrap
+msgid "make i18n-remove-key key=the.key.to.remove\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:83
+#: en/./internationalization.md:103
+#, markdown-text
msgid ""
-"By default, the sharing list is empty. ![Sharing "
-"configuration](../img/users/configuration.sharing.png)"
+"Finally, if the English version of a string needs to be changed, you need to "
+"consider two cases. If the change doesn’t impact the meaning of the "
+"sentence, and therefore other languages don’t need to change (e.g. to fix a "
+"typo), you should make the change manually in the file. In any other case, "
+"you should use the following command:"
+msgstr ""
+
+#. type: Fenced code block (sh)
+#: en/./internationalization.md:104
+#, no-wrap
+msgid ""
+"make i18n-update-key key=the.key.to.change value='The new string in "
+"English'\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:85
-msgid "To add a new item to the list, please follow the following simple steps:"
+#: en/./internationalization.md:109
+#, markdown-text
+msgid "The key will simply be removed and added back with the new value."
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:90
-msgid "Select the desired sharing method in the drop-down list."
+#. type: Title ##
+#: en/./internationalization.md:110
+#, markdown-text, no-wrap
+msgid "How to access a translation programmatically"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:90
-msgid "Press the ```✚``` button to add it to the list."
+#. type: Plain text
+#: en/./internationalization.md:113
+#, markdown-text
+msgid ""
+"To access these translations, you must use the `_t()` function (which is a "
+"shortcut for `Minz_Translate::t()`). Code example:"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:90
+#. type: Fenced code block (html)
+#: en/./internationalization.md:114
+#, no-wrap
msgid ""
-"Configure the method in the list. All names can be modified in the "
-"display. Some methods need the sharing URL to be able to work properly (ex: "
-"Shaarli)."
+"<p>\n"
+"\t<?= _t('gen.freshrss.about') ?>\n"
+"</p>\n"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:90 en/./users/05_Configuration.md:95
-msgid "Submit your changes."
+#. type: Plain text
+#: en/./internationalization.md:121
+#, markdown-text
+msgid ""
+"The function expects a translation key, but there’s a special case that "
+"sometimes makes life easier: the `_` identifier. This must necessarily be "
+"present at the end of the chain and gives a value to the higher-level "
+"identifier. It’s pretty hard to explain but very simple to understand. In "
+"the example given above, an `_` is associated with the value `FreshRSS`: "
+"this means that there is no need to write `_t('gen.freshrss._')` but "
+"`_t('gen.freshrss')` suffices."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:92
-msgid "To remove an item from the list, follow those simple steps:"
+#: en/./internationalization.md:123
+#, markdown-text
+msgid ""
+"`_t()` can take any number of variables. The variables will then be replaced "
+"in the translation if it contains some “conversion specifications” (usually "
+"`%s` or `%d`). You can learn more about these specifications in the "
+"[`sprintf()` PHP function "
+"documentation](https://www.php.net/manual/function.sprintf)."
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:95
-msgid "Press the ```❌``` button next to the share method you want to remove."
+#. type: Plain text
+#: en/./internationalization.md:125
+#, markdown-text, no-wrap
+msgid ""
+"For instance, the English translation for `gen.auth.keep_logged_in` is `Keep "
+"me logged in <small>(%s days)</small>`. It means this translation expects a "
+"string to be passed as an argument to the `t()` function (well, it should be "
+"a `%d` because we want a number here, but it doesn’t matter). For "
+"instance:\n"
msgstr ""
-#. type: Title #
-#: en/./users/05_Configuration.md:96
+#. type: Fenced code block (php)
+#: en/./internationalization.md:126
#, no-wrap
-msgid "Shortcuts"
+msgid ""
+"<label>\n"
+"\t<input type=\"checkbox\" name=\"keep_logged_in\" />\n"
+"\t<?= _t('gen.auth.keep_logged_in', 30) ?>\n"
+"</label>\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:100
+#: en/./users/02_First_steps.md:2
+#, markdown-text
msgid ""
-"To ease the use of the application, FreshRSS comes with a lot of predefined "
-"keyboard shortcuts. They allow actions to improve the user experience with "
-"a keyboard."
+"Learning how to handle a new application is not always easy. We’ve tried to "
+"make FreshRSS as intuitive as possible, but you might still need a little "
+"help to master the program."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:102
+#: en/./users/02_First_steps.md:4
+#, markdown-text
msgid ""
-"Of course, if you’re not satisfied with the key mapping, you can change you "
-"configuration to fit your needs."
+"This section will guide you to the pages you need to get started. The order "
+"is tailored to newcomers."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:104
-msgid "There are 4 types of shortcuts:"
+#: en/./users/02_First_steps.md:6
+#, markdown-text
+msgid ""
+"[After installing the application](../admins/03_Installation.md), the first "
+"step is to add some feeds. You have a few options:"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:109
-msgid "Views: they allow switching views with ease."
+#. type: Bullet: '1. '
+#: en/./users/02_First_steps.md:10
+#, markdown-text
+msgid "[Add a feed manually](04_Subscriptions.md#adding-a-feed)"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:109
-msgid "Navigation: they allow navigation through articles, feeds, and categories."
+#. type: Bullet: '2. '
+#: en/./users/02_First_steps.md:10
+#, markdown-text
+msgid "[Import an OPML or JSON file](04_Subscriptions.md#import-and-export)"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:109
+#. type: Bullet: '3. '
+#: en/./users/02_First_steps.md:10
+#, markdown-text
+msgid "[Use the bookmarklet](04_Subscriptions.md#use-bookmarklet)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/02_First_steps.md:12
+#, markdown-text
msgid ""
-"Article actions: they allow interactions with an article, like sharing or "
-"opening it on the original web-site."
+"Once you have added your feeds to FreshRSS, it is time to read them. There "
+"are three available reading modes:"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:109
+#. type: Bullet: '1. '
+#: en/./users/02_First_steps.md:16
+#, markdown-text
msgid ""
-"Other actions: they allow other interactions with the application, like "
-"opening the user queries menu or accessing the documentation."
+"[The normal view](03_Main_view.md#normal-view) enables you to quickly read "
+"new articles"
msgstr ""
-#. type: Plain text
-#: en/./users/05_Configuration.md:112
+#. type: Bullet: '2. '
+#: en/./users/02_First_steps.md:16
+#, markdown-text
msgid ""
-"It’s worth noting that the share article action has two levels. Once you "
-"press the shortcut, a menu containing all the share options opens. To "
-"choose one share option, you need to select it by its number. When there is "
-"only one option, it’s selected automatically though."
+"[The global view](03_Main_view.md#global-view) shows you an overview of the "
+"status of your feeds in one glance"
msgstr ""
-#. type: Plain text
-#: en/./users/05_Configuration.md:114
-msgid "The same process applies to the user queries."
+#. type: Bullet: '3. '
+#: en/./users/02_First_steps.md:16
+#, markdown-text
+msgid ""
+"[The reader view](03_Main_view.md#reader-view) offers you a comfortable "
+"reading experience"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:117
+#: en/./users/02_First_steps.md:18
+#, markdown-text
msgid ""
-"Be aware that there is no validation on the selected shortcuts. This means "
-"that if you assign a shortcut to more than one action, you’ll end up with "
-"some unexpected behavior."
+"Now that you’ve mastered basic use, it’s time to configure FreshRSS to "
+"improve your reading experience. It’s highly configurable, so it’s "
+"recommended to play around with them to find a configuration that suits you "
+"well. Here are a few resources to help you improve your daily FreshRSS "
+"experience:"
msgstr ""
-#. type: Title #
-#: en/./users/05_Configuration.md:118
-#, no-wrap
-msgid "User queries"
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Organize your feeds in categories](04_Subscriptions.md#feed-management)"
msgstr ""
-#. type: Plain text
-#: en/./users/05_Configuration.md:122
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Change the home page](05_Configuration.md#changing-the-view)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Choose the reading options](05_Configuration.md#reading-options)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Refresh feeds](09_refreshing_feeds.md)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Filter articles](10_filter.md) for a fast access to a selection"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
msgid ""
-"You can configure your [user queries](./03_Main_view.md) in that "
-"section. There is not much to say here as it is pretty straightforward. You "
-"can only change user query titles or drop them."
+"[search for an article](10_filter.md#with-the-search-field) published some "
+"time ago"
msgstr ""
-#. type: Plain text
-#: en/./users/05_Configuration.md:124
-msgid "At the moment, there is no helper to build a user query from here."
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Access your feeds on a mobile device](06_Mobile_access.md)"
msgstr ""
-#. type: Title #
-#: en/./users/05_Configuration.md:125
-#, no-wrap
-msgid "Users"
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Add some extensions](https://github.com/FreshRSS/Extensions)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/02_First_steps.md:27
+#, markdown-text
+msgid "[Frequently asked questions](07_Frequently_Asked_Questions.md)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/03_Main_view.md:4
+#, markdown-text
+msgid "FreshRSS has three primary viewing modes: Normal, Global, and Reader view."
msgstr ""
#. type: Title ##
-#: en/./users/05_Configuration.md:129
-#, no-wrap
-msgid "Authentication methods"
+#: en/./users/03_Main_view.md:5
+#, markdown-text, no-wrap
+msgid "Normal view"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/03_Main_view.md:8
+#, markdown-text
+msgid ""
+"Normal view will allow you to view articles in a compressed view. They can "
+"be separated by category or individual feed, or viewed in the \"main "
+"stream\" containing all feeds. Clicking a feed in the sidebar (mobile users "
+"will need to click the folder icon to open it) will open that feed’s view."
msgstr ""
#. type: Title ###
-#: en/./users/05_Configuration.md:131
-#, no-wrap
-msgid "HTTP Authentication (Apache)"
+#: en/./users/03_Main_view.md:9
+#, markdown-text, no-wrap
+msgid "Article List"
msgstr ""
-#. type: Bullet: ' 1. '
-#: en/./users/05_Configuration.md:137
-msgid "User control is based on the `.htaccess` file."
+#. type: Plain text
+#: en/./users/03_Main_view.md:18
+#, markdown-text
+msgid ""
+"By default, the normal view includes six items per article. From left to "
+"right: * **Read status:** An envelope icon to show if the article has been "
+"read or not. Closed envelopes are unread, open envelopes are read. Clicking "
+"on the icon will toggle the read status. * **Favourite status:** A star "
+"icon to show if the article has been favourited or not. Filled stars are "
+"favourited, empty stars are not. Clicking on the icon will toggle the "
+"favourite status. * **Feed name:** The name of the feed that the article is "
+"from. Clicking the feed name will move to that feed’s view in normal view. "
+"* **Article title:** The title of the article. Clicking will open the "
+"article for viewing within FreshRSS. * **Article date/time:** The time the "
+"article was posted. * **Link to original article:** A globe icon that can "
+"be clicked to go to the article on the original website."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/03_Main_view.md:19
+#, markdown-text, no-wrap
+msgid "Normal View Sidebar"
msgstr ""
-#. type: Bullet: ' 2. '
-#: en/./users/05_Configuration.md:137
+#. type: Plain text
+#: en/./users/03_Main_view.md:28
+#, markdown-text
msgid ""
-"It is best practice to place the `.htaccess` file in the `./i/` subdirectory "
-"so the API and other third party services can work."
+"Clicking the gear icon next to an individual feed will display additional "
+"options for that feed. * **Filter:** Run the defined filter to mark "
+"articles as read * **Statistics:** View statistics about the feed * **See "
+"website:** Open the feed’s website in another tab * **Manage:** Configure "
+"the feed * **Actualize:** Force-update the feed * **Mark as read:** Mark all "
+"items in the feed as read"
msgstr ""
-#. type: Bullet: ' 3. '
-#: en/./users/05_Configuration.md:137
+#. type: Title ##
+#: en/./users/03_Main_view.md:29
+#, markdown-text, no-wrap
+msgid "Global view"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/03_Main_view.md:32
+#, markdown-text
msgid ""
-"If you want to limit all access to registered users only, place the file in "
-"the FreshRSS directory itself or in a parent directory. Note that WebSub and "
-"API will not work!"
+"Global view allows quick views of feed’s statuses at once. Feeds and "
+"categories are shown with the number of unread articles next to "
+"them. Clicking a feed’s name will open it in a view similar to normal view."
msgstr ""
-#. type: Bullet: ' 4. '
-#: en/./users/05_Configuration.md:137
-msgid "Example `.htaccess` file for a user \"marie\":"
+#. type: Title ##
+#: en/./users/03_Main_view.md:33
+#, markdown-text, no-wrap
+msgid "Reader view"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:138
-#, no-wrap
+#: en/./users/03_Main_view.md:36
+#, markdown-text
msgid ""
-"AuthUserFile /home/marie/repertoire/.htpasswd\n"
-"AuthGroupFile /dev/null\n"
-"AuthName \"Chez Marie\"\n"
-"AuthType Basic\n"
-"Require user marie\n"
+"Reader view will display a feed will all articles already open for "
+"reading. Feeds can be switched by clicking the folder icon at the top to "
+"bring up the category/feed sidebar."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:147
+#: en/./users/03_Main_view.md:40
+#, markdown-text
msgid ""
-"More information can be found in the [Apache "
-"documentation](http://httpd.apache.org/docs/trunk/howto/auth.html#gettingitworking)."
+"Read more: * [Refreshing the feeds](./09_refreshing_feeds.md) * [Filter the "
+"feeds and search](./10_filter.md)"
msgstr ""
#. type: Title #
-#: en/./users/05_Configuration.md:148
-#, no-wrap
+#: en/./users/04_Subscriptions.md:1
+#, markdown-text, no-wrap
+msgid "Adding a feed"
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/04_Subscriptions.md:10
+#, markdown-text
+msgid ""
+"To add a feed, copy the URL of its RSS or Atom file (for instance, the "
+"Framablog RSS URL is `https://framablog.org/feed/`). FreshRSS is able to "
+"automatically find the address of the feed for websites that are declaring "
+"it in a standard way."
+msgstr ""
+
+#. type: Bullet: '2. '
+#: en/./users/04_Subscriptions.md:10
+#, markdown-text
+msgid "In FreshRSS, click the \"**+**\" button next to “Subscriptions management”."
+msgstr ""
+
+#. type: Bullet: '3. '
+#: en/./users/04_Subscriptions.md:10
+#, markdown-text
+msgid "Paste the URL in the “Feed URL” field."
+msgstr ""
+
+#. type: Bullet: '4. '
+#: en/./users/04_Subscriptions.md:10
+#, markdown-text
+msgid ""
+"(optional): You can select the category for your feed. By default, it will "
+"be in “Uncategorized”."
+msgstr ""
+
+#. type: Bullet: '5. '
+#: en/./users/04_Subscriptions.md:10
+#, markdown-text
+msgid ""
+"(optional): If the subscription requires credentials, you can enter them in "
+"the \"HTTP username\" and \"HTTP password\" fields."
+msgstr ""
+
+#. type: Bullet: '6. '
+#: en/./users/04_Subscriptions.md:10
+#, markdown-text
+msgid "(optional): You can set a timeout for the feed request."
+msgstr ""
+
+#. type: Bullet: '7. '
+#: en/./users/04_Subscriptions.md:10
+#, markdown-text
+msgid ""
+"(optional): You can choose to ignore SSL certificate errors (such as with "
+"self-signed certificates) by setting \"Verify SSL security\" to \"No\". This "
+"is not recommended, and it is better to either add the root certificate to "
+"the FreshRSS server or to fix the SSL certificate problems on the feed "
+"hosting server."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/04_Subscriptions.md:11
+#, markdown-text, no-wrap
msgid "Subscription management"
msgstr ""
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:14
+#, markdown-text
+msgid ""
+"The \"Subscription management\" submenu allows categories and feeds to be "
+"configured. Feeds can be moved between categories by drag-and-drop, or in "
+"the individual feed’s settings. Hovering over a feed/category will cause a "
+"gear icon to appear. Clicking the icon will bring up the settings for that "
+"item."
+msgstr ""
+
#. type: Title ##
-#: en/./users/05_Configuration.md:150
-#, no-wrap
+#: en/./users/04_Subscriptions.md:15
+#, markdown-text, no-wrap
+msgid "Category Settings"
+msgstr ""
+
+#. type: Title ###
+#: en/./users/04_Subscriptions.md:17
+#, markdown-text, no-wrap
msgid "Information"
msgstr ""
+#. type: Bullet: '* '
+#: en/./users/04_Subscriptions.md:21
+#, markdown-text
+msgid "**Title:** Name of category"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/04_Subscriptions.md:21
+#, markdown-text
+msgid ""
+"**Display position:** Defines the order of categories. Lower numbers get "
+"priority, non-numbered items come last, and equally numbered items will sort "
+"by alphabetical order."
+msgstr ""
+
#. type: Title ##
-#: en/./users/05_Configuration.md:158
-#, no-wrap
-msgid "Login"
+#: en/./users/04_Subscriptions.md:22 en/./users/05_Configuration.md:115
+#, markdown-text, no-wrap
+msgid "Archiving"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:25
+#, markdown-text
+msgid ""
+"If \"Purge Policy\" has \"By default\" selected, then the [default purge "
+"policy](./05_Configuration.md) is used and the other options are not "
+"displayed. Category options will override the default policy, but they will "
+"not override feed-specific options."
msgstr ""
#. type: Title ##
-#: en/./users/05_Configuration.md:162
-#, no-wrap
-msgid "Advanced"
+#: en/./users/04_Subscriptions.md:26
+#, markdown-text, no-wrap
+msgid "Feed Settings"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:29
+#, markdown-text
+msgid ""
+"These fields will be auto-filled when adding a feed, but they can be "
+"modified later. **Visibility** will define if the feed is displayed in the "
+"main feed, only in specific categories, or not at all."
+msgstr ""
+
+#. type: Title #
+#: en/./users/04_Subscriptions.md:30 en/./users/05_Configuration.md:113
+#, markdown-text, no-wrap
+msgid "Archival"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:33
+#, markdown-text
+msgid ""
+"This section will let you override the default settings for feed archiving "
+"and update frequency."
msgstr ""
#. type: Title ###
-#: en/./users/05_Configuration.md:164
-#, no-wrap
-msgid "Retrieve a truncated stream from within FreshRSS"
+#: en/./users/04_Subscriptions.md:34
+#, markdown-text, no-wrap
+msgid "Login"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:167
+#: en/./users/04_Subscriptions.md:37
+#, markdown-text
+msgid ""
+"Some feeds require a username/password submitted over HTTP. These usually "
+"aren’t needed for feeds."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/04_Subscriptions.md:38
+#, markdown-text, no-wrap
+msgid "Advanced"
+msgstr ""
+
+#. type: Title ####
+#: en/./users/04_Subscriptions.md:40
+#, markdown-text, no-wrap
+msgid "Retrieve a truncated feed from within FreshRSS"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:43
+#, markdown-text
msgid ""
-"This question comes up regularly, so we will try to clarify how one can "
+"This question comes up regularly, so we’ll try to clarify how one can "
"retrieve a truncated RSS feed with FreshRSS. Please note that the process is "
"absolutely not user friendly, but it works. :)"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:169
+#: en/./users/04_Subscriptions.md:45
+#, markdown-text
msgid ""
"Please be aware that this way you’ll generate much more traffic to the "
"originating sites, and they might block you accordingly. FreshRSS "
@@ -4416,34 +5994,35 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:171
+#: en/./users/04_Subscriptions.md:47
+#, markdown-text
msgid ""
-"What’s meant by \"CSS path of articles on the original site\" actually "
-"corresponds to the \"path\" consisting of IDs and classes (which in HTML, "
-"matches the id and class attributes) to retrieve only the interesting part "
-"that corresponds to the article. Ideally, this path starts with an id (which "
-"is unique to the page)."
+"The \"Article CSS selector on original website\" corresponds to the \"path\" "
+"consisting of IDs and classes (which in HTML, matches the id and class "
+"attributes) to retrieve only the interesting part that corresponds to the "
+"article. Ideally, this path starts with an id (which is unique to the "
+"page). The basics are explained "
+"[here](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors)."
msgstr ""
-#. type: Title ####
-#: en/./users/05_Configuration.md:172
-#, no-wrap
+#. type: Title #####
+#: en/./users/04_Subscriptions.md:48
+#, markdown-text, no-wrap
msgid "Example: Rue89"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:175
+#: en/./users/04_Subscriptions.md:52
+#, markdown-text
msgid ""
"To find this path, you have to go to the address of one of the truncated "
-"articles (for example, "
-"http://www.rue89.com/2013/10/15/prof-maths-jai-atteint-lextase-dihn-pedagogie-inversee-246635). "
-"You look have to look for the \"block\" of HTML that corresponds to article "
-"content (in the source code!)."
+"articles. You look have to look for the \"block\" of HTML that corresponds "
+"to article content (in the source code!)."
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:177
-#, no-wrap
+#: en/./users/04_Subscriptions.md:54
+#, markdown-text, no-wrap
msgid ""
"Here we find that the block that encompasses nothing but the content of the "
"article is ```<div class=\"content clearfix\">```. We’ll only use the "
@@ -4453,623 +6032,1158 @@ msgid ""
".content```.\n"
msgstr ""
-#. type: Title ####
-#: en/./users/05_Configuration.md:178
-#, no-wrap
+#. type: Title #####
+#: en/./users/04_Subscriptions.md:55
+#, markdown-text, no-wrap
msgid ""
"Add the corresponding classes to the article CSS path on the feed "
-"configuration page. Examples:"
+"configuration page"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:58
+#, markdown-text
+msgid "Examples:"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/05_Configuration.md:184
+#. type: Bullet: '* '
+#: en/./users/04_Subscriptions.md:63
+#, markdown-text
msgid "Rue89: ```#article .content```"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/05_Configuration.md:184
+#. type: Bullet: '* '
+#: en/./users/04_Subscriptions.md:63
+#, markdown-text
msgid "PCINpact: ```#actu_content```"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/05_Configuration.md:184
+#. type: Bullet: '* '
+#: en/./users/04_Subscriptions.md:63
+#, markdown-text
msgid "Lesnumériques: ```article#body div.text.clearfix```"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/05_Configuration.md:184
+#. type: Bullet: '* '
+#: en/./users/04_Subscriptions.md:63
+#, markdown-text
msgid "Phoronix: ```#main .content```"
msgstr ""
-#. type: Title ###
-#: en/./users/05_Configuration.md:185
+#. type: Title #####
+#: en/./users/04_Subscriptions.md:64
+#, markdown-text, no-wrap
+msgid "Combining CSS Classes"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:67
+#, markdown-text
+msgid ""
+"Let’s say we have an article which contains ads, and we do not want to have "
+"those ads retrieved by FreshRSS. Example HTML:"
+msgstr ""
+
+#. type: Fenced code block (html)
+#: en/./users/04_Subscriptions.md:68
#, no-wrap
-msgid "Retrieve a truncated stream with external tools"
+msgid ""
+"<div id=\"article\">\n"
+"<h2>wanted</h2>\n"
+"<p class=\"content\">wanted content</p>\n"
+"<p class=\"ad\">unwanted content</p>\n"
+"<h2>wanted</h2>\n"
+"<p class=\"content\">wanted content</p>\n"
+"<h2>wanted</h2>\n"
+"<p class=\"ad\">unwanted content</p>\n"
+"<p class=\"content\">wanted content</p>\n"
+"</div>\n"
msgstr ""
#. type: Plain text
-#: en/./users/05_Configuration.md:188
-msgid "Complimentary tools can be used to retrieve full article content, such as:"
+#: en/./users/04_Subscriptions.md:82
+#, markdown-text
+msgid ""
+"In this case it’s possible to combine multiple CSS selectors with a comma: "
+"```#article p.content, #article h2```"
+msgstr ""
+
+#. type: Title ####
+#: en/./users/04_Subscriptions.md:83
+#, markdown-text, no-wrap
+msgid "Retrieve a truncated feed with external tools"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/04_Subscriptions.md:86
+#, markdown-text
+msgid "Complementary tools can be used to retrieve full article content, such as:"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/05_Configuration.md:190
+#: en/./users/04_Subscriptions.md:89
+#, markdown-text
msgid "[RSS-Bridge](https://github.com/RSS-Bridge/rss-bridge)"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/05_Configuration.md:190
+#: en/./users/04_Subscriptions.md:89
+#, markdown-text
msgid "[Full-Text RSS](https://bitbucket.org/fivefilters/full-text-rss)"
msgstr ""
-#. type: Title #
-#: en/./users/06_Fever_API.md:1
-#, no-wrap
-msgid "FreshRSS - Fever API implementation"
+#. type: Title ###
+#: en/./users/04_Subscriptions.md:90
+#, markdown-text, no-wrap
+msgid "Filter"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:5
+#: en/./users/04_Subscriptions.md:93
+#, markdown-text
msgid ""
-"See the [page about our Google Reader compatible API](06_Mobile_access.md) "
-"for another possibility and general aspects of API access."
+"Articles can be automatically marked as read based on some search terms. See "
+"[filtering](./10_filter.md) for more information on how to create these "
+"filters."
msgstr ""
#. type: Title ##
-#: en/./users/06_Fever_API.md:6
-#, no-wrap
-msgid "RSS clients"
+#: en/./users/04_Subscriptions.md:94
+#, markdown-text, no-wrap
+msgid "Import / export"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:11
+#: en/./users/04_Subscriptions.md:97
+#, markdown-text
msgid ""
-"There are many RSS clients that support the Fever API, but they seem to "
-"understand the Fever API a bit differently. If your favourite client "
-"does not work properly with this API, please create an issue and we will have a "
-"look. But we can **only** do that for free clients."
+"See [SQLite export/import]( "
+"https://github.com/FreshRSS/FreshRSS/tree/edge/cli) as an alternative."
msgstr ""
-#. type: Title ###
-#: en/./users/06_Fever_API.md:12
-#, no-wrap
-msgid "Usage & Authentication"
+#. type: Title ##
+#: en/./users/04_Subscriptions.md:98
+#, markdown-text, no-wrap
+msgid "Export"
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid "To export your list of feeds, go to “Subscriptions management”."
+msgstr ""
+
+#. type: Bullet: '2. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid "Click on “Import / export”"
+msgstr ""
+
+#. type: Bullet: '3. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid "You can select for your export:"
+msgstr ""
+
+#. type: Bullet: ' 1. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid "the list of feeds"
+msgstr ""
+
+#. type: Bullet: ' 2. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid "labelled articles"
+msgstr ""
+
+#. type: Bullet: ' 3. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid "favourite articles"
+msgstr ""
+
+#. type: Bullet: ' 4. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid ""
+"and finally, you can select feeds you want to export (by default, all feeds "
+"are selected)"
+msgstr ""
+
+#. type: Bullet: '4. '
+#: en/./users/04_Subscriptions.md:108
+#, markdown-text
+msgid "Click on “export”."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/04_Subscriptions.md:109
+#, markdown-text, no-wrap
+msgid "Import"
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/04_Subscriptions.md:114
+#, markdown-text
+msgid "Go to the page “Import / export”."
+msgstr ""
+
+#. type: Bullet: '2. '
+#: en/./users/04_Subscriptions.md:114
+#, markdown-text
+msgid "Click on “Browse” and select your OPML or archive file on your computer."
+msgstr ""
+
+#. type: Bullet: '3. '
+#: en/./users/04_Subscriptions.md:114
+#, markdown-text
+msgid "Click on “Import”"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:16
+#: en/./users/04_Subscriptions.md:122
+#, markdown-text, no-wrap
msgid ""
-"Before you can start using this API, you have to enable and setup API "
-"access, which is [documented "
-"here](https://freshrss.github.io/FreshRSS/en/users/06_Mobile_access.html), "
-"and then reset the user’s API password."
+"> **Important**: you can not import directly a list of feeds from a text "
+"file.\n"
+"> You need to convert it beforehand to _OPML_.\n"
+"> Here is some tools you could use :\n"
+">\n"
+"> * [Pandoc](https://pandoc.org/) available for most systems,\n"
+"> * [OPML generator](https://opml-gen.ovh/) available online,\n"
+"> * [txt2opml](https://alterfiles.com/convert/txt/opml) available online.\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/04_Subscriptions.md:123
+#, markdown-text, no-wrap
+msgid "Use bookmarklet"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:18
+#: en/./users/04_Subscriptions.md:126
+#, markdown-text
msgid ""
-"Then point your mobile application to the `fever.php` address "
-"(e.g. `https://freshrss.example.net/api/fever.php`)."
+"Bookmarklets are little scripts that you can execute to perform various "
+"tasks. FreshRSS offers a bookmarklet for subscribing to newsfeeds."
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/04_Subscriptions.md:129
+#, markdown-text
+msgid "Open “Subscriptions management”."
+msgstr ""
+
+#. type: Bullet: '2. '
+#: en/./users/04_Subscriptions.md:129
+#, markdown-text
+msgid "Click on “Subscription tools”."
+msgstr ""
+
+#. type: Bullet: '3. '
+#: en/./users/04_Subscriptions.md:129
+#, markdown-text
+msgid ""
+"Drag the “Subscribe” button to your bookmark toolbar or right click and "
+"choose your browser’s “Bookmark link” action."
msgstr ""
#. type: Title #
-#: en/./users/06_Fever_API.md:19 en/./users/06_Mobile_access.md:44
-#, no-wrap
-msgid "Compatible clients"
+#: en/./users/05_Configuration.md:2
+#, markdown-text, no-wrap
+msgid "Display"
msgstr ""
-#. type: Plain text
-#: en/./users/06_Fever_API.md:22
-msgid "Tested with:"
+#. type: Title ##
+#: en/./users/05_Configuration.md:4
+#, markdown-text, no-wrap
+msgid "Language"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:25
-#, no-wrap
+#: en/./users/05_Configuration.md:9
+#, markdown-text
msgid ""
-"* Android\n"
-" * "
-"[Readably](https://play.google.com/store/apps/details?id=com.isaiasmatewos.readably) "
-"(Closed source)\n"
+"FreshRSS is currently available in 22 languages. After confirming your "
+"choice, the interface will be displayed in your preferred language. "
+"Depending on the language chosen, parts of the interface may not be not "
+"translated yet. If you’re willing to help translate the missing bits or "
+"would like to add a new language, please take a look at how you can "
+"[contribute to the "
+"project](../contributing.md#contribute-to-internationalization-i18n)."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:30
-#, no-wrap
+#: en/./users/05_Configuration.md:11
+#, markdown-text
msgid ""
-"* iOS\n"
-" * [Fiery "
-"Feeds](https://apps.apple.com/app/fiery-feeds-rss-reader/id1158763303) "
-"(Closed source)\n"
-" * [Unread](https://apps.apple.com/app/unread-rss-reader/id1252376153) "
-"(Commercial)\n"
-" * [Reeder](https://www.reederapp.com/) (Commercial) (Use its Google Reader "
-"API / native FreshRSS option when possible)\n"
+"Some parts of FreshRSS are not translated and are not intended to be "
+"translated either. For now, this includes the logs visible in the "
+"application as well as the log generated by automatic update scripts."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:33
-#, no-wrap
-msgid ""
-"* MacOS\n"
-" * [ReadKit](https://apps.apple.com/app/readkit/id588726889) (Commercial)\n"
+#: en/./users/05_Configuration.md:13
+#, markdown-text
+msgid "Available languages are:"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:38
+#, markdown-text, no-wrap
+msgid ""
+"| Language (English name) | Language (Endonym) | Ordered by language code "
+"(ISO-639-1) |\n"
+"|:------------------------|:-----------------------|:-------------------------------------|\n"
+"| Czech | Čeština | cz "
+"|\n"
+"| German | Deutsch | de "
+"|\n"
+"| Greek | Ελληνικά | el "
+"|\n"
+"| English | English | en "
+"|\n"
+"| English (United States) | English (United States) | en-us "
+"|\n"
+"| Spanish | Español | es "
+"|\n"
+"| French | Français | fr "
+"|\n"
+"| Hebrew | עברית | he "
+"|\n"
+"| Indonesian | Bahasa Indonesia | id "
+"|\n"
+"| Italian | Italiano | it "
+"|\n"
+"| Japanease | 日本語 | ja "
+"|\n"
+"| Korean | 한국어 | ko "
+"|\n"
+"| Latvian | Latviešu | lv "
+"|\n"
+"| Dutch | Nederlands | nl "
+"|\n"
+"| Occitan | Occitan | oc "
+"|\n"
+"| Polish | Polski | pl "
+"|\n"
+"| Brazilian Portuguese | Português (Brasil) | pt-br "
+"|\n"
+"| Russian | Русский | ru "
+"|\n"
+"| Slovak | Slovenčina | sk "
+"|\n"
+"| Turkish | Türkçe | tr "
+"|\n"
+"| Chinese (Simplified, People’s Republic of China) | 简体中文 | zh-cn "
+"|\n"
+"| Chinese (Traditional, Taiwan) | 正體中文 | zh-tw "
+"|\n"
msgstr ""
#. type: Title ##
-#: en/./users/06_Fever_API.md:35
-#, no-wrap
-msgid "Features"
+#: en/./users/05_Configuration.md:39
+#, markdown-text, no-wrap
+msgid "Theme"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:38
-msgid "The following features are implemented:"
+#: en/./users/05_Configuration.md:42
+#, markdown-text
+msgid ""
+"There’s no accounting for tastes, which is why FreshRSS offers 13 official "
+"themes:"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "fetching categories"
+#. type: Plain text
+#: en/./users/05_Configuration.md:58
+#, markdown-text, no-wrap
+msgid ""
+"| Theme | designed by | Notes "
+"|\n"
+"|:--------------|:-------------------------------------------------------|:--------------------------------------------------------------|\n"
+"| Alternative Dark | Ghost | |\n"
+"| Ansum | Thomas Guesnon | |\n"
+"| Blue Lagoon |Mister aiR | No longer supported. Will be removed with "
+"FreshRSS V1.22.0 |\n"
+"| Dark | AD | |\n"
+"| Dark pink | Miicat_47 | |\n"
+"| Flat design | Marien Fressinaud | |\n"
+"| Mapco | Thomas Guesnon | |\n"
+"| Nord theme | joelchrono12 | |\n"
+"| Origine | Marien Fressinaud | (default theme) |\n"
+"| Origine-compact | Kevin Papst | |\n"
+"| Pafat | Plopoyop | |\n"
+"| Screwdriver | Mister aiR | No longer supported. Will be removed with "
+"FreshRSS V1.22.0 |\n"
+"| Swage | Patrick Crandol | |\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:60
+#, markdown-text
+msgid ""
+"If you can’t find any themes you like, it’s always possible to [create your "
+"own](../developers/04_Frontend/02_Design.md)."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "fetching feeds"
+#. type: Plain text
+#: en/./users/05_Configuration.md:62
+#, markdown-text
+msgid ""
+"To select a theme, simply scroll through the themes and select one that "
+"strikes your fancy. After confirmation, the theme will be applied to the "
+"interface."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
+#. type: Title ##
+#: en/./users/05_Configuration.md:63
+#, markdown-text, no-wrap
+msgid "Content width"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:66
+#, markdown-text
msgid ""
-"fetching RSS items (new, favorites, unread, by_id, by_feed, by_category, "
-"since)"
+"Some people prefer short lines of text, while others prefer to maximize the "
+"available screen space. To satisfy the maximum number of people, it’s "
+"possible to customize the width of the displayed content. There are four "
+"settings available:"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "fetching favicons"
+#: en/./users/05_Configuration.md:71
+#, markdown-text
+msgid "**Fine** displays content up to a maximum width of 550 pixels"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "setting read marker for item(s)"
+#: en/./users/05_Configuration.md:71
+#, markdown-text
+msgid "**Medium** displays content up to a maximum width of 800 pixels"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "setting starred marker for item(s)"
+#: en/./users/05_Configuration.md:71
+#, markdown-text
+msgid "**Large** displays content up to a maximum width of 1000 pixels"
msgstr ""
#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "setting read marker for feed"
+#: en/./users/05_Configuration.md:71
+#, markdown-text
+msgid "**No limit** displays the content on 100% of the available space"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "setting read marker for category"
+#. type: Title ##
+#: en/./users/05_Configuration.md:72
+#, markdown-text, no-wrap
+msgid "Article icons"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:48
-msgid "supports FreshRSS extensions, which use the `entry_before_display` hook"
+#. type: Plain text
+#: en/./users/05_Configuration.md:75
+#, markdown-text
+msgid "Please note that this section only affects normal view."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:50
-msgid "The following features are not supported:"
+#: en/./users/05_Configuration.md:77
+#, markdown-text
+msgid "![Article icons configuration](../img/users/configuration.article.icons.png)"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:52
+#. type: Plain text
+#: en/./users/05_Configuration.md:80
+#, markdown-text
msgid ""
-"**Hot Links** aka **hot** as there is nothing in FreshRSS yet that is "
-"similar or could be used to simulate it."
+"Each article is rendered with a header (top line) and a footer (bottom "
+"line). In that section, you can choose what will be displayed in those."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:84
+#, markdown-text
+msgid ""
+"If you disable every item in the top line, you’ll still be able to see it "
+"since it contains the feed name and the article title. But if you do the "
+"same thing for the bottom line, it will be empty."
msgstr ""
#. type: Title ##
-#: en/./users/06_Fever_API.md:53
-#, no-wrap
-msgid "Testing and debugging"
+#: en/./users/05_Configuration.md:85
+#, markdown-text, no-wrap
+msgid "HTML5 notification timeout"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:56
+#: en/./users/05_Configuration.md:88
+#, markdown-text
msgid ""
-"If this API does not work as expected in your RSS reader, you can test it "
-"manually with a tool like [Postman](https://www.getpostman.com/)."
+"After automatically updating the feeds, FreshRSS can pop up a notification "
+"using the HTML5 notification API."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:58
+#: en/./users/05_Configuration.md:90
+#, markdown-text
+msgid "The duration of this notification can be set. By default, the value is 0."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/05_Configuration.md:91
+#, markdown-text, no-wrap
+msgid "Show the navigation button"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:94
+#, markdown-text
msgid ""
-"Configure a POST request to the URL "
-"https://freshrss.example.net/api/fever.php?api which should give you the "
-"result:"
+"By default, FreshRSS displays buttons to ease the article navigation when "
+"browsing on mobile. The drawback is that they eat up some precious space."
msgstr ""
-#. type: Code fence info string
-#: en/./users/06_Fever_API.md:58 en/./users/06_Fever_API.md:80
-#, no-wrap
-msgid "json"
+#. type: Plain text
+#: en/./users/05_Configuration.md:96
+#, markdown-text
+msgid ""
+"![navigation button "
+"configuration](../img/users/configuration.navigation.button.png)"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:58
-#, no-wrap
+#: en/./users/05_Configuration.md:98
+#, markdown-text
msgid ""
-"{\n"
-"\t\"api_version\": 3,\n"
-"\t\"auth\": 0\n"
-"}\n"
+"If you don’t use those buttons because you never browse on mobile or because "
+"you browse with gestures, you can disable them from the interface."
+msgstr ""
+
+#. type: Title #
+#: en/./users/05_Configuration.md:99
+#, markdown-text, no-wrap
+msgid "Reading"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/05_Configuration.md:101
+#, markdown-text, no-wrap
+msgid "Number of articles per page"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:65
-msgid "Great, the base setup seems to work!"
+#: en/./users/05_Configuration.md:104
+#, markdown-text
+msgid ""
+"This setting defines the number of articles to display at once before "
+"needing to load more. In normal and reading view, more articles are loaded "
+"automatically. In global view, a button will appear at the bottom of the "
+"list."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/05_Configuration.md:105
+#, markdown-text, no-wrap
+msgid "Articles to display"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:68
+#: en/./users/05_Configuration.md:108
+#, markdown-text
msgid ""
-"Now lets try an authenticated call. Fever uses an `api_key`, which is the "
-"MD5 hash of `\"$username:$apiPassword\"`. Assuming the user is `kevin` and "
-"the password `freshrss`, here is a command-line example to compute the "
-"resulting `api_key`"
+"The status of articles to display when loading FreshRSS. \"Adjust showing\" "
+"will display only unread articles by default, but will display all articles "
+"when there are no unread articles to show."
msgstr ""
-#. type: Code fence info string
-#: en/./users/06_Fever_API.md:69 en/./users/06_Fever_API.md:75 en/./users/06_Mobile_access.md:69 en/./users/07_Frequently_Asked_Questions.md:37 en/./users/07_Frequently_Asked_Questions.md:45
-#, no-wrap
-msgid "sh"
+#. type: Title ##
+#: en/./users/05_Configuration.md:109
+#, markdown-text, no-wrap
+msgid "Use “lazy load” mode to load images"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:69
-#, no-wrap
-msgid "api_key=`echo -n \"kevin:freshrss\" | md5sum | cut -d' ' -f1`\n"
+#: en/./users/05_Configuration.md:112
+#, markdown-text
+msgid ""
+"This will set images to load as they are viewed. This can save data, but "
+"will can cause images to load in later."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:74
+#: en/./users/05_Configuration.md:118
+#, markdown-text
msgid ""
-"Add a body to your POST request encoded as `form-data` and one key named "
-"`api_key` with the value `your-password-hash`:"
+"These are the global options for fetching and retaining articles from "
+"feeds. They can be overridden by individual feed’s settings."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/05_Configuration.md:119
+#, markdown-text, no-wrap
+msgid "Maintenance"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:75
-#, no-wrap
+#: en/./users/05_Configuration.md:122
+#, markdown-text
msgid ""
-"curl -s -F \"api_key=$api_key\" "
-"'https://freshrss.example.net/api/fever.php?api'\n"
+"This allows for purging/optimizing the current user’s articles in the "
+"database."
+msgstr ""
+
+#. type: Title #
+#: en/./users/05_Configuration.md:123
+#, markdown-text, no-wrap
+msgid "Sharing"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:80
-msgid "This should give:"
+#: en/./users/05_Configuration.md:126
+#, markdown-text
+msgid "To make your life easier, you can share articles straight from FreshRSS."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:80
-#, no-wrap
+#: en/./users/05_Configuration.md:128
+#, markdown-text
msgid ""
-"{\n"
-"\t\"api_version\": 3,\n"
-"\t\"auth\": 1,\n"
-"\t\"last_refreshed_on_time\": \"1520013061\"\n"
-"}\n"
+"At the moment, FreshRSS supports [20+ sharing "
+"services](08_sharing_services.md), ranging from self-hosted services "
+"(Shaarli, etc.) to proprietary services (Facebook, etc.)."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:88
+#: en/./users/05_Configuration.md:131
+#, markdown-text
msgid ""
-"Perfect, you’re now authenticated and you can start testing the more "
-"advanced features. To do so, change the URL and append the possible API "
-"actions to your request parameters. Please refer to the [original Fever "
-"documentation](https://feedafever.com/api) for more information."
+"By default, the sharing list is empty. ![Sharing "
+"configuration](../img/users/configuration.sharing.png)"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:90
-msgid "Some basic calls are:"
+#: en/./users/05_Configuration.md:133
+#, markdown-text
+msgid "To add a new item to the list, please follow the following simple steps:"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&items"
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:138
+#, markdown-text
+msgid "Select the desired sharing method in the drop-down list."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&feeds"
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:138
+#, markdown-text
+msgid "Press the ```✚``` button to add it to the list."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&groups"
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:138
+#, markdown-text
+msgid ""
+"Configure the method in the list. All names can be modified in the "
+"display. Some methods need the sharing URL to be able to work properly (ex: "
+"Shaarli)."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&unread_item_ids"
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:138 en/./users/05_Configuration.md:143
+#, markdown-text
+msgid "Submit your changes."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&saved_item_ids"
+#. type: Plain text
+#: en/./users/05_Configuration.md:140
+#, markdown-text
+msgid "To remove an item from the list, follow those simple steps:"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&items&since_id=some_id"
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:143
+#, markdown-text
+msgid "Press the ```❌``` button next to the share method you want to remove."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&items&max_id=some_id"
+#. type: Title #
+#: en/./users/05_Configuration.md:145
+#, markdown-text, no-wrap
+msgid "Shortcuts"
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&mark=item&as=read&id=some_id"
+#. type: Plain text
+#: en/./users/05_Configuration.md:149
+#, markdown-text
+msgid ""
+"To ease the use of the application, FreshRSS comes with a lot of predefined "
+"keyboard shortcuts. They allow actions to improve the user experience with "
+"a keyboard."
msgstr ""
-#. type: Bullet: '* '
-#: en/./users/06_Fever_API.md:100
-msgid "https://freshrss.example.net/api/fever.php?api&mark=item&as=unread&id=some_id"
+#. type: Plain text
+#: en/./users/05_Configuration.md:151
+#, markdown-text
+msgid ""
+"Of course, if you’re not satisfied with the key mapping, you can change you "
+"configuration to fit your needs."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:102
+#: en/./users/05_Configuration.md:153
+#, markdown-text
+msgid "There are 4 types of shortcuts:"
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:158
+#, markdown-text
+msgid "Views: they allow switching views with ease."
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:158
+#, markdown-text
+msgid "Navigation: they allow navigation through articles, feeds, and categories."
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:158
+#, markdown-text
msgid ""
-"Replace `some_id` with a real ID from your `freshrss_username_entry` "
-"database."
+"Article actions: they allow interactions with an article, like sharing or "
+"opening it on the original web-site."
msgstr ""
-#. type: Title ###
-#: en/./users/06_Fever_API.md:103
-#, no-wrap
-msgid "Debugging"
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:158
+#, markdown-text
+msgid ""
+"Other actions: they allow other interactions with the application, like "
+"opening the user queries menu or accessing the documentation."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:106
+#: en/./users/05_Configuration.md:161
+#, markdown-text
msgid ""
-"If nothing helps and your client is still misbehaving, you can add the "
-"following lines to the beginning of the `fever.api` file to determine the "
-"cause of the problems:"
+"It’s worth noting that the share article action has two levels. Once you "
+"press the shortcut, a menu containing all the share options opens. To "
+"choose one share option, you need to select it by its number. When there is "
+"only one option, it’s selected automatically though."
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:107
-#, no-wrap
+#: en/./users/05_Configuration.md:163
+#, markdown-text
+msgid "The same process applies to the user queries."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:166
+#, markdown-text
msgid ""
-"file_put_contents(__DIR__ . '/fever.log', $_SERVER['HTTP_USER_AGENT'] . ': ' "
-". json_encode($_REQUEST) . PHP_EOL, FILE_APPEND);\n"
+"Be aware that there is no validation on the selected shortcuts. This means "
+"that if you assign a shortcut to more than one action, you’ll end up with "
+"some unexpected behavior."
+msgstr ""
+
+#. type: Title #
+#: en/./users/05_Configuration.md:167
+#, markdown-text, no-wrap
+msgid "User queries"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:112
+#: en/./users/05_Configuration.md:171
+#, markdown-text
msgid ""
-"Then use your RSS client to query the API and afterwards check the file "
-"`fever.log`."
+"You can configure your [user queries](./03_Main_view.md) in that "
+"section. There is not much to say here as it is pretty straightforward. You "
+"can only change user query titles or drop them."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:173
+#, markdown-text
+msgid "At the moment, there is no helper to build a user query from here."
+msgstr ""
+
+#. type: Title #
+#: en/./users/05_Configuration.md:174
+#, markdown-text, no-wrap
+msgid "Profile"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:177
+#, markdown-text
+msgid ""
+"You can change your email address or password here. The authentication token "
+"is required for accessing the aggregated RSS feed for a user. A blank token "
+"will disable accessing the RSS feed without being logged in."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/05_Configuration.md:181
+#, markdown-text
+msgid ""
+"Extensions can be managed from this menu. Note that while extensions can be "
+"removed from the web interface, they cannot be added from it."
+msgstr ""
+
+#. type: Title #
+#: en/./users/05_Configuration.md:182
+#, markdown-text, no-wrap
+msgid "Users"
msgstr ""
#. type: Title ##
-#: en/./users/06_Fever_API.md:113
+#: en/./users/05_Configuration.md:186
+#, markdown-text, no-wrap
+msgid "Authentication methods"
+msgstr ""
+
+#. type: Title ###
+#: en/./users/05_Configuration.md:188
+#, markdown-text, no-wrap
+msgid "HTTP Authentication (Apache)"
+msgstr ""
+
+#. type: Bullet: '1. '
+#: en/./users/05_Configuration.md:194
+#, markdown-text
+msgid "User control is based on the `.htaccess` file."
+msgstr ""
+
+#. type: Bullet: '2. '
+#: en/./users/05_Configuration.md:194
+#, markdown-text
+msgid ""
+"It is best practice to place the `.htaccess` file in the `./i/` subdirectory "
+"so the API and other third party services can work."
+msgstr ""
+
+#. type: Bullet: '3. '
+#: en/./users/05_Configuration.md:194
+#, markdown-text
+msgid ""
+"If you want to limit all access to registered users only, place the file in "
+"the FreshRSS directory itself or in a parent directory. Note that WebSub and "
+"API will not work!"
+msgstr ""
+
+#. type: Bullet: '4. '
+#: en/./users/05_Configuration.md:194
+#, markdown-text
+msgid "Example `.htaccess` file for a user \"marie\":"
+msgstr ""
+
+#. type: Fenced code block (apache)
+#: en/./users/05_Configuration.md:195
#, no-wrap
-msgid "Credits"
+msgid ""
+"AuthUserFile /home/marie/repertoire/.htpasswd\n"
+"AuthGroupFile /dev/null\n"
+"AuthName \"Chez Marie\"\n"
+"AuthType Basic\n"
+"Require user marie\n"
msgstr ""
#. type: Plain text
-#: en/./users/06_Fever_API.md:115
+#: en/./users/05_Configuration.md:204
+#, markdown-text
msgid ""
-"This plugin was inspired by the "
-"[tinytinyrss-fever-plugin](https://github.com/dasmurphy/tinytinyrss-fever-plugin)."
+"More information can be found in the [Apache "
+"documentation](http://httpd.apache.org/docs/trunk/howto/auth.html#gettingitworking)."
msgstr ""
#. type: Plain text
#: en/./users/06_Mobile_access.md:2
+#, markdown-text
msgid ""
"This page assumes you have completed the [server "
-"setup](../admins/02_Installation.md)."
+"setup](../admins/03_Installation.md)."
msgstr ""
#. type: Title #
#: en/./users/06_Mobile_access.md:3
-#, no-wrap
+#, markdown-text, no-wrap
+msgid "Mobile Access"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/06_Mobile_access.md:6
+#, markdown-text
+msgid "You can access FreshRSS on mobile devices via browser and via mobile apps."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/06_Mobile_access.md:8
+#, markdown-text, no-wrap
+msgid "Access via Browser"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/06_Mobile_access.md:11
+#, markdown-text
+msgid ""
+"The FreshRSS user interface is optimized for both small and large "
+"screens. The content will fit nicely on small mobile device screens as well."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/06_Mobile_access.md:13
+#, markdown-text, no-wrap
+msgid "Access via Mobile App"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/06_Mobile_access.md:16
+#, markdown-text
+msgid ""
+"FreshRSS supports access from mobile / native apps for Linux, Android, iOS, "
+"Windows and macOS, via two distinct APIs: Google Reader API (best), and "
+"Fever API (limited features and less efficient)."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/06_Mobile_access.md:18
+#, markdown-text
+msgid ""
+"A list of known apps is available on the [FreshRSS GitHub "
+"page](https://github.com/FreshRSS/FreshRSS#apis--native-apps)."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/06_Mobile_access.md:20
+#, markdown-text, no-wrap
msgid "Enable the API in FreshRSS"
msgstr ""
#. type: Bullet: '1. '
-#: en/./users/06_Mobile_access.md:9
+#: en/./users/06_Mobile_access.md:26
+#, markdown-text
msgid ""
"Under the section “Authentication”, enable the option “Allow API access "
"(required for mobile apps)”."
msgstr ""
-#. type: Plain text
-#: en/./users/06_Mobile_access.md:9
-#, no-wrap
+#. type: Bullet: '2. '
+#: en/./users/06_Mobile_access.md:26
+#, markdown-text
+msgid ""
+"Under the section “Profile”, fill-in the field “API password (e.g., for "
+"mobile apps)”."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:26
+#, markdown-text
+msgid "Every user must define an API password."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:26
+#, markdown-text
msgid ""
-"2. Under the section “Profile”, fill-in the field “API password (e.g., for "
-"mobile apps)”.\n"
-"\t* Every user must define an API password.\n"
-"\t* The reason for an API-specific password is that it may be used in less "
-"safe situations than the main password, and does not grant access to as many "
-"things.\n"
+"The reason for an API-specific password is that it may be used in less safe "
+"situations than the main password, and does not grant access to as many "
+"things."
msgstr ""
#. type: Plain text
-#: en/./users/06_Mobile_access.md:12
+#: en/./users/06_Mobile_access.md:29
+#, markdown-text
msgid ""
-"The rest of this page is about the Google Reader compatible API. See the "
-"[page about the Fever compatible API](06_Fever_API.md) for another "
-"possibility."
+"See the [page about the Google Reader compatible "
+"API](../developers/06_GoogleReader_API.md) for more details. See the [page "
+"about the Fever compatible API](../developers/06_Fever_API.md) for more "
+"details."
msgstr ""
-#. type: Title #
-#: en/./users/06_Mobile_access.md:14
-#, no-wrap
+#. type: Title ###
+#: en/./users/06_Mobile_access.md:31
+#, markdown-text, no-wrap
msgid "Testing"
msgstr ""
-#. type: Bullet: '3. '
-#: en/./users/06_Mobile_access.md:21
+#. type: Bullet: '1. '
+#: en/./users/06_Mobile_access.md:38
+#, markdown-text
msgid ""
"Under the section “Profile”, click on the link like "
"`https://rss.example.net/api/` next to the field “API password”."
msgstr ""
-#. type: Plain text
-#: en/./users/06_Mobile_access.md:21
-#, no-wrap
+#. type: Bullet: '2. '
+#: en/./users/06_Mobile_access.md:38
+#, markdown-text
+msgid "Click on first link “Check full server configuration”:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:38
+#, markdown-text
+msgid "If you get *PASS* then you are done; all is well."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:38
+#, markdown-text
msgid ""
-"4. Click on first link “Check full server configuration”:\n"
-"\t* If you get *PASS* then you are done, all is good: you may proceed to "
-"step 6.\n"
-"\t* If you get *Bad Request!* or *Not Found*, then your server probably does "
-"not accept slashes `/` that are escaped `%2F`. Proceed to step 5.\n"
-"\t* If you get any other error message, proceed to step 5.\n"
+"If you get *Bad Request!* or *Not Found*, then your server probably does not "
+"accept slashes `/` that are escaped `%2F`, see the next section \"Fix server "
+"configuration\"."
msgstr ""
-#. type: Title #
-#: en/./users/06_Mobile_access.md:23
-#, no-wrap
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:38
+#, markdown-text
+msgid ""
+"If you receive any other error message, see the next section “Fix server "
+"configuration”."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/06_Mobile_access.md:39
+#, markdown-text, no-wrap
msgid "Fix server configuration"
msgstr ""
-#. type: Plain text
-#: en/./users/06_Mobile_access.md:42
-#, no-wrap
+#. type: Bullet: '* '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
msgid ""
-"5. Click on the second link “Check partial server configuration (without "
-"`%2F` support)”:\n"
-"\t* If you get `PASS`, then the problem is indeed that your server does not "
-"accept slashes `/` that are escaped `%2F`.\n"
-"\t\t* With Apache, remember the directive [`AllowEncodedSlashes "
-"On`](http://httpd.apache.org/docs/trunk/mod/core.html#allowencodedslashes)\n"
-"\t\t* Or use a client that does not escape slashes (such as EasyRSS), in "
-"which case proceed to step 6.\n"
-"\t* If you get *Service Unavailable!*, then check from step 1 again.\n"
-"\t* With __Apache__:\n"
-"\t\t* If you get *FAIL getallheaders!*, the combination of your PHP version "
-"and your Web server does not provide access to "
-"[`getallheaders`](http://php.net/getallheaders)\n"
-"\t\t\t* Turn on Apache `mod_setenvif` (often enabled by default), or "
-"`mod_rewrite` with the following procedure:\n"
-"\t\t\t\t* Allow [`FileInfo` in "
-"`.htaccess`](http://httpd.apache.org/docs/trunk/mod/core.html#allowoverride): "
-"see the [server setup](../admins/02_Installation.md) again.\n"
-"\t\t\t\t* Enable "
-"[`mod_rewrite`](http://httpd.apache.org/docs/trunk/mod/mod_rewrite.html):\n"
-"\t\t\t\t\t* With Debian / Ubuntu: `sudo a2enmod rewrite`\n"
-"\t* With __nginx__:\n"
-"\t\t* If you get *Bad Request!*, check your server `PATH_INFO` "
-"configuration.\n"
-"\t\t* If you get *File not found!*, check your server "
-"`fastcgi_split_path_info`.\n"
-"\t* If you get *FAIL 64-bit or GMP extension!*, then your PHP version does "
-"not pass the requirement of being 64-bit and/or have PHP "
-"[GMP](http://php.net/gmp) extension.\n"
-"\t\t* The easiest is to add the GMP extension. On Debian / Ubuntu: `sudo apt "
-"install php-gmp`\n"
-"\t* Update and try again from step 3.\n"
-msgstr ""
-
-#. type: Plain text
-#: en/./users/06_Mobile_access.md:48
-#, no-wrap
+"Click on the second link “Check partial server configuration (without `%2F` "
+"support)”:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
msgid ""
-"6. On the same FreshRSS API page, note the address given under “Your API "
-"address”, like `https://freshrss.example.net/api/greader.php`\n"
-"\t* Type the API address in a client, together with your FreshRSS username, "
-"and the corresponding special API password.\n"
+"If you get `PASS`, then the problem is indeed that your server does not "
+"accept slashes `/` that are escaped `%2F`."
msgstr ""
-#. type: Plain text
-#: en/./users/06_Mobile_access.md:63
-#, no-wrap
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
msgid ""
-"7. Pick a client supporting a Google Reader-like API. Selection:\n"
-"\t* Android\n"
-"\t\t* "
-"[News+](https://github.com/noinnion/newsplus/blob/master/apk/NewsPlus_202.apk) "
-"with [News+ Google Reader "
-"extension](https://github.com/noinnion/newsplus/tree/master/extensions/GoogleReaderCloneExtension) "
-"(Closed source)\n"
-"\t\t* [FeedMe "
-"3.5.3+](https://play.google.com/store/apps/details?id=com.seazon.feedme) "
-"(Closed source)\n"
-"\t\t* [EasyRSS](https://github.com/Alkarex/EasyRSS) (Open source, "
-"[F-Droid](https://f-droid.org/packages/org.freshrss.easyrss/))\n"
-"\t* Linux\n"
-"\t\t* [FeedReader 2.0+](https://jangernert.github.io/FeedReader/) (Open "
-"source)\n"
-"\t* MacOS\n"
-"\t\t* [Vienna RSS](http://www.vienna-rss.com/) (Open source)\n"
-"\t\t* [Reeder](https://www.reederapp.com/) (Commercial)\n"
-"\t* iOS\n"
-"\t\t* [Reeder](https://www.reederapp.com/) (Commercial)\n"
-"\t* Firefox\n"
-"\t\t* "
-"[FreshRSS-Notify](https://addons.mozilla.org/firefox/addon/freshrss-notify-webextension/) "
-"(Open source)\n"
+"With Apache, remember the directive [`AllowEncodedSlashes "
+"On`](http://httpd.apache.org/docs/trunk/mod/core.html#allowencodedslashes)"
msgstr ""
-#. type: Title #
-#: en/./users/06_Mobile_access.md:65
-#, no-wrap
-msgid "Google Reader compatible API"
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid ""
+"Or use a client that does not escape slashes (such as EasyRSS) ([`check "
+"client list`](https://github.com/FreshRSS/FreshRSS#apis--native-apps))."
msgstr ""
-#. type: Plain text
-#: en/./users/06_Mobile_access.md:68
-msgid "Examples of basic queries:"
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid ""
+"If you get *Service Unavailable!*, then check the preceding section “Enable "
+"the API in FreshRSS” again."
msgstr ""
-#. type: Plain text
-#: en/./users/06_Mobile_access.md:69
-#, no-wrap
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid "With __Apache__:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
msgid ""
-"# Initial login, using API password (Email and Passwd can be given either as "
-"GET, or POST - better)\n"
-"curl "
-"'https://freshrss.example.net/api/greader.php/accounts/ClientLogin?Email=alice&Passwd=Abcdef123456'\n"
-"SID=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\n"
-"Auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\n"
-"\n"
-"# Examples of read-only requests\n"
-"curl -s -H \"Authorization:GoogleLogin "
-"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
-" "
-"'https://freshrss.example.net/api/greader.php/reader/api/0/subscription/list?output=json'\n"
-"\n"
-"curl -s -H \"Authorization:GoogleLogin "
-"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
-" "
-"'https://freshrss.example.net/api/greader.php/reader/api/0/unread-count?output=json'\n"
-"\n"
-"curl -s -H \"Authorization:GoogleLogin "
-"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
-" "
-"'https://freshrss.example.net/api/greader.php/reader/api/0/tag/list?output=json'\n"
-"\n"
-"# Retrieve a token for requests making modifications\n"
-"curl -H \"Authorization:GoogleLogin "
-"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
-" 'https://freshrss.example.net/api/greader.php/reader/api/0/token'\n"
-"8e6845e089457af25303abc6f53356eb60bdb5f8ZZZZZZZZZZZZZZZZZ\n"
-"\n"
-"# Get articles, piped to jq for easier JSON reading\n"
-"curl -s -H \"Authorization:GoogleLogin "
-"auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8\" \\\n"
-" "
-"'https://freshrss.example.net/api/greader.php/reader/api/0/stream/contents/reading-list' "
-"| jq .\n"
+"If you get *FAIL getallheaders!*, the combination of your PHP version and "
+"your Web server does not provide access to "
+"[`getallheaders`](http://php.net/getallheaders)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid ""
+"Turn on Apache `mod_setenvif` (often enabled by default), or `mod_rewrite` "
+"with the following procedure:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid ""
+"Allow [`FileInfo` in "
+"`.htaccess`](http://httpd.apache.org/docs/trunk/mod/core.html#allowoverride): "
+"see the [server setup](../admins/03_Installation.md) again."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid ""
+"Enable "
+"[`mod_rewrite`](http://httpd.apache.org/docs/trunk/mod/mod_rewrite.html):"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid "With Debian / Ubuntu: `sudo a2enmod rewrite`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid "With __nginx__:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid "If you get *Bad Request!*, check your server `PATH_INFO` configuration."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid "If you get *File not found!*, check your server `fastcgi_split_path_info`."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid ""
+"If you get *FAIL 64-bit or GMP extension!*, then your PHP version does not "
+"pass the requirement of being 64-bit and/or have PHP "
+"[GMP](http://php.net/gmp) extension."
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid ""
+"The easiest is to add the GMP extension. On Debian / Ubuntu: `sudo apt "
+"install php-gmp`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/06_Mobile_access.md:57
+#, markdown-text
+msgid "Update and try again from the preceding section “Testing”."
msgstr ""
#. type: Plain text
#: en/./users/07_Frequently_Asked_Questions.md:2
+#, markdown-text
msgid ""
"We may not have answered all of your questions in the previous sections. The "
"FAQ contains some questions that have not been answered elsewhere."
@@ -5077,17 +7191,19 @@ msgstr ""
#. type: Title ##
#: en/./users/07_Frequently_Asked_Questions.md:3
-#, no-wrap
+#, markdown-text, no-wrap
msgid "What is `/i` at the end of the application URL?"
msgstr ""
#. type: Plain text
#: en/./users/07_Frequently_Asked_Questions.md:6
+#, markdown-text
msgid "Of course, ```/i``` has a purpose! It’s used for performance and usability:"
msgstr ""
#. type: Bullet: '* '
#: en/./users/07_Frequently_Asked_Questions.md:11
+#, markdown-text
msgid ""
"It allows for serving icons, images, styles and scripts without "
"cookies. Without that trick, those files would be downloaded more often, "
@@ -5097,6 +7213,7 @@ msgstr ""
#. type: Bullet: '* '
#: en/./users/07_Frequently_Asked_Questions.md:11
+#, markdown-text
msgid ""
"The ```./p/``` public root can be served without any HTTP access "
"restrictions. Whereas it could be implemented in ```./p/i/```."
@@ -5104,6 +7221,7 @@ msgstr ""
#. type: Bullet: '* '
#: en/./users/07_Frequently_Asked_Questions.md:11
+#, markdown-text
msgid ""
"It avoids problems while serving public resources like ```favicon.ico```, "
"```robots.txt```, etc."
@@ -5111,6 +7229,7 @@ msgstr ""
#. type: Bullet: '* '
#: en/./users/07_Frequently_Asked_Questions.md:11
+#, markdown-text
msgid ""
"It allows the logo to be displayed instead of a white page while hitting a "
"restriction or a delay during the loading process."
@@ -5118,12 +7237,13 @@ msgstr ""
#. type: Title ##
#: en/./users/07_Frequently_Asked_Questions.md:12
-#, no-wrap
+#, markdown-text, no-wrap
msgid "Why is `robots.txt` located in a sub-folder?"
msgstr ""
#. type: Plain text
#: en/./users/07_Frequently_Asked_Questions.md:15
+#, markdown-text
msgid ""
"To increase security, FreshRSS is hosted in two sections. The first section "
"is public (the `./p` folder) and the second section is private (everything "
@@ -5131,29 +7251,31 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:17
+#: en/./users/07_Frequently_Asked_Questions.md:18
+#, markdown-text
msgid ""
-"As explained in the [security "
-"section](/en/User_documentation/Installation/Security), it’s highly "
-"recommended to make only the public section available at the domain "
-"level. With that configuration, `./p` is the root folder for "
-"http://demo.freshrss.org/, thus making `robots.txt` available at the root of "
-"the application."
+"As explained in the [security section](../admins/09_AccessControl.html), "
+"it’s highly recommended to make only the public section available at the "
+"domain level. With that configuration, `./p` is the root folder for "
+"<https://demo.freshrss.org/>, thus making `robots.txt` available at the root "
+"of the application."
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:19
+#: en/./users/07_Frequently_Asked_Questions.md:20
+#, markdown-text
msgid "The same principle applies to `favicon.ico` and `.htaccess`."
msgstr ""
#. type: Title ##
-#: en/./users/07_Frequently_Asked_Questions.md:20
-#, no-wrap
+#: en/./users/07_Frequently_Asked_Questions.md:21
+#, markdown-text, no-wrap
msgid "Why do I have errors while registering a feed?"
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:26
+#: en/./users/07_Frequently_Asked_Questions.md:27
+#, markdown-text
msgid ""
"There can be different origins for that problem. The feed syntax can be "
"invalid, it can be unrecognized by the SimplePie library, the hosting server "
@@ -5162,7 +7284,8 @@ msgid ""
msgstr ""
#. type: Bullet: '1. '
-#: en/./users/07_Frequently_Asked_Questions.md:30
+#: en/./users/07_Frequently_Asked_Questions.md:31
+#, markdown-text
msgid ""
"__Verify if the feed syntax is valid__ with the [W3C on-line "
"tool](https://validator.w3.org/feed/ \"RSS and Atom feed validator\"). If "
@@ -5170,7 +7293,8 @@ msgid ""
msgstr ""
#. type: Bullet: '1. '
-#: en/./users/07_Frequently_Asked_Questions.md:30
+#: en/./users/07_Frequently_Asked_Questions.md:31
+#, markdown-text
msgid ""
"__Verify SimplePie validation__ with the [SimplePie on-line "
"tool](https://simplepie.org/demo/ \"SimplePie official demo\"). If it’s not "
@@ -5178,7 +7302,8 @@ msgid ""
msgstr ""
#. type: Bullet: '1. '
-#: en/./users/07_Frequently_Asked_Questions.md:30
+#: en/./users/07_Frequently_Asked_Questions.md:31
+#, markdown-text
msgid ""
"__Verify FreshRSS integration__ with the [demo](https://demo.freshrss.org "
"\"FreshRSS official demo\"). If it’s not working, you need to [create an "
@@ -5188,13 +7313,14 @@ msgid ""
msgstr ""
#. type: Title ##
-#: en/./users/07_Frequently_Asked_Questions.md:31
-#, no-wrap
+#: en/./users/07_Frequently_Asked_Questions.md:32
+#, markdown-text, no-wrap
msgid "How can you change a forgotten password?"
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:35
+#: en/./users/07_Frequently_Asked_Questions.md:36
+#, markdown-text
msgid ""
"Since the [1.10.0](https://github.com/FreshRSS/FreshRSS/releases/tag/1.10.0) "
"release, admins can change user passwords directly from the interface. This "
@@ -5203,7 +7329,8 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:37
+#: en/./users/07_Frequently_Asked_Questions.md:38
+#, markdown-text
msgid ""
"Since the [1.8.0](https://github.com/FreshRSS/FreshRSS/releases/tag/1.8.0) "
"release, admins can change user passwords using a terminal. It worth "
@@ -5211,38 +7338,40 @@ msgid ""
"the following command:"
msgstr ""
-#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:37
+#. type: Fenced code block (sh)
+#: en/./users/07_Frequently_Asked_Questions.md:39
#, no-wrap
msgid "./cli/update_user.php --user <username> --password <password>\n"
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:41
+#: en/./users/07_Frequently_Asked_Questions.md:44
+#, markdown-text
msgid ""
"For more information on that matter, please refer to the [dedicated "
-"documentation](../../cli/README.md)."
+"documentation](https://github.com/FreshRSS/FreshRSS/blob/edge/cli/README.md)."
msgstr ""
#. type: Title ##
-#: en/./users/07_Frequently_Asked_Questions.md:42
-#, no-wrap
+#: en/./users/07_Frequently_Asked_Questions.md:45
+#, markdown-text, no-wrap
msgid "Permissions under SELinux"
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:45
+#: en/./users/07_Frequently_Asked_Questions.md:48
+#, markdown-text
msgid ""
"Some Linux distribution, like Fedora or RedHat Enterprise Linux, have "
"SELinux enabled. This acts similar to a firewall application, so that "
"applications can’t write or modify files under certain conditions. While "
-"installing FreshRSS, step 2 can fail if the httpd process cannot write to "
+"installing FreshRSS, step 2 can fail if the httpd process can’t write to "
"some data sub-directories. The following command should be executed as root "
"to fix this problem:"
msgstr ""
-#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:45
+#. type: Fenced code block (sh)
+#: en/./users/07_Frequently_Asked_Questions.md:49
#, no-wrap
msgid ""
"semanage fcontext -a -t httpd_sys_rw_content_t "
@@ -5251,13 +7380,14 @@ msgid ""
msgstr ""
#. type: Title ##
-#: en/./users/07_Frequently_Asked_Questions.md:50
-#, no-wrap
+#: en/./users/07_Frequently_Asked_Questions.md:54
+#, markdown-text, no-wrap
msgid "Why do I have a blank page while trying to configure the sharing options?"
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:53
+#: en/./users/07_Frequently_Asked_Questions.md:57
+#, markdown-text
msgid ""
"The `sharing` word in the URL is a trigger word for some ad-blocker "
"rules. Starting with version 1.16, `sharing` has been replaced by "
@@ -5266,7 +7396,8 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:55
+#: en/./users/07_Frequently_Asked_Questions.md:59
+#, markdown-text
msgid ""
"If you are using a version prior to 1.16, you can disable your ad-blocker "
"for FreshRSS or you can add a rule to allow the `sharing` page to be "
@@ -5274,21 +7405,1360 @@ msgid ""
msgstr ""
#. type: Plain text
-#: en/./users/07_Frequently_Asked_Questions.md:57
+#: en/./users/07_Frequently_Asked_Questions.md:61
+#, markdown-text
msgid "Examples with _uBlock_:"
msgstr ""
-#. type: Bullet: '- '
-#: en/./users/07_Frequently_Asked_Questions.md:59
+#. type: Bullet: '* '
+#: en/./users/07_Frequently_Asked_Questions.md:64
+#, markdown-text
msgid ""
"Whitelist your FreshRSS instance by adding it in _uBlock > Open the "
"dashboard > Whitelist_."
msgstr ""
-#. type: Bullet: '- '
-#: en/./users/07_Frequently_Asked_Questions.md:59
+#. type: Bullet: '* '
+#: en/./users/07_Frequently_Asked_Questions.md:64
+#, markdown-text
msgid ""
"Authorize your FreshRSS instance to call `sharing` configuration page by "
"adding the rule `*sharing,domain=~yourdomain.com` in _uBlock > Open the "
"dashboard > My filters_"
msgstr ""
+
+#. type: Title ##
+#: en/./users/07_Frequently_Asked_Questions.md:65
+#, markdown-text, no-wrap
+msgid "Problems with firewalls"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/07_Frequently_Asked_Questions.md:68
+#, markdown-text
+msgid ""
+"If you have the error \"Blast! This feed has encountered a problem. Please "
+"verify that it is always reachable then update it.\", it might be because of "
+"a firewall misconfiguration."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/07_Frequently_Asked_Questions.md:70
+#, markdown-text
+msgid "To identify the problem, here are the steps to follow:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/07_Frequently_Asked_Questions.md:73
+#, markdown-text
+msgid ""
+"step 1: Try to reach the feed locally to discard a problem with the feed "
+"itself. You can use your browser to this purpose."
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/07_Frequently_Asked_Questions.md:73
+#, markdown-text
+msgid ""
+"step 2: Try to reach the feed from the host in which FreshRSS is "
+"installed. Something like `time curl -v "
+"'https://github.com/FreshRSS/FreshRSS/commits/edge.atom'` should make the "
+"deal. If you are running FreshRSS within a Docker container, then you can "
+"check connectivity from within the container itself with something similar "
+"to `sudo docker exec freshrss php -r "
+"\"readfile('https://github.com/FreshRSS/FreshRSS/commits/edge.atom');\"`. If "
+"none of this works, then it might be a problem with your firewall."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/07_Frequently_Asked_Questions.md:75
+#, markdown-text
+msgid ""
+"Then to fix it, you need to do check your firewall configuration and ensure "
+"that you are not blocking connections to IPs and/or ports in which your "
+"feeds are located. If using iptables and you are blocking inbound "
+"connections to ports 80/443, check that the rules are properly configured "
+"and you are not also blocking outbound connections to the very same ports."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/07_Frequently_Asked_Questions.md:76
+#, markdown-text
+msgid ""
+"For example, when using the firewall provided by Synology, you can block "
+"traffic for certain applications (i.e., ports). One could think that these "
+"rules would be applied only to incoming connections but specifying * for the "
+"originating host of the requests will also include your local networks. To "
+"deal with this issue, you will have to add exceptions for your local "
+"networks to be able to access those ports with a higher priority than the "
+"one blocking incoming connections. This could be similar for other frontends "
+"to iptables. Please check the following discussion about a [similar "
+"issue](https://www.reddit.com/r/synology/comments/8fo2sj/ds918_firewall_blocking_outgoing_traffic_from/)."
+msgstr ""
+
+#. type: Title #
+#: en/./users/08_sharing_services.md:1
+#, markdown-text, no-wrap
+msgid "Sharing Services"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/08_sharing_services.md:4
+#, markdown-text
+msgid "FreshRSS has the option to share links with a bunch of services."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/08_sharing_services.md:5
+#, markdown-text, no-wrap
+msgid "Available Services: Simple Sharing"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/08_sharing_services.md:12
+#, markdown-text, no-wrap
+msgid ""
+"| Service | Short description | "
+"Notes |\n"
+"|:--------------|:-------------------------------------------------------|:--------------------------------------------------------------|\n"
+"| Clipboard | Copy article link into the operation system clipboard | "
+"|\n"
+"| Email | Open the email app to send the article link | "
+"|\n"
+"| Print | Open browser’s print dialog to print out the article | "
+"|\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/08_sharing_services.md:13
+#, markdown-text, no-wrap
+msgid "Available Services: Hosted Services"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/08_sharing_services.md:39
+#, markdown-text, no-wrap
+msgid ""
+"| Service | Short description | "
+"Links | Notes "
+"|\n"
+"|:------------------|:-----------------------------------------------------|:-------------------------------------------------|:--------------------------------------------------------------|\n"
+"| Blogotext | A little more than a lightweight SQLite Blog-Engine. | "
+"[GitHub](https://github.com/BlogoText/blogotext) | Deprecated since FreshRSS "
+"V1.20.0 (2022). Will be deleted in 2023 (scheduled to FreshRSS V1.22.0) |\n"
+"| Buffer | Buffer.com is a social media management platform for "
+"scheduling, publishing, and analyzing content. | "
+"[Website](https://buffer.com) ||\n"
+"| Diaspora* | The online social world where you are in control | "
+"[Website](https://diasporafoundation.org/), "
+"[Wikipedia](https://en.wikipedia.org/wiki/Diaspora_(social_network)) | |\n"
+"| Facebook | Worldwide social network (by Meta Platforms) | "
+"[Website](https://facebook.com), "
+"[Wikipedia](https://en.wikipedia.org/wiki/Facebook)\n"
+"| GNU social | Social communication software for both public and "
+"private communications | [Website](https://gnu.io/social/) | |\n"
+"| Journal du hacker | Le Journal du hacker s'inspire directement du site "
+"anglophone Hacker News | [Website](https://www.journalduhacker.net/) |\n"
+"| Known based sites | Its robust open source framework can be used to build "
+"fully-fledged community sites, or a blog for a single user. | "
+"[Website](https://withknown.com/) | |\n"
+"| Lemmy | Selfhosted social link aggregation and discussion "
+"platform | [Website](https://join-lemmy.org/) | |\n"
+"| Linkding | Selfhosted bookmark service | "
+"[Website](https://github.com/sissbruecker/linkding) | |\n"
+"| LinkedIn | Business and employment-oriented online service | "
+"[Website](https://www.linkedin.com/), "
+"[Wikipedia](https://en.wikipedia.org/wiki/LinkedIn)| |\n"
+"| Mastodon | Self-hosted social networking & microblogging services "
+"| [Website](https://joinmastodon.org/), "
+"[Wikipedia](https://en.wikipedia.org/wiki/Mastodon_(software)) | |\n"
+"| Movim | A powerful web frontend for XMPP | "
+"[Website](https://movim.eu/) | |\n"
+"| Pinboard | Social Bookmarking for Introverts | "
+"[Website](https://pinboard.in/) | |\n"
+"| Pinterest | Is an image sharing and social media service designed "
+"to enable saving and discovery of information| "
+"[Website](https://pinterest.com/), "
+"[Wikipedia](https://en.wikipedia.org/wiki/Pinterest) | |\n"
+"| Pocket | Social bookmarking (previous \"Read it Later\", owned "
+"by Mozilla) | [Website](https://getpocket.com), "
+"[Wikipedia](https://en.wikipedia.org/wiki/Pocket_(service)) | |\n"
+"| Raindrop.io | All-in-one bookmark manager | "
+"[Website](https://raindrop.io/)| |\n"
+"| Reddit | A network of communities where people can dive into "
+"their interests, hobbies and passions| [Website](https://www.reddit.com/), "
+"[Wikipedia](https://en.wikipedia.org/wiki/Reddit)| |\n"
+"| Shaarli | Self-hosted minimalist bookmark manager and link "
+"sharing service | [Website](https://shaarli.readthedocs.io/) | |\n"
+"| Twitter | Microblogging social network | "
+"[Website](https://twitter.com), "
+"[Wikipedia](https://de.wikipedia.org/wiki/Twitter) | |\n"
+"| wallabag | Save and classify articles. Read them later. Freely | "
+"[Website](https://www.wallabag.org) | Compatible to version 1 and 2\n"
+"| Whatsapp | Instant messaging and voice-over-IP service owned by "
+"Meta Platforms| [Website](https://www.whatsapp.com), "
+"[Wikipedia](https://en.wikipedia.org/wiki/WhatsApp) | |\n"
+"| XING | Career-oriented social networking site, operated by "
+"New Work SE | [Website](https://www.xing.com/), "
+"[Wikipedia](https://en.wikipedia.org/wiki/XING) | |\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/08_sharing_services.md:40
+#, markdown-text, no-wrap
+msgid "Configuration"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/08_sharing_services.md:43
+#, markdown-text
+msgid ""
+"Select the needed sharing services in the configuration menu (Configuration "
+"/ Sharing)."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/08_sharing_services.md:44
+#, markdown-text, no-wrap
+msgid "Usage"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/08_sharing_services.md:47
+#, markdown-text
+msgid ""
+"Activate the sharing menu in configuration menu (Configuration / "
+"Display). It is only available for the bottom line."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/08_sharing_services.md:49
+#, markdown-text
+msgid "The menu with the selected services is available in the footer of article."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/08_sharing_services.md:50
+#, markdown-text, no-wrap
+msgid "Add More Sharing Services"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/08_sharing_services.md:52
+#, markdown-text
+msgid ""
+"Please open a new issue on "
+"[GitHub](https://github.com/FreshRSS/FreshRSS/issues) and support us with "
+"information."
+msgstr ""
+
+#. type: Title #
+#: en/./users/09_refreshing_feeds.md:1
+#, markdown-text, no-wrap
+msgid "Refreshing feeds"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:4
+#, markdown-text
+msgid ""
+"To take full advantage of FreshRSS, it needs to retrieve new items from the "
+"feeds you have subscribed to. There are several ways to do this:"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Manual update](#manual-update)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Complete update](#complete-update)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Partial update](#partial-update)"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Automatic update with cron](#automatic-update-with-cron)"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Online cron](#online-cron)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[For Form Authentication](#for-form-authentication)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[For HTTP authentication](#for-http-authentication)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[For No authentication None](#for-no-authentication-none)"
+msgstr ""
+
+#. type: Bullet: '- '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid ""
+"[Feed configuration of “Do not automatically refresh more often "
+"than”](#feed-configuration-of-do-not-automatically-refresh-more-often-than)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Background](#background)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Default value](#default-value)"
+msgstr ""
+
+#. type: Bullet: ' - '
+#: en/./users/09_refreshing_feeds.md:17
+#, markdown-text
+msgid "[Individual feed configuration](#individual-feed-configuration)"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/09_refreshing_feeds.md:18
+#, markdown-text, no-wrap
+msgid "Manual update"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:21
+#, markdown-text
+msgid ""
+"If you can’t or don’t want to use the automatic method, you can update "
+"manually. There are two methods for updating all or some of the feeds."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:22
+#, markdown-text, no-wrap
+msgid "Complete update"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:25
+#, markdown-text
+msgid ""
+"This update occurs on all feeds. To trigger it, simply click on the update "
+"link in the navigation menu."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:27
+#, markdown-text
+msgid "![Navigation menu](../img/users/refresh.1.png)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:29
+#, markdown-text
+msgid ""
+"When the update starts, a progress bar appears and changes while feeds are "
+"processed."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:31
+#, markdown-text
+msgid "![Progress bar](../img/users/refresh.5.png)"
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:32
+#, markdown-text, no-wrap
+msgid "Partial update"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:35
+#, markdown-text
+msgid ""
+"This update occurs on the selected feed only. To trigger it, simply click on "
+"the update link in the feed menu."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:37
+#, markdown-text
+msgid "![Feed menu](../img/users/refresh.2.png)"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/09_refreshing_feeds.md:38
+#, markdown-text, no-wrap
+msgid "Automatic update with cron"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:41
+#, markdown-text
+msgid "This is the recommended method."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:43
+#, markdown-text
+msgid ""
+"This method is only available if you have access to the scheduled tasks of "
+"the machine on which your FreshRSS instance is installed."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:45
+#, markdown-text
+msgid ""
+"The script is named *actualize_script.php* and is located in the *app* "
+"folder. The scheduled task syntax will not be explained here. However, here "
+"is [a quick introduction to "
+"crontab](http://www.adminschoice.com/crontab-quick-reference/) that might "
+"help you."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:47
+#, markdown-text
+msgid "Here is an example to trigger article update every hour."
+msgstr ""
+
+#. type: Fenced code block (cron)
+#: en/./users/09_refreshing_feeds.md:48
+#, no-wrap
+msgid ""
+"0 * * * * php /path/to/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log "
+"2>&1\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/09_refreshing_feeds.md:52
+#, markdown-text, no-wrap
+msgid "Online cron"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:55
+#, markdown-text
+msgid ""
+"If you do not have access to the installation server scheduled task, you can "
+"still automate the update process."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:58
+#, markdown-text
+msgid ""
+"To do so, you need to create a scheduled task, which need to call a specific "
+"URL: <https://freshrss.example.net/i/?c=feed&a=actualize> (it could be "
+"different depending on your installation). Depending on your application "
+"authentication method, you need to adapt the scheduled task."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:60
+#, markdown-text
+msgid "Special parameters to configure the script - all parameters can be combined:"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:64
+#, markdown-text
+msgid ""
+"- Parameter \"force\" "
+"<https://freshrss.example.net/i/?c=feed&a=actualize&force=1> If *force* is "
+"set to 1 all feeds will be refreshed at once."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:68
+#, markdown-text
+msgid ""
+"- Parameter \"ajax\" "
+"<https://freshrss.example.net/i/?c=feed&a=actualize&ajax=1> Only a status "
+"site is returned and not a complete website. Example: \"OK\""
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:72
+#, markdown-text
+msgid ""
+"- Parameter \"maxFeeds\" "
+"<https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=30> If "
+"*maxFeeds* is set the configured amount of feeds is refreshed at once. The "
+"default setting is \"10\"."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:76
+#, markdown-text
+msgid ""
+"- Parameter \"token\" "
+"<https://freshrss.example.net/i/?c=feed&a=actualize&token=542345872345734> "
+"Security parameter to prevent unauthorized refreshes. For detailed "
+"Documentation see \"Form authentication\"."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:77
+#, markdown-text, no-wrap
+msgid "For Form Authentication"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:80
+#, markdown-text
+msgid ""
+"If your FreshRSS instance is using Form Authentication, you can configure an "
+"authentication token to grant access to the online cron."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:82
+#, markdown-text
+msgid "![Token configuration](../img/users/token.1.png)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:84
+#, markdown-text
+msgid ""
+"You can target a specific user by adding their username to the query string, "
+"with `&user=insert-username`:"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:86
+#, markdown-text
+msgid "The scheduled task syntax should look as follows:"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:88
+#, markdown-text
+msgid "<https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=10&ajax=1&user=someone&token=my-token>"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:90
+#, markdown-text
+msgid ""
+"Alternatively, but not recommended, if you configure the application to "
+"allow anonymous reading, you can also allow anonymous users to update feeds "
+"(“Allow anonymous refresh of the articles”), and that does not require a "
+"token."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:92
+#, markdown-text
+msgid "![Anonymous access configuration](../img/users/anonymous_access.1.png)"
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:93
+#, markdown-text, no-wrap
+msgid "For HTTP authentication"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:96
+#, markdown-text
+msgid ""
+"If your FreshRSS instance is using HTTP authentication, you’ll need to "
+"provide your credentials to the scheduled task."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:98
+#, markdown-text, no-wrap
+msgid ""
+"**Note:** This method is discouraged as your credentials are stored in plain "
+"text.\n"
+msgstr ""
+
+#. type: Fenced code block (cron)
+#: en/./users/09_refreshing_feeds.md:99
+#, no-wrap
+msgid ""
+"0 * * * * curl -u alice:password123 "
+"'https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=10&ajax=1&user=alice'\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:104
+#, markdown-text
+msgid "On some systems, that syntax might also work:"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:106
+#, markdown-text
+msgid "<https://alice:password123@freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=10&ajax=1&user=alice>"
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:107
+#, markdown-text, no-wrap
+msgid "For No authentication (None)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:110
+#, markdown-text
+msgid ""
+"If your FreshRSS instance uses no authentication (public instance, default "
+"user):"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:112
+#, markdown-text
+msgid "<https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=10&ajax=1>"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/09_refreshing_feeds.md:113
+#, markdown-text, no-wrap
+msgid "Feed configuration of “Do not automatically refresh more often than”"
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:115
+#, markdown-text, no-wrap
+msgid "Background"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:118
+#, markdown-text
+msgid ""
+"FreshRSS does not, by design, supports pull refreshes at frequencies higher "
+"than once every 15 minutes. But FreshRSS supports instant push (WebSub)."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:120
+#, markdown-text
+msgid ""
+"FreshRSS is part of an RSS ecosystem. A typical reaction that we have seen "
+"from several servers is to simply ban by, IP, user-agent, or to remove their "
+"RSS feed altogether. Bad user behaviours affect the larger community."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:121
+#, markdown-text, no-wrap
+msgid "Default value"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:124
+#, markdown-text, no-wrap
+msgid ""
+"The default value of “Do not automatically refresh more often than” is set "
+"in Configuration -> Archiving.\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:126
+#, markdown-text
+msgid ""
+"The lowest global/default purposely cannot be set faster than every 20 "
+"minutes, to avoid wasting resources and make sure the RSS ecosystem remains "
+"sane."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/09_refreshing_feeds.md:127
+#, markdown-text, no-wrap
+msgid "Individual feed configuration"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:130
+#, markdown-text
+msgid "Under the settings for individual feeds, you can go down to 15min."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/09_refreshing_feeds.md:134
+#, markdown-text
+msgid ""
+"Read more: - [Normal, Global and Reader view](./03_Main_view.md) - [Filter "
+"the feeds and search](./10_filter.md)"
+msgstr ""
+
+#. type: Title #
+#: en/./users/10_filter.md:2
+#, markdown-text, no-wrap
+msgid "Filtering articles"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:4
+#, markdown-text, no-wrap
+msgid "Purpose"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:7
+#, markdown-text
+msgid ""
+"When the number of articles stored by FreshRSS inevitably grows larger, it’s "
+"important to use efficient filters to display only a subset of the "
+"articles. There are several methods that filter with different "
+"criteria. Usually those methods can be combined."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:8
+#, markdown-text, no-wrap
+msgid "By category"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:11
+#, markdown-text
+msgid ""
+"This is the easiest method. You only need to click on the category title in "
+"the side panel. There are two special categories at the top of the panel:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:14
+#, markdown-text
+msgid ""
+"*Main feed* displays only articles from feeds marked as available in that "
+"category"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:14
+#, markdown-text
+msgid "*Favourites* displays only articles marked as favourites"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:15
+#, markdown-text, no-wrap
+msgid "By feed"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:18
+#, markdown-text
+msgid "There are several methods to filter articles by feed:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:23
+#, markdown-text
+msgid "by clicking the feed title in the side panel"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:23
+#, markdown-text
+msgid "by clicking the feed title in the article details"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:23
+#, markdown-text
+msgid "by filtering in the feed options from the side panel"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:23
+#, markdown-text
+msgid "by filtering in the feed configuration"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:25
+#, markdown-text
+msgid "![Feed filter](../img/users/feed.filter.1.png)"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:26
+#, markdown-text, no-wrap
+msgid "By status"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:29
+#, markdown-text
+msgid ""
+"Each article has two attributes that can be combined. The first attribute "
+"indicates whether or not the article has been read. The second attribute "
+"indicates if the article was marked as favorite or not."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:31
+#, markdown-text
+msgid ""
+"In version 0.7, attribute filters are available in the article display "
+"dropdown list. With this version, it’s not possible to combine filters. For "
+"instance, it’s not possible to display only read and favorite articles."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:33
+#, markdown-text
+msgid "![Attribute filters in 0.7](../img/users/status.filter.0.7.png)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:35
+#, markdown-text
+msgid ""
+"Starting with version 0.8, all attribute filters are visible as toggle "
+"icons. They can be combined. As any combination is possible, some have the "
+"same result. For instance, the result for all filters selected is the same "
+"as no filter selected."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:37
+#, markdown-text
+msgid "![Attribute filters in 0.8](../img/users/status.filter.0.8.png)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:39
+#, markdown-text
+msgid "By default, this filter displays only unread articles"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:40
+#, markdown-text, no-wrap
+msgid "By content"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:43
+#, markdown-text
+msgid ""
+"It is possible to filter articles by their content by inputting a string in "
+"the search field."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:44
+#, markdown-text, no-wrap
+msgid "With the search field"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:47
+#, markdown-text
+msgid "You can use the search field to further refine results:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "by feed ID: `f:123` or multiple feed IDs (*or*): `f:123,234,345`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "by author: `author:name` or `author:'composed name'`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "by title: `intitle:keyword` or `intitle:'composed keyword'`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "by URL: `inurl:keyword` or `inurl:'composed keyword'`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "by tag: `#tag` or `#tag+with+whitespace`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "by free-text: `keyword` or `'composed keyword'`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid ""
+"by date of discovery, using the [ISO 8601 time interval "
+"format](http://en.wikipedia.org/wiki/ISO_8601#Time_intervals): "
+"`date:<date-interval>`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "From a specific day, or month, or year:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-03-30`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-03` or `date:201403`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "From a specific time of a given day:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-05-30T13`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-05-30T13:30`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "Between two given dates:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-02/2014-04`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-02--2014-04`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-02/04`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-02-03/05`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-02-03T22:00/22:15`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-02-03T22:00/15`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "After a given date:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-03/`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "Before a given date:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:/2014-03`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "For a specific duration after a given date:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:2014-03/P1W`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "For a specific duration before a given date:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:P1W/2014-05-25T23:59:59`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "For the past duration before now (the trailing slash is optional):"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:P1Y/` or `date:P1Y` (past year)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:P2M/` (past two months)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:P3W/` (past three weeks)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:P4D/` (past four days)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:PT5H/` (past five hours)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:PT30M/` (past thirty minutes)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:PT90S/` (past ninety seconds)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "`date:P1DT1H/` (past one day and one hour)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid "by date of publication, using the same format: `pubdate:<date-interval>`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid ""
+"by custom label ID `L:12` or multiple label IDs: `L:12,13,14` or with any "
+"label: `L:*`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid ""
+"by custom label name `label:label`, `label:\"my label\"` or any label name "
+"from a list (*or*): `labels:\"my label,my other label\"`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid ""
+"by several label names (*and*): `label:\"my label\" label:\"my other "
+"label\"`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid ""
+"by entry (article) ID: `e:1639310674957894` or multiple entry IDs (*or*): "
+"`e:1639310674957894,1639310674957893`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid ""
+"by user query (saved search) name: `search:myQuery`, `search:\"My query\"` "
+"or saved search ID: `S:3`"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: en/./users/10_filter.md:93
+#, markdown-text
+msgid ""
+"internally, those references are replaced by the corresponding user query in "
+"the search expression"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:95
+#, markdown-text
+msgid "Be careful not to enter a space between the operator and the search value."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:98
+#, markdown-text
+msgid ""
+"Some operators can be used negatively, to exclude articles, with the same "
+"syntax as above, but prefixed by a `!` or `-`: `!f:234`, `-author:name`, "
+"`-intitle:keyword`, `-inurl:keyword`, `-#tag`, `!keyword`, `!date:2019`, "
+"`!date:P1W`, `!pubdate:P3d/`."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:101
+#, markdown-text
+msgid ""
+"It is also possible to combine keywords to create a more precise filter. "
+"For example, you can enter multiple instances of `f:`, `author:`, "
+"`intitle:`, `inurl:`, `#`, and free-text."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:104
+#, markdown-text
+msgid ""
+"Combining several search criteria implies a logical *and*, but the keyword ` "
+"OR ` can be used to combine several search criteria with a logical *or* "
+"instead: `author:Dupont OR author:Dupond`"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:107
+#, markdown-text
+msgid ""
+"You don’t have to do anything special to combine multiple negative "
+"operators. Writing `!intitle:'thing1' !intitle:'thing2'` implies AND, see "
+"above. For more pointers on how AND and OR interact with negation, see [this "
+"GitHub "
+"comment](https://github.com/FreshRSS/FreshRSS/issues/3236#issuecomment-891219460). "
+"Additional reading: [De Morgan’s "
+"laws](https://en.wikipedia.org/wiki/De_Morgan%27s_laws)."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:109
+#, markdown-text
+msgid ""
+"Finally, parentheses may be used to express more complex queries, with basic "
+"negation support:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:115
+#, markdown-text
+msgid "`(author:Alice OR intitle:hello) (author:Bob OR intitle:world)`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:115
+#, markdown-text
+msgid "`(author:Alice intitle:hello) OR (author:Bob intitle:world)`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:115
+#, markdown-text
+msgid "`!((author:Alice intitle:hello) OR (author:Bob intitle:world))`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:115
+#, markdown-text
+msgid "`(author:Alice intitle:hello) !(author:Bob intitle:world)`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: en/./users/10_filter.md:115
+#, markdown-text
+msgid "`!(S:1 OR S:2)`"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:117
+#, markdown-text, no-wrap
+msgid ""
+"> ℹ️ If you need to search for a parenthesis, it needs to be escaped like "
+"`\\(` or `\\)`\n"
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:118
+#, markdown-text, no-wrap
+msgid "By sorting by date"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:121
+#, markdown-text
+msgid ""
+"You can change the sort order by clicking the toggle button available in the "
+"header."
+msgstr ""
+
+#. type: Title ##
+#: en/./users/10_filter.md:122
+#, markdown-text, no-wrap
+msgid "Store your filters"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:125
+#, markdown-text
+msgid ""
+"Once you came up with your perfect filter, it would be a shame if you need "
+"to recreate it every time you need to use it."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:129
+#, markdown-text
+msgid ""
+"Hopefully, there is a way to bookmark them for later use. We call them "
+"*user queries*. You can create as many as you want, the only limit is how "
+"they will be displayed on your screen."
+msgstr ""
+
+#. type: Title ###
+#: en/./users/10_filter.md:130
+#, markdown-text, no-wrap
+msgid "Bookmark the current query"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:134
+#, markdown-text
+msgid ""
+"Display the user queries drop-down by clicking the button next to the state "
+"buttons. ![User queries "
+"drop-down](../img/users/user.queries.drop-down.empty.png)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:136
+#, markdown-text
+msgid "Then click on the bookmark action."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:138
+#, markdown-text
+msgid "Congratulations, you’re done!"
+msgstr ""
+
+#. type: Title ###
+#: en/./users/10_filter.md:139
+#, markdown-text, no-wrap
+msgid "Using a bookmarked query"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:143
+#, markdown-text
+msgid ""
+"Display the user queries drop-down by clicking the button next to the state "
+"buttons. ![User queries "
+"drop-down](../img/users/user.queries.drop-down.not.empty.png)"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:145
+#, markdown-text
+msgid ""
+"Then click on the bookmarked query, the previously stored query will be "
+"applied."
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:148
+#, markdown-text, no-wrap
+msgid ""
+"> Note that only the query is stored, not the articles.\n"
+"> The results you are seeing now could be different from the results on the "
+"day you've created the query.\n"
+msgstr ""
+
+#. type: Plain text
+#: en/./users/10_filter.md:152
+#, markdown-text
+msgid ""
+"Read more: * [Normal, Global and Reader view](./03_Main_view.md) * "
+"[Refreshing the feeds](./09_refreshing_feeds.md)"
+msgstr ""