Пользовательский ввод данных рабочего процесса AEM - PullRequest
0 голосов
/ 30 января 2020

Мне нужно создать рабочий процесс в AEM, который для страницы (указанной как полезная нагрузка) находит все ресурсы, используемые на странице, и загружает их список во внешнюю службу. Пока у меня большая часть кода готова, но бизнес-процесс требует, чтобы я использовал специальный код для каждой из страниц (различный для каждого запуска рабочего процесса), чтобы список загружался в правильное место.

Вот тогда у меня возникает вопрос - Можете ли вы как-нибудь добавить дополнительные входные значения для рабочего процесса AEM? Может быть, расширив начальный диалог или добавив какой-то особый шаг, который требует ввода пользователя? Мне нужно как-то указать код при запуске рабочего процесса или во время его выполнения.

Я прочитал много документации, но, поскольку я впервые использую рабочие процессы, я мог упустить что-то действительно очевидное. Буду благодарен за любой совет, включая ссылку на соответствующий документ.

Ответы [ 2 ]

0 голосов
/ 31 января 2020

Вы можете:

  1. Создать настраиваемую запись меню где-нибудь в AEM (например, Редактор страниц, /apps/wcm/core/content/editor/_jcr_content/content/items/content/header/items/headerbar/items/pageinfopopover/items/list/items/<my-action>, примеры см. В библиотеках)

  2. Создайте клиентскую библиотеку с categories="[cq.authoring.editor]". Таким образом, он загружается как часть редактора страниц (а не внутри iframe с вашей страницей)

  3. Создайте JS -Listener, который открывает диалог, если пункт меню был нажал (см. код). Вы можете использовать либо простые диалоги Coral UI, либо в моем примере неправильно использовалось диалоговое окно страницы Granite (Granite считывает структуру данных в диалоге cq: и создает из него диалог редактирования компонента Coral UI - в то время как Coral - обычный JS UI-framework)

  4. Создайте Java -Servlet, который ловит ваш запрос и создает рабочий процесс. Вы можете теоретически использовать сервлет AEM. Но мне часто приходится писать свои собственные, потому что в нем отсутствуют некоторые функции.


Вот JS Слушатель:

/*global Granite,jQuery,document,window */
(function ($, ns, channel, window) {
    "use strict";

    var START_WORKFLOW_ACTIVATOR_SELECTOR = ".js-editor-myexample-activator";

    function onSuccess() {
        ns.ui.helpers.notify({
            heading: "Example Workflow",
            content: "successfully started",
            type: ns.ui.helpers.NOTIFICATION_TYPES.SUCCESS
        });
    }

    function onSubmitFail(event, jqXHR) {
        var errorMsg = Granite.I18n.getVar($(jqXHR.responseText).find("#Message").html());
        ns.ui.helpers.notify({
            heading: "Example Workflow",
            content: errorMsg,
            type: ns.ui.helpers.NOTIFICATION_TYPES.ERROR
        });
    }

    function onReady() {
        // add selector for special servlet to form action-url
        var $form = ns.DialogFrame.currentFloatingDialog.find("form");
        var action = $form.attr("action");
        if (action) {
            $form.attr("action", action + ".myexample-selector.html");
        }

        // register dialog-fail event, to show a relevant error message
        $(document).on("dialog-fail", onSubmitFail);

        // init your dialog here ...
    }


    function onClose() {
        $(document).off("dialog-fail", onSubmitFail);
    }

    // Listen for the tap on the 'myexample' activator
    channel.on("click", START_WORKFLOW_ACTIVATOR_SELECTOR, function () {
        var activator = $(this);
        // this is a dirty trick, to use a Granite dialog directly (point to data-structure like in cq:dialog)
        var dialogUrl = Granite.HTTP.externalize("/apps/...." + Granite.author.ContentFrame.getContentPath());

        var dlg = new ns.ui.Dialog({
            getConfig: function () {
                return {
                    src: dialogUrl,
                    loadingMode: "auto",
                    layout: "auto"
                }
            },
            getRequestData: function () {
                return {};
            },
            "onSuccess": onSuccess,
            "onReady": onReady,
            "onClose": onClose
        });

        ns.DialogFrame.openDialog(dlg);
    });

}(jQuery, Granite.author, jQuery(document), window));

А вот и сервлет

@Component(service = Servlet.class,
        property = {
                SLING_SERVLET_RESOURCE_TYPES + "=cq:Page",
                SLING_SERVLET_SELECTORS + "=myexample-selector",
                SLING_SERVLET_METHODS + "=POST",
                SLING_SERVLET_EXTENSIONS + "=html"
        })
public class RequestExampleWorkflowServlet extends SlingAllMethodsServlet {

    @Override
    protected void doPost(@Nonnull SlingHttpServletRequest request, @Nonnull SlingHttpServletResponse response) throws IOException {

        final Page page = request.getResource().adaptTo(Page.class);

        if (page != null) {
            Map<String, Object> wfMetaData = new HashMap<>();
            wfMetaData.put("workflowTitle", "Request Translation for " + page.getTitle());
            wfMetaData.put("something", "Hello World");

            try {
                WorkflowSession wfSession = request.getResourceResolver().adaptTo(WorkflowSession.class);
                if (wfSession != null) {
                    WorkflowModel wfModel = wfSession.getModel("/var/workflow/models/example-workflow");
                    WorkflowData wfData = wfSession.newWorkflowData(PayloadInfo.PAYLOAD_TYPE.JCR_PATH.name(), page.getPath());
                    wfSession.startWorkflow(wfModel, wfData, wfMetaData);
                    MyServletUtil.respondSlingStyleHtml(response, HttpServletResponse.SC_OK, "Triggered Example Workflow");
                } else {
                    throw new WorkflowException("Cannot retrieve WorkflowSession");
                }
            } catch (WorkflowException e) {
                MyServletUtil.respondSlingStyleHtml(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
            }
        } else {
            MyServletUtil.respondSlingStyleHtml(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal error - cannot get page");
        }
    }
}
0 голосов
/ 30 января 2020

Да, это возможно. Вам необходимо реализовать шаг диалога в вашем рабочем процессе: https://docs.adobe.com/content/help/en/experience-manager-64/developing/extending-aem/extending-workflows/workflows-step-ref.html#dialog -participant-step

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...