Views

SuiteCRM follows the MVC (Model-View-Controller) pattern and as such has the concept of views. Views are responsible for gathering and displaying data . There are a number of default views in SuiteCRM. These include:

ListView

Displays a list of records and provides links to the EditViews and DetailViews of those records. The ListView also allows some operations such as deleting and mass updating records. This is (usually) the default view for a module.

DetailView

Displays the details of a single record and also displays subpanels of related records.

EditView

The EditView allows editing the various fields of a record and provides validation on these values.

Location

Views can be found in modules/<TheModule>/views/ or, for custom views, custom/modules/<TheModule>/views/, and are named in the following format: view.<viewname>.php. For example, the Accounts DetailView can be found in modules/Accounts/views/view.detail.php with a customised version in custom/modules/Accounts/views/view.detail.php. The custom version is used if it exists. If it doesn’t then the module version is used. Finally, if neither of these exist then the SuiteCRM default is used in include/MVC/View/views/.

Customising

In order to customise a View we first need to create the appropriate view file. This will vary depending on the module we wish to target.

Custom module

In this case we can place the file directly into our module. Create a new file (if it doesn’t exist) at modules/<TheModule>/views/view.<viewname>.php. The contents will look similar to:

Example 5.1: View for a custom module
<?php

require_once 'include/MVC/View/views/view.<viewname>.php';

if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class <TheModule>View<ViewName> extends View<ViewName>
{

}

A more concrete example would be for the detail view for a custom module called ABC_Vehicles:

Example 5.2: Detail view for a custom module, ABC_Vehicles
<?php

require_once 'include/MVC/View/views/view.detail.php';

if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class ABC_VehiclesViewDetail extends ViewDetail
{

}

Preexisting modules

For preexisting modules you will want to add the view to
custom/modules/<TheModule>/views/view.<viewname>.php.

The contents of this file will vary depending on whether you wish to extend the existing view (if it exists) or create your own version completely. It is usually best to extend the existing view, since this will retain important logic. Note the naming convention here. We name the class Custom<TheModule>View<ViewName> (for example CustomAccountsViewDetail).

Here we don’t extend the existing view or no such view exists:

Example 5.3: Custom view for an existing module
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once 'include/MVC/View/views/view.<viewname>.php';

class Custom<TheModule>View<ViewName> extends ViewDetail
{

}

Otherwise we extend the existing view. Note that we are requiring the existing view:

Example 5.4: Overriding a view for an existing module
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once 'modules/<TheModule>/views/view.<viewname>.php';

class Custom<TheModule>View<ViewName> extends <TheModule>View<ViewName>
{

}

For example, overriding the List View of Accounts:

Example 5.5: Overriding the Accounts List View
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once 'modules/Accounts/views/view.list.php';

class CustomAccountsViewList extends AccountsViewList
{

}

Making changes

Now that we have a custom view what can we actually do? The views have various methods which we can now override to change/add behaviour. The most common ones to override are:

preDisplay

Explicitly intended to allow logic to be called before display() is called. This can be used to alter arguments to the list view or to output anything to appear before the main display code (such as, for example, adding JavaScript).

display

Does the actual work of displaying the view. Can be overridden to alter this behaviour or to output anything after the main display. You usually want to call parent::display(); to ensure that the display code is run (unless, of course, you are adding your own display logic).

Customising with Smarty templates

Instead of using including HTML files in PHP, you can use Smarty templates to create complex HTML for custom views.

Let’s say you’re adding a custom module called Store, and you’ve made a file at custom/modules/Store/views/view.store.php that uses HTML in HEREDOCs and Strings to create a dynamic page:

<?php
if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once('include/MVC/View/SugarView.php');

class StoreView extends SugarView
{
    public function display()
    {
        $storeName = $store->storeName;
        $location = $store->location;
        $products = $store->products;

        $html = <<<"HTML"
<h1>$storeName</h1>
<h2>Location: $location</h2>

<ul>
HTML;

        foreach ($products as $id => $product) {
            $html .= "<li>$product->name: $product->price</li>";
        }

        $html .= <<<"HTML"
</ul>
HTML;

        echo $html;
    }
}

This works, but it isn’t very nice to look at, and it’s hard to maintain and understand. You’re combining your backend logic with the frontend HTML, which we should try to avoid as much as possible.

Instead, we can accomplish the same thing using a Smarty template. We can change the custom/modules/Store/views/view.store.php file to just provide the variables for the Smarty template, instead of creating the HTML itself.

<?php
if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once('include/MVC/View/SugarView.php');

class StoreView extends SugarView
{
    public function display()
    {
        $smarty = new Sugar_Smarty();
        $smarty->assign('storeName', $store->storeName);
        $smarty->assign('location', $store->location);
        $smarty->assign('products', $store->products);
        $storePage = $smarty->fetch('custom/modules/Store/templates/store.tpl');
        return $storePage;
    }
}

And then we’ll create a file at custom/modules/Store/templates/store.tpl, that looks like this:

<h1>{$storeName}</h1>
<h2>Location: {$location}</h2>

<ul>
    {foreach name=productsIteration from=$products key=id item=product}
        <li>{$product->name}: {$product->price}</li>
    {/foreach}
</ul>

Much simpler!

You can read more about Smarty template files and their syntax in the Smarty documentation.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.