diff options
author | Frederic Guillot <fred@kanboard.net> | 2016-09-03 16:43:47 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2016-09-03 16:43:47 -0400 |
commit | 736afa524c8608a6df1b91cfe06742fa19386e7a (patch) | |
tree | e34f3d19174f55782ebcea97639b13fa855f78bf /doc | |
parent | 6bad0523e581c6af1ab06dce726e2af1a08d9017 (diff) |
Merge manually PR #2633
Diffstat (limited to 'doc')
-rw-r--r-- | doc/es_ES/api-action-procedures.markdown | 245 | ||||
-rw-r--r-- | doc/es_ES/api-board-procedures.markdown | 158 | ||||
-rw-r--r-- | doc/es_ES/api-external-task-link-procedures.markdown | 221 | ||||
-rw-r--r-- | doc/es_ES/api-group-member-procedures.markdown | 188 | ||||
-rw-r--r-- | doc/es_ES/suse-installation.markdown | 14 | ||||
-rw-r--r-- | doc/es_ES/translations.markdown | 68 |
6 files changed, 894 insertions, 0 deletions
diff --git a/doc/es_ES/api-action-procedures.markdown b/doc/es_ES/api-action-procedures.markdown new file mode 100644 index 00000000..dc39fb93 --- /dev/null +++ b/doc/es_ES/api-action-procedures.markdown @@ -0,0 +1,245 @@ +API Procedimiento de acciones automaticas +================================ + +## getAvailableActions [Obtener acciones disponibles] + +- Propósito: **Obtener una lista de acciones automaticas disponibles** +- Parametros: ninguno +- Resultado satisfactorio: **list of actions** +- Resultado fallido: **falso** + +Ejemplo de solicitud: + +```json +{ + "jsonrpc": "2.0", + "method": "getAvailableActions", + "id": 1217735483 +} +``` + +Ejemplo de respuesta: + +```json +{ + "jsonrpc": "2.0", + "id": 1217735483, + "result": { + "\Kanboard\Action\TaskLogMoveAnotherColumn": "Agregar un comentario moviendo las tareas entre columnas", + "\Kanboard\Action\TaskAssignColorUser": "Asignar un color especifico aun usuario", + "\Kanboard\Action\TaskAssignColorColumn": "Asignar un color cuando la tarea es movida a una columna especifica", + "\Kanboard\Action\TaskAssignCategoryColor": "Asignar automaticamente una categoria basado en un color", + "\Kanboard\Action\TaskAssignColorCategory": "Asignar automaticamente un color basado en una categoria", + "\Kanboard\Action\TaskAssignSpecificUser": "Asigar tareas a un usuario especifico", + "\Kanboard\Action\TaskAssignCurrentUser": "Asignar tareas a la persona que hace la acción", + "\Kanboard\Action\TaskUpdateStartDate": "Automaticamente actualizar la fecha de inicio", + "\Kanboard\Action\TaskAssignUser": "Cambiar asigando basado en un nombre de usuario [username] externo", + "\Kanboard\Action\TaskAssignCategoryLabel": "Cambiar la categoria basado en un etiqueta externa", + "\Kanboard\Action\TaskClose": "Cerrar una tarea", + "\Kanboard\Action\CommentCreation": "Crear un comentario desde un proveedor externo", + "\Kanboard\Action\TaskCreation": "Crear una tarea desde un proveedor externo", + "\Kanboard\Action\TaskDuplicateAnotherProject": "Duplicar la tarea a otro proyecto", + "\Kanboard\Action\TaskMoveColumnAssigned": "Mover la tarea a otra columna cuando es asiganada a un usuario", + "\Kanboard\Action\TaskMoveColumnUnAssigned": "Mover la tarea a otra columna cuando la asignación es limpiada", + "\Kanboard\Action\TaskMoveAnotherProject": "Mover la tarea a otro proyecto", + "\Kanboard\Action\TaskOpen": "Abrir una Tarea" + } +} +``` + +## getAvailableActionEvents [obtener acciones de eventos disponibles] + +- Propósito: **Obtener una lista de acciones disponibles para los eventos** +- Parametros: ninguno +- Resultado satisfactorio: **lista de eventos** +- Resultado fallÃdo : **falso** + +Ejemplo de petición: + +```json +{ + "jsonrpc": "2.0", + "method": "getAvailableActionEvents", + "id": 2116665643 +} +``` + +Ejemplo de respuesta: + +```json +{ + "jsonrpc": "2.0", + "id": 2116665643, + "result": { + "bitbucket.webhook.commit": "Bitbucket commit recibido", + "task.close": "Cerrando tarea", + "github.webhook.commit": "Github commit recibido", + "github.webhook.issue.assignee": "Github issue asignación cambiada", + "github.webhook.issue.closed": "Github issue cerrada", + "github.webhook.issue.commented": "Github issue comentario creado", + "github.webhook.issue.label": "Github issue etiqueta cambiada", + "github.webhook.issue.opened": "Github issue abierta", + "github.webhook.issue.reopened": "Github issue reabierto", + "gitlab.webhook.commit": "Gitlab commit recibido", + "gitlab.webhook.issue.closed": "Gitlab issue cerrado", + "gitlab.webhook.issue.opened": "Gitlab issue abierto", + "task.move.column": "Mover una tarea a otra columna", + "task.open": "Abrir una tarea abierta", + "task.assignee_change": "Tarea cambio de asignación", + "task.create": "Creación de tarea", + "task.create_update": "Creación de tarea o modificación", + "task.update": "Modificación de tarea" + } +} +``` + +## getCompatibleActionEvents [Obtener acciones compatibles con eventos] + +- Propósito: **Obtener una lista de eventos compatibles con una acción** +- Parametros: + - **action_name** (string, required) +- Resultado satisfactorio: **lista de eventos** +- Resultado fallido: **falso** + +Ejemplo de petición: + +```json +{ + "jsonrpc": "2.0", + "method": "getCompatibleActionEvents", + "id": 899370297, + "params": [ + "\Kanboard\Action\TaskClose" + ] +} +``` + +Ejemplo de respuesta: + +```json +{ + "jsonrpc": "2.0", + "id": 899370297, + "result": { + "bitbucket.webhook.commit": "Bitbucket commit recibido", + "github.webhook.commit": "Github commit recibido", + "github.webhook.issue.closed": "Github issue cerrada", + "gitlab.webhook.commit": "Gitlab commit recibido", + "gitlab.webhook.issue.closed": "Gitlab issue cerrado", + "task.move.column": "Mover una tarea a otra columna" + } +} +``` + +## getActions [Obtener acciones] + +- Propósito: **Obtener una lista de acciones para un proyecto** +- Parametros: + - **project_id** (integer, required) +- Resultado satisfactorio: **lista de propiedades de las acciones** +- Resultado fallido: **falso** + +Ejemplo de petición: + +```json +{ + "jsonrpc": "2.0", + "method": "getActions", + "id": 1433237746, + "params": [ + "1" + ] +} +``` + +Ejemplo de respuesta: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": [ + { + "id" : "13", + "project_id" : "2", + "event_name" : "task.move.column", + "action_name" : "\Kanboard\Action\TaskAssignSpecificUser", + "params" : { + "column_id" : "5", + "user_id" : "1" + } + } + ] +} +``` + +## createAction [Creación de acciones] + +- Proposito: **Crear una acción** +- Parametros: + - **project_id** (integer, required) + - **event_name** (string, required) + - **action_name** (string, required) + - **params** (key/value parameters, required) +- Resultados satisfactorios: **action_id** +- Resultados fallidos: **falso** + +Ejemplo de petición: + +```json +{ + "jsonrpc": "2.0", + "method": "createAction", + "id": 1433237746, + "params": { + "project_id" : "2", + "event_name" : "task.move.column", + "action_name" : "\Kanboard\Action\TaskAssignSpecificUser", + "params" : { + "column_id" : "3", + "user_id" : "2" + } + } +} +``` + +Ejemplo de respuestas: + +```json +{ + "jsonrpc": "2.0", + "id": 1433237746, + "result": 14 +} +``` + +## removeAction [Eliminar una acción] + +- Proposito: **Eliminar una acción** +- Parametros: + - **action_id** (integer, required) +- Resultados satisfactorios: **true** +- Resultados fallidos: **false** + +Ejemplo de petición: + +```json +{ + "jsonrpc": "2.0", + "method": "removeAction", + "id": 1510741671, + "params": [ + 1 + ] +} +``` + +Ejemplo de respuesta: + +```json +{ + "jsonrpc": "2.0", + "id": 1510741671, + "result": true +} +``` diff --git a/doc/es_ES/api-board-procedures.markdown b/doc/es_ES/api-board-procedures.markdown new file mode 100644 index 00000000..583e6449 --- /dev/null +++ b/doc/es_ES/api-board-procedures.markdown @@ -0,0 +1,158 @@ +API Procedimientos Del Tablero +=============================== + +## getBoard [obtener tablero] + +- Propósito: **Obtener todo la información necesaria para visualizar el tablero** +- Parametros: + - **project_id** (integer, required) +- Resultado satisfactorio : **Propiedades del tablero** +- Resultado fallido: **Lista vacÃa** + +Ejemplo de solicitud: + +```json +{ + "jsonrpc": "2.0", + "method": "getBoard", + "id": 827046470, + "params": [ + 1 + ] +} +``` + +Ejemplo de respuesta: + +```json +{ + "jsonrpc": "2.0", + "id": 827046470, + "result": [ + { + "id": 0, + "name": "Default swimlane", + "columns": [ + { + "id": "1", + "title": "Backlog", + "position": "1", + "project_id": "1", + "task_limit": "0", + "description": "", + "tasks": [], + "nb_tasks": 0, + "score": 0 + }, + { + "id": "2", + "title": "Ready", + "position": "2", + "project_id": "1", + "task_limit": "0", + "description": "", + "tasks": [ + { + "nb_comments":"0", + "nb_files":"0", + "nb_subtasks":"0", + "nb_completed_subtasks":"0", + "nb_links":"0", + "id":"2", + "reference":"", + "title":"Test", + "description":"", + "date_creation":"1430870507", + "date_modification":"1430870507", + "date_completed":null, + "date_due":"0", + "color_id":"yellow", + "project_id":"1", + "column_id":"2", + "swimlane_id":"0", + "owner_id":"0", + "creator_id":"1", + "position":"1", + "is_active":"1", + "score":"0", + "category_id":"0", + "date_moved":"1430870507", + "recurrence_status":"0", + "recurrence_trigger":"0", + "recurrence_factor":"0", + "recurrence_timeframe":"0", + "recurrence_basedate":"0", + "recurrence_parent":null, + "recurrence_child":null, + "assignee_username":null, + "assignee_name":null + } + ], + "nb_tasks": 1, + "score": 0 + }, + { + "id": "3", + "title": "Trabajo en progreso", + "position": "3", + "project_id": "1", + "task_limit": "0", + "description": "", + "tasks": [ + { + "nb_comments":"0", + "nb_files":"0", + "nb_subtasks":"1", + "nb_completed_subtasks":"0", + "nb_links":"0", + "id":"1", + "reference":"", + "title":"Task with comment", + "description":"", + "date_creation":"1430783188", + "date_modification":"1430783188", + "date_completed":null, + "date_due":"0", + "color_id":"red", + "project_id":"1", + "column_id":"3", + "swimlane_id":"0", + "owner_id":"1", + "creator_id":"0", + "position":"1", + "is_active":"1", + "score":"0", + "category_id":"0", + "date_moved":"1430783191", + "recurrence_status":"0", + "recurrence_trigger":"0", + "recurrence_factor":"0", + "recurrence_timeframe":"0", + "recurrence_basedate":"0", + "recurrence_parent":null, + "recurrence_child":null, + "assignee_username":"admin", + "assignee_name":null + } + ], + "nb_tasks": 1, + "score": 0 + }, + { + "id": "4", + "title": "Done", + "position": "4", + "project_id": "1", + "task_limit": "0", + "description": "", + "tasks": [], + "nb_tasks": 0, + "score": 0 + } + ], + "nb_columns": 4, + "nb_tasks": 2 + } + ] +} +``` diff --git a/doc/es_ES/api-external-task-link-procedures.markdown b/doc/es_ES/api-external-task-link-procedures.markdown new file mode 100644 index 00000000..d276dd7a --- /dev/null +++ b/doc/es_ES/api-external-task-link-procedures.markdown @@ -0,0 +1,221 @@ +API de Procedimientos de tarea de enlace externo
+=================================
+
+## getExternalTaskLinkTypes
+
+- Propósito: **Obtener todos los proveedores registrados de enlaces externos**
+- Parámetros: **ninguno**
+- Resultado en caso de éxito: **dict**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{"jsonrpc":"2.0","method":"getExternalTaskLinkTypes","id":477370568}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "result": {
+ "auto": "Auto",
+ "attachment": "Attachment",
+ "file": "Local File",
+ "weblink": "Web Link"
+ },
+ "id": 477370568
+}
+```
+
+## getExternalTaskLinkProviderDependencies
+
+- Propósito: **Obtener las dependencias disponibles para un determinado proveedor**
+- Parametros:
+ - **providerName** (string, required)
+- Resultado en caso de éxito: **dict**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{"jsonrpc":"2.0","method":"getExternalTaskLinkProviderDependencies","id":124790226,"params":["weblink"]}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "result": {
+ "related": "Related"
+ },
+ "id": 124790226
+}
+```
+
+## createExternalTaskLink
+
+- Propósito: **Crear una nueva tarea de enlace externo**
+- Parametros:
+ - **task_id** (integer, required)
+ - **url** (string, required)
+ - **dependency** (string, required)
+ - **type** (string, optional)
+ - **title** (string, optional)
+- Resultado en caso de éxito: **link_id**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{"jsonrpc":"2.0","method":"createExternalTaskLink","id":924217495,"params":[9,"http:\/\/localhost\/document.pdf","related","attachment"]}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "result": 1,
+ "id": 924217495
+}
+```
+
+## updateExternalTaskLink
+
+- Propósito: **Actualizar tarea de enlace externo**
+- Parametros:
+ - **task_id** (integer, required)
+ - **link_id** (integer, required)
+ - **title** (string, required)
+ - **url** (string, required)
+ - **dependency** (string, required)
+- Resultado en caso de éxito: **true**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{
+ "jsonrpc":"2.0",
+ "method":"updateExternalTaskLink",
+ "id":1123562620,
+ "params": {
+ "task_id":9,
+ "link_id":1,
+ "title":"New title"
+ }
+}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "result": true,
+ "id": 1123562620
+}
+```
+
+## getExternalTaskLinkById
+
+- Propósito: **Obtener un enlace de tarea externo**
+- Parametros:
+ - **task_id** (integer, required)
+ - **link_id** (integer, required)
+- Resultado en caso de éxito: **dict**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{"jsonrpc":"2.0","method":"getExternalTaskLinkById","id":2107066744,"params":[9,1]}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "result": {
+ "id": "1",
+ "link_type": "attachment",
+ "dependency": "related",
+ "title": "document.pdf",
+ "url": "http:\/\/localhost\/document.pdf",
+ "date_creation": "1466965256",
+ "date_modification": "1466965256",
+ "task_id": "9",
+ "creator_id": "0"
+ },
+ "id": 2107066744
+}
+```
+
+## getAllExternalTaskLinks
+
+- Propósito: **Obtener todos los enlaces externos conectados a una tarea**
+- Parametros:
+ - **task_id** (integer, required)
+- Resultado en caso de éxito: **list of external links**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{"jsonrpc":"2.0","method":"getAllExternalTaskLinks","id":2069307223,"params":[9]}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "result": [
+ {
+ "id": "1",
+ "link_type": "attachment",
+ "dependency": "related",
+ "title": "New title",
+ "url": "http:\/\/localhost\/document.pdf",
+ "date_creation": "1466965256",
+ "date_modification": "1466965256",
+ "task_id": "9",
+ "creator_id": "0",
+ "creator_name": null,
+ "creator_username": null,
+ "dependency_label": "Related",
+ "type": "Attachment"
+ }
+ ],
+ "id": 2069307223
+}
+```
+
+## removeExternalTaskLink
+
+- Propósito: **Remover una tarea de enlace externo**
+- Parametros:
+ - **task_id** (integer, required)
+ - **link_id** (integer, required)
+- Resultado en caso de éxito: **true**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{"jsonrpc":"2.0","method":"removeExternalTaskLink","id":552055660,"params":[9,1]}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "result": true,
+ "id": 552055660
+}
+```
diff --git a/doc/es_ES/api-group-member-procedures.markdown b/doc/es_ES/api-group-member-procedures.markdown new file mode 100644 index 00000000..7c7cb25c --- /dev/null +++ b/doc/es_ES/api-group-member-procedures.markdown @@ -0,0 +1,188 @@ +Group Member API Procedures
+===========================
+
+## getMemberGroups
+
+- Propósito: **Obtener todos los grupos de un usuario determinado**
+- Parámetros:
+ - **user_id** (integer, required)
+- Resultado en caso de éxito: **List of groups**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "getMemberGroups",
+ "id": 1987176726,
+ "params": [
+ "1"
+ ]
+}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1987176726,
+ "result": [
+ {
+ "id": "1",
+ "name": "My Group A"
+ }
+ ]
+}
+```
+
+## getGroupMembers
+
+- Propósito: **Obtener todos los miembros de un grupo**
+- Parámetros:
+ - **group_id** (integer, required)
+- Resultado en caso de éxito: **List of users**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "getGroupMembers",
+ "id": 1987176726,
+ "params": [
+ "1"
+ ]
+}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1987176726,
+ "result": [
+ {
+ "group_id": "1",
+ "user_id": "1",
+ "id": "1",
+ "username": "admin",
+ "is_ldap_user": "0",
+ "name": null,
+ "email": null,
+ "notifications_enabled": "0",
+ "timezone": null,
+ "language": null,
+ "disable_login_form": "0",
+ "notifications_filter": "4",
+ "nb_failed_login": "0",
+ "lock_expiration_date": "0",
+ "is_project_admin": "0",
+ "gitlab_id": null,
+ "role": "app-admin"
+ }
+ ]
+}
+```
+
+## addGroupMember
+
+- Propósito: **Agregar un usuario a un grupo**
+- Parámetros:
+ - **group_id** (integer, required)
+ - **user_id** (integer, required)
+- Resultado en caso de éxito: **true**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "addGroupMember",
+ "id": 1589058273,
+ "params": [
+ 1,
+ 1
+ ]
+}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1589058273,
+ "result": true
+}
+```
+
+## removeGroupMember
+
+- Propósito: **Quitar un usuario de un grupo**
+- Parámetros:
+ - **group_id** (integer, required)
+ - **user_id** (integer, required)
+- Resultado en caso de éxito: **true**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "removeGroupMember",
+ "id": 1730416406,
+ "params": [
+ 1,
+ 1
+ ]
+}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1730416406,
+ "result": true
+}
+```
+
+## isGroupMember
+
+- Propósito: **Comprobar si un usuario es miembro de un grupo**
+- Parámetros:
+ - **group_id** (integer, required)
+ - **user_id** (integer, required)
+- Resultado en caso de éxito: **true**
+- Resultado en caso de falla: **false**
+
+Ejemplo de solicitud:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "isGroupMember",
+ "id": 1052800865,
+ "params": [
+ 1,
+ 1
+ ]
+}
+```
+
+Ejemplo de respuesta:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1052800865,
+ "result": false
+}
+```
diff --git a/doc/es_ES/suse-installation.markdown b/doc/es_ES/suse-installation.markdown new file mode 100644 index 00000000..934554e1 --- /dev/null +++ b/doc/es_ES/suse-installation.markdown @@ -0,0 +1,14 @@ +Instalacion en OpenSuse +======================== + +OpenSuse Leap 42.1 +------------------ + +```bash---terminal +sudo zypper install php5 php5-sqlite php5-gd php5-json php5-mcrypt php5-mbstring php5-openssl +cd /srv/www/htdocs +sudo wgethttps://kanboard.net/kanboard-latest.zip +sudo unzip kanboard-latest.zip +sudo chmod -R 777 kanboard +sudo rm kanboard-latest.zip + diff --git a/doc/es_ES/translations.markdown b/doc/es_ES/translations.markdown new file mode 100644 index 00000000..074d9ae3 --- /dev/null +++ b/doc/es_ES/translations.markdown @@ -0,0 +1,68 @@ +Translations +============ + +How to translate Kanboard to a new language? +-------------------------------------------- + +- Translations are stored inside the directory `app/Locale` +- There is a subdirectory for each language, for example in French we have `fr_FR`, Italian `it_IT` etc. +- A translation is a PHP file that returns an Array with a key-value pairs +- The key is the original text in English and the value is the translation of the corresponding language +- **French translations are always up to date** +- Always use the last version (branch master) + +### Create a new translation: + +1. Make a new directory: `app/Locale/xx_XX` for example `app/Locale/fr_CA` for French Canadian +2. Create a new file for the translation: `app/Locale/xx_XX/translations.php` +3. Use the content of the French locales and replace the values +4. Update the file `app/Model/Language.php` +5. Check with your local installation of Kanboard if everything is OK +6. Send a [pull-request with Github](https://help.github.com/articles/using-pull-requests/) + +How to update an existing translation? +-------------------------------------- + +1. Open the translation file `app/Locale/xx_XX/translations.php` +2. Missing translations are commented with `//` and the values are empty, just fill blank and remove the comment +3. Check with your local installation of Kanboard and send a [pull-request](https://help.github.com/articles/using-pull-requests/) + +How to add new translated text in the application? +-------------------------------------------------- + +Translations are displayed with the following functions in the source code: + +- `t()`: display text with HTML escaping +- `e()`: display text without HTML escaping + +Always use the english version in the source code. + +Text strings use the function `sprintf()` to replace elements: + +- `%s` is used to replace a string +- `%d` is used to replace an integer + +All formats are available in the [PHP documentation](http://php.net/sprintf). + +How to find missing translations in the applications? +----------------------------------------------------- + +From a terminal, run the following command: + +```bash +./kanboard locale:compare +``` + +All missing and unused translations are displayed on the screen. +Put that in the French locale and sync other locales (see below). + +How to synchronize translation files? +------------------------------------- + +From a Unix shell run this command: + +```bash +./kanboard locale:sync +``` + +The French translation is used a reference to other locales. |