−
Table of content

You certainly may have to initialize the same CSS stylesheet, the same zone of
content, and other same personnalization stuff, on your response object in most
of your controllers. Instead of repeating all this operations, you could create
a response object which already do all this personnalization.

If you want to create reusable modules, creating your own response is a good
thing since everything which is not specific to a module is done outside the
module. So the module is more independent of the application, unlike the case
where it manages himself the stylesheet declaration, the header of a page etc..

Your own responses could inherits from jResponseHtml (but it can be an other
jResponse* class provided by jelix). When you create a new application with
jelix-scripts, a such class is created for you: myHtmlResponse. It is stored
into the responses/ directory of the application.

In this class, you can:

redefine the constructor to do things before the call of the getResponse() method of controllers

redefine the doAfterActions(). Note that this method exists only in
jResponseHtml. In this method, you can do all things you want, which
will be executed after each actions, and just before the output.

Let's see how the process is done precisely.

You have your HTML page which have the <head> part and the <body> part:

You will have a main template which contains the main content of the
<body> part, and this template will be used by your custom response
object. Here is an example of responses/myHtmlResponse.class.php:

This zones A, B, C, D and MAIN can be generated by sub-templates or jZone objects:

In particular, the MAIN part will be generated by each actions (with or without the help of a template, a zone..)

So, your custom response object could support the A part (if this part is
common to all pages), and the other parts will be filled by each action if
needed. So in the custom response object, we have:

require_once (JELIX_LIB_CORE_PATH.'response/jResponseHtml.class.php');
class myHtmlResponse extends jResponseHtml {
public $bodyTpl = 'myapp~main';
protected function doAfterActions(){
// all pages will have a login form
$this->body->assignZone("A", "auth~login");
// In the case where nothing is declared for each other parts,
// we set an empty content
$this->body->assignIfNone('B','');
$this->body->assignIfNone('C','');
$this->body->assignIfNone('D','');
$this->body->assignIfNone('MAIN','<p>No content</p>');
// we can set other template variables needed by the main template
$this->body->assign('date', date('Y-m-d'));
}
}

In the controllers, we could do things like that:

function my_action() {
$resp = $this->getResponse('html');
// we set the content for the B part
$resp->assign('B','<h2>Hello !</h2>');
// we set the content for the D part
$resp->assignZone('D', 'my_sidebar');
// No content for C in this action, so we do nothing for C
// Now, the main part. we use a sub-template
$tplMain = new jtpl();
$tplMain->assign(...);
$resp->assign('MAIN', $tplMain->fetch('mymodule~mytpl'));
return $resp;
}

Of course, the custom response can define other things than templates: CSS
stylsheets, javascript links, default title etc. So you don't have to do it in
controllers.

class myHtmlResponse extends jResponseHtml {
public $bodyTpl = 'myapp~main';
// the constructor is called before any getResponse
public function __construct() {
parent::__construct();
$this->addCSSLink('design/screen.css');
}
protected function doAfterActions(){
$this->title .= ($this->title !=''?' - ':'').' My App';
// all pages will have a login form
$this->body->assignZone("A", "auth~login");
// In the case where nothing is declared for each other parts,
// we set an empty content
$this->body->assignIfNone('B','');
$this->body->assignIfNone('C','');
$this->body->assignIfNone('D','');
$this->body->assignIfNone('MAIN','<p>No content</p>');
// we can set other template variables needed by the main template
$this->body->assign('date', date('Y-m-d'));
}
}

Note : you mustn't assign zone in the constructor of the response,
especially if the zone wants to add css style sheet (through its template for
example) or to modify the response, because at this step, the response object is
not known yet in the global scope.

The class of the custom response is declared in the configuration like that:

[responses]
html=myHtmlResponse

Jelix will search the class into the responses/ directory of the application.
If it is stored into the responses/ directory of a module ("main" for example)
you should indicate the module like a selector:

[responses]
html="main~myHtmlResponse"

So all actions which will then use the "html" response (by doing this,
$this->getResponse('html')), will provide a page with a login form generated
by the 'auth~login' zone, and a default content for all other parts.

If in an action, you want to use the original class provided by Jelix for the
"html" code, and not to use a redefined response, then you should use a second
parameter in getResponse() (the boolean true):

$resp = $this->getResponse('html', true);

In our example, $resp contains an object of type jResponseHtml, not myHtmlResponse.

This manual is distributed under the terms of licence Creative Commons by-nc-sa 3.0. Therefore you're allowed to copy, modify and distribute and transmit it publicly under the following conditions: Attribution, Noncommercial, Share Alike.