PHPIndex

This page lists files in the current directory. You can view content, get download/execute commands for Wget, Curl, or PowerShell, or filter the list using wildcards (e.g., `*.sh`).

admins
developers
img
users
contributing.md
wget 'https://sme10.lists2.roe3.org/FreshRSS/docs/en/contributing.md'
View Content
## Report a bug

Have you found a bug? Don’t panic, here are some steps to report it with ease:

1. Search for it on [the bug tracker](https://github.com/FreshRSS/FreshRSS/issues) (don’t forget to use the search bar).
2. If you find a similar bug, don’t hesitate to post a comment to add more importance to the related ticket.
3. If you didn’t find it, [open a new ticket](https://github.com/FreshRSS/FreshRSS/issues/new).

If you have to create a new ticket, please try to keep in mind the following advice:

* Give an explicit title to the ticket so it will be easier to find it later.
* Be as exhaustive as possible in the description: what did you do? What is the bug? What are the steps to reproduce the bug?

We also need some information:

* Your FreshRSS version (on the about page or in the `constants.php` file)
* Your server configuration: the type of hosting and the PHP version
* Your storage system (SQLite, MySQL, MariaDB, PostgreSQL)
* If possible, the related logs (PHP logs and FreshRSS logs under `data/users/your_user/log.txt`)

For a more detailed guide on writing bug reports, please refer to [the in-depth guide on reporting bugs](developers/06_Reporting_Bugs).

## Fix a bug

Would you like to fix a bug? For optimum coordination between collaborators, you should follow these indications:

1. Be sure the bug is associated with a ticket and indicate that you’ll work on it.
2. [Fork the project repository](https://help.github.com/articles/fork-a-repo/).
3. [Create a new branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/). The name of the branch should be clear, and ideally prefixed by the related ticket id. For instance, `783-contributing-file` to fix [ticket #783](https://github.com/FreshRSS/FreshRSS/issues/783).
4. Make your changes to your fork and [send a pull request](https://help.github.com/articles/using-pull-requests/).

If you have to write code, please follow [our coding style recommendations](developers/02_First_steps.md).

**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)” ticket label.

## Submit an idea

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 to ask if we can implement it. The greatest ideas often come from the shyest suggestions!

If your idea is nice, we’ll have a look at it.

## Contribute to internationalization (i18n)

Learn how to contribute to translations in [the dedicated documentation](./internationalization.md).

## Contribute to the documentation

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)!

## Contribute to the system themes

FreshRSS offers some official themes. If you have a good sense for great UI you are invited to share your theme with the community (via a [show&tell discussion thread](https://github.com/FreshRSS/FreshRSS/discussions/categories/show-and-tell) or as a [Pull Request](https://github.com/FreshRSS/FreshRSS/pulls)).

Basic Information for creating a new theme are written [here](./developers/04_Frontend/02_Design.md).

This checklist is designed to ensure high-quality system themes while minimizing maintenance efforts.

* Essential files include: [metadata.json, loader.gif, original.png](./developers/04_Frontend/02_Design.md) (located in the `thumbs` directory).
* Include _frss.css in the "files" section of [`metadata.json`](./developers/04_Frontend/02_Design.md).
* Theme-specific icons reside in the `icons` directory.
	* Icons should be provided as `svg` files.
		* Ensure clean code without any unnecessary fragments; utilize tools like [SVGOMG](https://jakearchibald.github.io/svgomg/) for cleaning.
		* The default color for icons is `#666666`; employ CSS filters for recoloring.
* Utilize CSS variables for colors to facilitate easy color adjustments with [CustomCSS extension](https://github.com/FreshRSS/Extensions).
* Implement a dark mode that aligns with the `.darkMode` CSS class.
* To streamline maintenance, avoid using CSS preprocessors; instead, employ well-structured plain CSS.
index.md
wget 'https://sme10.lists2.roe3.org/FreshRSS/docs/en/index.md'
View Content
![FreshRSS logo](img/logo_freshrss.png)

# FreshRSS manual (English)

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.

## Features

FreshRSS has a lot of features including:

* RSS and Atom aggregation
* Mark article as favorite if you liked it or if you want to read it later
* Filter and search functionality helps to easily find articles ([more information](./users/10_filter.html))
* Statistics to show you the publishing frequency all the websites you follow
* Import/export of your feeds into OPML format ([more information](./users/04_Subscriptions.html#import--export))
* Several themes created by the community ([more information](./admins/11_Themes.html))
* Several extensions created by the community ([more information](./admins/15_extensions.html))
* "Google Reader"-like API to connect Android applications ([more information](./users/06_Mobile_access.html#access-via-mobile-app))
* The application is "responsive," which means it adapts to small screens so you can bring articles in your pocket
* Self-hosted: the code is free ([under AGPL3 licence](https://github.com/FreshRSS/FreshRSS/blob/edge/LICENSE.txt)), so you can host your own instance of FreshRSS ([more information](./admins/02_Prerequisites.md))
* Multi-user, so you can also host for your friends and family ([more information](./admins/12_User_management.md))
* share article links with a bunch of services ([more information](./users/08_sharing_services.md))
* And a lot more!

## Manual Chapters

This documentation is split into different sections:

* [User documentation](./users/02_First_steps.md), where you can discover all the possibilities offered by FreshRSS
* [Administrator documentation](./admins/01_Index.md) for detailed installation and maintenance related tasks
* [Developer documentation](./developers/01_Index.md) to guide you in the source code of FreshRSS and to help you if you want to contribute
* [Contributor guidelines](./contributing.md) for those who want to help improve FreshRSS

## Demo

The official demo of FreshRSS is available under [https://demo.freshrss.org/](https://demo.freshrss.org/).

Login credentials:

* Username: demo
* Password: demodemo

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).

## Licence

FreshRSS is licensed under the [GNU Affero General Public License v3.0](https://github.com/FreshRSS/FreshRSS/blob/edge/LICENSE.txt).
internationalization.md
wget 'https://sme10.lists2.roe3.org/FreshRSS/docs/en/internationalization.md'
View Content
# Contributing to internationalization (i18n)

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.

## Overview

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.

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:

* `admin.php` for anything related to FreshRSS administration
* `conf.php` for configuration
* `feedback.php` contains translations of feedback messages
* `gen.php` stores what is global to FreshRSS (`gen` stands for “general”)
* `index.php` for the main page that lists feeds and the About page
* `install.php` contains strings related to the installation
* `sub.php` for subscription management (`sub` stands for “subscription”)
* `user.php` contains some strings related to the User model

This organization makes it possible to avoid a single huge translation file.

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):

```php
<?php
return array(
	'action' => array(
		'actualize' => 'Actualiser',
		'back_to_rss_feeds' => '← Retour à vos flux RSS',
		'cancel' => 'Annuler',
		'create' => 'Créer',
		'disable' => 'Désactiver',
	),
	'freshrss' => array(
		'_' => 'FreshRSS',
		'about' => 'À propos de FreshRSS',
	),
	// ...
);
```

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.

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.

## Add support for a new language

If you want to add support for a language which isn’t supported by FreshRSS yet, you can run this command:

```sh
make i18n-add-language lang=[your language code]
```

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.

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.

## Translate the interface

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!

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:

```sh
make i18n-format
```

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).

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:

```sh
git grep TODO app/i18n/he
```

## Acknowledge a false-positive

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 acknowledge such translations, you can run:

```sh
make i18n-ignore-key lang=fr key=index.about.version
```

This command adds an IGNORE comment on the translation so the key can be considered as translated.

## Add/remove/update a key

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:

```sh
make i18n-add-key key=the.key.to.add value='Your string in English'
```

This adds the key to all the files. It’ll be in English, waiting for other translators.

Conversely, you may want to remove a key that is no longer used in the application with:

```sh
make i18n-remove-key key=the.key.to.remove
```

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:

```sh
make i18n-update-key key=the.key.to.change value='The new string in English'
```

The key will simply be removed and added back with the new value.

## How to access a translation programmatically

To access these translations, you must use the `_t()` function (which is a shortcut for `Minz_Translate::t()`). Code example:

```html
<p>
	<?= _t('gen.freshrss.about') ?>
</p>
```

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.

`_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).

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:

```php
<label>
	<input type="checkbox" name="keep_logged_in" />
	<?= _t('gen.auth.keep_logged_in', 30) ?>
</label>
```