Migrating an app to Magnolia 6 UI
This page provides a step-by-step guide to migrating an app from Magnolia 5 to Magnolia 6 UI. The following example shows how to migrate the Tours app, but you can use this information to migrate other apps as well.
| Most configuration snippets are used in already migrated apps. For some
examples, see  | 
| A large number of classes have been replaced or deleted, with many
definition converters introduced for easier migration. See changes-in-magnolia-6-ui.csvfor a full list of changes. | 
I. Maven module
- 
Create a new module next to the Magnolia 5 UI app module for easy comparison during development. mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate -DarchetypeCatalog=https://nexus.magnolia-cms.com/repository/public/
- 
Set the new module as a light module in the magnolia.propertiesfile of your webapp.WEB-INF/config/default/magnolia.properties... magnolia.resource.dir=<user-path>/git/demo-projects/community/magnolia-travel-tours-app/src/main/resources ...
- 
Start the webapp. 
II. App descriptor
- 
Create an app descriptor file. 2020-06-26 08:36:21,622 INFO magnolia.config.source.yaml.YamlConfigurationSource: Registered definition from YAML file [/magnolia-travel-tours-app/apps/tours-app.yaml]: [app] definition [tours-app] with reference id: [tours-app] from module [magnolia-travel-tours-app] at [tours-app]Refresh AdminCentral and check that the app is added to the App launcher. To hide the Magnolia 5 UI app, add it to /modules/ui-admincentral/config/appLauncherLayout/hiddenApps.
- 
Define the app descriptor. Open an already migrated app descriptor on the side, so you can directly copy from it. Do not download the Magnolia 5 UI definition as YAML and rewrite it. This is more error-prone and difficult to debug. Minimal app descriptorclass: info.magnolia.ui.contentapp.configuration.ContentAppDescriptor appClass: info.magnolia.ui.framework.app.BaseApp datasource: $type: jcrDatasource workspace: tours subApps: browser: class: info.magnolia.ui.contentapp.configuration.BrowserDescriptor workbench: contentViews: - name: tree $type: treeView columns: - name: jcrName actionbar: sections: - name: folderNow is a good time to learn more about workbench, content view and column definitions. 
- 
After defining the app descriptor: - 
Read the logs. 2020-06-26 10:07:21,634 WARN magnolia.config.source.yaml.YamlConfigurationSource: 0 major and 1 minor problems have been encountered
- 
Check the Definitions app for possible problems. Keep the Definitions app running in another tab, so you do not have to switch between apps. 
 
- 
III. Detail subapp
- 
Define an edit action. Edit actionactions: edit: $type: openDetailSubappAction appName: tours-app subAppName: detail viewType: edit
- 
Define a detail subapp. Minimal detail subappdetail: class: info.magnolia.ui.contentapp.detail.DetailDescriptor itemProvider: $type: jcrNodeFromLocationProvider workspace: tours nodeType: mgnl:tour form: properties: jcrName: $type: textField
IV. Custom action
The following definitions in both frameworks will produce the same results.
public class AddNodeAction extends AbstractAction<AddNodeActionDefinition> {
    public AddNodeAction(AddNodeActionDefinition definition, JcrItemAdapter item, @Named(AdmincentralEventBus.NAME) EventBus eventBus) {
        super(definition, item, eventBus);
    }
    @Override
    protected void onExecute(JcrItemAdapter item) throws RepositoryException {
        if (item.getJcrItem().isNode()) {
            Node node = (Node) item.getJcrItem();
            Node newNode = node.addNode("untitled");
            item.getJcrItem().getSession().save();
            // Resolve item id for the newly created node and pass it on as a modified one
            JcrItemId newItemId = JcrItemUtil.getItemId(newNode);
            eventBus.fireEvent(new ContentChangedEvent(newItemId));
        }
    }
}public class AddNodeAction extends AbstractAction<AddNodeActionDefinition> {
    @Inject
    public AddNodeAction(AddNodeActionDefinition definition, ValueContext<Node> item) {
        super(definition, item, eventBus);
    }
    @Override
    protected void execute() {
            Node node = valueContext.getSingleOrThrow();
            Node newNode = node.addNode("untitled");
            newNode.getSession().save();
        }
    }
}Magnolia 6 UI does not have Vaadin 7 Item abstraction. You can now
work with actual items (for example, JCR nodes):
- 
Inject ValueContext<Node>instead ofJcrNodeAdapter.
- 
Use Session#saveinstead ofJcrItemAdapter#applyChanges.
In addition, ContentChangedEvent is no longer needed. Magnolia 6 UI
has an observation mechanism that refreshes the grid on changes for all
UI users.
| Inject   |