Message-ID: <1837235317.3784.1485855328248.JavaMail.confluence@ip-10-127-227-164> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_3783_311964086.1485855328248" ------=_Part_3783_311964086.1485855328248 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html Define a View

Define a View

=20
=20
=20
=20

Views in PlatformUI

Each route defines a View to render when the route is matched. As explai= ned in the Platf= ormUI technical introduction, this kind of view is called a Mai= n View. Like any view, it can have an arbitrary number of sub-view= s.

Good practice: keep the views small and do not hesitate= to create sub-views. This eases the maintenance and allows you to reuse th= e small sub-views in different context.

A View is responsible for generating the User Interface and handling the= user input (click, keyboard, drag and drop, etc.). In its lifecycle, a vie= w first receives a set of parameters, then it is rendered and added to DOM.=

PlatformUI reuses the YUI View= system. Y.View is designed to be a very simple component.= PlatformUI extends this concept to have views with more features like temp= lates or asynchronous behavior.

Creating and using a= custom Main View

Creating a new View

As for the plugin in the previous step, the first thing to do is to decl= are a new module in the extension bundle yui.yml file:


New module in yui.yml
=20
ezconf-listview:
    requires: ['ez-view']
    path: %extending_platformui.public_dir%/js/views/ezconf-listview.js=20

Our basic view will extend the PlatformUI basic view which is available = in the ez-view module. As a result, ez-view has t= o be added in the module requirements.

Then we have to create the corresponding module file. In this file, we'l= l create a new View component by extending Y.eZ.View provided = by ez-view.

%extending_platformui.public_dir%/js/views/ezconf-listview.js
=20
YUI.add('ezconf-listview', function (Y) {
    Y.namespace('eZConf');

    Y.eZConf.ListView =3D Y.Base.create('ezconfListView', Y.eZ.View, [], {
        initializer: function () {
            console.log("Hey, I'm the list view");
        },

        render: function () {
            // this.get('container') is an auto generated <div>
            // here, it's not yet in the DOM of the page and it will be add=
ed
            // after the execution of render().
            this.get('container').setContent(
                "Hey, I'm the listView and I was rendered it seems"
            );
            this.get('container').setStyles({
                background: '#fff',
                fontSize: '200%',
            });
            return this;
        },
    });
});
=20

This code creates the Y.eZConf.ListView by extending = Y.eZ.View. The newly created view component has a custom rende= r method. As its name suggests, this method is called when the view = needs to be rendered. For now, we are directly manipulating the DOM. = this.get('container') in a View allows you to retrieve the container= DOM node, it's actually a Y.Node instance that is autom= atically created and added to the page when the View is needed in the appli= cation.

A View is responsible for handling only what happens in its own containe= r. While it's technically possible, it is a very bad practice for a View to= handle anything that is outside its own container.

At this point, if you open/refresh PlatformUI in your browser, nothing w= ill have really changed, because the newly added View is not used anywhere = yet.

Using it as a Main View

Now that we have a View, it's time to change the route configuration add= ed in the previous step so that our custom route uses it. To do that, we'll= have to change the application plugin to register the new view as a main v= iew in the application and then to define the custom route with that view. = Since we want to use the new view in the plugin, the ezconf-listview<= /code> module becomes a dependency of the plugin module. The plugin module = declaration becomes:

=20
ezconf-listapplugin:
    requires: ['ez-pluginregistry', 'plugin', 'base', 'ezconf-listview'] # =
we've added 'ezconf-listview'
    dependencyOf: ['ez-platformuiapp']
    path: %extending_platformui.public_dir%/js/apps/plugins/ezconf-listappp=
lugin.js
=20

Then in the plugin, Y.eZConf.ListView becomes available; we= can register it as a potential main view and change the route to use it:

ezconf-listappplugin.js
=20
YUI.add('ezconf-listapplugin', function (Y) {
    Y.namespace('eZConf.Plugin');

    Y.eZConf.Plugin.ListAppPlugin =3D Y.Base.create('ezconfListAppPlugin', =
Y.Plugin.Base, [], {
        initializer: function () {
            var app =3D this.get('host'); // the plugged object is called h=
ost

            console.log("Hey, I'm a plugin for PlatformUI App!");
            console.log("And I'm plugged in ", app);

            console.log('Registering the ezconfListView in the app');
            app.views.ezconfListView =3D {
                type: Y.eZConf.ListView,
            };

            console.log("Let's add a route");
            app.route({
                name: "eZConfList",
                path: "/ezconf/list",
                view: "ezconfListView", // because we registered the view i=
n app.views.ezconfListView
                sideViews: {'navigationHub': true, 'discoveryBar': false},
                callbacks: ['open', 'checkUser', 'handleSideViews', 'handle=
MainView'],
            });
        },
    }, {
        NS: 'ezconfTypeApp' // don't forget that
    });

    Y.eZ.PluginRegistry.registerPlugin(
        Y.eZConf.Plugin.ListAppPlugin, ['platformuiApp']
    );
});
=20

After doing that, /ez#/ezconf/list should no longer display= the dashboard, but you should see the message generated by Y.eZConf.= ListView.

Using a template

Manipulating the DOM in a view render method is fine for small changes b= ut not very handy as soon as you want to generate a more complex UI. It's a= lso a great way to separate pure UI/markup code from the actual view logic.=

In PlatformUI, most views are using a template to generate their own mar= kup, those templates are interpreted by the Handlebars= .js template engine embed into YUI.

The templates are made available in the application by defining them as = modules in yui.yml. The template modules are a bit special tho= ugh. To be recognized as a template and correctly handled by the applicatio= n, a template module has a type property that should be set to= template. Also, to get everything ready automatically, the module name should follow a naming convention. The module name shoul= d consist of the lowercase View internal name (the first Y.Base.= create parameter) where the template is supposed to be used followed= by the suffix -ez-template. In our case, the internal name of= Y.eZConf.ListView is ezconfListView, so if we wa= nt to use a template in this view, the module for this template should be <= code>ezconflistview-ez-template. The template module must also be ad= ded as a dependency of the view module using it (ezconf-listview in this case). As a result, the modules declaration for the template and= the view will be:

=20
ezconf-listview:
    requires: ['ez-templatebasedview', 'ezconflistview-ez-template']
    path: %extending_platformui.public_dir%/js/views/ezconf-listview.js
ezconflistview-ez-template: # internal view name + '-ez-template' suffix
    type: 'template' # mandatory so that the template is available in JavaS=
cript
    path: %extending_platformui.public_dir%/templates/ezconflistview.hbt=20

In yui.yml, we also have to change the ezconf-listvie= w module to now require ez- templatebasedview instead of ez-view so = that Y.eZConf.ListView can inherit from Y.eZ.Templa= teBasedView instead of Y.eZ.View. Once that is in place, the rendering logic can be changed to use= the template:

=20
YUI.add('ezconf-listview', function (Y) {
    Y.namespace('eZConf');

    Y.eZConf.ListView =3D Y.Base.create('ezconfListView', Y.eZ.TemplateBase=
dView, [], { // Y.eZ.TemplateBasedView now!
        initializer: function () {
            console.log("Hey, I'm the list view");
        },

        render: function () {
            // when extending Y.eZ.TemplateBasedView
            // this.template is the result of the template
            // compilation, it's a function. You can pass an object
            // in parameters and each property will be available in the tem=
plate
            // as a variable named after the property.
            this.get('container').setHTML(
                this.template({
                    "name": "listView"
                })
            );
            this.get('container').setStyles({
                background: '#fff',
                fontSize: '200%',
            });
            return this;
        },
    });
});
=20

And the last part of the chain is the Handlebars template file itself:

ezconflistview.hbt
=20
<h1 class=3D"ezconf-list-title">List view</h1>

Hey, I'm the {{ name }} and I'm rendered with the template!
=20

At this point, /ez#/ezconf/list should display the  <= span class=3D"x x-first x-last"> Y.eZConf.ListView rendered with the template.

Adding a CSS

We've just moved the markup logic from the view component to a template = file. It is also time to do the same for the CSS styles that are still in t= he render method. For that, a CSS file can be created on the d= isk to replace the inline styles:

list.css
=20
.ez-view-ezconflistview {
    background: #fff;
}

.ez-view-ezconflistview .ezconf-list-title {
    margin-top: 0;
}
=20

By default, a view container element has an auto-generated class built f= rom the internal view name.

Good practice: using that auto-generated class to write= the CSS rule greatly limits the risk of side effects when styling a view.<= /p>

 

Then this file has to be listed in the extension bundle css.yml configuration file:

css.yml
=20
system:
    default:
        css:
            files:
                - %extending_platformui.css_dir%/views/list.css
=20

After this is done, a custom view is now used when reaching /ez#/e= zconf/list and the UI is now styled with a custom external styleshee= t.

Results and next step:

The resulting code can be seen in the 4_view tag on GitHub, this step result can also be= viewed as a diff between tags 3_routing and 4_view .

The next step is then to configure the navigation so that user can easily reach the new= page.

=20
=20
=20
=20
Tutorial path
=20

=20
    =20
    =20
    =20
=20
=20 =20 = =20 =20 =20 =20 =20 =20 =20 = =20 =20 =20 =20 =20
=20 =20
=20
=20
=20

=20
=20
=20
=20
------=_Part_3783_311964086.1485855328248--