Skip to content

Nesting of blocks

Rosario Carvello edited this page Feb 5, 2018 · 35 revisions

Introduction

There are two general purposes of using the nesting of blocks:

  1. To show a set of different values when each value, in turn, contains a set of shared values
  2. To show a set of different values when each value, in turn, contains a set of custom values

Nesting of blocks for showing a subset of shared values

We start by showing you the following templates\nested_blocks.html.tpl

<!DOCTYPE html>
<html>
<head>
    <title>Users list</title>
</head>
<body>
<h1>Users list</h1>
{CurrentAction}
<table border="1">
    <thead>
    <tr>
        <th>User</th>
        <th>Email</th>
        <th>Actions</th>
    <tr>
    </thead>
    <tbody>
    <!-- BEGIN Users -->
    <tr>
        <td>{UserName}</td>
        <td>{UserEmail}</td>
        <td>
            <ul>
                <!-- BEGIN UserActions -->
                <li><a href="{GLOBAL:SITEURL}/nested_blocks/do_action/{ActionName}/{UserEmail}">{ActionCaption}</a> </li>
                <!-- END UserActions -->
            </ul>
        </td>
    </tr>
    <!-- END Users -->
    </tbody>
</table>

</body>
</html>

As you can guess from the code above the purpose of this template is to representing the static structure of a table of users and to show, for each user, a set of links for performing some actions on a user, e.g. send email, edit or delete the user data.
To build this, we nested the block UserActions inside the main block Users we used to show users. Then we designed inside UserActions the static representation of an unnumbered list of actions links. Note that, like we have done for the user data, we coded only the static representation of one action link by representing a call to doAction() method of controller\NestedBlocks controller and by passing it two parameters: the action name and the user email, their respectively designed by using {ActionName} and {UserEmail} placeholders. Pay also attention we used:

  • the placeholder {CurrentAction} for dynamically showing an information about the link clicked by the user
  • the global placeholder {GLOBAL:SITEURL} for getting the root URL of links that will be generated at runtime

For dynamically producing the output we also code: views\NestedBlocks

<?php

namespace views;

use framework\View;

class NestedBlocks extends View
{
    /**
     * @override framework\View __construct()
     */
    public function __construct($tplName = null)
    {
        if (empty($tplName)) {
            $tplName = "/nested_blocks";
        }
        parent::__construct($tplName);
    }

    /**
     * Shows the given $user in the block Users
     * of tempalates\nested_blocks.html.tpl
     *
     * @param array $users Array of users in the format:
     *                      array( array('Username'=>'','UserEmail'=>'') )
     */
    public function setUsersBlock($users)
    {
        $this->openBlock("Users");
        foreach ($users as $user) {
            $this->setVar("UserName", $user["UserName"]);
            $this->setVar("UserEmail", $user["UserEmail"]);
            $this->parseCurrentBlock();
        }
        $this->setBlock();
    }

    /**
     * Shows the given $actions in the block UserActions
     * of tempalates\nested_blocks.html.tpl
     *
     * @param array $actions Array of actions in the format:
     *                       array( array('ActionName'=>'','ActionCaption'=>'') )
     */
    public function setUserActionsBlock($actions)
    {
        $this->openBlock("UserActions");
        foreach ($actions as $action) {
            $this->setVar("ActionName", $action["ActionName"]);
            $this->setVar("ActionCaption", $action["ActionCaption"]);
            $this->parseCurrentBlock();
        }
        $this->setBlock();
    }
}

Finally we code controllers\NestedBlocks :

<?php

namespace controllers;

use framework\Controller;
use views\NestedBlocks as NestedBlockView;

class NestedBlocks extends Controller
{
    /**
     * @override framework\Controller __construct()
     */
    public function __construct()
    {
        $this->view = new NestedBlockView();
        parent::__construct($this->view);

        $actions = $this->getUserActions();
        $this->view->setUserActionsBlock($actions);

        $users = $this->getUsersData();
        $this->view->setUsersBlock($users);
    }

    /**
     * Set the default behaviour when no actions is performed
     */
    protected function autorun($parameters = null)
    {
        $this->view->setVar("CurrentAction","Please, perform an action on user");
    }

    /**
     * Provides users data.
     *
     * @return array  Array of users in the
     *                format array( array('Username'=>'','UserEmai'=>'') )
     */
    private function getUsersData()
    {
        $users = array(
            array('UserName' => 'Mark', 'UserEmail' => '[email protected]'),
            array('UserName' => 'Elen', 'UserEmail' => '[email protected]'),
            array('UserName' => 'John', 'UserEmail' => '[email protected]')
        );
        return $users;
    }

    /**
     * Provides users actions.
     *
     * @param array $actions Array of actions in the format:
     *                       array( array('ActionName'=>'','ActionCaption'=>'') )
     */
    private function getUserActions()
    {
        $userActions = array(
            array("ActionName" => "email" ,"ActionCaption" => "Send email"),
            array("ActionName" => "edit"  ,"ActionCaption" => "Edit information"),
            array("ActionName" => "erase","ActionCaption" => "Delete user")
        );
        return $userActions;
    }

    /**
     * Performs the given action on a given user.
     * 
     * @param string $actionName The action to performs
     * @param string $userEmail The user email on which to perform the action
     */
    public function doAction($actionName,$userEmail)
    {
        $currentAction = "Current action: $actionName on user $userEmail";
        $this->view->setVar("CurrentAction",$currentAction);
        $this->render();
    }
}

The result //TODO

Clone this wiki locally