Desarrollar proyectos en AEM

Este es un tutorial de desarrollo que ilustra cómo desarrollar para AEM Projects. En este tutorial crearemos una plantilla de proyecto personalizada que se pueda utilizar para crear nuevos proyectos en AEM para administrar los flujos de trabajo y las tareas de creación de contenido.

Este vídeo ofrece una breve demostración del flujo de trabajo terminado que se crea en el tutorial siguiente.

Introducción

AEM Projects es una función de AEM diseñada para facilitar la gestión y agrupación de todos los flujos de trabajo y tareas asociados con la creación de contenido como parte de una implementación de AEM Sites o Assets.

AEM Projects viene con varias plantillas de proyecto OOTB. Al crear un nuevo proyecto, los autores pueden elegir entre estas plantillas disponibles. Las implementaciones AEM grandes con requisitos empresariales únicos desearán crear plantillas de proyecto personalizadas, adaptadas a sus necesidades. Al crear una plantilla de proyecto personalizada, los desarrolladores pueden configurar el panel del proyecto, conectar los flujos de trabajo personalizados y crear funciones comerciales adicionales para un proyecto. Echaremos un vistazo a la estructura de una plantilla de proyecto y crearemos una plantilla de ejemplo.

Tarjeta de proyecto personalizada

Configuración

Este tutorial detalla el código necesario para crear una plantilla de proyecto personalizada. Puede descargar e instalar el paquete adjunto en un entorno local para seguirlo junto con el tutorial. También puede acceder al proyecto completo de Maven alojado en GitHub.

Este tutorial asume algunos conocimientos básicos de AEM prácticas de desarrollo y cierta familiaridad con AEM configuración del proyecto Maven. Todo el código mencionado está pensado para utilizarse como referencia y solo debe implementarse en una instancia de desarrollo local AEM.

Estructura de una plantilla de proyecto

Las plantillas de proyecto deben estar bajo control de código fuente y deben estar debajo de la carpeta de la aplicación en /apps. Lo ideal es que se coloquen en una subcarpeta con la convención de nomenclatura /projects/templates/<my-template>. Al colocar después de esta convención de nombres, las nuevas plantillas personalizadas estarán disponibles automáticamente para los autores al crear un proyecto. La configuración de las plantillas de proyecto disponibles se establece en: /content/projects/jcr:content nodo por la propiedad cq:allowedTemplates. De forma predeterminada, se trata de una expresión regular: **/(apps|libs)/./projects/templates/.***

El nodo raíz de una plantilla de proyecto tendrá un jcr:primaryType de cq:Template. Debajo del nodo raíz hay 3 nodos: gadgets, roles y flujos de trabajo. Todos estos nodos son nt:unstructured. Debajo del nodo raíz también puede haber un archivo thumbnail.png que se muestra al seleccionar la plantilla en el asistente Crear proyecto .

La estructura completa del nodo:

/apps/<my-app>
    + projects (nt:folder)
         + templates (nt:folder)
              + <project-template-root> (cq:Template)
                   + gadgets (nt:unstructured)
                   + roles (nt:unstructured)
                   + workflows (nt:unstructured)

Raíz de plantilla del proyecto

El nodo raíz de la plantilla de proyecto será del tipo cq:Template. En este nodo puede configurar las propiedades jcr:title y jcr:description que se mostrarán en el Asistente para crear proyectos. También hay una propiedad llamada wizard que apunta a un formulario que rellenará las Propiedades del proyecto. El valor predeterminado de: /libs/cq/core/content/projects/wizard/steps/defaultproject.html debería funcionar bien en la mayoría de los casos, ya que permite al usuario rellenar las propiedades básicas del proyecto y agregar miembros del grupo.

Tenga en cuenta que el Asistente para crear proyectos no utiliza el servlet de POST de Sling. En su lugar, los valores se publican en un servlet personalizado:​com.adobe.cq.projects.impl.servlet.ProjectServlet**. Esto debe tenerse en cuenta al agregar campos personalizados.*

Puede encontrar un ejemplo de asistente personalizado para la plantilla de proyecto de traducción: /libs/cq/core/content/projects/wizard/translation/project/defaultproject.

Gadgets

No hay propiedades adicionales en este nodo, pero los elementos secundarios del nodo gadgets controlan qué mosaicos de proyecto rellenan el panel del proyecto cuando se crea un nuevo proyecto. Los mosaicos del proyecto (también conocidos como gadgets o pods) son tarjetas simples que rellenan el lugar de trabajo de un proyecto. Puede encontrar una lista completa de los mosaicos ootb en: /libs/cq/gui/components/projects/admin/pod. Los propietarios del proyecto siempre pueden agregar o eliminar mosaicos después de crear un proyecto.

Funciones

Hay 3 roles predeterminados para cada proyecto: Observadores, Editores y Propietarios. Al agregar nodos secundarios debajo del nodo de funciones, puede agregar funciones de proyecto específicas del negocio adicionales para la plantilla. A continuación, puede vincular estas funciones a flujos de trabajo específicos asociados al proyecto.

Flujos de trabajo

Una de las razones más atractivas para crear una plantilla de proyecto personalizada es que le permite configurar los flujos de trabajo disponibles para usar con el proyecto. Pueden utilizar flujos de trabajo OOTB o flujos de trabajo personalizados. Debajo del nodo workflows debe haber un nodo models (también nt:unstructured) y nodos secundarios debajo de especifique los modelos de flujo de trabajo disponibles. La propiedad modelId apunta al modelo de flujo de trabajo en /etc/workflow y la propiedad wizard apunta al cuadro de diálogo utilizado al iniciar el flujo de trabajo. Una gran ventaja de Proyectos es la capacidad de agregar un cuadro de diálogo personalizado (asistente) para capturar metadatos específicos de la empresa al principio del flujo de trabajo que pueden impulsar más acciones dentro del flujo de trabajo.

<projects-template-root> (cq:Template)
    + workflows (nt:unstructured)
         + models (nt:unstructured)
              + <workflow-model> (nt:unstructured)
                   - modelId = points to the workflow model
                   - wizard = dialog used to start the workflow

Creación de una plantilla de proyecto

Como principalmente copiaremos/configuraremos nodos, utilizaremos CRXDE Lite. En la instancia de AEM local, abra CRXDE Lite.

  1. Comience creando una nueva carpeta debajo de /apps/&lt;your-app-folder&gt; denominada projects. Cree otra carpeta debajo del nombre templates.

    /apps/aem-guides/projects-tasks/
                        + projects (nt:folder)
                                 + templates (nt:folder)
    
  2. Para facilitar las cosas, iniciaremos nuestra plantilla personalizada desde la plantilla de proyecto simple existente.

    1. Copie y pegue el nodo /libs/cq/core/content/projects/templates/default debajo de la carpeta templates creada en el paso 1.
    /apps/aem-guides/projects-tasks/
                 + templates (nt:folder)
                      + default (cq:Template)
    
  3. Ahora debe tener una ruta como /apps/aem-guides/projects-tasks/projects/templates/authoring-project.

    1. Edite las propiedades jcr:title y jcr:description del nodo autor-proyecto a valores de título y descripción personalizados.

      1. Deje la propiedad wizard que señala a las propiedades predeterminadas de Project.
    /apps/aem-guides/projects-tasks/projects/
             + templates (nt:folder)
                  + authoring-project (cq:Template)
                       - jcr:title = "Authoring Project"
                       - jcr:description = "A project to manage approval and publish process for AEM Sites or Assets"
                       - wizard = "/libs/cq/core/content/projects/wizard/steps/defaultproject.html"
    
  4. Para esta plantilla de proyecto queremos utilizar Tareas.

    1. Añada un nuevo nodo nt:unstructured debajo de authoring-project/gadgets denominado tasks.
    2. Agregue propiedades de cadena al nodo de tareas para cardWeight = "100", jcr:title="Tasks" y sling:resourceType="cq/gui/components/projects/admin/pod/taskpod".

    Ahora, el mosaico Tareas se mostrará de forma predeterminada cuando se cree un nuevo proyecto.

    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
             + team (nt:unstructured)
             + asset (nt:unstructured)
             + work (nt:unstructured)
             + experiences (nt:unstructured)
             + projectinfo (nt:unstructured)
             ..
             + tasks (nt:unstructured)
                  - cardWeight = "100"
                  - jcr:title = "Tasks"
                  - sling:resourceType = "cq/gui/components/projects/admin/pod/taskpod"
    
  5. Añadiremos una función de aprobador personalizada a nuestra plantilla de proyecto.

    1. Debajo del nodo plantilla de proyecto (authoring-project), agregue un nuevo nodo nt:unstructured etiquetado como roles.
    2. Agregue otro nodo nt:unstructured etiquetado de aprobadores como secundario del nodo de funciones.
    3. Agregar propiedades de cadena jcr:title = "Aprobadores", filas ="propietario", roleid="aprobadores".
      1. El nombre del nodo aprobadores, así como jcr:title y roleid pueden ser cualquier valor de cadena (siempre que roleid sea único).
      2. ​roleclassgobierna los permisos aplicados a esa función en función de los [3 roles OOTB] (https://docs.adobe.com/docs/en/aem/6-3/author/projects.html#User Funciones en un proyecto): propietario, editor y observador.
      3. En general, si la función personalizada es más una función de administración, la clase de rol puede ser propietario; si es una función de creación más específica como fotógrafo o Designer, entonces la clase de rol editor debería ser suficiente. La gran diferencia entre owner y editor es que los propietarios del proyecto pueden actualizar las propiedades del proyecto y agregar nuevos usuarios al proyecto.
    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
        + roles (nt:unstructured)
            + approvers (nt:unstructured)
                 - jcr:title = "Approvers"
                 - roleclass = "owner"
                 - roleid = "approver"
    
  6. Al copiar la plantilla Proyecto simple , se configurarán 4 flujos de trabajo OOTB. Cada nodo debajo de flujos de trabajo o modelos apunta a un flujo de trabajo específico y a un asistente de diálogo de inicio para ese flujo de trabajo. Más adelante en este tutorial, se creará un flujo de trabajo personalizado para este proyecto. Por ahora, elimine los nodos debajo del flujo de trabajo o los modelos:

    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
        + roles (nt:unstructured)
        + workflows (nt:unstructured)
             + models (nt:unstructured)
                - (remove ootb models)
    
  7. Para facilitar a los autores de contenido la identificación de la plantilla de proyecto, puede agregar una miniatura personalizada. El tamaño recomendado sería de 319 x 319 píxeles.

    1. En CRXDE Lite, cree un nuevo archivo como un elemento del mismo nivel de nodos de gadgets, roles y flujos de trabajo llamados thumbnail.png.
    2. Guarde y, a continuación, vaya al nodo jcr:content y haga doble clic en la propiedad jcr:data (evite hacer clic en "ver").
      1. Esto debería solicitarle un cuadro de diálogo de edición de jcr:data archivo y puede cargar una miniatura personalizada.
    ../projects/templates/authoring-project
        + gadgets (nt:unstructured)
        + roles (nt:unstructured)
        + workflows (nt:unstructured)
        + thumbnail.png (nt:file)
    

Representación XML finalizada de la plantilla de proyecto:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:description="A project to manage approval and publish process for AEM Sites or Assets"
    jcr:primaryType="cq:Template"
    jcr:title="Authoring Project"
    ranking="{Long}1"
    wizard="/libs/cq/core/content/projects/wizard/steps/defaultproject.html">
    <jcr:content
        jcr:primaryType="nt:unstructured"
        detailsHref="/projects/details.html"/>
    <gadgets jcr:primaryType="nt:unstructured">
        <team
            jcr:primaryType="nt:unstructured"
            jcr:title="Team"
            sling:resourceType="cq/gui/components/projects/admin/pod/teampod"
            cardWeight="60"/>
        <tasks
            jcr:primaryType="nt:unstructured"
            jcr:title="Tasks"
            sling:resourceType="cq/gui/components/projects/admin/pod/taskpod"
            cardWeight="100"/>
        <work
            jcr:primaryType="nt:unstructured"
            jcr:title="Workflows"
            sling:resourceType="cq/gui/components/projects/admin/pod/workpod"
            cardWeight="80"/>
        <experiences
            jcr:primaryType="nt:unstructured"
            jcr:title="Experiences"
            sling:resourceType="cq/gui/components/projects/admin/pod/channelpod"
            cardWeight="90"/>
        <projectinfo
            jcr:primaryType="nt:unstructured"
            jcr:title="Project Info"
            sling:resourceType="cq/gui/components/projects/admin/pod/projectinfopod"
            cardWeight="100"/>
    </gadgets>
    <roles jcr:primaryType="nt:unstructured">
        <approvers
            jcr:primaryType="nt:unstructured"
            jcr:title="Approvers"
            roleclass="owner"
            roleid="approvers"/>
    </roles>
    <workflows
        jcr:primaryType="nt:unstructured"
        tags="[]">
        <models jcr:primaryType="nt:unstructured">
        </models>
    </workflows>
</jcr:root>

Prueba de la plantilla de proyecto personalizada

Ahora podemos probar nuestra plantilla de proyecto creando un nuevo proyecto.

  1. Debería ver la plantilla personalizada como una de las opciones para la creación del proyecto.

    Elegir plantilla

  2. Después de seleccionar la plantilla personalizada, haga clic en "Siguiente" y observe que al rellenar Miembros del proyecto puede agregarlos como una función Aprobador .

    Aprobar

  3. Haga clic en "Crear" para terminar de crear el proyecto basado en la plantilla personalizada. Verá en el panel del proyecto que el mosaico Tareas y los demás mosaicos configurados en gadgets aparecen automáticamente.

    Mosaico Tareas

¿Por qué el flujo de trabajo?

Tradicionalmente, AEM flujos de trabajo centrados en un proceso de aprobación han utilizado los pasos del flujo de trabajo Participante. AEM Bandeja de entrada incluye detalles sobre Tareas y Flujo de trabajo, así como una integración mejorada con Proyectos AEM. Estas funciones hacen que el uso de los pasos del proceso Crear tarea de proyectos sea una opción más atractiva.

¿Por qué las tareas?

El uso de un paso de creación de tareas sobre los pasos de participante tradicionales ofrece un par de ventajas:

  • Fecha de inicio y de vencimiento : facilita a los autores la administración de su hora, ya que la nueva función Calendario hace uso de estas fechas.
  • Prioridad : las prioridades integradas de Bajo, Normal y Alto permiten a los autores priorizar el trabajo
  • Comentarios enlazados: mientras los autores trabajan en una tarea, tienen la capacidad de dejar comentarios y aumentar la colaboración
  • Visibilidad : los mosaicos de tareas y las vistas con Proyectos permiten a los administradores ver cómo se pasa el tiempo
  • Integración de proyectos : las tareas ya están integradas con las funciones y los paneles del proyecto

Al igual que los pasos del participante, las tareas se pueden asignar y enrutar dinámicamente. Los metadatos de tareas como Título, Prioridad también se pueden definir dinámicamente en función de acciones anteriores, como se verá en el siguiente tutorial.

Aunque las tareas tienen algunas ventajas con respecto a los pasos de los participantes, conllevan gastos adicionales y no son tan útiles fuera de un proyecto. Además, todo el comportamiento dinámico de Tasks debe codificarse mediante secuencias de comandos ecma que tengan sus propias limitaciones.

Requisitos de caso de uso de muestra

Diagrama del proceso del flujo de trabajo

El diagrama anterior describe los requisitos de alto nivel para nuestro flujo de trabajo de aprobación de muestras.

El primer paso será crear una tarea para finalizar la edición de un fragmento de contenido. Permitiremos que el iniciador del flujo de trabajo elija el usuario asignado de esta primera tarea.

Una vez finalizada la primera tarea, el usuario asignado tendrá tres opciones para enrutar el flujo de trabajo:

Normal- el enrutamiento normal crea una tarea asignada al grupo Aprobador del proyecto para revisarla y aprobarla. La prioridad de la tarea es Normal y la fecha de vencimiento es de 5 días a partir de la fecha de creación.

Rush : el enrutamiento rápido también crea una tarea asignada al grupo Aprobador del proyecto. La prioridad de la tarea es Alta y la fecha de vencimiento es solo 1 día.

Omitir : en este flujo de trabajo de muestra, el participante inicial tiene la opción de evitar el grupo de aprobación. (sí, esto podría ser contrario al objetivo de un flujo de trabajo "Aprobación", pero nos permite ilustrar capacidades de enrutamiento adicionales)

El grupo de aprobadores puede aprobar el contenido o enviarlo de nuevo al usuario asignado inicial para que lo vuelva a trabajar. En el caso de que se devuelva para que se vuelva a trabajar, se crea una nueva tarea con la etiqueta "Enviado de nuevo para que se vuelva a trabajar".

El último paso del flujo de trabajo utiliza el paso de proceso Activar página/recurso y replica la carga útil.

Creación del modelo de flujo de trabajo

  1. En el menú Inicio de AEM, vaya a Herramientas -> Flujo de trabajo -> Modelos. Haga clic en "Crear" en la esquina superior derecha para crear un nuevo modelo de flujo de trabajo.

    Asigne un título al nuevo modelo: "Flujo de trabajo de aprobación de contenido" y un nombre de URL: "content-approval-workflow".

    Cuadro de diálogo Crear flujo de trabajo

    Para obtener más información relacionada con la creación de flujos de trabajo, lea aquí.

  2. Como práctica recomendada, los flujos de trabajo personalizados deben agruparse en su propia carpeta debajo de /etc/workflow/models. En el CRXDE Lite, cree un nuevo 'nt:folder' debajo de /etc/workflow/models llamados "aem-guides". Añadir una subcarpeta garantiza que los flujos de trabajo personalizados no se sobrescriban accidentalmente durante las actualizaciones o instalaciones del Service Pack.

    *Tenga en cuenta que es importante no colocar nunca la carpeta o los flujos de trabajo personalizados bajo subcarpetas ootb como /etc/workflow/models/dam o /etc/workflow/models/projects, ya que todas las subcarpetas también se pueden sobrescribir mediante actualizaciones o service packs.

    Ubicación del modelo de flujo de trabajo en 6.3

    Ubicación del modelo de flujo de trabajo en 6.3

    NOTA

    Si se utiliza AEM 6.4+, la ubicación del flujo de trabajo ha cambiado. Consulte aquí para obtener más información.

    Si se utiliza AEM 6.4+, el modelo de flujo de trabajo se creará en /conf/global/settings/workflow/models. Repita los pasos anteriores con el directorio /conf y añada una subcarpeta llamada aem-guides y mueva el content-approval-workflow debajo de él.

    Definición de flujo de trabajo moderna
    ubicaciónUbicación del modelo de flujo de trabajo en la versión 6.4 o posterior

  3. La introducción de AEM 6.3 es la capacidad de añadir etapas de flujo de trabajo a un flujo de trabajo determinado. Los pasos aparecerán para el usuario desde la bandeja de entrada en la pestaña Información del flujo de trabajo . Muestra al usuario la fase actual del flujo de trabajo, así como las etapas anteriores y posteriores al flujo de trabajo.

    Para configurar los escenarios, abra el cuadro de diálogo Propiedades de página desde la barra de tareas. La cuarta pestaña se denomina "Etapas". Añada los siguientes valores para configurar las tres etapas de este flujo de trabajo:

    1. Editar contenido
    2. Aprobación
    3. Publicación

    configuración de las etapas del flujo de trabajo

    Configure las etapas del flujo de trabajo desde el cuadro de diálogo Propiedades de página.

    barra de progreso del flujo de trabajo

    La barra de progreso del flujo de trabajo tal como se ve desde la bandeja de entrada de AEM.

    Opcionalmente, puede cargar una Imagen en las Propiedades de página que se utilizará como miniatura del flujo de trabajo cuando los usuarios la seleccionen. Las dimensiones de la imagen deben ser de 319 x 319 píxeles. Añadir una Description a las Propiedades de página también aparecerá cuando un usuario vaya a seleccionar el flujo de trabajo.

  4. El proceso de flujo de trabajo Crear tarea de proyecto está diseñado para crear una tarea como paso en el flujo de trabajo. Solo después de completar la tarea avanzará el flujo de trabajo. Un aspecto importante del paso Crear tarea de proyecto es que puede leer los valores de metadatos del flujo de trabajo y utilizarlos para crear la tarea de forma dinámica.

    Primero elimine la etapa de participante que se crea de forma predeterminada. En la barra de tareas del menú de componentes, expanda el subencabezado "Proyectos" y arrastre y suelte el encabezado "Crear tarea de proyecto" en el modelo.

    Haga doble clic en el paso "Crear tarea de proyecto" para abrir el cuadro de diálogo del flujo de trabajo. Configure las siguientes propiedades:

    Esta pestaña es común para todos los pasos del proceso del flujo de trabajo y estableceremos el Título y la Descripción (estos no serán visibles para el usuario final). La propiedad importante que estableceremos es el paso del flujo de trabajo a "Editar contenido" en el menú desplegable.

    Common Tab
    -----------------
        Title = "Start Task Creation"
        Description = "This the first task in the Workflow"
        Workflow Stage = "Edit Content"
    

    El proceso de flujo de trabajo Crear tarea de proyecto está diseñado para crear una tarea como paso en el flujo de trabajo. La pestaña Task permite establecer todos los valores de la tarea. En nuestro caso, queremos que el usuario asignado sea dinámico, por lo que lo dejaremos en blanco. El resto de los valores de propiedad:

    Task Tab
    -----------------
        Name* = "Edit Content"
        Task Priority = "Medium"
        Description = "Edit the content and finalize for approval. Once finished submit for approval."
        Due In - Days = "2"
    

    La pestaña routing es un cuadro de diálogo opcional que puede especificar acciones disponibles para el usuario que completa la tarea. Estas acciones son solo valores de cadena y se guardan en los metadatos del flujo de trabajo. Estos valores se pueden leer mediante secuencias de comandos o pasos de proceso más adelante en el flujo de trabajo para "enrutar" dinámicamente el flujo de trabajo. En función de los objetivos de flujo de trabajo agregaremos tres acciones a esta pestaña:

    Routing Tab
    -----------------
        Actions =
            "Normal Approval"
            "Rush Approval"
            "Bypass Approval"
    

    Esta pestaña nos permite configurar una secuencia de comandos de tarea previa a la creación en la que podemos decidir mediante programación varios valores de la tarea antes de crearla. Tenemos la opción de apuntar el script a un archivo externo o incrustar un script corto directamente en el cuadro de diálogo. En nuestro caso, apuntaremos el Script de tarea de precreación a un archivo externo. En el paso 5 crearemos ese script.

    Advanced Settings Tab
    -----------------
       Pre-Create Task Script = "/apps/aem-guides/projects/scripts/start-task-config.ecma"
    
  5. En el paso anterior hemos hecho referencia a un script de tarea de precreación. Ahora crearemos esa secuencia de comandos en la que estableceremos el Usuario asignado de la tarea en función del valor de un valor de metadatos de flujo de trabajo "usuario asignado". El valor "assignee" se establecerá cuando se inicie el flujo de trabajo. También leeremos los metadatos del flujo de trabajo para elegir dinámicamente la prioridad de la tarea leyendo el valor "taskPriority" de los metadatos del flujo de trabajo, así como el valor "taskDueDate" para establecer dinámicamente cuando venza la primera tarea.

    Con fines organizativos, hemos creado una carpeta debajo de la carpeta de la aplicación para guardar todos los scripts relacionados con el proyecto: /apps/aem-guides/projects-tasks/projects/scripts. Cree un nuevo archivo bajo esta carpeta llamado "start-task-config.ecma". *Tenga en cuenta que la ruta al archivo start-task-config.ecma coincide con la ruta establecida en la ficha Configuración avanzada del paso 4.

    Añada lo siguiente como contenido del archivo :

    // start-task-config.ecma
    // Populate the task using values stored as workflow metadata originally posted by the start workflow wizard
    
    // set the assignee based on start workflow wizard
    var assignee = workflowData.getMetaDataMap().get("assignee", Packages.java.lang.String);
    task.setCurrentAssignee(assignee);
    
    //Set the due date for the initial task based on start workflow wizard
    var dueDate = workflowData.getMetaDataMap().get("taskDueDate", Packages.java.util.Date);
    if (dueDate != null) {
        task.setProperty("taskDueDate", dueDate);
    }
    
    //Set the priority based on start workflow wizard
    var taskPriority = workflowData.getMetaDataMap().get("taskPriority", "Medium");
    task.setProperty("taskPriority", taskPriority);
    
  6. Vuelva al flujo de trabajo de aprobación de contenido. Arrastre y suelte el componente OR Split (que se encuentra en la barra de tareas debajo de la categoría "Flujo de trabajo") debajo del paso Iniciar tarea. En el cuadro de diálogo común, seleccione el botón de opción para 3 ramas. La división OR leerá el valor de metadatos del flujo de trabajo "lastTaskAction" para determinar la ruta del flujo de trabajo. La propiedad "lastTaskAction" se establecerá en uno de los valores de la ficha Enrutamiento configurada en el paso 4. Para cada una de las fichas Rama, rellene el área de texto Script con los siguientes valores:

    function check() {
    var lastAction = workflowData.getMetaDataMap().get("lastTaskAction","");
    
    if(lastAction == "Normal Approval") {
        return true;
    }
    
    return false;
    }
    
    function check() {
    var lastAction = workflowData.getMetaDataMap().get("lastTaskAction","");
    
    if(lastAction == "Rush Approval") {
        return true;
    }
    
    return false;
    }
    
    function check() {
    var lastAction = workflowData.getMetaDataMap().get("lastTaskAction","");
    
    if(lastAction == "Bypass Approval") {
        return true;
    }
    
    return false;
    }
    

    *Tenga en cuenta que estamos haciendo una coincidencia de cadena directa para determinar la ruta, por lo que es importante que los valores configurados en las secuencias de comandos de rama coincidan con los valores de ruta establecidos en el paso 4.

  7. Arrastre y suelte otro paso "Crear tarea de proyecto" en el modelo al extremo izquierdo (Rama 1) debajo de la división O. Complete el cuadro de diálogo con las siguientes propiedades:

    Common Tab
    -----------------
        Title = "Approval Task Creation"
        Description = "Create a an approval task for Project Approvers. Priority is Medium."
        Workflow Stage = "Approval"
    
    Task Tab
    ------------
        Name* = "Approve Content for Publish"
        Task Priority = "Medium"
        Description = "Approve this content for publication."
        Days = "5"
    
    Routing Tab - Actions
    ----------------------------
        "Approve and Publish"
        "Send Back for Revision"
    

    Dado que esta es la ruta de aprobación normal, la prioridad de la tarea se establece en Media. Además, damos al grupo Aprobadores 5 días para completar la tarea. El usuario asignado se deja en blanco en la ficha Tarea, ya que lo asignaremos de forma dinámica en la ficha Configuración avanzada . Asignamos al grupo Aprobadores dos rutas posibles al completar esta tarea: "Aprobar y publicar" si aprueban el contenido y este se puede publicar y "Enviar de vuelta para revisión" si hay problemas que el editor original debe corregir. El aprobador puede dejar comentarios que el editor original verá si se le devuelve el flujo de trabajo.

Anteriormente, en este tutorial, creamos una plantilla de proyecto que incluía una función de aprobadores. Cada vez que se crea un nuevo proyecto a partir de esta plantilla, se crea un grupo específico para el proyecto para la función Aprobadores . Al igual que una etapa de participante, una tarea solo se puede asignar a un usuario o grupo. Queremos asignar esta tarea al grupo de proyectos que corresponda al Grupo de Aprobadores. Todos los flujos de trabajo que se inician desde un proyecto tienen metadatos que asignan las funciones del proyecto al grupo específico del proyecto.

Copie y pegue el siguiente código en el área de texto Script de la pestaña Configuración avanzada. Este código leerá los metadatos del flujo de trabajo y asignará la tarea al grupo Aprobadores del proyecto. Si no encuentra el valor del grupo aprobadores, volverá a asignar la tarea al grupo Administradores .

var projectApproverGrp = workflowData.getMetaDataMap().get("project.group.approvers","administrators");

task.setCurrentAssignee(projectApproverGrp);
  1. Arrastre y suelte otro paso "Crear tarea de proyecto" en el modelo a la rama central (Rama 2) debajo de la división O. Complete el cuadro de diálogo con las siguientes propiedades:

    Common Tab
    -----------------
        Title = "Rush Approval Task Creation"
        Description = "Create a an approval task for Project Approvers. Priority is High."
        Workflow Stage = "Approval"
    
    Task Tab
    ------------
        Name* = "Rush Approve Content for Publish"
        Task Priority = "High"
        Description = "Rush approve this content for publication."
        Days = "1"
    
    Routing Tab - Actions
    ----------------------------
        "Approve and Publish"
        "Send Back for Revision"
    

    Dado que esta es la ruta Rush Approval, la prioridad de la tarea se establece en High. Además, damos al grupo Aprobadores un solo día para completar la tarea. El usuario asignado se deja en blanco en la ficha Tarea, ya que lo asignaremos de forma dinámica en la ficha Configuración avanzada .

    Podemos reutilizar el mismo fragmento de secuencia de comandos que en el paso 7 para rellenar el área de texto Script en la pestaña Configuración avanzada. Copie y pegue el siguiente código:

    var projectApproverGrp = workflowData.getMetaDataMap().get("project.group.approvers","administrators");
    
    task.setCurrentAssignee(projectApproverGrp);
    
  2. Arrastre y suelte un componente Sin operación a la rama derecha (Rama 3). El componente Sin operación no realiza ninguna acción y avanzará inmediatamente, representando el deseo del editor original de omitir el paso de aprobación. Técnicamente, podemos dejar esta rama sin ningún paso de flujo de trabajo, pero como práctica recomendada añadiremos un paso Sin operación . Esto deja claro a otros desarrolladores cuál es el propósito de la Rama 3.

    Haga doble clic en el paso del flujo de trabajo y configure el Título y la Descripción:

    Common Tab
    -----------------
        Title = "Bypass Approval"
        Description = "Placeholder step to indicate that the original editor decided to bypass the approver group."
    

    modelo de flujo de trabajo OR dividido

    El modelo de flujo de trabajo debe tener este aspecto después de configurar las tres ramas de la división OR.

  3. Dado que el grupo Aprobadores tiene la opción de enviar el flujo de trabajo de nuevo al editor original para revisiones adicionales, dependeremos del paso Ir a para leer la última acción realizada y enrutar el flujo de trabajo al principio o permitir que continúe.

    Arrastre y suelte el componente Paso Ir a (que se encuentra en la barra de tareas en Flujo de trabajo) debajo de la división O donde se vuelve a unir. Haga doble clic en y configure las siguientes propiedades en el cuadro de diálogo:

    Common Tab
    ----------------
        Title = "Goto Step"
        Description = "Based on the Approver groups action route the workflow to the beginning or continue and publish the payload."
    
    Process Tab
    ---------------
        The step to go to. = "Start Task Creation"
    

    La última pieza que configuraremos es el Script como parte del paso de proceso Goto. El valor Script se puede incrustar mediante el cuadro de diálogo o configurar para que apunte a un archivo externo. El Goto Script debe contener una función check() y devolver true si el flujo de trabajo debe ir al paso especificado. Un retorno de false hace que el flujo de trabajo avance.

    Si el grupo de aprobadores elige la acción "Send Back for Revision" (configurada en los pasos 7 y 8), deseamos devolver el flujo de trabajo al paso "Start Task Creation".

    En la ficha Proceso, agregue el siguiente fragmento de código al área de texto Script:

    function check() {
    var lastAction = workflowData.getMetaDataMap().get("lastTaskAction","");
    
    if(lastAction == "Send Back for Revision") {
        return true;
    }
    
    return false;
    }
    
  4. Para publicar la carga útil, utilizaremos el paso de proceso Activar página/recurso ootb. Este paso del proceso requiere poca configuración y añade la carga útil del flujo de trabajo a la cola de replicación para su activación. Añadimos el paso debajo del paso Ir a y de esta forma solo se puede acceder si el grupo Aprobador ha aprobado el contenido para su publicación o si el editor original ha elegido la ruta Omitir aprobación .

    Arrastre y suelte el paso Activar página/recurso Proceso (que se encuentra en la barra de tareas en Flujo de trabajo de WCM) debajo del paso Ir a del modelo.

    finalización del modelo de flujo de trabajo

    Aspecto del modelo de flujo de trabajo después de añadir el paso Ir a y el paso Activar página/recurso .

  5. Si el grupo Aprobador devuelve el contenido para su revisión, queremos informar al editor original. Podemos conseguirlo cambiando dinámicamente las propiedades de creación de tareas. Se desactivará el valor de la propiedad lastActionTaken de "Enviar para revisión". Si ese valor está presente, modificaremos el título y la descripción para indicar que esta tarea es el resultado de que el contenido se devuelve para su revisión. También actualizaremos la prioridad a "High" para que sea el primer elemento en el que funciona el editor. Finalmente, estableceremos la fecha de vencimiento de la tarea en un día a partir del momento en que se devolvió el flujo de trabajo para su revisión.

    Reemplace el script de inicio start-task-config.ecma (creado en el paso 5) por lo siguiente:

    // start-task-config.ecma
    // Populate the task using values stored as workflow metadata originally posted by the start workflow wizard
    
    // set the assignee based on start workflow wizard
    var assignee = workflowData.getMetaDataMap().get("assignee", Packages.java.lang.String);
    task.setCurrentAssignee(assignee);
    
    //Set the due date for the initial task based on start workflow wizard
    var dueDate = workflowData.getMetaDataMap().get("taskDueDate", Packages.java.util.Date);
    if (dueDate != null) {
        task.setProperty("taskDueDate", dueDate);
    }
    
    //Set the priority based on start workflow wizard
    var taskPriority = workflowData.getMetaDataMap().get("taskPriority", "Medium");
    task.setProperty("taskPriority", taskPriority);
    
    var lastAction = workflowData.getMetaDataMap().get("lastTaskAction","");
    
    //change the title and priority if the approver group sent back the content
    if(lastAction == "Send Back for Revision") {
      var taskName = "Review and Revise Content";
    
      //since the content was rejected we will set the priority to High for the revison task
      task.setProperty("taskPriority", "High"); 
    
      //set the Task name (displayed as the task title in the Inbox) 
      task.setProperty("name", taskName);
      task.setProperty("nameHierarchy", taskName);
    
      //set the due date of this task 1 day from current date
      var calDueDate = Packages.java.util.Calendar.getInstance();
      calDueDate.add(Packages.java.util.Calendar.DATE, 1);
      task.setProperty("taskDueDate", calDueDate.getTime());
    
    }
    

Creación del asistente de "inicio del flujo de trabajo"

Al iniciar un flujo de trabajo desde un proyecto, debe especificar un asistente para iniciar el flujo de trabajo. El asistente predeterminado: /libs/cq/core/content/projects/workflowwizards/default_workflow permite al usuario introducir un título de flujo de trabajo, un comentario de inicio y una ruta de carga útil para que se ejecute el flujo de trabajo. También hay otros ejemplos encontrados en: /libs/cq/core/content/projects/workflowwizards.

La creación de un asistente personalizado puede ser muy eficaz, ya que puede recopilar información crítica antes de que se inicie el flujo de trabajo. Los datos se almacenan como parte de los metadatos del flujo de trabajo y los procesos de flujo de trabajo pueden leerlos y cambiar de forma dinámica el comportamiento en función de los valores introducidos. Se creará un asistente personalizado para asignar dinámicamente la primera tarea del flujo de trabajo en función de un valor del asistente de inicio.

  1. En CRXDE-Lite crearemos una subcarpeta debajo de la carpeta /apps/aem-guides/projects-tasks/projects llamada "asistentes". Copie el asistente predeterminado desde: /libs/cq/core/content/projects/workflowwizards/default_workflow debajo de la carpeta de asistentes recién creada y renómbrala a content-approval-start. La ruta completa debería ser: /apps/aem-guides/projects-tasks/projects/wizards/content-approval-start.

    El asistente predeterminado es un asistente de dos columnas, con la primera columna que muestra el Título, la Descripción y la Miniatura del modelo de flujo de trabajo seleccionado. La segunda columna incluye los campos Título del flujo de trabajo, Comentar inicio y Ruta de carga útil. El asistente es un formulario estándar de interfaz de usuario táctil y utiliza componentes estándar de Granite UI Form para rellenar los campos.

    asistente de flujo de trabajo de aprobación de contenido

  2. Se agregará un campo adicional al asistente que se utilizará para establecer el usuario asignado de la primera tarea del flujo de trabajo (consulte Creación del modelo de flujo de trabajo: Paso 5).

    Debajo de ../content-approval-start/jcr:content/items/column2/items cree un nuevo nodo de tipo nt:unstructured denominado "assign". Se utilizará el componente Selector de usuario de proyectos (que se basa en el Componente Selector de usuario de Granite). Este campo de formulario facilita restringir la selección de usuarios y grupos a aquellos que pertenecen al proyecto actual.

    A continuación se muestra la representación XML del nodo assign:

    <assign
        granite:class="js-cq-project-user-picker"
        jcr:primaryType="nt:unstructured"
        sling:resourceType="cq/gui/components/projects/admin/userpicker"
        fieldLabel="Assign To"
        hideServiceUsers="{Boolean}true"
        impersonatesOnly="{Boolean}true"
        showOnlyProjectMembers="{Boolean}true"
        name="assignee"
        projectPath="${param.project}"
        required="{Boolean}true"/>
    
  3. También se añade un campo de selección de prioridad que determina la prioridad de la primera tarea del flujo de trabajo (consulte Crear el modelo de flujo de trabajo: Paso 5).

    Debajo de /content-approval-start/jcr:content/items/column2/items cree un nuevo nodo de tipo nt:unstructured denominado priority. Utilizaremos el Granite UI Select component para rellenar el campo de formulario.

    Debajo del nodo priority añadiremos un nodo items de nt:unstructured. Bajo el nodo items agregue 3 nodos más para rellenar las opciones de selección de Alto, Medio y Bajo. Cada nodo es de tipo nt:unstructured y debe tener una propiedad text y value. Tanto el texto como el valor deben ser el mismo:

    1. Alta
    2. Media
    3. Baja

    Para el nodo Medio, añada una propiedad booleana adicional denominada "selected" con un valor establecido en true. Esto garantizará que Medio sea el valor predeterminado en el campo de selección.

    A continuación se muestra una representación XML de la estructura y las propiedades del nodo:

    <priority
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/form/select"
        fieldLabel="Task Priority"
        name="taskPriority">
            <items jcr:primaryType="nt:unstructured">
                <high
                    jcr:primaryType="nt:unstructured"
                    text="High"
                    value="High"/>
                <medium
                    jcr:primaryType="nt:unstructured"
                    selected="{Boolean}true"
                    text="Medium"
                    value="Medium"/>
                <low
                    jcr:primaryType="nt:unstructured"
                    text="Low"
                    value="Low"/>
                </items>
    </priority>
    
  4. Permitiremos que el iniciador del flujo de trabajo establezca la fecha de vencimiento de la tarea inicial. Se utilizará el campo de formulario Granite UI DatePicker para capturar esta entrada. También se agregará un campo oculto con TypeHint para garantizar que la entrada se almacene como propiedad de tipo Date en el JCR.

    Añada dos nodos nt:unstructured con las siguientes propiedades representadas a continuación en XML:

    <duedate
        granite:rel="project-duedate"
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/form/datepicker"
        displayedFormat="YYYY-MM-DD HH:mm"
        fieldLabel="Due Date"
        minDate="today"
        name="taskDueDate"
        type="datetime"/>
    <duedatetypehint
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/form/hidden"
        name="taskDueDate@TypeHint"
        type="datetime"
        value="Calendar"/>
    
  5. Puede ver el código completo del cuadro de diálogo del asistente de inicio aquí.

Conexión del flujo de trabajo y la plantilla del proyecto

Lo último que tenemos que hacer es garantizar que el modelo de flujo de trabajo esté disponible para su inicio dentro de uno de los proyectos. Para ello, necesitamos volver a visitar la plantilla de proyecto que creamos en la parte 1 de esta serie.

La configuración de flujo de trabajo es un área de una plantilla de proyecto que especifica los flujos de trabajo disponibles para usar con ese proyecto. La configuración también se encarga de especificar el Asistente para iniciar el flujo de trabajo al iniciar el flujo de trabajo (que hemos creado en los pasos anteriores). La configuración de flujo de trabajo de una plantilla de proyecto está "activa", lo que significa que la actualización de la configuración del flujo de trabajo afectará a los nuevos proyectos creados, así como a los proyectos existentes que utilicen la plantilla.

  1. En CRXDE-Lite, vaya a la plantilla de proyecto de creación creada anteriormente en /apps/aem-guides/projects-tasks/projects/templates/authoring-project/workflows/models.

    Debajo del nodo de modelos, agregue un nuevo nodo denominado contentapproval con un tipo de nodo nt:unstructured. Agregue las siguientes propiedades al nodo :

    <contentapproval
        jcr:primaryType="nt:unstructured"
        modelId="/etc/workflow/models/aem-guides/content-approval-workflow/jcr:content/model"
        wizard="/apps/aem-guides/projects-tasks/projects/wizards/content-approval-start.html"
    />
    
    NOTA

    Si se utiliza AEM 6.4, la ubicación del flujo de trabajo ha cambiado. Asigne la propiedad modelId a la ubicación del modelo de flujo de trabajo en tiempo de ejecución en /var/workflow/models/aem-guides/content-approval-workflow

    Consulte aquí para obtener más información sobre el cambio en la ubicación del flujo de trabajo.

    <contentapproval
        jcr:primaryType="nt:unstructured"
        modelId="/var/workflow/models/aem-guides/content-approval-workflow"
        wizard="/apps/aem-guides/projects-tasks/projects/wizards/content-approval-start.html"
    />
    
  2. Una vez que el flujo de trabajo de aprobación de contenido se haya añadido a la plantilla de proyecto, debería estar disponible para iniciarse desde el mosaico de flujo de trabajo del proyecto. Adelante, inicie y reproduzca con las distintas rutas que hemos creado.

Materiales de apoyo

En esta página