Using an AppController in Lithium PHP to pass data to the layout post

Comments

Note: This article may not be pushing best practices. Instead of setting view data via an AppController, we can create a helper for any arbitrary data we need. Due to Lithium's autoloading, this takes care of including our helper as needed and may make a bit more sense than injecting view variables via an AppController.

A concept that has been somewhat glossed over in the Lithium PHP community,  but is standard practice when coming from CakePHP is the use of an AppController class. The idea here is that all your app's controllers will extend from this custom controller instead of \lithium\action\Controller. This allows us to share some common controller functionality across our entire application. Obviously with Lithium's Filter system, application wide callbacks are not as essential as they once were, nor as cumbersome, but I still think extending an AppController (and AppModel btw) is a good practice. One specific example is the passing of variables to a common layout that should be present on every page of your website.

Creating the AppController class is trivial.

in app/controllers/AppController.php

<?php
namespace app\controllers;

use lithium\security\Auth;

class AppController extends \lithium\action\Controller {

  public function render($options = array()) {
    $auth = Auth::check('default');
    $this->set(compact('auth'));
    parent::render($options);
  }
}

Inside our AppController, we are extends the core Lithium controller class. Since we want to pass some auth data to the layout to be available on every page (via the layout) we need to override the render method of the controller. lithium\action\Controller::render() takes one argument, which is an array of options. We can leave this alone for now but we want to make sure to follow the same method signature as what the method we are extending.

In order to make the data appear in every view (or layout), we need to use the Controller::set() method. Controller::set() simply takes a 'key' => $value array of variables to set. This should already be a familiar way to send data to the view, only now we are setting the data for every controller action called from a controller that extends AppController.

Here is an example of a controller extending AppController:

in app/controllers/UsersController.php

<?php
namespace app\controllers;

use app\models\Users;

class UsersController extends \app\controllers\AppController {

  public function index() {
    $users = Users::all();
    return compact('users');
  }
}

In our Users::index() view, we should expect $users to be available to us, and since we are extending AppController, the $auth variable is populated with user Authentication data (or false if check failed). In fact $auth will be available in the view for any controller action extending AppController.

Here is a snippet from my layout:

in app/views/layouts.default.html.php

<!doctype html>
<head>
  <?php
  /* Head stuff <em>/
  ?>
</head>
<body>
  <ul>
    <li class="active"><?php echo $this->html->link('Home', '/'); ?></li>
      <li>
      <?php
      if ($auth) {
        echo $this->html->link('Logout', 'Users::logout');
      } else {
        echo $this->html->link('Login', 'Users::login');
      }
      ?>
    </li>
  </ul>
</body>
</html>
  • Tags:
  • AppController
  • auth
  • layout
  • lithium
  • lithium php
  • passing data to layout
  • php
  • view

explosive web programming MODERN CODE TACTICS

by James Fuller