Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The flickr-simple-browser module is an example of how to build a custom content app. The module installs an app that allows you to browse photos on Flickr. We use a String as ItemId, which is easy to implement but has the disadvantage that we cannot tell the difference between photos and albums. This example also shows how to use an external Web service as the data source. The list view and the thumbnail view use the same Container coupled to a 

Javadoc resource link
rangeHigherVersion6.0
classNameinfo.magnolia.ui.vaadin.integration.contentconnector.ContentConnector
renderTypeasynchronous
. See also Content app with an Object ItemId and different containers for an example of a hierarchical container.

...

flickr-simple-browser

required

App

subAppssubapps

required


browser

required

Subapp

class

required

Javadoc
0info.magnolia.ui.contentapp.browser.BrowserSubAppDescriptor
rangeHigherVersion6.0
classNameinfo.magnolia.ui.contentapp.browser.BrowserSubAppDescriptor
renderTypeasynchronous

subAppClass

required

Javadoc
0info.magnolia.ui.contentapp.browser.BrowserSubApp

appClass

rangeHigherVersion

required

6.0
className
Must be 
Javadoc
0info.magnolia.ui.contentapp.ContentApp
 or a subclass
browser.
BrowserSubApp
renderTypeasynchronous

appClass

required

Must be 

Javadoc resource link
0info.magnolia.ui.contentapp.ContentApp
rangeHigherVersion6.0
classNameinfo.magnolia.ui.contentapp.ContentApp
renderTypeasynchronous
 or a subclass.

For the For the details of contentConnector, workbench and imageProvider definition, see below.

...

An Item has properties and every property is identified by its property ID. Define the properties in an interface. In this module we define the interface 

Javadoc
0info.magnolia.flickr.simplebrowser.app.item.SimpleFlickrItem
rangeHigherVersion1.0
classNameinfo.magnolia.flickr.simplebrowser.app.item.SimpleFlickrItem
renderTypeasynchronous
.

Code Block
languagejava
titleinfo.magnolia.flickr.simplebrowser.app.item.SimpleFlickrItem
public interface SimpleFlickrItem extends BasicFlickrItem {

}

The interface extends 

Javadoc
0info.magnolia.flickr.app.item.BasicFlickrItem
rangeHigherVersion1.2
classNameinfo.magnolia.flickr.app.item.BasicFlickrItem
renderTypeasynchronous
 in the  flickr-integration  module which is the basic item interface that other submodules extend.  SimpleFlickrItem  has no other properties.

...

The implementation class allows us to handle a set of identified properties. 

Javadoc
0info.magnolia.flickr.simplebrowser.app.item.SimpleFlickrPropertysetItem
rangeHigherVersion1.2
classNameinfo.magnolia.flickr.simplebrowser.app.item.SimpleFlickrPropertysetItem
renderTypeasynchronous
 extends PropertysetItem, one of the implementations provided by Vaadin.

...

  • getItemUrlFragment(Object itemId) (see line 16) and getItemIdByUrlFragment(String urlFragment) (see line 20) methods can return their input parameters since our ItemId is a string and the URL fragment and the ItemId are identical in this simple example.
  • getDefaultItemId() method does not need to be implemented. It can return null. But since FlickrService provides a default photo we implement the method. In some cases it is helpful to work with a default item.
  • canHandle() should reject invalid ItemIds. The app could fire an event with an ID / and the event would be handled by the ContentConnector but there is no Flickr photo with the ID /.
  • The 
    Javadoc
    0info.magnolia.flickr.app.flickrservice.FlickrService
     interface is injected in the constructor. FlickrService is instantiated by
    rangeHigherVersion1.2
    className
    Javadoc
    0info.magnolia.flickr.app.flickrservice.FlickrServiceProvider
     which is
    FlickrService
    renderTypeasynchronous
     interface is injected in the constructor. FlickrService is instantiated by
    Javadoc resource link
    0info.magnolia.flickr.app.flickrservice.FlickrServiceProvider
    rangeHigherVersion1.2
    classNameinfo.magnolia.flickr.app.flickrservice.FlickrServiceProvider
    renderTypeasynchronous
     which is registered in the flickr-integration module.

...

Every subapp must configure its own content connector. The 

Javadoc
0info.magnolia.flickr.simplebrowser.app.contentconnector.ConfiguredSimpleFlickrBrowserContentConnectorDefinition
 class extends  Javadoc0
rangeHigherVersion1.2
classNameinfo.magnolia.
ui
flickr.
vaadin
simplebrowser.
integration
app.contentconnector.
ConfiguredContentConnectorDefinition and sets the implementation class  javadoc
ConfiguredSimpleFlickrBrowserContentConnectorDefinition
renderTypeasynchronous
 class extends 
Javadoc resource link
0info.magnolia.ui.vaadin.integration.contentconnector.ConfiguredContentConnectorDefinition
rangeHigherVersion6.0
classNameinfo.magnolia.ui.vaadin.integration.contentconnector.ConfiguredContentConnectorDefinition
renderTypeasynchronous
 and
 sets the implementation class 
Javadoc
0info.magnolia.flickr.simplebrowser.app.contentconnector.SimpleFlickrBrowserContentConnectorImpl
.

Localtab Group
Localtab
activetrue
titleYAML
Code Block
languagejs
browser:
  contentConnector:
    class: info.magnolia.flickr.simplebrowser.app.contentconnector.ConfiguredSimpleFlickrBrowserContentConnectorDefinition
Localtab
titleJCR node
Advanced Tables - Table Plus
heading0
multiplefalse
enableHeadingAttributesfalse
enableSortingfalse
classm5-configuration-tree
enableHighlightingfalse
Node nameValue

Mgnl n
browser


Mgnl n
contentConnector


Mgnl p
class

info.magnolia.flickr.simplebrowser.app.contentconnector.ConfiguredSimpleFlickrBrowserContentConnectorDefinition

Javadoc
0info.magnolia.ui.contentapp.contentconnector.ContentConnectorProvider
rangeHigherVersion6.0
classNameinfo.magnolia.ui.contentapp.contentconnector.ContentConnectorProvider
renderTypeasynchronous
 creates and provides only one instance of  SimpleFlickrBrowserContentConnector  in our subapp. The content connector can be injected into any class used within the subapp. You can cast it to your own type if required.

...

We use the same container for the tree view and the thumbnail view. In this case it would be sufficient to implement just the base interface Container. However, we also implement 

Javadoc
0info.magnolia.ui.workbench.container.Refreshable
rangeHigherVersion6.0
classNameinfo.magnolia.ui.workbench.container.Refreshable
renderTypeasynchronous
 so we can use the refresh mechanism in the Magnolia workbench. We also need the Container.Indexed subinterface for lazy loading.

...

In the presenter class, extend 

Javadoc
0info.magnolia.ui.workbench.thumbnail.ThumbnailPresenter
rangeHigherVersion6.0
classNameinfo.magnolia.ui.workbench.thumbnail.ThumbnailPresenter
renderTypeasynchronous
 and initialize the container:

...

To improve the performance, we could use a POJO as an ItemId. We do so in the second tutorial  Content app with an Object ItemId and different containers . Alternatively, extend javadoc

Code Block

...

0info.magnolia.ui.workbench.thumbnail.ThumbnailContainer

...

languagejava
title

...

info.magnolia.

...

flickr.

...

simplebrowser.

...

app.

...

imageprovider.

...

SimpleFlickrBrowserPreviewImageProvider
collapsetrue
Code Block
languagejava
titleinfo.magnolia.flickr.simplebrowser.app.imageprovider.SimpleFlickrBrowserPreviewImageProvider
collapsetrue
public class SimpleFlickrBrowserPreviewImageProvider implements ImageProvider {


    private final FlickrService flickrService;

    @Inject
    public SimpleFlickrBrowserPreviewImageProvider(FlickrService flickrService) {
        this.flickrService = flickrService;
    }

    @Override
    public String getPortraitPath(Object itemId) {
        return null;
    }

    @Override
    public String getThumbnailPath(Object itemId) {
        return null;
    }

    @Override
    public String resolveIconClassName(String mimeType) {
        return null;
    }

    @Override
    public Object getThumbnailResource(Object itemId, String generator) {
        Resource resource = null;

        if (itemId instanceof String) {
            String photoId = (String) itemId;
            if (StringUtils.isNotBlank(photoId)) {
 /** * To grep data from flickr          /**
                 * To grep data from flickr API here is very costly - since a thumbnail container could call this method here many 100s100 of times.
                 * Here it would make sense to add the smallUrl as a property of a more sophisticated ItemId
 */ Photo photo = flickrService.getPhoto(photoId); if (photo != null) { String smallPicUrl = photo.getSmallUrl(); if (StringUtils.isNotBlank(smallPicUrl)) {  */
                Photo photo = flickrService.getPhoto(photoId);
                if (photo != null) {
                    String smallPicUrl = photo.getSmallUrl();
                    if (StringUtils.isNotBlank(smallPicUrl)) {
                        resource = new ExternalResource(smallPicUrl);
                    }
                }
            }
        }
        return resource;
    } 
}

Anchor
Creating and configuring an image provider-
Creating and configuring an image provider-
Configuration

...