Adding objects in Agile Toolkit

Adding is the fundamental concept of Agile Toolkit. You don't produce HTML strings like you do with other toolkits, you manipulate with objects. You add objects like this:

$view $page->add('LoremIpsum');

Try this code. Copy it into "page/index.php" inside function init() of your local Agile Toolkit installation. You will see that a few paragraphs of "Lorem Ipsum" text filler will appear on your page.

Geeky Note — encapsulation and dependency injection.

Run-time Tree

In the real world, certain objects are containers. Your bag may contain your wallet and your wallet may contain your credit cards. In Agile Toolkit all objects are also containers. You can also imagine it as a tree-like structure. The top node or a top container is called "Application". This object may contain controllers, models and a page. The page will contain views such as Forms, Text, Buttons, LoremIpsum object etc.

When you add objects it also cross-links them with the "owner". When you added LoremIpsum into $page, the $page became "owner" of LoremIpsum, LoremIpsum became "Element" of $page. All objects are also given a unique identifier within it's owner - short_name. Another property which is automatically added to any object is "name": globally unique identifier.

Geeky Note — Object Presence and independence.

Result

 

Code

$page->add('Button')->set('Click me');

init() method

When you add an object, Agile Toolkit will automatically execute method init() of a new object. This method is often used to initialize an object. When you are creating your own object, the first method you'll learn to define would be init() method. In fact — you have already created a custom object. You have changed the init() method of your index page.

You can also extend and define your own View classes. By adding code in their init() method, you can build more advanced objects or an object with altered behaviour. Please always remember to call parent::init() before you place any code of your own.

Geeky Note — Constructors: Encapsulation versus Inheritance

Next, let's create our own button class with a slightly different behaviour from the button supplied by Agile Toolkit. This button's label will be automatically set to "Click Me". Place the following code inside lib/MyButton.php

class MyButton extends Button {
    function 
init(){
        
parent::init();
        
$this->set('Click Me');
    }
}

Next add this on your index page:

$page->add('MyButton');

As you have expected the newly created button will have a different label. Remember this principle and every time you feel a need to duplicate some code, put it inside a separate class instead. Here is another example which can help you create a re-usable contact form. Place this code inside lib/Form/ContactForm.php:

class Form_ContactForm extends Form {
    function 
init(){
        
parent::init();

        
$this->addField('Line','name');
        
$this->addField('Line','surname');
        
$this->addSubmit('Send');
    }
}

Notice that you might, optionally, add more fields or buttons outside of the class on your page after object is added:

$contact_form $page->add('Form_ContactForm');
$contact_form->addButton('Cancel');

Apart from using $contact_form instead of $this, the syntax and effect is identical. Always put code you want to re-use inside the class but remember that you can still tweak it on a per-use basis.

Indirect Adding of Objects

For convenience, objects may define new methods for adding certain types of objects. For example, in the form above you can see "addField". This method will actually call add() but will use "Form_Field_Line" class instead of just "Line". You must remember that you can always use "add" method instead of addField, addSubmit or addButton for maximum control.

Most functions starting with "add" are wrappers for add(). There are some functions which do not use this convention: js(), dsql() and exception() will also rely on add(). $grid->addColumn(), however, this does not currently create new object.

The second argument

In some cases you would like to specify a short_name of a new object. You do that when you add a field to a form class. A short_name of a field object will be used to construct POST reply. When it's important to specify the new object's short_name the second argument of add() method can be used to specify the new name.

It is also possible to change the name of an object after it was added using rename() method, although only use that method if you have no other alternative (some objects may not work well with renaming)

Geeky Note — changing default properties
$page->add('Form','my_form');

if(
$page->hasElement('my_form')){
  
// has form
}

$page->getElement('my_form')->owner;  // refers back to $page
$model->add('MyObject',array('foo'=>'bar'));
echo 
$model->foo;

Working with existing objects

$this->hasElement($short_name) return child object if found, or false if not found.

$this->getElement($short_name) similar to hasElement() but will produce an exception if not found. Use this when chaining.

$this->destroy() remove the current object from its owner. For a view, this will remove it from rendered page.

$this->rename($new_short_name) can rename an object, but might not work with some objects.

$this->newInstance() will add a copy of the object and add into the same owner. Unlike cloning, object state is not copied.

Properties: $this->name name is unique to the system. $this->short_name is unique amongst owners children. $this->template reference to the SMlite template for the current view. $this->owner reference to the object whose add() was used (the parent). $this->api refers to the API class of the parent object.

Excercise

Create your own class which will produce video playback controls. You don't need to link it with video or make controls work, just make it look like one:

Once you are ready with this task, create another instance of a video playback controls and destroy "play" button:

For solution look at the source of ths page