Magnolia CMS: переименование страницы создает 404 при использовании модуля Urltrans

Модуль Urltrans помогает мне иметь интернационализированные URL, но единую иерархию.


В целом он работает хорошо, за исключением этого случая:

  1. Назад в Magnolia CMS admin central, в приложении pages, откройте страницу
  2. Допустим, я визуализирую страницу страница на немецком языке
  3. Откройте диалоговое окно Свойства страницы
  4. Изменение (локализованного) имени
  5. Сохранить
  6. 404 error message на вкладке «Просмотр страницы». Журнал говорит 2016-11-01 11:17:57,413 WARN info.magnolia.rendering.engine.RenderingFilter : Resource not found: [/<path>/<to>/<page>?mgnlPreview=false&mgnlChannel=desktop]

Это происходит просто потому, что страница, которую я сейчас пытаюсь увидеть в admin central, по-прежнему имеет «прежнее имя», следовательно, «бывший путь url», следовательно, страница, которая больше не существует.

Я нашел эту проблему, упомянутую в строке 51 UrltransSaveHandler.java (я думаю, что это то, что я имею в виду).

Любая идея, как я мог бы предотвратить это, например:

  • просто программно закрыть текущую Pages appвкладку при изменении имени страницы?
  • перенаправьте текущую вкладку на страницу с новым URL-путем
  • не разрешайте пользователям редактировать имя страницы из любого места, кроме Page app's browser
  • может быть, другое решение?

1 ответ

  1. Объяснение

    UrltransSaveHandler.java фактически не используется.

    Однако SaveDialogAction.javaон настроен в диалоговом окне Action Definitionon.

    Это соответствующее диалоговое окно (если вы не переопределили его): admincentral#app:configuration:browser;/modules/standard-templating-kit/dialogs/generic/master/basePageProperties:treeview:.

    SaveDialogAction.java звонит setNodeName(node, item)по line 81адресу .

    Этот метод очень похож на то, что происходило в line 51of UrltransSaveHandler.java: он делает » if (node's "name" property has changed?){rename node itself}«.


    Решение: в двух словах

    1. Создайте новыйAction Definition, который делает точно так же, как за SaveDialogActionисключением этого вызоваsetNodeName(node, item);, который происходит, только если родительский узел не имеет NodeType mgnl:variant
    2. Назначьте это новое ClassCommitдействию в соответствующей диалоговой конфигурации

    Класс определения действия

    package com.myproject.dialog;
    
    import info.magnolia.ui.admincentral.dialog.action.SaveDialogActionDefinition;
    import info.magnolia.ui.api.action.Action;
    
    public class MyProjectUrltransSaveActionDefinition extends SaveDialogActionDefinition {
    
        public MyProjectUrltransSaveActionDefinition() {
            setImplementationClass((Class<? extends Action>) MyProjectUrltransSaveAction.class);
        }
    
    }
    

    Класс action

    package com.myproject.dialog;
    
    import javax.jcr.Node;
    import javax.jcr.nodetype.NodeType;
    import javax.jcr.Property;
    import javax.jcr.RepositoryException;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.vaadin.data.Item;
    
    import info.magnolia.cms.core.Path;
    import info.magnolia.jcr.util.NodeUtil;
    import info.magnolia.ui.admincentral.dialog.action.SaveDialogAction;
    import info.magnolia.ui.api.action.ActionExecutionException;
    import info.magnolia.ui.form.EditorCallback;
    import info.magnolia.ui.form.EditorValidator;
    import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
    import info.magnolia.ui.vaadin.integration.jcr.ModelConstants;
    
    
    public class MyProjectUrltransSaveAction<T extends MyProjectUrltransSaveActionDefinition> extends SaveDialogAction {
    
        private static final Logger log = LoggerFactory.getLogger(MyProjectUrltransSaveAction.class);
    
        public MyProjectUrltransSaveAction(T definition, Item item, EditorValidator validator, EditorCallback callback) {
            super(definition, item, validator, callback);
        }
    
        public void execute() throws ActionExecutionException {
            if (validateForm()) {
                final JcrNodeAdapter item = (JcrNodeAdapter) this.item;
                try {
                    final Node node = item.applyChanges();
                    final Node parentNode = node.getParent();
                    final String parentNodeType = parentNode.getPrimaryNodeType().getName();
                    if(!parentNodeType.equals("mgnl:variant")){
                        setNodeName(node, item);
                    }
                    node.getSession().save();
                } catch (final RepositoryException e) {
                    throw new ActionExecutionException(e);
                }
                callback.onSuccess(getDefinition().getName());
            }
        }
    
        /**
         * Set the node Name.
         * Node name is set to: <br>
         * the value of the property 'name' if it is present.
         */
        protected void setNodeName(Node node, JcrNodeAdapter item) throws RepositoryException {
            String propertyName = "name";
            if (node.hasProperty(propertyName) && !node.hasProperty(ModelConstants.JCR_NAME)) {
                Property property = node.getProperty(propertyName);
                String newNodeName = property.getString();
                if (!node.getName().equals(Path.getValidatedLabel(newNodeName))) {
                    newNodeName = Path.getUniqueLabel(node.getSession(), node.getParent().getPath(), Path.getValidatedLabel(newNodeName));
                    item.setNodeName(newNodeName);
                    NodeUtil.renameNode(node, newNodeName);
                }
            }
        }
    
    }