TooBasic: Controller Exports

What are these?

Controller exports are special functions provided inside view templates that help with some tedious aspects.

For example, if you have multiple installations of your site in different URL and sub-folders of the DocumentRoot, generating a proper URL for a src or href attribute may become a real pain in t... problem. For these cases, TooBasic offers these functions to free you from this problem while it takes care of it.

In the following sections we'll try to explain these functions.

Warning

This has been tested through the Smarty view adapter which means it could have issues if a new view adapter is developed and it attempts to make use of this functionality.

Also, all the examples on this page will be using the Smarty view adapter.

How to call an exported function

The first thing you need to know is how to call one of these functions, and here is an example of it:

    <a href="{$ctrl->link('?action=moreinfo&id=10')}" target="_blank">{$tr->label_more_info}</a>

Once rendered, it may look like this:

    <a href="/mysite/moreinfo/10" target="_blank">More Info</a>

In this example, we've used $ctrl->link() to clean an URL of our site and make sure that it uses the right absolute path and route transformations.

An easy way to identify this kind of functions is by the object $ctrl because all of them belong to it inside view templates.

Basic path expansion

The functions we'll explain in this section are exported function that simply generate proper paths for a link or an asset.

$ctrl->css()

This exporting method takes a stylesheet name, assumes its extension as .css and looks for it inside the folder styles on each module and then the site, and the first one found is returned as an absolute URI. If it's not found it will return an empty string.

$ctrl->js()

Idem for JavaScript files and they are looked for inside the folder called scripts.

$ctrl->img()

Idem for image files and they are looked for inside folders called images and img.

By default, this method assumes the .png extension, but it may be change using a second parameter:

{$ctrl->img('imagename','jpeg')}

$ctrl->lib()

This method is a little more simple, it takes a path and checks if it is inside ROOTDIR/libraries, when it is, it returns it's path as an absolute URI, otherwise it returns an empty string.

This method is a little more complex. First of all, it follows some basic rules:

  • If it takes a full URL containing a host name, it won't touch it and return it as it is.
  • When the URL starts with a slash (/), it won't touch it either.
  • When there's no parameter given or when it is an empty string it will return the sites root URI.

In other cases, it will prepend the sites root URI and attempt to transform it using route specifications. For example, when you write this:

<a class="HelpButton" href="{$ctrl->link('?action=product&id=204578&view_mode=clean&expand=description')}" target="_blank">Help Me Please!</a>

Your browser may end up receiving something like this:

<a class="HelpButton" href="/mysite/product/204578?view_mode=clean&expand=description" target="_blank">Help Me Please!</a>

... supposing you have this route too:

{
    "routes": [{
        "route": "product/:id:int",
        "action": "product"
    }]
}

Controller insertion

There's an exported function called $ctrl->insert() that allows you to call another controller, execute it, render its view and then insert its result somewhere in a template. This mechanism allows you to extract some functionality you'll be repeating and place it inside a controller along with its template, later on you can call such controller from anywhere in your templates and expect it to be inserted.

Let's say we have something like this inside one of our templates:

    <div class="AdsSection">
        {$ctrl->insert('ads')}
    </div>

Also, you have a template (using the virtual controller) called ads.html with something like this inside:

<div class="Ads">
    <h4>Visite our market pages at:
    <ul>
        <li><a href="http://www.amazon.com/oursite">Amazon</a></li>
        <li><a href="http://www.ebay.com/oursite">eBay</a></li>
    </ul>
</div>

When you call the first page, it will generate something like this:

    <div class="AdsSection">
<div class="Ads">
    <h4>Visite our market pages at:
    <ul>
        <li><a href="http://www.amazon.com/oursite">Amazon</a></li>
        <li><a href="http://www.ebay.com/oursite">eBay</a></li>
    </ul>
</div>
    </div>

Snippets

There's an exported function called $ctrl->snippet() similar to $ctrl->insert(), but more simple in the way it works. If you want to read more about it you may visit this link.

HTML assets

Your first question may be what is a HTML asset in TooBasic? and that would be any JavaScript or CSS file either inside the libraries folder or inside one of the known folders for these kind of files.

As an example, let's say your layout imports three different Javascript files called:

  • jsquery.siteplugins.js
  • links.sanitizer.js
  • magic_menu.js
    • This one inside the folder scripts of a module called MagicMenu.

Also you have some stylesheets to include:

  • site.styles.css
  • magic_menu.css
    • Also from that module.

If you read the above sections, you'll probably be thinking on writing something like this:

    <script src="{$ctrl->js('jsquery.siteplugins')}"></script>
    <script src="{$ctrl->js('links.sanitizer')}" type="text/javascript"></script>
    <script type="text/javascript" src="{$ctrl->js('magic_menu')}"></script>

    <link rel="stylesheet" type="text/css" href="{$ctrl->css('site.styles')}"/>
    <link type="text/css" rel="stylesheet" href="{$ctrl->css('magic_menu')}"/>

... and it wouldn't be wrong, but you can also write something like this:

{$ctrl->htmlAllScripts()}
{$ctrl->htmlAllStyles()}

These two functions will generate the same inclusions based on HTML assets configurations.

HTML assets configuration

The previous example may look like magic, but truth is you'll have to make same configuration to make it work. If we continue the example with those assets, you'll have to add a configuration like this at ROOTDIR/site/config.php:

$Defaults[GC_DEFAULTS_HTMLASSETS][GC_DEFAULTS_HTMLASSETS_SCRIPTS][] = 'jsquery.siteplugins';
$Defaults[GC_DEFAULTS_HTMLASSETS][GC_DEFAULTS_HTMLASSETS_SCRIPTS][] = 'links.sanitizer';
$Defaults[GC_DEFAULTS_HTMLASSETS][GC_DEFAULTS_HTMLASSETS_SCRIPTS][] = 'magic_menu';
$Defaults[GC_DEFAULTS_HTMLASSETS][GC_DEFAULTS_HTMLASSETS_STYLES][] = 'site.styles';
$Defaults[GC_DEFAULTS_HTMLASSETS][GC_DEFAULTS_HTMLASSETS_STYLES][] = 'magic_menu';

This mechanism allows you to add templates in your layout without modifying its template. Also, any module may add its own assets in a cleaner way.

Specifics

Throughout many pages is common to see a bunch of JavaScript files included inside tag <head> and another bunch of them at the end of tag <body>, which can be a problem for the previous configuration explanation. But don't panic, there's a way in which you can specify which assets are included at the end or wherever inside a controllers template.

Let's suppose the same example we've been using and add the idea of a fourth javascript file called 'magic_menu.fixes.js' that must be included at the end of tag <body>. Also, let's suppose our layout is called my_layout.

The first thing to do is to create an specific configuration of assets:

$Defaults[GC_DEFAULTS_HTMLASSETS_SPECIFICS]['bottom_assets'] = [
    GC_DEFAULTS_HTMLASSETS_SCRIPTS => ['magic_menu.fixes']
];

Once you have this kind of configuration in your site, you can write something like this:

        . . .
        {$ctrl->htmlAllScripts('bottom_assets')}
    </body>
</html>

In this way, you'll be creating a section with only some specific assets.

Now, let's say you have this:

$Defaults[GC_DEFAULTS_HTMLASSETS_SPECIFICS]['my_layout'] = [
    GC_DEFAULTS_HTMLASSETS_SCRIPTS => ['magic_menu.fixes']
];

With this configuration you may either use $ctrl->htmlAllScripts('my_layout') or $ctrl->htmlAllScripts(true) and obtain the same result. Giving a value true implies that the name of the controller is also de name of a specific configuration. This mechanism allows you to have separated configurations for each controller, but we'll leave that to your imagination and needs of your site.

Note: Just remember, if you use a specific configuration and it happens to be undefined, it will use the main configuration.

Libraries

At the beginning of this section we said that an asset may be inside a library, but we've given no examples of it. If you find yourself in this situation and you need to include, for example, a JavaScript file from a library, you can do something like this:

$Defaults[GC_DEFAULTS_HTMLASSETS][GC_DEFAULTS_HTMLASSETS_SCRIPTS][] = 'lib:jquery/jquery-2.1.3.min.js';

The prefix lib: will be removed and the rest will be used as a path inside the folder ROOTDIR/libraries.

Ajax insert

In essence, $ctrl->ajaxInsert() is similar to $ctrl->insert(), but instead of rendering and inserting a controller's result, it just inserts a simple <div> tag that may be used to asynchronously insert a controller's result.

Let's reuse the example we gave in section Controller insertion and say that we want that view called ads.html to load asynchronously. The only change we need to do would be this:

    <div class="AdsSection">
        {$ctrl->ajaxInsert('ads')}
    </div>

And it will generate something like this:

    <div class="AdsSection">
        <div data-toobasic-insert="?action=ads"></div>
    </div>

Or something like this if there's a route configuration supporting it:

    <div class="AdsSection">
        <div data-toobasic-insert="/mysite/ads"></div>
    </div>

Autoloading

Yes, you made the change and nothing happens, it doesn't "asynchronously load" a thing. The problem here is really simple and it comes from the idea of giving you the flexibility of writing your own code to perform these asynchronous loads. Nonetheless, if you don't want to worry about it, just add this to your configuration:

$Defaults[GC_DEFAULTS_HTMLASSETS][GC_DEFAULTS_HTMLASSETS_SCRIPTS][] = 'toobasic_asset';

Or something like this to your layout:

<script type="text/javascript" src="{$ctrl->js('toobasic_asset')}"></script>

Among other functionalities, this JavaScript file provides a way to asynchronously load <div> tags created by $ctrl->ajaxInsert().

Parameters

If you take a closer look to $ctrl->insert() you'll notice that it uses parameters from the current URL, but when you use a asynchronous load, such URL is not accessible. Now, how do we solve this problem?

Let's suppose our add section requires a parameter called pattern what will allow targeted ads in future implementations. Let's also suppose our layout makes this assignment:

$this->assign('adsparams', ['pattern' => 'vodka']);

Then you change your layout's template to something like this:

{$ctrl->ajaxInsert('ads',$adsparams)}

... and you'll get this:

<div data-toobasic-insert="?action=ads&pattern=vodka"></div>

Attributes

Something else you may want is to add some attributes to these <div> tags. Again let's say our layout makes this assignment:

$this->assign('adsattrs', [
    'id' => 'mainAds',
    'class' => 'AdsSection'
]);

Then you change your template:

{$ctrl->ajaxInsert('ads',$adsparams,$adsattrs)}

... you'll end up with something like this:

<div data-toobasic-insert="?action=ads&pattern=vodka" id="mainAds" class="AdsSection"></div>

Yes, you can also call it this way:

{$ctrl->ajaxInsert('ads',false,$adsattrs)}

Reloading

Following the example and supposing your using the toobasic_asset.js file, at anytime you may execute something like this to reload one of this ajax insertions:

$('#mainAds').tooBasicReload();

Suggestions

You may also want to visit these pages:

results matching ""

    No results matching ""