[fix] Config panel doc

This commit is contained in:
ljf 2023-08-21 00:50:20 +02:00 committed by ljf (zamentur)
parent 07c602e9d0
commit ecbda6efba
2 changed files with 44 additions and 27 deletions

View file

@ -14,14 +14,14 @@ Those panels could aslo be used as interface generator to extend quickly capabil
! Please: Keep in mind the YunoHost spirit, and try to build your panels in such a way as to expose only really useful parameters, and if there are many of them, to relegate those corresponding to rarer use cases to "Advanced" sub-sections. ! Please: Keep in mind the YunoHost spirit, and try to build your panels in such a way as to expose only really useful parameters, and if there are many of them, to relegate those corresponding to rarer use cases to "Advanced" sub-sections.
## How does config_panel.toml work ## How does `config_panel.toml` work
Basically, configuration panels for apps uses at least a `config_panel.toml` at the root of your package. For advanced usecases, this TOML file could also be paired with a `config` script inside the scripts directory of your package. Basically, configuration panels for apps uses at least a `config_panel.toml` at the root of your package. For advanced usecases, this TOML file could also be paired with a `config` script inside the scripts directory of your package.
The `config_panel.toml` file describes one or several panels, containing some sections, containing some questions generally binded to a params in a configuration file. The `config_panel.toml` file describes one or several panels, containing some sections, containing some questions generally binded to a params in a configuration file.
We supposed we have an upstream app with this simple config.yml file: We supposed we have an upstream app with this simple config.yml file:
``` ```yaml
title: 'My dummy apps' title: 'My dummy apps'
theme: 'white' theme: 'white'
max_rate: 10 max_rate: 10
@ -29,7 +29,7 @@ max_age: 365
``` ```
We could for example create a simple configuration panel for it like this one, by following the syntax `\[PANEL.SECTION.QUESTION\]`: We could for example create a simple configuration panel for it like this one, by following the syntax `\[PANEL.SECTION.QUESTION\]`:
``` ```toml
version = "1.0" version = "1.0"
[main] [main]
@ -63,7 +63,7 @@ Here we have created one `main` panel, containing the `main` and `limits` sectio
For performance reasons, questions short keys should be unique in all the `config_panel.toml` file, not just inside its panel or its section. For performance reasons, questions short keys should be unique in all the `config_panel.toml` file, not just inside its panel or its section.
So you can't have So you can't have
``` ```toml
[manual.vpn.server_ip] [manual.vpn.server_ip]
[advanced.dns.server_ip] [advanced.dns.server_ip]
``` ```
@ -87,12 +87,12 @@ If you have not defined a specific getter/setter (see bellow), and without `bind
If you want to read and save the value into a variable (called like the option name) of a file (json, yaml, ini, php, py ...) you can do: If you want to read and save the value into a variable (called like the option name) of a file (json, yaml, ini, php, py ...) you can do:
``` ```toml
bind = ":__INSTALL_DIR__/config.yml" bind = ":__INSTALL_DIR__/config.yml"
``` ```
If you want to read and save the value into an other variable than the `config_panel.toml` question short key (email in the example) of a file (json, yaml, ini, php, py ...) you can do: If you want to read and save the value into an other variable than the `config_panel.toml` question short key (email in the example) of a file (json, yaml, ini, php, py ...) you can do:
``` ```toml
bind = "email:__FINALPATH__/config.yml" bind = "email:__FINALPATH__/config.yml"
``` ```
@ -100,14 +100,14 @@ bind = "email:__FINALPATH__/config.yml"
Sometimes, you want to read and save a value in a variable name that appears several time in the configuration file (for example variables called `max`). The `bind` property allows you to change the value on the variable following a regex in a the file: Sometimes, you want to read and save a value in a variable name that appears several time in the configuration file (for example variables called `max`). The `bind` property allows you to change the value on the variable following a regex in a the file:
``` ```toml
bind = "importExportRateLimiting>max:__INSTALL_DIR__/conf.json" bind = "importExportRateLimiting>max:__INSTALL_DIR__/conf.json"
``` ```
#### Read / write an entire file #### Read / write an entire file
If you have a question of type file or text you could want to save the content into a specific path on the system. If you have a question of type file or text you could want to save the content into a specific path on the system.
``` ```toml
bind = "__INSTALL_DIR__/img/logo.png" bind = "__INSTALL_DIR__/img/logo.png"
``` ```
@ -125,6 +125,19 @@ For all of those use cases, there are the specific getter or setter mechanism fo
To create specific getter / setter, you first need to create a `config` script inside the `scripts` directory To create specific getter / setter, you first need to create a `config` script inside the `scripts` directory
scripts/config
```bash
#!/bin/bash
source /usr/share/yunohost/helpers
ynh_abort_if_errors
# Put your getter, setter and validator here
# Keep this last line
ynh_app_config_run $1
```
#### Getter #### Getter
A getter is a bash function called `getter_QUESTION_SHORT_KEY()` which returns data through stdout. A getter is a bash function called `getter_QUESTION_SHORT_KEY()` which returns data through stdout.
@ -135,7 +148,7 @@ Returns could have 2 formats:
[details summary="<i>Basic example : Get the login inside the first line of a file </i>" class="helper-card-subtitle text-muted"] [details summary="<i>Basic example : Get the login inside the first line of a file </i>" class="helper-card-subtitle text-muted"]
scripts/config scripts/config
``` ```bash
get__login_user() { get__login_user() {
if [ -s /etc/openvpn/keys/credentials ] if [ -s /etc/openvpn/keys/credentials ]
then then
@ -147,7 +160,7 @@ get__login_user() {
``` ```
config_panel.toml config_panel.toml
``` ```toml
[main.auth.login_user] [main.auth.login_user]
ask = "Username" ask = "Username"
type = "string" type = "string"
@ -156,14 +169,14 @@ type = "string"
[details summary="<i>Advanced example 1 : Display a list of available plugins</i>" class="helper-card-subtitle text-muted"] [details summary="<i>Advanced example 1 : Display a list of available plugins</i>" class="helper-card-subtitle text-muted"]
scripts/config scripts/config
``` ```bash
get__plugins() { get__plugins() {
echo "choices: [$(ls $install_dir/plugins/ | tr '\n' ',')]" echo "choices: [$(ls $install_dir/plugins/ | tr '\n' ',')]"
} }
``` ```
config_panel.toml config_panel.toml
``` ```toml
[main.plugins.plugins] [main.plugins.plugins]
ask = "Plugin to activate" ask = "Plugin to activate"
type = "tags" type = "tags"
@ -173,7 +186,7 @@ config_panel.toml
[details summary="<i>Example 2 : Display the status of a VPN</i>" class="helper-card-subtitle text-muted"] [details summary="<i>Example 2 : Display the status of a VPN</i>" class="helper-card-subtitle text-muted"]
scripts/config scripts/config
``` ```bash
get__status() { get__status() {
if [ -f "/sys/class/net/tun0/operstate" ] && [ "$(cat /sys/class/net/tun0/operstate)" == "up" ] if [ -f "/sys/class/net/tun0/operstate" ] && [ "$(cat /sys/class/net/tun0/operstate)" == "up" ]
then then
@ -193,7 +206,7 @@ EOF
``` ```
config_panel.toml config_panel.toml
``` ```toml
[main.cube.status] [main.cube.status]
ask = "Custom getter alert" ask = "Custom getter alert"
type = "alert" type = "alert"
@ -210,7 +223,7 @@ You probably should use `ynh_print_info` in order to display info for user about
[details summary="<i>Basic example : Set the login into the first line of a file </i>" class="helper-card-subtitle text-muted"] [details summary="<i>Basic example : Set the login into the first line of a file </i>" class="helper-card-subtitle text-muted"]
scripts/config scripts/config
``` ```bash
set__login_user() { set__login_user() {
if [ -z "${login_user}" ] if [ -z "${login_user}" ]
then then
@ -221,7 +234,7 @@ set__login_user() {
``` ```
config_panel.toml config_panel.toml
``` ```toml
[main.auth.login_user] [main.auth.login_user]
ask = "Username" ask = "Username"
type = "string" type = "string"
@ -232,13 +245,13 @@ type = "string"
You will often need to validate data answered by the user before to save it somewhere. You will often need to validate data answered by the user before to save it somewhere.
Validation can be made with regex through `pattern` argument Validation can be made with regex through `pattern` argument
``` ```toml
pattern.regexp = '^.+@.+$' pattern.regexp = '^.+@.+$'
pattern.error = 'An email is required for this field' pattern.error = 'An email is required for this field'
``` ```
You can also restrict several types with a choices list. You can also restrict several types with a choices list.
``` ```toml
choices.option1 = "Plop1" choices.option1 = "Plop1"
choices.option2 = "Plop2" choices.option2 = "Plop2"
choices.option3 = "Plop3" choices.option3 = "Plop3"
@ -249,11 +262,10 @@ Some other type specific argument exist like
| ----- | --------------------------- | | ----- | --------------------------- |
| `number`, `range` | `min`, `max`, `step` | | `number`, `range` | `min`, `max`, `step` |
| `file` | `accept` | | `file` | `accept` |
| `tags` | `limit` |
| `boolean` | `yes` `no` | | `boolean` | `yes` `no` |
Finally, if you need specific or multi variable validation, you can use custom validators function: Finally, if you need specific or multi variable validation, you can use custom validators function:
``` ```bash
validate__login_user() { validate__login_user() {
if [[ "${#login_user}" -lt 4 ]]; then echo 'Too short user login'; fi if [[ "${#login_user}" -lt 4 ]]; then echo 'Too short user login'; fi
} }
@ -265,7 +277,7 @@ validate__login_user() {
You can use the services key to specify which service need to be reloaded or restarted You can use the services key to specify which service need to be reloaded or restarted
``` ```toml
services = [ 'nginx', '__APP__' ] services = [ 'nginx', '__APP__' ]
``` ```
@ -275,7 +287,7 @@ This argument could be on panel, section, or question.
All main configuration helpers are overwritable, example: All main configuration helpers are overwritable, example:
``` ```bash
ynh_app_config_apply() { ynh_app_config_apply() {
# Stop vpn client # Stop vpn client

View file

@ -18,18 +18,18 @@ YunoHost uses a lot of forms. You can found here information on supported types
| Property | Scope | Description | Example | | Property | Scope | Description | Example |
|----------|--------------|-------------|---------| |----------|--------------|-------------|---------|
| `type` | Everywhere | Specify the type of the question (see bellow for the list) | | | `type` | Everywhere | Specify the type of the question (see bellow for the list) | `type = "string"` |
| `ask` | Everywhere | The title of the question | `ask.en = "Cats or dogs ?"` | | `ask` | Everywhere | The title of the question | `ask.en = "Cats or dogs ?"` |
| `help` | Everywhere | An help message | `help.en = "Think carefully!"` | | `help` | Everywhere | An help message | `help.en = "Think carefully!"` |
| `optional`| Everywhere | Set true if the question is not mandatory | `optional = true` | | `optional`| Everywhere | Set true if the question is not mandatory | `optional = true` |
| `readonly`| Everywhere | Avoid user to be able to change the value | `readonly = true` | | `readonly`| Everywhere | Avoid user to be able to change the value | `readonly = true` |
| `example` | Everywhere | Give an example to help to understand the format of the answer|| | `example` | Everywhere | Give an example to help to understand the format of the answer| `example = "camille@example.com"` |
| `pattern.regexp` | Everywhere | Regex to validate the new value|| | `pattern.regexp` | Everywhere | Regex to validate the new value| `pattern.regexp = "^.+@.+$"` |
| `pattern.error` | Everywhere | Error to display if the pattern doesn't match | | | `pattern.error` | Everywhere | Error to display if the pattern doesn't match | |
| `redact` | Everywhere | Avoid a confidential value to be logged | `redact = true` | | `redact` | Everywhere | Avoid a confidential value to be logged | `redact = true` |
| `default` | Install | A default value for the question | | | `default` | Install | A default value for the question | |
| `visible` | ConfigPanel | A simple js expression based on other short keys questions to hide or display dynamically the question| `visible = "login && ! private_key"` | | `visible` | ConfigPanel | A simple js expression based on other short keys questions to hide or display dynamically the question| `visible = "login && ! private_key"` |
| `bind` | AppConfigPanel | See [App configuration panel doc](/packaging_config_panels) | | `bind` | AppConfigPanel | See [App configuration panel doc](/packaging_config_panels) | `bind = "__INSTALL_DIR__/config.yml"` |
* `help`, `optional`, `readonly` and `visible` are also available on panels and sections entities. * `help`, `optional`, `readonly` and `visible` are also available on panels and sections entities.
* Long help messages could not to be correctly displayed for user using yunohost CLI * Long help messages could not to be correctly displayed for user using yunohost CLI
@ -110,6 +110,7 @@ By default it ask for a web URL but you can change the `pattern` if you want to.
### `file` ### `file`
File question File question
| Property | Description | Example | | Property | Description | Example |
|----------|--------------|---------| |----------|--------------|---------|
| `accept` | Same format than HTML file input | | | `accept` | Same format than HTML file input | |
@ -117,11 +118,15 @@ File question
! This file type is not made for big files transfer, it's just for small logo, or config files. ! This file type is not made for big files transfer, it's just for small logo, or config files.
### `select` ### `select`
Dropdown
| Property | Description | Example | | Property | Description | Example |
|----------|--------------|---------| |----------|--------------|---------|
| `choices` | list or dictionary of choices | | | `choices` | list or dictionary of choices | |
### `tags` ### `tags`
Multi choices selection.
| Property | Description | Example | | Property | Description | Example |
|----------|--------------|---------| |----------|--------------|---------|
| `choices` | List or dictionary of choices | | | `choices` | List or dictionary of choices | |