Working with substitution skins

svowl edited this page Jun 8, 2011 · 2 revisions
Clone this wiki locally

Suppose, we have a module named JohnSmith/Example, which has declared a skin named example.

1. Internal templates

A skin may have its internal templates, which no analogs in other skins. Such templates can be displayed via:

Widget lists

A template can be inserted into a list with the @ListChild annotation. Here is an example:

{* vim: set ts=2 sw=2 sts=2 et: *}
{**
* Shopping cart Go to checkout button
*
* @author    Creative Development LLC <info@cdev.ru>
* @copyright Copyright (c) 2011 Creative Development LLC <info@cdev.ru>. All rights reserved
* @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @link      http://www.litecommerce.com/
* @since     1.0.0
*
* @ListChild (list="cart.childs", weight="100")
*}
<span>Example</span>

Here is rather a compact than correct, in terms of code style, way:

{* vim: set ts=2 sw=2 sts=2 et: *}
{**
* @ListChild (list="cart.childs", weight="1000")
*}
<span>Example</span>

In these examples, the template has been included in the cart.childs list with the weight of 1000.

Internal widget class

Obviously, a template can be called directly from any widget class, which in its turn can also be called:

  • Via a widget list or

  • As the central-part widget when calling the controller that emerged in just that skin-module

There is a recommendation though that if a module adds both a new skin and some custom widgets, it is better to have the templates for those widgets added for the default skin too — not only for the newly created skin. This allows to achieve better scalability, especially when this module is extended by other one, with its own skin, written in view of the current module with its widgets and their templates.

External widget class

A module can also override an external widget class and replace the template being displayed with its own. Here is a small example:

<?php

namespace XLite\Module\JohnSmith\Example\View;

abstract class Cart extends \XLite\View\Cart implements \XLite\Base\IDecorator
{
   protected function getDir()
   {
       return 'modules/JohnSmith/Example/my_shopping_cart';
   }
}

In this example, to display the cart widget, the program calls the template modules/JohnSmith/Example/my_shopping_cart/body.tpl instead of shopping_cart/body.tpl. However, it is still recommended to create this directory in the default skin first; then, as the directory is created, it can be overridden in the newly created skin.

2. Complete template overriding

Any template of the default skin can be completely overridden. For example, there is a the welcome.tpl template. If the new skin has a template with the same path related to the root directory of the skin, the template of the new skin would be called.

Overriding template element of widget list

If a template is overridden, its @ListChild directive is disregarded. For example, the default template has the directive:

...
* @ListChild (list="cart.panel", weight="200")
...

and the substitution skin template (this template overrides the default one) has the directive:

...
* @ListChild (list="cart.childs", weight="1000")
...

The template will be inserted into the cart.childs list with the weight of 1000 and won’t be inserted into the cart.panel list. Moreover, if the overriding template has the directive:

...
* @ListChild (list="cart.childs")
...

the initial weight of the overridden template will be disregarded. This template will be inserted into the cart.childs list with the maximum weight.

If you need the overriding template to have the same list location as the overridden one, omit the @ListChild annotation in it.

Use the @InheritedListChild annotation to insert the template into other widget lists too, not only into the child list of the overridden template.

Example: The overridden template has the directive:

...
* @ListChild (list="cart.panel", weight="200")
...

and the overriding template has:

...
* @InheritedListChild ()
* @ListChild (list="cart.childs", weight="1000")
...

In this case, the template will be inserted into both cart.panel and cart.childs lists.

3. Calling overriden templates

Sometimes it may be necessary to make certain modifications to a template in the default skin. If this template is not a part of a widget list, that can be done by overriding the template and then calling the inherited (overridden) default skin template. Here is the example with the welcome.tpl template:

<h1>Welcome!</h1>
<widget template=”parent” />

In this example, the name of the called template is parent. Thus, the program attempts to call the template of the overridden skin. In the case when several substitution skins are installed, the program will sequentially call the overridden templates in the inheritance chain down to the default skin.

4. Calling specific template from overriden skin

Besides same templates, it is also possible to call templates with a specific name from the overriden skin. Here is an example:

<h1>Welcome!</h1>
<widget template=”parent:cart.tpl” />

5. Calling specific template from specific skin

It is also possible to call any template by specifiyng its name and the skin where it is to be called from. Example:

<h1>Welcome!</h1>
<widget template=”default:cart.tpl” />

In this example, the program attempts to call the welcome.tpl template from default skin.

6. Overriding other elements

Besides templates, it is possible to completely override other skin elements, such as images, CSS and JS files. For example, if the images/logo.png image exists in the substitution skin, it will appear instead of the default one.