mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
doc:form: complete with ljf comments found in app example
This commit is contained in:
parent
1221fd1458
commit
900f462791
2 changed files with 95 additions and 39 deletions
|
@ -34,11 +34,6 @@ routes:
|
||||||
|
|
||||||
# Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/{current_commit}/doc/generate_options_doc.py) on {today} (YunoHost version {version})
|
# Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/{current_commit}/doc/generate_options_doc.py) on {today} (YunoHost version {version})
|
||||||
|
|
||||||
# Options
|
|
||||||
|
|
||||||
Options are fields declaration that renders as form items in the web-admin and prompts in cli.
|
|
||||||
They are used in app manifests to declare the before installation form and in config panels.
|
|
||||||
|
|
||||||
## Glossary
|
## Glossary
|
||||||
|
|
||||||
You may encounter some named types which are used for simplicity.
|
You may encounter some named types which are used for simplicity.
|
||||||
|
@ -60,7 +55,7 @@ You may encounter some named types which are used for simplicity.
|
||||||
- operators availables: `==`, `!=`, `!`, `&&`, `||`, `+`, `-`, `*`, `/`, `%`, `match()`
|
- operators availables: `==`, `!=`, `!`, `&&`, `||`, `+`, `-`, `*`, `/`, `%`, `match()`
|
||||||
- [examples available in the advanced section](#advanced-use-cases)
|
- [examples available in the advanced section](#advanced-use-cases)
|
||||||
- `Binding`: bind a value to a file/property/variable/getter/setter/validator
|
- `Binding`: bind a value to a file/property/variable/getter/setter/validator
|
||||||
- save the value in `settings.yaml` when not defined (`None`)
|
- save the value in `settings.yaml` when not defined
|
||||||
- nothing at all with `"null"`
|
- nothing at all with `"null"`
|
||||||
- a custom getter/setter/validator with `"null"` + a function starting with `get__`, `set__`, `validate__` in `scripts/config`
|
- a custom getter/setter/validator with `"null"` + a function starting with `get__`, `set__`, `validate__` in `scripts/config`
|
||||||
- a variable/property in a file with `:__FINALPATH__/my_file.php`
|
- a variable/property in a file with `:__FINALPATH__/my_file.php`
|
||||||
|
@ -74,6 +69,7 @@ You may encounter some named types which are used for simplicity.
|
||||||
pattern.error.en = "Provide a room like F12: one uppercase and 2 numbers"
|
pattern.error.en = "Provide a room like F12: one uppercase and 2 numbers"
|
||||||
pattern.error.fr = "Entrez un numéro de salle comme F12: une lettre majuscule et deux chiffres."
|
pattern.error.fr = "Entrez un numéro de salle comme F12: une lettre majuscule et deux chiffres."
|
||||||
```
|
```
|
||||||
|
- IMPORTANT: your pattern should be between simple quote, not double.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@ -87,9 +83,7 @@ content = open(fname).read()
|
||||||
tree = ast.parse(content)
|
tree = ast.parse(content)
|
||||||
|
|
||||||
OptionClasses = [
|
OptionClasses = [
|
||||||
c
|
c for c in tree.body if isinstance(c, ast.ClassDef) and c.name.endswith("Option")
|
||||||
for c in tree.body
|
|
||||||
if isinstance(c, ast.ClassDef) and c.name.endswith("Option")
|
|
||||||
]
|
]
|
||||||
|
|
||||||
OptionDocString = {}
|
OptionDocString = {}
|
||||||
|
@ -201,13 +195,65 @@ Lorem ipsum dolor et si qua met!
|
||||||
|
|
||||||
Config panels only
|
Config panels only
|
||||||
|
|
||||||
`bind` allows us to alter the generic behavior of option's values which is: get from and set in `settings.yml`.
|
`bind` allows us to alter the generic behavior of option's values which is: get from and set in the app `settings.yml`.
|
||||||
|
|
||||||
We can:
|
We can:
|
||||||
- alter the source the value comes from with getters.
|
- alter the source the value comes from with getters or binds to file.
|
||||||
- alter the destination with setters
|
- alter the destination with setters or binds to file.
|
||||||
- parse/validate the value before destination with validators
|
- parse/validate the value before destination with validators
|
||||||
|
|
||||||
|
----------------
|
||||||
|
IMPORTANT: with the exception of `bind = "null"` options, options ids should almost **always** correspond to an app setting initialized / reused during install/upgrade.
|
||||||
|
Not doing so may result in inconsistencies between the config panel mechanism and the use of ynh_add_config
|
||||||
|
|
||||||
|
----------------
|
||||||
|
|
||||||
|
##### bind to file
|
||||||
|
|
||||||
|
You can bind a `text` or directly a `file` to a specific file by using `bind = "FILEPATH`.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[panel.section.config_file]
|
||||||
|
type = "file"
|
||||||
|
bind = "__FINALPATH__/config.ini"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[panel.section.config_content]
|
||||||
|
type = "text"
|
||||||
|
bind = "__FINALPATH__/config.ini"
|
||||||
|
default = "key: 'value'"
|
||||||
|
```
|
||||||
|
|
||||||
|
##### bind a value inside a file
|
||||||
|
|
||||||
|
Settings usually correspond to key/values in actual app configurations. Hence, a more useful mode is to have `bind = ":FILENAME"` with a colon `:` before. In that case, YunoHost will automagically find a line with `KEY=VALUE` in `FILENAME` (with the adequate separator between `KEY` and `VALUE`).
|
||||||
|
|
||||||
|
YunoHost will then use this value for the read/get operation. During write/set operations, YunoHost will overwrite the value in **both** FILENAME and in the app's settings.yml
|
||||||
|
|
||||||
|
Configuration file format supported: `yaml`, `toml`, `json`, `ini`, `env`, `php`, `python`.
|
||||||
|
The feature probably works with others formats, but should be tested carefully.
|
||||||
|
|
||||||
|
Note that this feature only works with relatively simple cases such as `KEY: VALUE`, but won't properly work with complex data structures like multilin array/lists or dictionnaries.
|
||||||
|
It also doesn't work with XML format, custom config function call, php define(), …
|
||||||
|
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[panel.section.config_value]
|
||||||
|
# Do not use `file` for this since we only want to insert/save a value
|
||||||
|
type = "string"
|
||||||
|
bind = ":__FINALPATH__/config.ini"
|
||||||
|
default = ""
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, `bind = ":FILENAME"` will use the option id as `KEY` but the option id may sometime not be the exact same `KEY` name in the configuration file.
|
||||||
|
For example, [In pepettes app](https://github.com/YunoHost-Apps/pepettes_ynh/blob/5cc2d3ffd6529cc7356ff93af92dbb6785c3ab9a/conf/settings.py##L11), the python variable is `name` and not `project_name`. In that case, the key name can be specified before the colon `:`.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[panel.section.project_name]
|
||||||
|
bind = "name:__FINALPATH__/config.ini"
|
||||||
|
```
|
||||||
|
|
||||||
##### Getters
|
##### Getters
|
||||||
|
|
||||||
Define an option's custom getter in a bash script `script/config`.
|
Define an option's custom getter in a bash script `script/config`.
|
||||||
|
|
|
@ -299,10 +299,20 @@ class Pattern(BaseModel):
|
||||||
|
|
||||||
class BaseOption(BaseModel):
|
class BaseOption(BaseModel):
|
||||||
"""
|
"""
|
||||||
|
Options are fields declaration that renders as form items, button, alerts or text in the web-admin and printed or prompted in CLI.
|
||||||
|
They are used in app manifests to declare the before installation form and in config panels.
|
||||||
|
|
||||||
|
[Have a look at the app config panel doc](/packaging_apps_config_panels) for details about Panels and Sections.
|
||||||
|
|
||||||
|
----------------
|
||||||
|
IMPORTANT: as for Panels and Sections you have to choose an id, but this one should be unique in all this document, even if the question is in an other panel.
|
||||||
|
|
||||||
|
----------------
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "string"
|
type = "string"
|
||||||
# ask as `str`
|
# ask as `str`
|
||||||
ask = "The text in english"
|
ask = "The text in english"
|
||||||
|
@ -346,14 +356,14 @@ class BaseOption(BaseModel):
|
||||||
- [`group`](#option-group)
|
- [`group`](#option-group)
|
||||||
- `ask`: `Translation` (default to the option's `id` if not defined):
|
- `ask`: `Translation` (default to the option's `id` if not defined):
|
||||||
- text to display as the option's label for inputs or text to display for readonly options
|
- text to display as the option's label for inputs or text to display for readonly options
|
||||||
|
- in config panels, questions are displayed on the left side and therefore have not much space to be rendered. Therefore, it is better to use a short question, and use the `help` property to provide additional details if necessary.
|
||||||
- `visible` (optional): `bool` or `JSExpression` (default: `true`)
|
- `visible` (optional): `bool` or `JSExpression` (default: `true`)
|
||||||
- define if the option is diplayed/asked
|
- define if the option is diplayed/asked
|
||||||
- if `false` and used alongside `readonly = true`, you get a context only value that can still be used in `JSExpression`s
|
- if `false` and used alongside `readonly = true`, you get a context only value that can still be used in `JSExpression`s
|
||||||
- `readonly` (optional): `bool` (default: `false`, forced to `true` for readonly types):
|
- `readonly` (optional): `bool` (default: `false`, forced to `true` for readonly types):
|
||||||
- If `true` for input types: forbid mutation of its value
|
- If `true` for input types: forbid mutation of its value
|
||||||
- `bind` (optional): `Binding` (default: `None`):
|
- `bind` (optional): `Binding`, config panels only! A powerful feature that let you configure how and where the setting will be read, validated and written
|
||||||
- (config panels only!) allow to choose where an option's is gathered/stored:
|
- if not specified, the value will be read/written in the app `settings.yml`
|
||||||
- if not specified, the value will be gathered/stored in the `settings.yml`
|
|
||||||
- if `"null"`:
|
- if `"null"`:
|
||||||
- the value will not be stored at all (can still be used in context evaluations)
|
- the value will not be stored at all (can still be used in context evaluations)
|
||||||
- if in `scripts/config` there's a function named:
|
- if in `scripts/config` there's a function named:
|
||||||
|
@ -440,7 +450,7 @@ class DisplayTextOption(BaseReadonlyOption):
|
||||||
##### Examples
|
##### Examples
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "display_text"
|
type = "display_text"
|
||||||
ask = "Simple text rendered as is."
|
ask = "Simple text rendered as is."
|
||||||
```
|
```
|
||||||
|
@ -456,7 +466,7 @@ class MarkdownOption(BaseReadonlyOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "display_text"
|
type = "display_text"
|
||||||
ask = "Text **rendered** in markdown."
|
ask = "Text **rendered** in markdown."
|
||||||
```
|
```
|
||||||
|
@ -480,7 +490,7 @@ class AlertOption(BaseReadonlyOption):
|
||||||
##### Examples
|
##### Examples
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "alert"
|
type = "alert"
|
||||||
ask = "The configuration seems to be manually modified..."
|
ask = "The configuration seems to be manually modified..."
|
||||||
style = "warning"
|
style = "warning"
|
||||||
|
@ -521,7 +531,7 @@ class ButtonOption(BaseReadonlyOption):
|
||||||
##### Examples
|
##### Examples
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[my_action_id]
|
[section.my_option_id]
|
||||||
type = "button"
|
type = "button"
|
||||||
ask = "Break the system"
|
ask = "Break the system"
|
||||||
style = "danger"
|
style = "danger"
|
||||||
|
@ -575,7 +585,7 @@ class BaseInputOption(BaseOption):
|
||||||
##### Examples
|
##### Examples
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "string"
|
type = "string"
|
||||||
# …any common props… +
|
# …any common props… +
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -751,7 +761,7 @@ class StringOption(BaseStringOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "string"
|
type = "string"
|
||||||
default = "E10"
|
default = "E10"
|
||||||
pattern.regexp = "^[A-F]\d\d$"
|
pattern.regexp = "^[A-F]\d\d$"
|
||||||
|
@ -774,7 +784,7 @@ class TextOption(BaseStringOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "text"
|
type = "text"
|
||||||
default = "multi\\nline\\ncontent"
|
default = "multi\\nline\\ncontent"
|
||||||
```
|
```
|
||||||
|
@ -797,7 +807,7 @@ class PasswordOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "password"
|
type = "password"
|
||||||
```
|
```
|
||||||
##### Properties
|
##### Properties
|
||||||
|
@ -849,7 +859,7 @@ class ColorOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "color"
|
type = "color"
|
||||||
default = "#ff0"
|
default = "#ff0"
|
||||||
```
|
```
|
||||||
|
@ -895,7 +905,7 @@ class NumberOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "number"
|
type = "number"
|
||||||
default = 100
|
default = 100
|
||||||
min = 50
|
min = 50
|
||||||
|
@ -970,7 +980,7 @@ class BooleanOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "boolean"
|
type = "boolean"
|
||||||
default = 1
|
default = 1
|
||||||
yes = "agree"
|
yes = "agree"
|
||||||
|
@ -1098,7 +1108,7 @@ class DateOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "date"
|
type = "date"
|
||||||
default = "2070-12-31"
|
default = "2070-12-31"
|
||||||
```
|
```
|
||||||
|
@ -1128,7 +1138,7 @@ class TimeOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "time"
|
type = "time"
|
||||||
default = "12:26"
|
default = "12:26"
|
||||||
```
|
```
|
||||||
|
@ -1161,7 +1171,7 @@ class EmailOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "email"
|
type = "email"
|
||||||
default = "Abc.123@test-example.com"
|
default = "Abc.123@test-example.com"
|
||||||
```
|
```
|
||||||
|
@ -1181,7 +1191,7 @@ class WebPathOption(BaseStringOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "path"
|
type = "path"
|
||||||
default = "/"
|
default = "/"
|
||||||
```
|
```
|
||||||
|
@ -1229,7 +1239,7 @@ class URLOption(BaseStringOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "url"
|
type = "url"
|
||||||
default = "https://example.xn--zfr164b/@handle/"
|
default = "https://example.xn--zfr164b/@handle/"
|
||||||
```
|
```
|
||||||
|
@ -1253,7 +1263,7 @@ class FileOption(BaseInputOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "file"
|
type = "file"
|
||||||
accept = ".json"
|
accept = ".json"
|
||||||
# bind the file to a location to save the file there
|
# bind the file to a location to save the file there
|
||||||
|
@ -1381,7 +1391,7 @@ class SelectOption(BaseChoicesOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "select"
|
type = "select"
|
||||||
choices = ["one", "two", "three"]
|
choices = ["one", "two", "three"]
|
||||||
choices = "one,two,three"
|
choices = "one,two,three"
|
||||||
|
@ -1409,7 +1419,7 @@ class TagsOption(BaseChoicesOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "tags"
|
type = "tags"
|
||||||
default = "word,another word"
|
default = "word,another word"
|
||||||
|
|
||||||
|
@ -1514,7 +1524,7 @@ class DomainOption(BaseChoicesOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "domain"
|
type = "domain"
|
||||||
```
|
```
|
||||||
##### Properties
|
##### Properties
|
||||||
|
@ -1568,7 +1578,7 @@ class AppOption(BaseChoicesOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "app"
|
type = "app"
|
||||||
filter = "is_webapp"
|
filter = "is_webapp"
|
||||||
```
|
```
|
||||||
|
@ -1621,7 +1631,7 @@ class UserOption(BaseChoicesOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "user"
|
type = "user"
|
||||||
```
|
```
|
||||||
##### Properties
|
##### Properties
|
||||||
|
@ -1681,7 +1691,7 @@ class GroupOption(BaseChoicesOption):
|
||||||
|
|
||||||
##### Examples
|
##### Examples
|
||||||
```toml
|
```toml
|
||||||
[my_option_id]
|
[section.my_option_id]
|
||||||
type = "group"
|
type = "group"
|
||||||
default = "visitors"
|
default = "visitors"
|
||||||
```
|
```
|
||||||
|
|
Loading…
Add table
Reference in a new issue