Technical details for config panel structure and form option types
Doc auto-generated by this script on 18/09/2025 (YunoHost version 12.1.25)
Glossary
You may encounter some named types which are used for simplicity.
-
Translation: a translated property-
used for properties:
ask,helpandPattern.error -
a
dictwith locales as keys and translations as values:ask.en = "The text in english"
ask.fr = "Le texte en français"It is not currently possible for translators to translate those string in weblate.
-
a single
strfor a single english default stringhelp = "The text in english"
-
-
JSExpression: astrJS expression to be evaluated totrueorfalse:- used for properties:
visibleandenabled - operators availables:
==,!=,>,>=,<,<=,!,&&,||,+,-,*,/,%andmatch()
- used for properties:
-
Binding: bind a value to a file/property/variable/getter/setter/validator- save the value in
settings.yamlwhen not defined - nothing at all with
"null" - a custom getter/setter/validator with
"null"+ a function starting withget__,set__,validate__inscripts/config - a variable/property in a file with
:__FINALPATH__/my_file.php - a whole file with
__FINALPATH__/my_file.php
- save the value in
-
Pattern: adictwith a regex to match the value against and an error messagepattern.regexp = '^[A-F]\d\d$'
pattern.error = "Provide a room number such as F12: one uppercase and 2 numbers"
# or with translated error
pattern.error.en = "Provide a room number such as F12: one uppercase and 2 numbers"
pattern.error.fr = "Entrez un numéro de salle comme F12: une lettre majuscule et deux chiffres."- IMPORTANT: your
pattern.regexpshould be between simple quote, not double.
- IMPORTANT: your
Configuration panel structure
ConfigPanel
This is the 'root' level of the config panel toml file
Examples
version = 1.0
[config]
# …refer to Panels doc
Properties
version:float(default:1.0), version that the config panel supports in terms of features.i18n(optional):str, an i18n property that let you internationalize options text.- However this feature is only available in core configuration panel (like
yunohost domain config), prefer the useTranslationinname,help, etc.
- However this feature is only available in core configuration panel (like
Panel
Panels are, basically, sections grouped together. Panels are dicts defined inside a ConfigPanel file and require a unique id (in the below example, the id is main). Keep in mind that this id will be used in CLI to refer to the panel, so choose something short and meaningfull.
Examples
[main]
name.en = "Main configuration"
name.fr = "Configuration principale"
help = ""
services = ["__APP__", "nginx"]
[main.customization]
# …refer to Sections doc
Properties
name:Translationorstr, displayed as the panel titlehelp(optional):Translationorstr, text to display before the first sectionservices(optional):listof services names toreload-or-restartwhen any option's value contained in the panel changes"__APP__will refer to the app instance name
actions: FIXME not sure what this does
Section
Sections are, basically, options grouped together. Sections are dicts defined inside a Panel and require a unique id (in the below example, the id is customization prepended by the panel's id main). Keep in mind that this combined id will be used in CLI to refer to the section, so choose something short and meaningfull. Also make sure to not make a typo in the panel id, which would implicitly create an other entire panel.
If at least one button is present it then become an action section.
Options in action sections are not considered settings and therefor are not saved, they are more like parameters that exists only during the execution of an action.
FIXME i'm not sure we have this in code.
Examples
[main]
[main.customization]
name.en = "Advanced configuration"
name.fr = "Configuration avancée"
help = "Every form items in this section are not saved."
services = ["__APP__", "nginx"]
[main.customization.option_id]
type = "string"
# …refer to Options doc
Properties
name(optional):Translationorstr, displayed as the section's title if anyhelp:Translationorstr, text to display before the first optionservices(optional):listof services names toreload-or-restartwhen any option's value contained in the section changes"__APP__will refer to the app instance name
optional:bool(default:true), set the defaultoptionalprop of all Options in the sectionvisible:boolorJSExpression(default:true), allow to conditionally display a section depending on user's answers to previous questions.- Be careful that the
visibleproperty should only refer to previous options's value. Hence, it should not make sense to have avisibleproperty on the very first section.
- Be careful that the
List of all option types
Common properties
Options are fields declaration that renders as form items, button, alert 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 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.
Example
[section.my_option_id]
type = "string"
# ask as `str`
ask = "The text in english"
# ask as `dict`
ask.en = "The text in english"
ask.fr = "Le texte en français"
# advanced props
visible = "my_other_option_id != 'success'"
readonly = true
# much advanced: config panel only?
bind = "null"
Properties
type: the actual type of the option, such as 'markdown', 'password', 'number', 'email', ...ask:Translation(default to the option'sidif not defined):- 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
helpproperty to provide additional details if necessary.
visible(optional):boolorJSExpression(default:true)- define if the option is diplayed/asked
- if
falseand used alongsidereadonly = true, you get a context only value that can still be used inJSExpressions
readonly(optional):bool(default:false, forced totruefor readonly types):- If
truefor input types: forbid mutation of its value
- If
bind(optional):Binding, config panels only! A powerful feature that let you configure how and where the setting will be read, validated and written- if not specified, the value will be read/written in the app
settings.yml - if
"null":- the value will not be stored at all (can still be used in context evaluations)
- if in
scripts/configthere's a function named:get__my_option_id: the value will be gathered from this custom getterset__my_option_id: the value will be passed to this custom setter where you can do whatever you want with the valuevalidate__my_option_id: the value will be passed to this custom validator before any custom setter
- if
bindis a file path:- if the path starts with
:, the value be saved as its id's variable/property counterpart- this only works for first level variables/properties and simple types (no array)
- else the value will be stored as the whole content of the file
- you can use
__FINALPATH__or__INSTALL_DIR__in your path to point to dynamic install paths- FIXME are other global variables accessible?
- if the path starts with
- refer to
binddoc for explaination and examples
- if not specified, the value will be read/written in the app
Common inputs properties
Rest of the option types available are considered inputs.
Example
[section.my_option_id]
type = "string"
# …any common props… +
optional = false
redact = false
default = "some default string"
help = "You can enter almost anything!"
example = "an example string"
placeholder = "write something…"
Properties
- common properties
optional:bool(default:false, buttruein config panels)redact:bool(default:false), to redact the value in the logs when the value contain private informationdefault: depends ontype, the default value to assign to the option- in case of readonly values, you can use this
defaultto assign a value (or return a dynamicdefaultfrom a custom getter)
- in case of readonly values, you can use this
help(optional):Translation, to display a short help message in cli and web-adminexample(optional):str, to display an example value in web-admin onlyplaceholder(optional):str, shown in the web-admin fields only
markdown (readonly)
Display markdown multi-line content. Markdown is currently only rendered in the web-admin
Example
[section.my_option_id]
type = "display_text"
ask = "Text **rendered** in markdown."
Properties
alert (readonly)
Alerts displays a important message with a level of severity.
You can use markdown in ask but will only be rendered in the web-admin.
Example
[section.my_option_id]
type = "alert"
ask = "The configuration seems to be manually modified..."
style = "warning"
icon = "warning"
Properties
- common properties
style: any of"success|info|warning|danger"(default:"info")icon(optional): any icon name from Fork Awesome- Currently only displayed in the web-admin
button (readonly)
Triggers actions.
Available only in config panels.
Renders as a button in the web-admin and can be called with yunohost [app|domain|settings] action run <action_id> in CLI.
Every options defined in an action section (a config panel section with at least one button) is guaranted to be shown/asked to the user and available in scripts/config's scope.
check examples in advanced use cases.
Example
[section.my_option_id]
type = "button"
ask = "Break the system"
style = "danger"
icon = "bug"
# enabled only if another option's value (a `boolean` for example) is positive
enabled = "aknowledged"
To be able to trigger an action we have to add a bash function starting with run__ in your scripts/config
run__my_action_id() {
ynh_print_info "Running 'my_action_id' action"
}
Properties
- common properties
bind: forced to"null"
style: any of"success|info|warning|danger"(default:"success")enabled:JSExpressionorbool(default:true)- when used with
JSExpressionyou can enable/disable the button depending on context
- when used with
icon(optional): any icon name from Fork Awesome- Currently only displayed in the web-admin
string (string)
Ask for a simple string.
Example
[section.my_option_id]
type = "string"
default = "E10"
pattern.regexp = '^[A-F]\d\d$'
pattern.error = "Provide a room like F12 : one uppercase and 2 numbers"
Properties
- common inputs properties
default:""
pattern(optional):Pattern, a regex to match the value against
text (string)
Ask for a multiline string.
Renders as a textarea in the web-admin and by opening a text editor on the CLI.
Example
[section.my_option_id]
type = "text"
default = "multi\nline\ncontent"
Properties
- common inputs properties
default:""
pattern(optional):Pattern, a regex to match the value against
password (input)
Ask for a password. The password is tested as a regular user password (at least 8 chars)
Example
[section.my_option_id]
type = "password"
Properties
- common inputs properties
default: forced to""redact: forced totrueexample: forbidden
color (input)
Ask for a color represented as a hex value (with possibly an alpha channel).
Renders as color picker in the web-admin and as a prompt that accept named color like yellow in CLI.
Example
[section.my_option_id]
type = "color"
default = "#ff0"
Properties
- common inputs properties
default:""
number (input)
Ask for a number (an integer).
Example
[section.my_option_id]
type = "number"
default = 100
min = 50
max = 200
step = 5
Properties
- common inputs properties
type:numberorrange(input or slider in the web-admin)
min(optional): minimal int value inclusivemax(optional): maximal int value inclusivestep(optional): currently only used in the webadmin as the<input/>step jump
boolean (input)
Ask for a boolean. Renders as a switch in the web-admin and a yes/no prompt in CLI.
Example
[section.my_option_id]
type = "boolean"
default = 1
yes = "agree"
no = "disagree"
Properties
- common inputs properties
default:0
yes(optional): (default:1) define as what the thruthy value should output- can be
true,True,"yes", etc.
- can be
no(optional): (default:0) define as what the thruthy value should output- can be
0,"false","n", etc.
- can be
date (input)
Ask for a date in the form "2025-06-14".
Renders as a date-picker in the web-admin and a regular prompt in CLI.
Can also take a timestamp as value that will output as an ISO date string.
Example
[section.my_option_id]
type = "date"
default = "2070-12-31"
Properties
- common inputs properties
default:""
time (input)
Ask for an hour in the form "22:35".
Renders as a date-picker in the web-admin and a regular prompt in CLI.
Example
[section.my_option_id]
type = "time"
default = "12:26"
Properties
- common inputs properties
default:""
email (input)
Ask for an email. Validation made with python-email-validator
Example
[section.my_option_id]
type = "email"
default = "Abc.123@test-example.com"
Properties
- common inputs properties
default:""
path (string)
Ask for an web path (the part of an url after the domain). Used by default in app install to define from where the app will be accessible.
Example
[section.my_option_id]
type = "path"
default = "/"
Properties
- common inputs properties
default:""
pattern(optional):Pattern, a regex to match the value against
url (string)
Ask for any url.
Example
[section.my_option_id]
type = "url"
default = "https://example.xn--zfr164b/@handle/"
Properties
- common inputs properties
default:""
pattern(optional):Pattern, a regex to match the value against
file (input)
Ask for file. Renders a file prompt in the web-admin and ask for a path in CLI.
Example
[section.my_option_id]
type = "file"
accept = ".json"
# bind the file to a location to save the file there
bind = "/tmp/my_file.json"
Properties
- common inputs properties
default:""
accept: a comma separated list of extension to accept like".conf, .ini- /!\ currently only work on the web-admin
select (choices)
Ask for value from a limited set of values.
Renders as a regular <select/> in the web-admin and as a regular prompt in CLI with autocompletion of choices.
Example
[section.my_option_id]
type = "select"
choices = ["one", "two", "three"]
choices = "one,two,three"
default = "two"
Properties
- common inputs properties
default:"", obviously the default has to be empty or an availablechoicesitem.
choices: a (coma separated) list of values
tags (choices)
Ask for series of values. Optionally from a limited set of values.
Renders as a multi select in the web-admin and as a regular prompt in CLI without autocompletion of choices.
This output as a coma separated list of strings "one,two,three"
Example
[section.my_option_id]
type = "tags"
default = "word,another word"
[my_other_option_id]
type = "tags"
choices = ["one", "two", "three"]
# choices = "one,two,three"
default = "two,three"
Properties
- common inputs properties
default:"", obviously the default has to be empty or an availablechoicesitem.
pattern(optional):Pattern, a regex to match all the values againstchoices(optional): a (coma separated) list of valuesicon(optional): any icon name from Fork Awesome- Currently only displayed in the web-admin
domain (choices)
Ask for a user domain. Renders as a select in the web-admin and as a regular prompt in CLI with autocompletion of registered domains.
Example
[section.my_option_id]
type = "domain"
Properties
- common inputs properties
default: forced to the instance main domain
app (choices)
Ask for a user app. Renders as a select in the web-admin and as a regular prompt in CLI with autocompletion of installed apps.
Example
[section.my_option_id]
type = "app"
filter = "is_webapp"
Properties
- common inputs properties
default:""
filter(optional):JSExpressionwith whatyunohost app info <app_id> --fullreturns as context (only first level keys)
user (choices)
Ask for a user. Renders as a select in the web-admin and as a regular prompt in CLI with autocompletion of available usernames.
Example
[section.my_option_id]
type = "user"
Properties
- common inputs properties
default: the first admin user found
group (choices)
Ask for a group. Renders as a select in the web-admin and as a regular prompt in CLI with autocompletion of available groups.
Example
[section.my_option_id]
type = "group"
default = "visitors"
Properties
- common inputs properties
default:"all_users","visitors"or"admins"(default:"all_users")