summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/es_ES/analytics-tasks.markdown24
-rw-r--r--doc/es_ES/board-collapsed-expanded.markdown18
-rw-r--r--doc/es_ES/board-configuration.markdown25
-rw-r--r--doc/es_ES/board-horizontal-scrolling-and-compact-view.markdown12
-rw-r--r--doc/es_ES/board-show-hide-columns.markdown12
-rw-r--r--doc/es_ES/contributing.markdown67
-rw-r--r--doc/es_ES/plugin-authentication-architecture.markdown99
-rw-r--r--doc/es_ES/plugin-authentication.markdown42
-rw-r--r--doc/es_ES/plugin-authorization-architecture.markdown39
-rw-r--r--doc/es_ES/plugin-automatic-actions.markdown61
-rw-r--r--doc/es_ES/plugin-avatar-provider.markdown32
-rw-r--r--doc/es_ES/plugin-directory.markdown15
-rw-r--r--doc/es_ES/plugin-events.markdown27
-rw-r--r--doc/es_ES/plugin-external-link.markdown79
-rw-r--r--doc/es_ES/plugin-group-provider.markdown54
-rw-r--r--doc/es_ES/plugin-helpers.markdown39
-rw-r--r--doc/es_ES/plugin-hooks.markdown249
-rw-r--r--doc/es_ES/plugin-ldap-client.markdown99
-rw-r--r--doc/es_ES/plugin-mail-transports.markdown49
-rw-r--r--doc/es_ES/plugin-metadata.markdown42
-rw-r--r--doc/es_ES/plugin-notifications.markdown59
-rw-r--r--doc/es_ES/plugin-overrides.markdown42
-rw-r--r--doc/es_ES/plugin-registration.markdown160
-rw-r--r--doc/es_ES/plugin-routes.markdown85
-rw-r--r--doc/es_ES/plugin-schema-migrations.markdown40
-rw-r--r--doc/es_ES/plugins.markdown46
26 files changed, 1516 insertions, 0 deletions
diff --git a/doc/es_ES/analytics-tasks.markdown b/doc/es_ES/analytics-tasks.markdown
new file mode 100644
index 00000000..fb2d347f
--- /dev/null
+++ b/doc/es_ES/analytics-tasks.markdown
@@ -0,0 +1,24 @@
+Análisis para tareas
+===================
+
+Cada tarea tiene una sección de análisis disponible en el menu izquierdo en la vista de tarea.
+
+Espera y tiempo de ciclo
+-------------------
+
+![Lead and cycle time](https://kanboard.net/screenshots/documentation/task-lead-cycle-time.png)
+
+- El tiempo de espera es el tiempo entre la creacion de la tarea y la fecha de finalización (Tarea cerrada).
+- El tiempo de ciclo es el tiempo entre la fecha de inicio y la fecha de finalización.
+- Si la tarea no esta cerrada el tiempo actual es usado en lugar de la fecha de finalización.
+- Si la fecha de inicio no es especificada, el tiempo de ciclo no es calculado.
+
+Nota: Puede configurar una accion automatica para definir la fecha de inicio automaticamente cuando se mueve una tarea a la columna de su eleccion.
+
+El tiempo invertido en cada columna
+---------------------------
+
+![Time spent into each column](https://kanboard.net/screenshots/documentation/time-into-each-column.png)
+
+- Esta gráfico muestra el total de tiempo invertido en cada columna para la tarea.
+- El tiempo invertido es calculado hasta que la tarea es cerrada.
diff --git a/doc/es_ES/board-collapsed-expanded.markdown b/doc/es_ES/board-collapsed-expanded.markdown
new file mode 100644
index 00000000..a8ba2beb
--- /dev/null
+++ b/doc/es_ES/board-collapsed-expanded.markdown
@@ -0,0 +1,18 @@
+Modo colapsar y expandir
+===========================
+
+Las tares en el tablero pueden visualizarse en modo colapsado o en modo expandido.
+El cambio entre el desplazamiento horizontal y la vista compacta se puede hacer con la combinación de teclas **"s"** o usar el menu drop-down que esta parte superior izquierda.
+
+Modo de colapsado
+--------------
+
+![Tareas colapsadas](screenshots/board-collapsed-mode.png)
+
+- Si la tarea es asignada a alguien, las iniciales de la persona se muestran junto al número de tareas
+- Si el titulo de la tarea es demasiado largo, tu puedes poner el puntero del ratón sobre la tarea de mostrar una información sobre herramientas con el título completo
+
+Modo expansivo
+--------------
+
+![Tasks expanded](screenshots/board-expanded-mode.png)
diff --git a/doc/es_ES/board-configuration.markdown b/doc/es_ES/board-configuration.markdown
new file mode 100644
index 00000000..112ebc21
--- /dev/null
+++ b/doc/es_ES/board-configuration.markdown
@@ -0,0 +1,25 @@
+Configuración del tablero
+==========================
+
+Ir al menu **Configuraciones **, elije **Ajustes de tablero ** a la izquierda.
+
+![Board settings](https://kanboard.net/screenshots/documentation/board-settings.png)
+
+### Resaltado de tarea
+
+Esta caracterista muestra una sombra alrededor de la tarea cuando una tarea se trasladó recientemente
+
+Establecer el valor 0 para desactivar esta caracterista, 2 dias por default (172800 segundos).
+
+Todo lo trasladó desde de 2 dias tendra una sombra alrededor de la tarea.
+
+### Recargar el intervalo para la pizarra publica
+
+Cuando tu compartes un tablero, la pagina se refresca cada 60 segundos automaticamente por default.
+
+### Refrescar el intervalo para un tablero privado
+
+Cuando su navegador está abierto un tablero, Kanboard comprueba cada 10 segundos si algo ha sido cambiado por otra persona.
+
+Técnicamente este proceso se lleva a cabo por el Ajax.
+
diff --git a/doc/es_ES/board-horizontal-scrolling-and-compact-view.markdown b/doc/es_ES/board-horizontal-scrolling-and-compact-view.markdown
new file mode 100644
index 00000000..9dab532a
--- /dev/null
+++ b/doc/es_ES/board-horizontal-scrolling-and-compact-view.markdown
@@ -0,0 +1,12 @@
+Horizontal scrolling y modo compacto
+=====================================
+
+Cuando el tablero no puede caber en su pantalla , una barra de scroll horizontal
+When the board cannot fit on your screen, a horizontal scroll bar aparecerá en la parte inferior.
+
+Sin embargo, es posible cambiar a una vista de modo compacto para visualizar todas las columnas en su pantalla.
+
+![Cambiar a modo compacto](screenshots/board-compact-mode.png)
+
+Cambiar entre scrolling y vista compacta
+El cambio entre el desplazamiento horizontal y la vista compacta se puede hacer con la combinación de teclas **"c"** o usar el menu drop-down que esta parte superior izquierda.
diff --git a/doc/es_ES/board-show-hide-columns.markdown b/doc/es_ES/board-show-hide-columns.markdown
new file mode 100644
index 00000000..6700b987
--- /dev/null
+++ b/doc/es_ES/board-show-hide-columns.markdown
@@ -0,0 +1,12 @@
+Mostrar y ocultar columnas en el tablero
+==================================
+
+Se puede ocultar o visualizar columnas muy facilmente en el tablero:
+
+![Ocultar una columna](screenshots/hide-column.png)
+
+Para ocultar una columna, click en la columna escoge en el menu dropdown "ocultar esta columna" :
+
+![Mostrar una columna](screenshots/show-column.png)
+
+Para mostar nuevamente la columna, click en el icono con el simbolo de suma "plus icon"
diff --git a/doc/es_ES/contributing.markdown b/doc/es_ES/contributing.markdown
new file mode 100644
index 00000000..7f18e6eb
--- /dev/null
+++ b/doc/es_ES/contributing.markdown
@@ -0,0 +1,67 @@
+Directrices del contribuyente
+======================
+
+¿Cómo puedo ayudar?
+-----------------
+
+Kanboard no es perfecto, pero hay muchas maneras de ayudar:
+
+- Dar opinión
+- Informar de los errores
+- Añadir o actualizar traducciones
+- Mejorar la documentación
+- Código de Escritura
+- Dile a tus amigos que Kanboard es impresionante
+
+Antes de hacer cualquier empresa grande, abrir un nuevo tema y explicar su propuesta.
+
+Quiero dar retroalimentación
+-----------------------
+- Usted piensa que algo debe ser mejorado (interface de usuario, peticiones de características)
+- Comprobar si aún no se propuso su idea
+- Abrir un nuevo tema
+- Describir su idea
+- Puede también hacer un voto con +1 en las propuestas existentes
+
+Quiero informar de un error
+---------------------------
+
+- Compruebe si el problema no se ha comunicado anteriormente
+- Abrir un nuevo ticket
+- Explicar lo que está roto
+- Describir la forma de reproducir el error
+- Describir su entorno (versión Kanboard, sistema operativo, servidor web, Versión de PHP , la versión de la base de datos, el proveedor de alojamiento)}
+
+Deseo traducir Kanboard
+----------------------------
+Kanboard se traduce en muchos idiomas.
+
+Sin embargo, las traducciones no están completas, observe la [guía de traducción para contribuir] (https://kanboard.net/documentation/translations).
+
+
+Quiero mejorar la documentación
+-----------------------------------
+- ¿Crees que algo no está claro, existen errores gramaticales, errores tipográficos, otra cosa ?
+- La documentación está escrita en Markdown y se almacena en la carpeta `docs`.
+- Editar los archivos y enviar un Pull-Request
+- La documentación se sincroniza con el repositorio y el sitio web oficial .
+
+Quiero contribuir al código
+--------------------------------
+Los pulls son siempre bienvenidos , al ser aceptado se tiene que seguir estas directrices:
+
+- ** Antes de hacer cualquier cambio grande o propuesta de diseño, abrir un nuevo ticket en comenzar una discusión **.
+- Si desea agregar una nueva función, respetar la filosofía detrás de Kanboard. ** Nos centramos en la simplicidad **, no queremos tener un software sobrecargado .
+- Lo mismo se aplica para la interface de usuario, ** ** simplicidad y eficiencia.
+- Enviar un solo pull por característica o corrección de errores.
+- Un pull más pequeño es más fácil y más rápido para revisar y fusionarlo.
+- Asegurarse [ de hacer las pruebas unitarias (tests.markdown).
+- Respetar los [estandares de codificación] (coding-standards.markdown).
+- Escribir código mantenible, evitar la duplicación de código, usar las buenas practicas de PHP.
+En cualquier caso, si no está seguro acerca de algo abierto crear un uevo ticket.
+
+Dile a tus amigos que Kanboard es impresionante
+---------------------------------------------
+
+Si utiliza Kanboard, corre la voz que le rodean.
+Diles que es software libre y de código abierto esto es cool.
diff --git a/doc/es_ES/plugin-authentication-architecture.markdown b/doc/es_ES/plugin-authentication-architecture.markdown
new file mode 100644
index 00000000..86069aa0
--- /dev/null
+++ b/doc/es_ES/plugin-authentication-architecture.markdown
@@ -0,0 +1,99 @@
+Arquitectura de autenticación
+=============================
+
+Kanboard provee una flexible y conectable arquitectura de autenticación.
+
+Por default, el usuario puede autenticarse con multiple metodos:
+
+- Autenticación por usuario y password (Base de datos local y LDAP)
+- Autenticación OAuth2
+- Autenticación Reverse-Proxy
+- Autenticación basada en Cookie (Recuerdame)
+
+Además, despues de una autenticación satisfactoria un puede hacerse post de autenticación Two-Factor .
+Kanboard sopoarta nativamente el standart TOTP.
+
+Interfaces de autenticación
+----------------------------
+
+Para tener un sistema conectable, los drivers de autenticación deben implementar un conjunto de interfaces
+
+| Interface | Rol |
+|------------------------------------------|------------------------------------------------------------------|
+| AuthenticationProviderInterface | Interface base para otras interfaces de autenticación |
+| PreAuthenticationProviderInterface | The user is already authenticated al alcanzar la aplicación, Usualmente los servidores web definen algunas variables de entorno |
+| PasswordAuthenticationProviderInterface | El metodo de autenticación que usa el username y password provienen del formulario de login |
+| OAuthAuthenticationProviderInterface | Proveedores OAuth2 |
+| PostAuthenticationProviderInterface | Drivers de autenticación Two-Factor ,pide el código a confirmar |
+| SessionCheckProviderInterface | Los proveedores que son capaces de comprobar si la sesión de usuario es válida |
+
+### Ejemplos de autenticación de proveedores:
+
+- Database por default metodos a implementar `PasswordAuthenticationProviderInterface` y `SessionCheckProviderInterface`
+- Reverse-Proxy metodos a implementar `PreAuthenticationProviderInterface` y `SessionCheckProviderInterface`
+- Google metodos a implementar `OAuthAuthenticationProviderInterface`
+- LDAP metodos a implementar `PasswordAuthenticationProviderInterface`
+- RememberMe cookie metodos a implementar `PreAuthenticationProviderInterface`
+- Two-Factor TOTP metodos a implementar `PostAuthenticationProviderInterface`
+
+flujo de trabajo de autenticación ** Workflow **
+------------------------------------------------
+
+Para cada peticion HTTP:
+
+1. Si la sesión de usuario esta abierta, ejecuta el registro de proveedores que implementa`SessionCheckProviderInterface`
+2. Ejecuta todos los proveedores que implementa `PreAuthenticationProviderInterface`
+3. Si el usuario final hace un submit al formulario del login, Los proveedores que implementa `PasswordAuthenticationProviderInterface` are executed
+4. Si el usuario final quiere usar OAuth2, el selecciona el proveedor a ejecutar
+5. Despues de una autenticación satisfactoria, el ultimo registro utilizará `PostAuthenticationProviderInterface`
+6. Sincronizar la información del usuario si es necesario
+
+Este workflow es manejado por la clase `Kanboard\Core\Security\AuthenticationManager`.
+
+Eventos disparados:
+
+- `AuthenticationManager::EVENT_SUCCESS`: autenticación satisfactoria
+- `AuthenticationManager::EVENT_FAILURE`: autenticación fallida
+
+Cada vez que se produce un evento de fallo , el contador de intentos fallidos se incrementa.
+
+La cuenta de usuario se puede bloquear para el período de tiempo configurado y un captcha puede ser mostrado para evitar ataques de fuerza bruta .
+
+Interface de usuario del proveedor
+---------------------------------
+
+Cuando la autenticación es satisfactoria, la `AuthenticationManager` pedura la información del usuario para que el driver llame al metodo `getUser()`.
+Este metodo debe regresar un objeto que implementa la interface `Kanboard\Core\User\UserProviderInterface`.
+
+Esta clase abstracta reune la información dede otro sistema.
+
+Ejemplos :
+
+- `DatabaseUserProvider` proporciona información para un usuario interno
+- `LdapUserProvider` para un usuario LDAP
+- `ReverseProxyUserProvider` para un usuario Reverse-Proxy
+- `GoogleUserProvider` represtan un usuario de Google
+
+Los métodos para la interface del proveedor de Usuario:
+
+- `isUserCreationAllowed()`: Regresa true para permitir la creación automática de usuarios
+- `getExternalIdColumn()`: Obtener Identificación del nombre de la columna externa (google_id, github_id, gitlab_id...)
+- `getInternalId()`: Obtener el id interno de la base de datos
+- `getExternalId()`: Obtener el id externo(Unique id)
+- `getRole()`: Obtener el rol de usuario
+- `getUsername()`: Obtener en nombre de usuario ** username **
+- `getName()`: Obtener nombre completo del usuario
+- `getEmail()`: Obtener el correo electronico del usuario
+- `getExternalGroupIds()`: Obtiene los ids externos del grupo, automáticamente sincroniza la membresia del grupo y la presenta
+- `getExtraAttributes()`: Obtiene los atributos extras para ser mostrados a el usuario durante la sincronización local
+
+No es obligatorio que el metodo devuelva un valor.
+
+Sincronización de un usuario local
+----------------------------------
+
+La información del usuario puede ser sincronizada automáticamente con la base de datos local.
+
+- Si el metodo`getInternalId()` regresa un valor no realiza la sincronización
+- Los metodos `getExternalIdColumn()` y `getExternalId()` debe regresar un valor para sincronizar el usuario
+- Las propiedades que regresan un ** String ** vacios no se sincronizan
diff --git a/doc/es_ES/plugin-authentication.markdown b/doc/es_ES/plugin-authentication.markdown
new file mode 100644
index 00000000..05742156
--- /dev/null
+++ b/doc/es_ES/plugin-authentication.markdown
@@ -0,0 +1,42 @@
+Plugin de autenticación
+=====================
+
+EL nuevo backend de autenticación se puede escribir con muy pocas lineas de codigo.
+
+Registro de proveedores
+-----------------------
+
+En el metodo `initialize()` nuestro plugin, llama al metodo `register()` de la clase `AuthenticationManager`:
+
+```php
+public function initialize()
+{
+ $this->authenticationManager->register(new ReverseProxyLdapAuth($this->container));
+}
+```
+
+El objeto proveniente de el metodo `register()` debe implementar one de las interfaces de autenticación predefidas.
+
+Esas interfaces estan definidas en los namespace `Kanboard\Core\Security`:
+
+- `Kanboard\Core\Security\PreAuthenticationProviderInterface`
+- `Kanboard\Core\Security\PostAuthenticationProviderInterface`
+- `Kanboard\Core\Security\PasswordAuthenticationProviderInterface`
+- `Kanboard\Core\Security\OAuthAuthenticationProviderInterface`
+
+
+
+El único requisito es implementar las interfaces, la clase se puede escribir de la manera deseada y situado en cualquier lugar en el disco
+
+Usuario del proveedor
+----------------------
+
+Cuando la autenticación es satisfactoria, tu driver debe regresar un objato que representa al usuario.
+Este objeto debe implementasr la interface `Kanboard\Core\User\UserProviderInterface`.
+
+Ejemplo de plugin de autenticación
+----------------------------------
+
+- [Autenticación de proveedores incluido en kanboard](https://github.com/kanboard/kanboard/tree/master/app/Auth)
+- [Reverse-Proxy Autenticación con soporte LDAP](https://github.com/kanboard/plugin-reverse-proxy-ldap)
+- [Two-Factor Autenticación SMS](https://github.com/kanboard/plugin-sms-2fa)
diff --git a/doc/es_ES/plugin-authorization-architecture.markdown b/doc/es_ES/plugin-authorization-architecture.markdown
new file mode 100644
index 00000000..884e90aa
--- /dev/null
+++ b/doc/es_ES/plugin-authorization-architecture.markdown
@@ -0,0 +1,39 @@
+Arquitecuta de autorización
+===========================
+
+Kanboard [soporta multiples roles](roles.markdown) a nivel de aplicación y a nivel de proyecto.
+
+Workflow de autorización
+--------------------------
+
+Para cada solicitud HTTP:
+
+1. Autorizar o no el acceso a los recursos en base a la lista de acceso a las aplicaciones
+2. Si el recurso es para un projecto (board, tarea...):
+ 1. Extrae los roles de usuario para este proyecto
+ 2. Permitir/Denegar accesos basados en el mapa de acceso del proyecto
+
+Extendiendo mapa de accesos
+---------------------------
+
+Lista de accesos (ACL) se basa en el nombre de clase del controlador y el nombre del método
+La lista de acceso está a cargo de la clase `Kanboard\Core\Security\AccessMap`.
+
+Hay dos mapa de acceso: una para la aplicación y la otra para un proyecto.
+
+- Acceso al mapa de aplicación : `$this->applicationAccessMap`
+- Acceso al mapa del proyecto: `$this->projectAccessMap`
+
+Ejemplos para definir una nueva política para tu plugin:
+
+```php
+// Todos los metodos de la clase MyController:
+$this->projectAccessMap->add('MyController', '*', Role::PROJECT_MANAGER);
+
+// Todos los metodos:
+$this->projectAccessMap->add('MyOtherController', array('create', 'save'), Role::PROJECT_MEMBER);
+```
+
+Los roles estan defidos en la clase `Kanboard\Core\Security\Role`.
+
+Clase de autorización (`Kanboard\Core\Security\Authorization`) comprobará el acceso de cada página.
diff --git a/doc/es_ES/plugin-automatic-actions.markdown b/doc/es_ES/plugin-automatic-actions.markdown
new file mode 100644
index 00000000..6e0a9b65
--- /dev/null
+++ b/doc/es_ES/plugin-automatic-actions.markdown
@@ -0,0 +1,61 @@
+Agregando acciones automáticas
+===============================
+
+Agregando una nueva acccion automática es bastante simple.
+
+Creando una nueva accion
+------------------------
+
+Tus acciones automáticas deben heradarse de la clase `Kanboard\Action\Base`.
+
+Varios métodos abstractos deben ser implementadas por sí mismo:
+
+| Metodos | Descripción |
+|-------------------------------------|------------------------------------------------------------------|
+| `getDescription()` | Descripcion visible en la interface del usuario |
+| `getCompatibleEvents()` | Obtener las listas de eventos compatibles |
+| `getActionRequiredParameters()` | Obtener los parametros requeridos para la acción (definidos por el usuario)|
+| `getEventRequiredParameters()` | Obtener los parametros requeridos para el evento |
+| `doAction(array $data)` | Ejecutar la acción, Debe regresar true si fue satisfactorio |
+| `hasRequiredCondition(array $data)` | Comprobar si los datos de eventos cumplen la condición de acción |
+
+Tu accion automatica es identificada en kanboard utilizando el nombre de la clase absoluta con el espacio de nombre incluido
+
+Agregando nuevos eventos
+------------------------
+
+La lista de eventos de la aplicación está disponible en la clase `Kanboard\Core\Event\EventManager::getAll()`.
+Sin embargo, si tu plugin dispara nuevos eventos, tu puedes registrar estos eventos :
+
+```php
+$this->actionManager->getAction('\Kanboard\Plugin\MyPlugin\MyActionName')->addEvent('my.event', 'My event description');
+```
+
+Tu puedes extender la lista de eventos compatibles de acciones existentes para ser usada en algun metodo.
+
+Registra la acción
+----------------------
+
+Tu tienes que llamar el metodo `register()` desde la clase `Kanboard\Core\Action\ActionManager`:
+
+```php
+<?php
+
+namespace Kanboard\Plugin\AutomaticAction;
+
+use Kanboard\Core\Plugin\Base;
+use Kanboard\Plugin\AutomaticAction\Action\TaskRename;
+
+class Plugin extends Base
+{
+ public function initialize()
+ {
+ $this->actionManager->register(new TaskRename($this->container));
+ }
+}
+```
+
+Ejemplo
+-------
+
+- [Ejemplo de acción automatica](https://github.com/kanboard/plugin-example-automatic-action)
diff --git a/doc/es_ES/plugin-avatar-provider.markdown b/doc/es_ES/plugin-avatar-provider.markdown
new file mode 100644
index 00000000..2cce0647
--- /dev/null
+++ b/doc/es_ES/plugin-avatar-provider.markdown
@@ -0,0 +1,32 @@
+Agregando un nuevo avatar del proveedor
+=======================================
+
+Registrar
+------------
+
+```php
+$this->avatarManager->register(new CustomAvatarProvider());
+```
+
+Interface
+---------
+
+El proveedor debe implementar la interface `Kanboard\Core\User\Avatar\AvatarProviderInterface`:
+
+
+| Metodo | Descripcion |
+|-------------------------------|---------------------------------------------------------------|
+| `render(array $user, $size)` | Renderizar HTML |
+| `isActive(array $user)` | Regresa un boolean si el proveedor esta activo |
+
+
+El argumento `$user` es un directorio que contiene estas llaves :
+
+```php
+[
+ 'id' => 123,
+ 'username' => 'admin',
+ 'name' => 'Administrator',
+ 'email' => 'me@localhost',
+]
+```
diff --git a/doc/es_ES/plugin-directory.markdown b/doc/es_ES/plugin-directory.markdown
new file mode 100644
index 00000000..a7ce114c
--- /dev/null
+++ b/doc/es_ES/plugin-directory.markdown
@@ -0,0 +1,15 @@
+Plugin de configuración del directorio
+======================================
+
+Para instalar, actualizar y eliminar plugins dede la interface de usuario, debes tener estos requerimientos:
+
+- El directorio del plugin debe ser de escritura por el usuario del servidor web
+- La extensión Zip debe estar disponible en tu server.
+- Los parametros de configuración `PLUGIN_INSTALLER` deben estar en `true`
+
+Para desactivar esta función , cambie el valor de `PLUGIN_INSTALLER` a `false` en tu archivo de configuración.
+También puede cambiar los permisos de la carpeta Plugin en el filesystem.
+
+Sólo los administradores pueden instalar plugins desde la interfaz de usuario.
+
+Por defecto, sólo plug-in que aparece en la página web de Kanboard están disponibles .
diff --git a/doc/es_ES/plugin-events.markdown b/doc/es_ES/plugin-events.markdown
new file mode 100644
index 00000000..1f8bdc24
--- /dev/null
+++ b/doc/es_ES/plugin-events.markdown
@@ -0,0 +1,27 @@
+Uso de eventos
+===============
+
+Kanboard usar internamente el [ Componente EventDispatcher de Symfony ](https://symfony.com/doc/2.3/components/event_dispatcher/index.html) para manegar internamente los eventos.
+
+Eventos escucha ** Listening **
+-------------------------------
+
+```php
+$this->on('app.bootstrap', function($container) {
+ // tu codigo
+});
+```
+
+- El primer argumento es el nombre del evento (string)
+- El segundo argumento es una funcion PHP callable (finalización o metodos de la clase)
+
+Agregando un nuevo evento
+-------------------------
+
+Para agregar un nuevo, tienes que llamar al metodo `register()` de la clase `Kanboard\Core\Event\EventManager`:
+
+```php
+$this->eventManager->register('my.event.name', 'Mi descripcion del nuevo evento');
+```
+
+Estos eventos pueden ser utilizados por otros componentes de Kanboard como acciones automáticas .
diff --git a/doc/es_ES/plugin-external-link.markdown b/doc/es_ES/plugin-external-link.markdown
new file mode 100644
index 00000000..343712a6
--- /dev/null
+++ b/doc/es_ES/plugin-external-link.markdown
@@ -0,0 +1,79 @@
+Vinculación externa de proveedores
+==================================
+
+Esta funcionalidad le permite vincular una tarea a los elementos adicionales almacenados en otro sistema.
+
+Por ejemplo, tu puedes vincular una tarea a:
+For example, you can link a task to:
+
+- Una pagina web tradicional
+- Datos adjuntos (Documentos PDF almacenados en la web, archivos ...)
+- Cualquier sitema de tickets (bug tracker, soporte personalizado de tickets...)
+
+Cada item tiene un tipo, u na URL, un tipo dedependencia y un titulo.
+
+Por default,Kanboard incluye dos tipos de proveedores
+
+- Vinculación Web : Copiar y pegar un enlace y Kanboard se ha podido ir a la página de título de forma automática.
+- Datos adjuntos: Enlace a todo lo que no es una página web
+
+Flujo de trabajo ** Workflow **
+--------------------------------
+
+1. El usuario final copia y pega el URL al submit del formulario.
+2.- Si el tipo de link es "auto", Kanboard crea un bucle a través de todos los proveedores registrados hasta que hay una coincidencia
+3. Entonces , el proveedor de enlace devuelve un objeto que implementa la interfaz de `ExternalLinkInterface`
+4. El formulario se muestra al usuario con todos los datos precargados antes de guardar el enlace
+
+Interfaces
+----------
+
+Para implementar un nuevo vinculo al proveedor desde un plugin, es necesario crear 2 clases que implementarlas en las interfaces:
+
+- `Kanboard\Core\ExternalLink\ExternalLinkProviderInterface`
+- `Kanboard\Core\ExternalLink\ExternalLinkInterface`
+
+### ExternalLinkProviderInterface
+
+| Method | Usage |
+|----------------------------|---------------------------------------------------------------------------------|
+| `getName()` | Obtener el nombre del proveedor(label) |
+| `getType()` | Obtener el tipo de link (se guardarán en la base de datos) |
+| `getDependencies()` | Obtener un diccionario de los tipos de dependencia soportados por el proveedor |
+| `setUserTextInput($input)` | Texto introducido por el usuario |
+| `match()` | Regresa true si el proveedor puede analizar correctamente la entrada del usuario|
+| `getLink()` | Obtener el enlace que se encuentra con las propiedades |
+
+### ExternalLinkInterface
+
+| Method | Usage |
+|-------------------|-----------------------------|
+| `getTitle()` | Obtiene un titulo de link |
+| `getUrl()` | Obtiene una link de URL |
+| `setUrl($url)` | URL del enlace |
+
+El registro de un nuevo proveedor de enlace
+------------------------------------------
+
+En tu `Plugin.php`, solo puedes llamar al metodo `register()` desde el objeto `ExternalLinkManager`:
+
+```php
+<?php
+
+namespace Kanboard\Plugin\MyExternalLink;
+
+use Kanboard\Core\Plugin\Base;
+
+class Plugin extends Base
+{
+ public function initialize()
+ {
+ $this->externalLinkManager->register(new MyLinkProvider());
+ }
+}
+```
+
+Ejemplos
+--------
+
+- Kanboard incluye proveedores por default "WebLink" y "Attachment"
diff --git a/doc/es_ES/plugin-group-provider.markdown b/doc/es_ES/plugin-group-provider.markdown
new file mode 100644
index 00000000..dd742249
--- /dev/null
+++ b/doc/es_ES/plugin-group-provider.markdown
@@ -0,0 +1,54 @@
+Personalizar grupos de proveedores
+==================================
+
+Kanboard es capaz de cargar grupos de un sistema externo.
+Esta caracteristica es principalmente usada para permisos de proyectos.
+
+Los **Projects Managers** pueden permitir el acceso a un proyecto para un grupo
+El usuario final **end-user** utilizara una caja de autocomplementar y busquedas para un grupo
+
+Cada vez que se ejecuta una consulta de grupo , todos los proveedores de grupo registrados se ejecutan .
+
+Flujo de trabajo del Grupo de Proveedores **Workflow**
+-----------------------------------------------------
+
+1. El usuario final **end-user** comienza a escribir el nombre del grupo y el campo se autocompleta
+2. EL `GroupManager` la clase ejecuta la consulta para todos los proveedores de grupo registrados
+3. Los resultados son fusionados y regresados a la interface de usuario
+4. Antes de seleccionar un grupo, a información del grupo se sincronizan con la base de datos local si es necesario
+
+Interface del grupo de proveedores
+----------------------------------
+
+interface a implementar: `Kanboard\Core\Group\GroupProviderInterface`.
+
+Las clases que implementa esta interface abstracta del grupo de información, solo hay 3 metodos:
+
+- `getInternalId()`: Obtiene el id interno de la base de datos, de otra manera regresa 0
+- `getExternalId()`: Obtiene un id unico externo
+- `getName()`: Obtiene el nombre de grupo
+
+Kanboard utilizará el ID externo para sincronizar con la base de datos local.
+
+Interface Backend del grupo de proveedores
+------------------------------------------
+Interface a implementar: `Kanboard\Core\Group\GroupBackendProviderInterface`.
+
+Esta interface requiere solo un metodo: `find($input)`.
+El argumento `$input` es el texto introducido desde la interfaz de usuario.
+
+Este metodo debe regresar una lista de `GroupProviderInterface`, es es el resultado de la busqueda.
+
+Backend de registro desde Plugins
+---------------------------------
+
+En el metodo `initialize()` de su plugins registrado se puede personalizar el backend :
+
+```php
+$groupManager->register(new MyCustomLdapBackendGroupProvider($this->container));
+```
+
+Ejemplos
+--------
+
+- [Kanboard incluye el grupo de provedores (LDAP y base de datos)](https://github.com/kanboard/kanboard/tree/master/app/Group)
diff --git a/doc/es_ES/plugin-helpers.markdown b/doc/es_ES/plugin-helpers.markdown
new file mode 100644
index 00000000..66591075
--- /dev/null
+++ b/doc/es_ES/plugin-helpers.markdown
@@ -0,0 +1,39 @@
+Registrar nuevos helpers
+=======================
+
+Estrucura del helper:
+
+```php
+<?php
+
+namespace Kanboard\Plugin\MyPlugin\Helper\MyHelper;
+
+use Kanboard\Core\Base;
+
+class MyHelper extends Base
+{
+ public function doSomething()
+ {
+ return 'foobar';
+ }
+}
+```
+Registrar tu helper en la clase:
+
+```php
+$this->helper->register('myHelper', '\Kanboard\Plugin\MyPlugin\Helper\MyHelper');
+```
+
+Usar tu helper desde una plantilla **Template**:
+
+```php
+<p>
+ <?= $this->myHelper->doSomething() ?>
+</p>
+```
+
+Usar tu helper dese otra clase:
+
+```php
+$this->helper->myHelper->doSomething();
+```
diff --git a/doc/es_ES/plugin-hooks.markdown b/doc/es_ES/plugin-hooks.markdown
new file mode 100644
index 00000000..46855d27
--- /dev/null
+++ b/doc/es_ES/plugin-hooks.markdown
@@ -0,0 +1,249 @@
+Plugin Hooks
+============
+
+Hooks de aplicación
+-----------------
+
+Los hooks pueden extender , reemplazar, filtar datos o cambiar los comportamientos por default, cad hook es identificado con unico nombre, ejemplo : `controller:calendar:user:events`
+
+### Escuchar en eventos hook
+
+En tu metodo `initialize()` tu necesitas llamar al metodo `on()` de la clase `Kanboard\Core\Plugin\Hook`:
+
+```php
+$this->hook->on('hook_name', $callable);
+```
+
+El primer argumento es el nombre del hook y el segundo es un callable PHP
+
+### Hooks ejecutado sólo una vez
+
+Algunos hooks solo tienen un listener:
+
+#### model:subtask-time-tracking:calculate:time-spent
+
+- Anular el cálculo del tiempo anterior cuando se detiene el temporizador de la subtarea
+- Argumentos :
+ - `$user_id` (integer)
+ - `$start` (DateTime)
+ - `$end` (DateTime)
+
+### Fusionar hooks
+
+"Fusionar hooks" actuar de la misma manera que la función de `array_merge`. el hook callback solo regresa un array. Este array se fusionará con la que viene por defecto.
+
+Ejemplo para agregar eventos en el calendario del usuario:
+
+```php
+class Plugin extends Base
+{
+ public function initialize()
+ {
+ $container = $this->container;
+
+ $this->hook->on('controller:calendar:user:events', function($user_id, $start, $end) use ($container) {
+ $model = new SubtaskForecast($container);
+ return $model->getCalendarEvents($user_id, $end); // Return new events
+ });
+ }
+}
+```
+
+Ejemplo para sobrescribir los valores por default de las tareas:
+
+```php
+class Plugin extends Base
+{
+ public function initialize()
+ {
+ $this->hook->on('controller:task:form:default', function (array $default_values) {
+ return empty($default_values['score']) ? array('score' => 4) : array();
+ });
+ }
+}
+```
+
+Lista de fusión de hooks:
+
+#### controller:task:form:default
+
+- sobrescribir los valores por default de las tareas
+- Argumentos:
+ - `$default_values`: actual default values (array)
+
+#### controller:calendar:project:events
+
+- Agregar mas eventos a el calendario del projecto
+- Argumentos:
+ - `$project_id` (integer)
+ - `$start` Calendar start date (string, ISO-8601 format)
+ - `$end` Calendar` end date (string, ISO-8601 format)
+
+#### controller:calendar:user:events
+
+- Agregar mas eventos a el calendario de usuario
+- Argumentos:
+ - `$user_id` (integer)
+ - `$start` Calendar start date (string, ISO-8601 format)
+ - `$end` Calendar end date (string, ISO-8601 format)
+
+Asset Hooks
+-----------
+
+Asset hooks pueden ser usados para agregar nuevas stylesheet facilmente o un nuevo archivo JavaScript en el layout. tu puedes usar estas caracteristicas para crear un tema y sobreescribir todo los estilos por dafault del kanboard.
+
+Ejemplo para agregar un stylesheet **hoja de estilo**
+
+```php
+<?php
+
+namespace Kanboard\Plugin\Css;
+
+use Kanboard\Core\Plugin\Base;
+
+class Plugin extends Base
+{
+ public function initialize()
+ {
+ $this->hook->on('template:layout:css', array('template' => 'plugins/Css/skin.css'));
+ }
+}
+```
+
+Lista de asset Hooks:
+
+- `template:layout:css`
+- `template:layout:js`
+
+
+Referencia de hooks
+---------------
+
+La reference hooks son pasados a una variable por referencia.
+
+Ejemplo:
+
+```php
+$this->hook->on('formatter:board:query', function (\PicoDb\Table &query) {
+ $query->eq('color_id', 'red');
+});
+```
+
+El código anterior mostrará sólo las tareas en rojo en el tablero.
+
+Lista de referencias de hooks:
+
+| Hook | Description |
+|--------------------------------------------|---------------------------------------------------------------|
+| `formatter:board:query` | Alterar consulta a la base antes de tablero de renderizado |
+| `pagination:dashboard:task:query` | Alterar consulta de base de datos para las tareas de la paginación en el dashboard |
+| `pagination:dashboard:subtask:query` | Alterar consulta a la base de la paginación en el subtareas del dashboard |
+| `model:task:creation:prepare` | Alterar los valores del formulario antes de guardar una tarea |
+| `model:task:modification:prepare` | Alterar los valores del formulario antes de editar una tarea
+
+Template Hooks
+--------------
+
+Template hooks permitirá añadir nuevos contenidos en las plantillas existentes.
+
+Ejemplo para agregar nuevos contenidos en el sidebar del dashboard:
+
+```php
+$this->template->hook->attach('template:dashboard:sidebar', 'myplugin:dashboard/sidebar');
+```
+
+Ejemplo para adjuntar un template con variables locales:
+
+```php
+$this->template->hook->attach('template:dashboard:sidebar', 'myplugin:dashboard/sidebar', array(
+ 'variable' => 'foobar',
+));
+```
+
+Ejemplo para adjuntar un template con un callable:
+
+```php
+$this->template->hook->attach('template:dashboard:sidebar', 'myplugin:dashboard/sidebar', function($hook_param1, $hook_param2) {
+ return array('new_template_variable' => 'foobar'); // Inyectar una nueva variable en la plantilla Plugin
+});
+```
+
+Este llamada es usualmente definida en el metodo `initialize()`
+El primer argumento es el nombre del hook y el segundo argumento es el nombre del template.
+
+Los nombres de plantillas con el prefijo del nombre del plugin y los dos puntos indican la ubicación de la plantilla.
+
+Ejemplo con `myplugin:dashboard/sidebar`:
+
+- `myplugin` Es el nombre de tu plugin (minusculas)
+- `dashboard/sidebar` es el nombre del template
+- En el filesystem, El plugin esta localizado aqui: `plugins\Myplugin\Template\dashboard\sidebar.php`
+- Templates estan escritos en puro PHP (no se olvide de escapar los datos)
+
+Los nombres de plantillas sin prefijo son plantillas básicas.
+
+Lista de templates hooks:
+
+| Hook | Descripción |
+|--------------------------------------------|----------------------------------------------------|
+| `template:analytic:sidebar` | Sidebar en paginas analiticas |
+| `template:app:filters-helper:before` | Filtro helper dropdown (top) |
+| `template:app:filters-helper:after` | Filtro helper dropdown (bottom) |
+| `template:auth:login-form:before` | Pagina de login (top) |
+| `template:auth:login-form:after` | Pagina de login (bottom) |
+| `template:board:private:task:before-title` | Tarea en un tablero privado : despues del titulo |
+| `template:board:private:task:after-title` | Tarea en un tablero privado : antes del titulo |
+| `template:board:public:task:before-title` | Tarea en un tablero publico : despues del titulo |
+| `template:board:public:task:after-title` | Tarea en un tablero publico : antes del titulo |
+| `template:board:task:footer` | Tarea en el tablero : footer |
+| `template:board:task:icons` | Tarea en el tablero: tooltip icon |
+| `template:board:column:dropdown` | Menu Dropdown en las columnas del tablero |
+| `template:config:sidebar` | Sidebar pagina de configuración |
+| `template:config:application ` | Aplicación de configuración del formulario |
+| `template:config:email` | Email settings page |
+| `template:config:integrations` | Integration page in global settings |
+| `template:dashboard:sidebar` | Sidebar en la pagina del dashboard |
+| `template:dashboard:show` | Pagina principal del dashboard |
+| `template:export:sidebar` | Sidebar para exportar paginas |
+| `template:import:sidebar` | Sidebar para importar paginas |
+| `template:header:dropdown` | Dropdown menu Pagina header (icono avatar de usuario) |
+| `template:header:creation-dropdown` | Dropdown menu Pagina header (plus icon) |
+| `template:layout:head` | Layout de la pagina `<head/>` tag |
+| `template:layout:top` | Layout de la pagina top header |
+| `template:layout:bottom` | Layout de la pagina footer |
+| `template:project:dropdown` | "Actions" menu a la izquierda vista para diferentes proyectos |
+| `template:project:header:before` | Filtros de Proyectos (antes) |
+| `template:project:header:after` | Filtros de Proyectos (despues) |
+| `template:project:integrations` | Pagina de integracion de configuración de proyectos|
+| `template:project:sidebar` | Sidebar configuración de proyectos |
+| `template:project-user:sidebar` | Sidebar en la página de la información de usuario del proyecto |
+| `template:task:layout:top` | Task layout top (antes page header) |
+| `template:task:details:top` | Resumen de tarea top |
+| `template:task:details:bottom` | Resumen de tarea bottom |
+| `template:task:details:first-column` | Resumen de tarea columna |
+| `template:task:details:second-column` | Resumen de tarea dos columnas |
+| `template:task:details:third-column` | Resumen de tarea tres columnas |
+| `template:task:details:fourth-column` | Resumen de tarea cuatro columnas |
+| `template:task:dropdown` | Task dropdown menu en listado de paginas |
+| `template:task:sidebar:actions` | Sidebar on task page (sección de acciones) |
+| `template:task:sidebar:information` | Sidebar on task page (sección de información) |
+| `template:task:form:first-column` | 1st columna en forma de tarea |
+| `template:task:form:second-column` | 2nd columna en forma de tarea |
+| `template:task:form:third-column` | 3nd columna en forma de tarea |
+| `template:task:show:top ` | Mostrar página de tareas : top |
+| `template:task:show:bottom` | Mostrar página de tareas : bottom |
+| `template:task:show:before-description` | Mostrar página de tareas : despues de la descripción |
+| `template:task:show:before-tasklinks` | Mostrar página de tareas : despues tasklinks |
+| `template:task:show:before-subtasks` | Mostrar página de tareas : despues subtareas |
+| `template:task:show:before-timetracking` | Mostrar página de tareas : despues timetracking |
+| `template:task:show:before-attachments` | Mostrar página de tareas : despues archivos adjuntos |
+| `template:task:show:before-comments` | Mostrar página de tareas : despues comentarios |
+| `template:user:authentication:form` | "Editar autenticación" formulario de perfil de usuario |
+| `template:user:create-remote:form` | "Crear un usuario remoto" formulario |
+| `template:user:external` | "Autenticación externa" la página de perfil de usuario |
+| `template:user:integrations` | Integración en el perfil de usuario |
+| `template:user:sidebar:actions` | Sidebar en el perfil de usuario (sección de acciones) |
+| `template:user:sidebar:information` | Sidebar en el perfil de usuario (sección de información) |
+
+
+Otro de los ganchos plantilla se pueden añadir en caso necesario , sólo hay que preguntar en el seguimiento de incidencias ** issue tracking **.
diff --git a/doc/es_ES/plugin-ldap-client.markdown b/doc/es_ES/plugin-ldap-client.markdown
new file mode 100644
index 00000000..1a34a880
--- /dev/null
+++ b/doc/es_ES/plugin-ldap-client.markdown
@@ -0,0 +1,99 @@
+Libreria LDAP
+============
+
+Para facilirar la integracion LDAP. kanboard tiene su propia libreria LDAP
+Esta libreria puede ejecutar operaciones comunes.
+
+Cliente
+-------
+
+Clase: `Kanboard\Core\Ldap\Client`
+
+Para conectar a tu servidor LDAP facilmente, usa este metodo:
+
+```php
+use Kanboard\Core\Ldap\Client as LdapClient;
+use Kanboard\Core\Ldap\ClientException as LdapException;
+
+try {
+ $client = LdapClient::connect();
+
+ // Get native LDAP resource
+ $resource = $client->getConnection();
+
+ // ...
+
+} catch (LdapException $e) {
+ // ...
+}
+```
+
+Consultas LDAP
+--------------
+
+Classes:
+
+- `Kanboard\Core\Ldap\Query`
+- `Kanboard\Core\Ldap\Entries`
+- `Kanboard\Core\Ldap\Entry`
+
+Ejemplo para una consulta al directorio LDAP:
+
+```php
+
+$query = new Query($client)
+$query->execute('ou=People,dc=kanboard,dc=local', 'uid=my_user', array('cn', 'mail'));
+
+if ($query->hasResult()) {
+ $entries = $query->getEntries(); // Return an instance of Entries
+}
+```
+
+Leer una entrada:
+
+```php
+$firstEntry = $query->getEntries()->getFirstEntry();
+$email = $firstEntry->getFirstValue('mail');
+$name = $firstEntry->getFirstValue('cn', 'Default Name');
+```
+
+Leer multiples entradas:
+
+```php
+foreach ($query->getEntries()->getAll() as $entry) {
+ $emails = $entry->getAll('mail'); // Fetch all emails
+ $dn = $entry->getDn(); // Get LDAP DN of this user
+
+ // Check if a value is present for an attribute
+ if ($entry->hasValue('mail', 'user2@localhost')) {
+ // ...
+ }
+}
+```
+
+Usuario Helper
+--------------
+
+Clase: `Kanboard\Core\Ldap\User`
+
+Obtener usuario en una sola linea
+
+```php
+// Return an instance of LdapUserProvider
+$user = User::getUser($client, 'my_username');
+```
+
+Grupo Helper
+------------
+
+Clase: `Kanboard\Core\Ldap\Group`
+
+Obtener grupos en una linea:
+
+```php
+// Define LDAP filter
+$filter = '(&(objectClass=group)(sAMAccountName=My group*))';
+
+// Return a list of LdapGroupProvider
+$groups = Group::getGroups($client, $filter);
+```
diff --git a/doc/es_ES/plugin-mail-transports.markdown b/doc/es_ES/plugin-mail-transports.markdown
new file mode 100644
index 00000000..1d999c81
--- /dev/null
+++ b/doc/es_ES/plugin-mail-transports.markdown
@@ -0,0 +1,49 @@
+Plugin: Agregar trasporte de email
+==================================
+
+Por default Kanboard soporta 3 estadares de trasporte de email:
+
+- Mail (PHP mail function)
+- Smtp
+- Sendmail command
+
+Con la API del plugin tu puedes agregar un driver para cualquier proveedor de email.
+Por ejemplo, nuestro plugin puede agregar un trasporte de email para un proveedor que usa un API HTTP.
+
+Implementación
+--------------
+
+Nuestro plugin dede implementgar la interface `Kanboard\Core\Mail\ClientInterface` y extiende desde `Kanboard\Core\Base`.
+El único método que necesita para implementar es `sendEmail()`:
+
+```php
+interface ClientInterface
+{
+ /**
+ * Send a HTML email
+ *
+ * @access public
+ * @param string $email
+ * @param string $name
+ * @param string $subject
+ * @param string $html
+ * @param string $author
+ */
+ public function sendEmail($email, $name, $subject, $html, $author);
+}
+```
+
+Para registrar el nuevo trasporte de email, usa el metodo `setTransport($transport, $class)` desde la clase `Kanboard\Core\Mail\Client`:
+
+```php
+$this->emailClient->setTransport('myprovider', '\Kanboard\Plugin\MyProvider\MyEmailHandler');
+```
+
+EL segundo argumento contiene el absoluto namespace de tu clase especifica
+
+Ejemplos de plugins para trasporte de email
+----------------------------------
+
+- [Sendgrid](https://github.com/kanboard/plugin-sendgrid)
+- [Mailgun](https://github.com/kanboard/plugin-mailgun)
+- [Postmark](https://github.com/kanboard/plugin-postmark)
diff --git a/doc/es_ES/plugin-metadata.markdown b/doc/es_ES/plugin-metadata.markdown
new file mode 100644
index 00000000..da4f025f
--- /dev/null
+++ b/doc/es_ES/plugin-metadata.markdown
@@ -0,0 +1,42 @@
+Metadatos
+=========
+
+Tu piedes adjutnar metadatos para cada projecto,tarea , usuaio o para toda la aplicación
+Los metadatos son campos personalisados, es una key/value de una tabla.
+
+Por ejemplo nuestro plugin puede almacenar información externa para una tarea o nuevas configuraciones para un proyecto.
+Básicamente le permiten ampliar los campos predeterminados sin tener que crear nuevas tablas .
+
+Adjuntar y eliminar metadatos para tareas
+--------------------------------------------
+
+```php
+
+// Return a dictionary of metadata (keys/values) for the $task_id
+$this->taskMetadataModel->getAll($task_id);
+
+// Get a value only for a task
+$this->taskMetadataModel->get($task_id, 'my_plugin_variable', 'default_value');
+
+// Return true if the metadata my_plugin_variable exists
+$this->taskMetadataModel->exists($task_id, 'my_plugin_variable');
+
+// Create or update metadata for the task
+$this->taskMetadataModel->save($task_id, ['my_plugin_variable' => 'something']);
+
+// Remove a metadata from a project
+$this->projectMetadataModel->remove($project_id, my_plugin_variable);
+```
+
+Tipos de metadatos
+------------------
+
+- TaskMetadata: `$this->taskMetadataModel`
+- ProjectMetadata: `$this->projectMetadataModel`
+- UserMetadata: `$this->userMetadataModel`
+- Settings/Config: `$this->configModel`
+
+Notas
+-----
+
+- Siempre prefijo del nombre de metadatos con el nombre del plugin
diff --git a/doc/es_ES/plugin-notifications.markdown b/doc/es_ES/plugin-notifications.markdown
new file mode 100644
index 00000000..9a99806d
--- /dev/null
+++ b/doc/es_ES/plugin-notifications.markdown
@@ -0,0 +1,59 @@
+Agregar notificaciones con los tipos de plugin
+==============================================
+
+Puede enviar notificaciones a casi cualquier sistema mediante la adición de un nuevo tipo .
+There are two kinds of notifications: project and user.
+
+- Project: Notificaciones configuradas a nivel de proyecto
+- Usuario: Notificaciones enviadas individualmente y configurada a cada perfil de usuario.
+
+Registra un nuevo tipo de notificación
+--------------------------------------
+
+En tu archivo de registro del plugin llama el metodo `setType()`:
+
+```php
+$this->userNotificationTypeModel->setType('irc', t('IRC'), '\Kanboard\Plugin\IRC\Notification\IrcHandler');
+$this->projectNotificationTypeModel->setType('irc', t('IRC'), '\Kanboard\Plugin\IRC\Notification\IrcHandler');
+```
+
+Su controlador puede ser registrado por el usuario o la notificación del proyecto. No necesariamente tienen que soportarlo .
+Cuando tu handler es registrdo, el usuario final **end-user** puede elegir recibir el nuevo tipo de notificación o no
+
+Notificación de Handler
+-----------------------
+
+Su controlador de notificación debe implementar la interfaz `Kanboard\Core\Notification\NotificationInterface`:
+
+```php
+interface NotificationInterface
+{
+ /**
+ * Envia notificación a un usuario
+ *
+ * @access public
+ * @param array $user
+ * @param string $event_name
+ * @param array $event_data
+ */
+ public function notifyUser(array $user, $event_name, array $event_data);
+
+ /**
+ * Envia notificacion a un projecto
+ *
+ * @access public
+ * @param array $project
+ * @param string $event_name
+ * @param array $event_data
+ */
+ public function notifyProject(array $project, $event_name, array $event_data);
+}
+```
+
+Ejemplo de notificacion de plugins
+---------------------------------
+
+- [Slack](https://github.com/kanboard/plugin-slack)
+- [Hipchat](https://github.com/kanboard/plugin-hipchat)
+- [Jabber](https://github.com/kanboard/plugin-jabber)
+
diff --git a/doc/es_ES/plugin-overrides.markdown b/doc/es_ES/plugin-overrides.markdown
new file mode 100644
index 00000000..f8b999f3
--- /dev/null
+++ b/doc/es_ES/plugin-overrides.markdown
@@ -0,0 +1,42 @@
+Plugin Reescritura
+================
+
+Reesritura HTTP Contenido Política de Seguridad
+-----------------------------------------------
+
+Si desea reemplazar el encabezado HTTP predeterminado de la directiva de seguridad del contenido, puede utilizar el método`setContentSecurityPolicy()`:
+
+```php
+<?php
+
+namespace Kanboard\Plugin\Csp;
+
+use Kanboard\Core\Plugin\Base;
+
+class Plugin extends Base
+{
+ public function initialize()
+ {
+ $this->setContentSecurityPolicy(array('script-src' => 'something'));
+ }
+}
+```
+
+Plantillas de reescrituras
+--------------------------
+
+Las plantillas definidas en el núcleo se pueden anular . Por ejemplo , se puede redefinir el diseño predeterminado o cambiar notificaciones por correo electrónico.
+
+Ejemolo de plantilla de reescritura:
+
+```php
+$this->template->setTemplateOverride('header', 'theme:layout/header');
+```
+
+El primer argumento es el nombre de la plantilla original y el segundo argumento de la plantilla para usar como reemplazo.
+
+Puede seguir utilizando la plantilla original utilizando el prefijo "kanboard:" :
+
+```php
+<?= $this->render('kanboard:header') ?>
+```
diff --git a/doc/es_ES/plugin-registration.markdown b/doc/es_ES/plugin-registration.markdown
new file mode 100644
index 00000000..5031427f
--- /dev/null
+++ b/doc/es_ES/plugin-registration.markdown
@@ -0,0 +1,160 @@
+Registracion de Plugin
+======================
+
+Estructura del directorio
+--------------------------
+
+Los Plugins estan almacenados en el subdirectorio `plugins. Un ejemplo de estructura del directorio de un plugin:
+
+```bash
+plugins
+└── Budget <= Plugin name
+ ├── Asset <= Javascript/CSS files
+ ├── Controller
+ ├── LICENSE <= Plugin license
+ ├── Locale
+ │ ├── fr_FR
+ │   ├── it_IT
+ │   ├── ja_JP
+ │   └── zh_CN
+ ├── Model
+ ├── Plugin.php <= Plugin registration file
+ ├── README.md
+ ├── Schema <= Database migrations
+ ├── Template
+ └── Test <= Unit tests
+```
+
+Solamente el archivo de registración `Plugin.php` es requerido. Las otras carpetas son opcionales.
+
+La primera letra del nombre del plugin debe ser capitalizada.
+
+Archivo de registración del plugin
+----------------------------------
+
+Kanboard Kanboard escaneará el directorio `plugins` y cargara automaticamente todo en este directorio. el archivo `Plugin.php` se utiliza para cargar y registrar el plugin.
+
+Ejemplo del archivo `Plugin.php` (`plugins/Foobar/Plugin.php`):
+
+```php
+<?php
+
+namespace Kanboard\Plugin\Foobar;
+
+use Kanboard\Core\Plugin\Base;
+
+class Plugin extends Base
+{
+ public function initialize()
+ {
+ $this->template->hook->attach('template:layout:head', 'theme:layout/head');
+ }
+}
+```
+
+Este archivo debera contener una clase `Plugin` se define en el namespace `Kanboard\Plugin\Yourplugin` y extiende `Kanboard\Core\Plugin\Base`.
+
+El único método requerido es `initialize()`. Este método se llama para cada petición cuando el plugin es cargado.
+
+Metodos del plugin
+--------------
+
+Los métodos disponibles son `Kanboard\Core\Plugin\Base`:
+
+- `initialize()`: ejecuta cuando el plugin es cargafo
+- `getClasses()`: Regresa todas las clases que se deben almacenar en el contenedor de inyección de dependencias
+- `on($event, $callback)`: Escucha eventos internos.
+- `getPluginName()`: devuelve el nombre del plugin.
+- `getPluginAuthor()`: Devuelve el autor del plugin.
+- `getPluginVersion()`: Devuelve la versíon del plugin.
+- `getPluginDescription()`: Devuelve la descripcion del plugin.
+- `getPluginHomepage()`: Devuelve la pagina inicial del plugin (link)
+- `setContentSecurityPolicy(array $rules)`: Reescribe las reglas por default del HTTP CSP.
+- `onStartup()`: Si está presente este método, se ejecuta automáticamente cuando el evento "app.bootstrap" se dispara.
+
+Su registro de plugin tambien puede heradar de la clase Kanboard\Core\Base, de esta manera se puede acceder a todas las clases y los métodos de Kanboard facilmente.
+
+En este ejemplo se obtendrá el usuario #123:
+
+```php
+$this->user->getById(123);
+```
+
+Plugin de traducción
+-------------------
+
+Este plugin se puede traducir en la misma forma que el resto de la aplicación . Debe cargar las traducciones a sí mismo cuando se crea la sesión :
+
+```php
+public function onStartup()
+{
+ Translator::load($this->languageModel->getCurrentLanguage(), __DIR__.'/Locale');
+}
+```
+
+Las traducciones deben ser almacenadas en el archivo `plugins/Myplugin/Locale/xx_XX/translations.php` (remplazar xx_XX por el codigo del lenguaje fr_FR, en_US...).
+
+Las traducciones estan almacenadas en un diccionario, Si desea sobreescribir una cadena existente, sólo tiene que utilizar la misma clave en el archivo de traducción.
+
+Inyección de dependencias de contenedores
+------------------------------
+Kanboard utiliza la Pimple , un simple inyección de contenedores de dependencia PHP . Sin embargo , Kanboard puede registrar cualquier clase en el contenedor fácilmente.
+
+Estas clases están disponibles en todas partes en la aplicación y se crea una única instancia .
+
+Aquí un ejemplo para registrar sus propios modelos en el contenedor:
+
+```php
+public function getClasses()
+{
+ return array(
+ 'Plugin\Budget\Model' => array(
+ 'HourlyRateModel',
+ 'BudgetModel',
+ )
+ );
+}
+```
+
+Ahora bien, si se utiliza una clase que se extiende desde `Core\Base`, tu puedes acceder directamente cualquier instancia de la clase:
+
+```php
+$this->hourlyRateModel->remove(123);
+$this->budgetModel->getDailyBudgetBreakdown(456);
+
+// It's the same thing as using the container:
+$this->container['hourlyRateModel']->getAll();
+```
+
+Llaves de los contenedores son únicos a través de la aplicación . Si reemplaza una clase existente , que va a cambiar el comportamiento por defecto .
+
+Agregar un metodo nuevo en la API
+---------------------------------
+
+Kanboard usa la libreria [JSON-RPC](https://github.com/fguillot/JsonRPC) para manejar las llamadas de la api.
+
+Para agregar un nuevo metodo tu puedes que puede hacer algo para llamar a tu plugin:
+
+```php
+$this->api->getProcedureHandler()->withCallback('my_method', function() {
+ return 'foobar';
+});
+```
+
+`$this->container['api']` or `$this->api` expose an instance of the object `JsonRPC\Server`.
+
+Leer la documentacion de la libreria para mas información.
+
+Agregar una nueva consola de comandos
+--------------------------------------
+
+Kanboard usa la libreria [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html) para manejar las lineas de comandos.
+
+Kanboard genera una instancia del objeto `Symfony\Component\Console\Application` via `$this->cli`.
+Tu puedes agregar nuevos comandos desde tu plugin:
+
+```php
+$this->cli->add(new MyCommand());
+```
+
+Lea la documentación de la biblioteca para obtener más información.
diff --git a/doc/es_ES/plugin-routes.markdown b/doc/es_ES/plugin-routes.markdown
new file mode 100644
index 00000000..eb4b9f36
--- /dev/null
+++ b/doc/es_ES/plugin-routes.markdown
@@ -0,0 +1,85 @@
+Personalizar Rutas
+==================
+
+Cuando está habilitada la reescritura de URL, tu puedes definir rutas personalizadas desde tus plugins.
+
+Definir nuevas rutas
+--------------------
+
+Las rutas son manejadas por la clase `Kanboard\Core\Http\Route`.
+
+Las nuevas rutas se pueden agregar mediante el uso del método `addRoute($path, $controller, $action, $plugin)`, here an example:
+
+```php
+$this->route->addRoute('/my/custom/route', 'myController', 'myAction', 'myplugin');
+```
+
+Cuando el usuario final **end-user** van a la URL `/my/custom/route`, el metodo `Kanboard\Plugin\Myplugin\Controller\MyController::myAction()` será ejecutado.
+
+El primer caracter del contraldor y el nombre del plugin serán convertidos en mayusculas con la funcion `ucfirst()`.
+
+Tu puedes ademas definir rutas con variables:
+
+```php
+$this->route->addRoute('/my/route/:my_variable', 'myController', 'myAction', 'myplugin');
+```
+
+El prefijo colon `:`, define una variable.
+Por ejemplo `:my_variable` declare el nombre de la nueva variable `my_variable`.
+
+Para extraer los valores de la variable puedes usar el metodo `getStringParam()` or `getIntegerParam()` desde la clase `Kanboard\Core\Http\Request`:
+
+Si tenemos la URL `/my/route/foobar`, el valor de `my_variable` es `foobar`:
+
+```php
+$this->request->getStringParam('my_variable'); // Return foobar
+```
+
+Generate links based on the routing table
+-----------------------------------------
+
+Desde las plantillas , se tiene que usar el helper `Kanboard\Helper\Url`.
+
+### Generar un link HTML
+
+```php
+<?= $this->url->link('My link', 'mycontroller', 'myaction', array('plugin' => 'myplugin')) ?>
+```
+
+Generara este HTML:
+
+```html
+<a href="/my/custom/route">My link</a>
+```
+
+### Generara solamente el atributo `href`:
+
+```php
+<?= $this->url->href('My link', 'mycontroller', 'myaction', array('plugin' => 'myplugin')) ?>
+```
+
+HTML salida:
+
+```html
+/my/custom/route
+```
+
+Salida HTML cuando la reescritura del URL no esta habilitada:
+
+```html
+?controller=mycontroller&amp;action=myaction&amp;plugin=myplugin
+```
+
+### Generar enlace de redirección:
+
+Desde un controlador, si tu necesitas para From a controller, si tu necesitas realizar una redirección:
+
+```php
+$this->url->to('mycontroller', 'myaction', array('plugin' => 'myplugin'));
+```
+
+Generar:
+
+```
+?controller=mycontroller&action=myaction&plugin=myplugin
+```
diff --git a/doc/es_ES/plugin-schema-migrations.markdown b/doc/es_ES/plugin-schema-migrations.markdown
new file mode 100644
index 00000000..b7165490
--- /dev/null
+++ b/doc/es_ES/plugin-schema-migrations.markdown
@@ -0,0 +1,40 @@
+Plugin Migración de esquemas
+============================
+
+Kanboard realiza migraciones de base de datos automaticamente para ti.
+Las migraciones deben ser almacenadas en una carpeta **Schema** y el nombre de archivo debe ser el mismo que el controlador de base de datos:
+
+```bash
+Schema
+├── Mysql.php
+├── Postgres.php
+└── Sqlite.php
+```
+
+Cada archivo contiene todas las migraciones, aqui un ejemple para Sqlite:
+
+```php
+<?php
+
+namespace Kanboard\Plugin\Something\Schema;
+
+const VERSION = 1;
+
+function version_1($pdo)
+{
+ $pdo->exec('CREATE TABLE IF NOT EXISTS something (
+ "id" INTEGER PRIMARY KEY,
+ "project_id" INTEGER NOT NULL,
+ "something" TEXT,
+ FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE
+ )');
+}
+```
+
+- La constante `VERSION` es la ultima versión de tu esquema
+- Cada funcion es una migración `version_1()`, `version_2()`, etc.
+- Una instancia `PDO` es pasado como un primer argumneto
+- Todo se ejecuta dentro de una transacción , si algo no funciona se realiza una operación de rollback y se muestra el error al usuario
+
+Kanboard siempre compara la version definida en tu esquema y la version almacenada en la base de datos. Si la versiones son diferentes, kanboard siempre ejecuta cada migración una por una hasta alcanzar la ultima version.
+
diff --git a/doc/es_ES/plugins.markdown b/doc/es_ES/plugins.markdown
new file mode 100644
index 00000000..587377d7
--- /dev/null
+++ b/doc/es_ES/plugins.markdown
@@ -0,0 +1,46 @@
+Desarrollo de Plugin
+====================
+
+Nota : el plugin API es **considerado alpha** en estos momentos.
+
+Los plugins son útiles para extender las funcionalidades básicas de Kanboard , la adición de características , la creación de temas o cambiar el comportamiento por defecto .
+
+Los creadores de plugins deben especificar explícitamente las versiones compatibles de Kanboard . El código interno de Kanboard puede cambiar con el tiempo y su extensión debe ser probado con nuevas versiones . Compruebe siempre el [ChangeLog](https://github.com/kanboard/kanboard/blob/master/ChangeLog) para realizar los cambios.
+
+- [Crear tu plugin](plugin-registration.markdown)
+- [Usar plugins hooks](plugin-hooks.markdown)
+- [Eventos](plugin-events.markdown)
+- [Rescribir compartamientos por default en la aplicación](plugin-overrides.markdown)
+- [Agregar plugins para migrar esquemas](plugin-schema-migrations.markdown)
+- [Personalizar rutas](plugin-routes.markdown)
+- [Agregar helpers](plugin-helpers.markdown)
+- [Agregar trasportes de email ](plugin-mail-transports.markdown)
+- [Agregar tipos de notificaciones](plugin-notifications.markdown)
+- [Agregar acciones automaticas](plugin-automatic-actions.markdown)
+- [Adjuntar metados para usuarios,tareas y proyectos](plugin-metadata.markdown)
+- [Arquitectura de autenticación](plugin-authentication-architecture.markdown)
+- [Registración de plugins de autenticación](plugin-authentication.markdown)
+- [Arquitectura de autorización](plugin-authorization-architecture.markdown)
+- [Personlizar grupos de proveedores](plugin-group-provider.markdown)
+- [Links externos para proveedores](plugin-external-link.markdown)
+- [Agregar avatar a proveedores](plugin-avatar-provider.markdown)
+- [Cliente LDAP](plugin-ldap-client.markdown)
+
+Ejemplos de plugins
+-------------------
+
+- [SMS Two-Factor Authentication](https://github.com/kanboard/plugin-sms-2fa)
+- [Reverse-Proxy Authentication with LDAP support](https://github.com/kanboard/plugin-reverse-proxy-ldap)
+- [Slack](https://github.com/kanboard/plugin-slack)
+- [Hipchat](https://github.com/kanboard/plugin-hipchat)
+- [Jabber](https://github.com/kanboard/plugin-jabber)
+- [Sendgrid](https://github.com/kanboard/plugin-sendgrid)
+- [Mailgun](https://github.com/kanboard/plugin-mailgun)
+- [Postmark](https://github.com/kanboard/plugin-postmark)
+- [Amazon S3](https://github.com/kanboard/plugin-s3)
+- [Budget planning](https://github.com/kanboard/plugin-budget)
+- [User timetables](https://github.com/kanboard/plugin-timetable)
+- [Subtask Forecast](https://github.com/kanboard/plugin-subtask-forecast)
+- [Automatic Action example](https://github.com/kanboard/plugin-example-automatic-action)
+- [Theme plugin example](https://github.com/kanboard/plugin-example-theme)
+- [CSS plugin example](https://github.com/kanboard/plugin-example-css)