Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
HTML Wrap
floatright
classmenu decimal

In this tutorial:

Children Display
pageDOCS57:Creating a custom content app

...

  1. Container wraps the data of the data source. It provides methods to get items by their ID, to get all Items, to get all itemIds and so on. Every Container must implement at least the Container interface.
  2. ItemId is the key to get an item. Vaadin doesn't type the itemId. It is just an object. A simple itemId could be a string. In some cases an itemId is a POJO with its own properties, for example 

    Javadoc
    0info.magnolia.ui.vaadin.integration.jcr.JcrItemId
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.vaadin.integration.jcr.JcrItemId
    renderTypeasynchronous
    . itemIds are sent by events.

  3. Item is comparable to a row in a database table; it must implement the Vaadin Item interface. An item contains a set of properties and offers methods to add, modify and remove the properties.
    Every property is identified by a property ID. The property ID is not typed either, it is just an object, usually a string. Use the property ID to configure columns in the content view.
  4. Property is the Vaadin interface for a item property. A property has a value and a type.

...

  • Write methods of the Container interface are not required when running in the content app. 

  • If you want to manipulate data - add, edit, delete - do not manipulate Container items. Instead, create actions that interact directly with the data source. After an action is executed, the view and its underlying Container are refreshed automatically if the Container implements
    Javadoc
    0info.magnolia.ui.workbench.container.Refreshable
    rangeHigherVersion5.
    7
    classNameinfo.magnolia.ui.workbench.container.Refreshable
    renderTypeasynchronous
    .
  • Create a fully customized Container or extend a Create a fully customized Container or extend a concrete implementation provided by Vaadin or Magnolia.
  • When creating a fully custom Container, implement "empty" write methods, they are not required.

    Expand
    titleClick to see the example of an "empty" method
    Code Block
    @Override
    public Object addItem() throws UnsupportedOperationException {
        throw new UnsupportedOperationException("addItem is not supported!");
    }

...

  • The Container interface is mandatory.
  • A Container of a tree view additionally requires at least Container.Hierarchical. Implementing Collapsible is not mandatory but helpful in a custom tree Container.
  • For lazy loading behavior implement also Container.Indexed.
  • Implementing 
    Javadoc
    0info.magnolia.ui.workbench.container.Refreshable
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.workbench.container.Refreshable
    renderTypeasynchronous
     is optional but recommended.

...

  • An ItemId must be unique within a Container.
  • The itemId must carry enough information to fetch data from the data source to instantiate its corresponding Item. This is required in the context of ContentConnector. For example
    Javadoc resource link
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.vaadin.integration.contentconnector.ContentConnector
    renderTypeasynchronous
    . For exampleJcrItemId is a plain Java object that carries two properties: uuid and workspace. These two properties are sufficient to get data from a JCR repository given that there is access to a Session.
  • It must be possible to get an ItemId by a given Item in the context of ContentConnector.of
    Javadoc resource link
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.vaadin.integration.contentconnector.ContentConnector
    renderTypeasynchronous
    .

What is a good ItemId? What is a good ItemId? String or POJO?

A String is a very simple and easy implementation for an ItemId. If your data source provides a unique String which is sufficient to build the corresponding item by querying the data source using only the String, then a String as ItemId is fine. However, if you must concatenate a String to build a unique itemId you should rather implement a plain Java object (POJO) for the ItemId.

...

  • Javadoc
    0info.magnolia.ui.workbench.ContentPresenter
     
    implementation Javadoc0
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.workbench.
    definition.ConfiguredContentPresenterDefinition
    ContentPresenter
    renderTypeasynchronous
     
    implementation  implementation
  • Javadoc resource link
    0info.magnolia.ui.workbench.definition.ConfiguredContentPresenterDefinition
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.workbench.definition.ConfiguredContentPresenterDefinition
    renderTypeasynchronous
     implementation 

A content view A content view is rendered by the content presenter which must be configured separately for each view. The data rendered on the view is provided by the Container. The presenter instantiates a suitable Container. 

...

  1. ContentPresenter for every content view in a content app. 
    1. class property
    2. columns node for configuring columns
  2. Javadoc
    0info.magnolia.ui.workbench.definition.ContentPresenterDefinition
     to set
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.workbench.definition.ContentPresenterDefinition
    renderTypeasynchronous
     to set the implementation class of the custom content presenter.
  3. ContentPresenter that extends
    Javadoc
    0info.magnolia.ui.workbench.AbstractContentPresenterBase
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.workbench.AbstractContentPresenterBase
    renderTypeasynchronous
    or one of its subclasses. Connected to a Container. Must implement the AbstractContentPresenterBase#initializeContainer method.
  4. Container that is bound to the content presenter.

...

Localtab Group
Localtab
activetrue
titleJCR node
Advanced Tables - Table Plus
heading0
multiplefalse
enableHeadingAttributesfalse
enableSortingfalse
classm5-configuration-tree
enableHighlightingfalse
Node nameValue

Mgnl n
contentViews

 


Mgnl n
columns

 

Mgnl n
title

 

Mgnl p
class

info.magnolia.flickr.app.contentview.FlickrBrowserItemColumnDefinition

Mgnl p
formatterClass

info.magnolia.flickr.app.contentview.FlickrBrowserItemColumnFormatter

Mgnl p
propertyName

title
Localtab
titleYAML
Code Block
languagejs
contentViews:
  columns:
    - name: title
      class: info.magnolia.flickr.app.contentview.FlickrBrowserItemColumnDefinition
      formatterClass: info.magnolia.flickr.app.contentview.FlickrBrowserItemColumnFormatter
      propertyName: title

...

<column name>

required

The name of a column is arbitrary, however, it makes sense to use the same or similar name as the propertyName.

class

required

A definition class which must extend 

Javadoc
0info.magnolia.ui.workbench.column.definition.AbstractColumnDefinition
rangeHigherVersion5.7
classNameinfo.magnolia.ui.workbench.column.definition.AbstractColumnDefinition
renderTypeasynchronous
.

formatterClass

required

A formatter class which must extend 

Javadoc
0info.magnolia.ui.workbench.column.AbstractColumnFormatter
rangeHigherVersion5.7

propertyName

required

Must be equal to a Container property ID.

classNameinfo.magnolia.ui.workbench.column.AbstractColumnFormatter
renderTypeasynchronous
.

propertyName

required

Must be equal to a Container property ID.

For all properties see Column definition.

...

When the user selects an item in a content app a 

Javadoc
0info.magnolia.ui.workbench.event.SelectionChangedEvent
rangeHigherVersion5.7
classNameinfo.magnolia.ui.workbench.event.SelectionChangedEvent
renderTypeasynchronous
 is fired. The event carries the ID of the selected item. The event leads to a change in the 
Javadoc
0info.magnolia.ui.contentapp.browser.BrowserLocation
rangeHigherVersion5.7
classNameinfo.magnolia.ui.contentapp.browser.BrowserLocation
renderTypeasynchronous
 object of the subapp. That's why the URL fragment methods are required.

...

Info
iconfalse
titleBest practice
Multiexcerpt
MultiExcerptNameMake Container instance available in ContentConnector

Make the Container instance available in your ContentConnector. This makes it easier to implement item and itemId related methods. This works only if you have only one Container per subapp. If you need more Containers you must decouple the Container and the ContentConnector.

Configure and register a ContentConnector

...

  1. Implement 
    Javadoc
    0info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector
    rangeHigherVersion5.
    Create an interface which extends
    7
    className
    Javadoc
    0info.magnolia.ui.vaadin.integration.contentconnector.ContentConnectorDefinition
    , for example FlickrBrowserContentConnectorDefinition.
    ContentConnector
    renderTypeasynchronous
    .
  2. Create an interface which extends
    Javadoc resource link
    0info.magnolia.ui.vaadin.integration.contentconnector.ContentConnectorDefinition
    rangeHigherVersion5.7
    classNameinfo.magnolia.ui.vaadin.integration.contentconnector.ContentConnectorDefinition
    renderTypeasynchronous
    , for example FlickrBrowserContentConnectorDefinition.
  3. Create a class which implements your interface and extends
    Javadoc resource link
    0info.magnolia.ui.vaadin.integration.contentconnector.ConfiguredContentConnectorDefinition
    rangeHigherVersion5.7
    className
    Create a class which implements your interface and extends
    Javadoc
    0info.magnolia.ui.vaadin.integration.contentconnector.ConfiguredContentConnectorDefinition
    renderTypeasynchronous
    . Set the implementation class.
  4. Configure the connector in the subapp:

    Localtab Group
    Localtab
    activetrue
    titleJCR node
    Advanced Tables - Table Plus
    heading0
    multiplefalse
    enableHeadingAttributesfalse
    enableSortingfalse
    classm5-configuration-tree
    enableHighlightingfalse
    Node nameValue

    Mgnl n
    <subapp>

     

    Mgnl n
    contentConnector

     


    Mgnl n
    class

     info.magnolia.flickr.app.contentconnector.FlickrBrowserContentConnectorDefinition
    Localtab
    titleYAML
    Code Block
    languagejs
    <subapp>:
      contentConnector:
        class:      class:  info.magnolia.flickr.app.contentconnector.FlickrBrowserContentConnectorDefinition

Injecting the ContentConnector

Javadoc resource link
0ContentConnectorProvider
rangeHigherVersion5.7
classNameinfo.magnolia.

...

ui.

...

contentapp.contentconnector.

...

ContentConnectorProvider

Injecting the ContentConnector

renderTypeasynchronous
Javadoc
0ContentConnectorProvider
 creates one instance of the type of connector you set in ConfiguredContentConnectorDefinition. You can inject your ContentConnector into different classes wherever it is required. You will always get the same instance.

...

Note

Since your subapp implementation class is either 

Javadoc
0info.magnolia.ui.contentapp.browser.BrowserSubApp
rangeHigherVersion5.7
classNameinfo.magnolia.ui.contentapp.browser.BrowserSubApp
renderTypeasynchronous
or a subclass, your subapp already injects the ContentConnector.