orbinson / aem-dictionary-translator

Translate AEM labels for i18n internationalisation
8 stars 4 forks source link

"URI too long" error on publication of large number of keys #45

Open jmagdrod opened 3 weeks ago

jmagdrod commented 3 weeks ago

When the dictionary contains a large number of keys and the user selects all entries and publish them, the following error is thrown: URI too long image

This request is using a GET method adding all the entries as query parameters which goes over the URI length limit.

kwin commented 3 weeks ago

Using a POST is reasonable here (also for semantic reasons).

royteeuwen commented 3 weeks ago

@jmagdrod will have to validate on how we can make this work, if it would be a direct publication without a dialog in between, the POST would be very easy to implement, but now it's using the action type foundation.dialog, which doesn't support opening it with a POST (that I know of), so will have to rewrite it a bit from scratch.

I wont have the time to fix it this week so if it's urgent I'm always open for contributions!

kwin commented 3 weeks ago

There is com.day.cq.replication.impl.servlets.CommandServlet which can be used for replication (registered for /bin/replicate) and com.day.cq.wcm.core.impl.commands.WCMCommandServlet (registered for /bin/wcmcommand). Both support POST requests (i.e. also consider parameters sent via request body in format application/x-www-form-urlencoded). The former supports the parameters:

  1. path
  2. agentId (to target either preview or publish, only in AEMaaCS)

and returns a JSON response (for exposing some useful error message to the user in case of errors). Also you can decide to block until the replication is done (via sync) or enable batch processing (via batch).

Both require obviously some glue code because they are not providing any dialog/ui functionality.

royteeuwen commented 3 weeks ago

Looking at the AEM code for making the dialog on quick publish, shouldnt be too hard to make the glue 😄

$(window).adaptTo("foundation-registry").register("foundation.collection.action.action", {
        name: "cq.wcm.quickpublish",
        handler: function(name, el, config, collection, selections) {
            var message = createEl("div");
            var intro = createEl("p").appendTo(message);
            if (selections.length === 1)
                intro.text(Granite.I18n.get("The page and their references will be published."));
            else
                intro.text(Granite.I18n.get("The {0} pages and their references will be published.", selections.length));
            var ui = $(window).adaptTo("foundation-ui");
            ui.prompt(QUICKPUBLISH_TITLE, message.html(), "notice", [{
                text: CANCEL_TEXT
            }, {
                text: PUBLISH_TEXT,
                primary: true,
                handler: function() {
                    activatePagesAndItsReferences(config, collection, selections)
                }
            }])
        }
    })

    // copy of part of the activation function:
    function activatePages() {
         $.ajax({
                    url: REPLICATE_URL,
                    type: "POST",
                    data: {
                        _charset_: "utf-8",
                        cmd: "Activate",
                        path: paths,
                        agentId: DEFAULT_REPLICATION_AGENT_ID
                    }
                }).always(function() {
                    ui.clearWait()
                }).done(function() {
                    var api = $(collection).adaptTo("foundation-collection");
                    if (api && "reload"in api) {
                        api.reload();
                        ui.notify(null, getSuccessMessage(selections));
                        return
                    }
                    var contentApi = $(".foundation-content").adaptTo("foundation-content");
                    if (contentApi)
                        contentApi.refresh();
                    ui.notify(null, getSuccessMessage(selections))
                }).fail(function(xhr) {
                    var title = Granite.I18n.get("Error");
                    var message = Granite.I18n.getVar($(xhr.responseText).find("#Message").html());
                    ui.alert(title, message, "error")
                })
}