How Type and Name attributes affect Sugar 7 Views

Post originally written by Joo Lee.

Sugar 7 allows you to define your own view metadata for creating new custom layouts and views.  In these custom view definitions, the correct use of the type and name attributes is essential when you want to reuse metadata, controllers, or templates from other Sidecar components. But what are type and name?  How are they used? In this post, we hope to provide you a better understanding of these attributes and how they are used by Sidecar when your components get created.  Most importantly, this post will serve as a guide for the correct use of type and name in your Sugar 7 view metadata that will maximize your ability to reuse.

Read more below!

Review of Basic Components

There are three basic Sidecar components in Sugar 7 user interfaces: layout, view, and field. A layout contains views and other layouts. It is primarily used to lay out various components of a page. For a simple application, a layout should be lightweight. It should create and define other components and nothing else. A view is where most of the work happens. It is also where fields are created and are defined.

Components consist of three parts: definition, controller, and templates. Component definition specifies the components to be created and its customizable attributes. Controller adds behavior and logic to components via JavaScript. Templates provide HTML to the component through Handlebars template engine.

For more information, you can read about layouts, views, and fields in the Sugar 7.5 Developer Guide.

Component Definition

There are two ways to create and define your components. The first is to reference an existing component definition. The second is to specify it directly in your component.

Layout example

foo.php

$viewdefs['base']['layout']['foo'] = array(
   'components' => array(
      array(
         'layout' => 'header', //reference another definition
      ),
      array(
         'layout' => array( //directly include definition
            'components' => array(
               array(
                  'view' => 'title', //reference another definition
               ),
               array(
                  'view' => 'content', //reference another definition
               ),
            ),
            'type' => 'base',
            'name' => 'my-custom-main',
         ),
      ),
   ),
   'type' => 'foo',
   'name' => 'my-custom-page'
),

In the above example, the layout definition tells the application that this is a “foo” layout and the name is “my-custom-page.” It directly defines “header” and “base” layouts. For the “header” layout, the application gets the definition from “header” layout to create its components. The “base” layout, which is defined directly, has two views “title” and “content.” These two views are referenced like the “header” layout. So, the application will retrieve these definitions from the two views to create them.

View example

foo.php

$viewdefs['base']['view']['foo'] = array(
   'buttons' => array( //directly include definition
      array(
         'type' => 'button',
         'name' => 'cancel',
      ),
      array(
         'type' => 'button',
         'name' => 'save',
      ),
   ),
),

In the above example, the view definition indicates that this is a "foo" view, and it has two buttons: cancel and save.  The two buttons, which are defined directly, are fields with type "button" with one named "cancel" and the other "save."

Component Controllers

Both the type and name attributes are used to determine which JavaScript controller is used for a particular component.

For all component types, when the type attribute is set then it is used to select the JavaScript controller to initialize.  For views and layouts, if type attribute does not exist then the name attribute is then used. For fields, only the type attribute is examined.

Layout example

foo.php

$viewdefs['base']['layout']['foo'] = array(
   'components' => array(),
   'type' => 'foo',
),

In the above example, since "foo" layout has type attribute specified, the application will use the "foo" layout JavaScript controller.

View example

foo.php

$viewdefs['base']['view']['foo'] = array(
   'buttons' => array(
      array(
         'type' => 'button',
         'name' => 'save',
      ),
   ),
   'name' => 'bar',
),

In the above example, "foo" view does not have type attribute. So, it will look at the name attribute to get the JavaScript controller. For the button inside "foo" view, JavaScript controller for button field is used.

Component Templates

The type and name attributes also affect which HTML templates are used.

For both layouts and views, the application uses the name attribute to select the HTML template. If that template does not exist, it uses the type attribute. For views only, the template attribute can be used to specify which template to use. For fields, the template is determined by the type attribute but also a variety of other factors such as user ACL, current action, and the name of the parent view.

Layout example

foo.php

$viewdefs['base']['layout']['foo'] = array(
   'components' => array(),
   'type' => 'foo',
   'name' => 'bar',
),

In the above example, "foo" layout will use "bar" template in "foo" layout. If the template does not exist, it will use "foo" template.

View example

foo.php

$viewdefs['base']['view']['foo'] = array(
   'buttons' => array(),
   'type' => 'foo',
   'name' => 'bar',
   'template' => 'detail',
),

In the above example, "foo" view will use "detail" template in "foo" view. If that template does not exist, "bar" template will be used. If "bar" template does not exist, it will use "foo" template.

Best Practices

  • For clarity, specify both type and name attributes when specifying your view definitions.
  • When referencing another view or layout in your definition, use the name attribute only.

  • For views and layouts, type and name attributes should have the same value in most cases. In cases where type and name attributes need to differ, please note that the component will use the name attribute to determine its metadata, the type attribute to determine its controller and the name attribute to determine its template.