Section: Generating HTML content
^ Responses: generating content | Generating plain text » |
− Table of content
To generate HTML/XHTML, you indicate the alias "html" or "basichtml" to the getResponse()
method in your controller's action. Then you retrieve respectively an instance of jResponseHtml
or jResponseBasicHtml
. Here is an example:
$resp = $this->getResponse('html')
XTHML or HTML ¶
jResponseHtml or jResponseBasicHtml is set to return XHTML output by default. You can enable, disable or fetch this setting:
$rep->setXhtmlOutput( true ); // XHTML output
$rep->setXhtmlOutput( false ); // HTML output
// Fetch the setting value :
$outputXhtml = $this->isXhtml();
Going further, you can specify your own DOCTYPE by overloading outputDocType()
(using jResponseHtml, not jResponseBasicHtml). This method should echo a valid DOCTYPE.
Returning the content of a static page ¶
Since Jelix 1.3, a new response object is available: jResponseBasicHtml
. It allows to return simply a static page stored in a file. This file should be a simple PHP file, and not a template for jTpl.
It should contain all the HTML code of a page, and three instructions to display these variables:
- $HEADBOTTOM : before the end tag
</head>
- $BODYTOP : after the begin tag
<body>
- $BODYBOTTOM : before the end tag
</body>
These variables contain HTML code given by the call of methods addHeadContent()
and addContent()
of the object jResponseBasicHtml
. These calls may be made by some components like controllers, classes, plugins... So you really should include these instructions. Here is an example of a such static file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_EN" lang="en_EN">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
<title>Hello From Jelix !</title>
<?php echo $HEADBOTTOM; ?>
</head>
<body>
<?php echo $BODYTOP; ?>
<h1>Hello YOU !</h1>
<p>This is a sample html page generated by Jelix</p>
<?php echo $BODYBOTTOM; ?>
</body>
</html>
In your controller, you must indicate where can jResponseBasicHtml
find this file, by giving its full path in the property $htmlFile
. Note that the object jCoordinator
owns a method allowing to retrieve the path of a module. So it is easy to give the path of a file stored in a module.
$rep = $this->getResponse('basichtml');
$rep->htmlFile = $GLOBALS['gJCoord']->getModulePath('unModule'). 'static/hello.php';
Generating dynamic contents ¶
To return dynamic content, you have to use the class jResponseHtml
, corresponding to the response type "html". This class implements additionnal methods and properties to manipulate the HTML/XHTML content. So it is more flexible for all consumers components (zones, templates, controllers..).
The source of an HTML page is split into two parts: the <head>
part, and the <body>
part.
jResponseHTML generates itself the content of the <head>
element, from data you give to the jResponseHTML via its dedicated methods. However, you are responsible of the generation of the content of the <body>
element.
Let's see all these things.
Generating (X)HTML headers ¶
jResponseHtml provides features to change document's title, favicon, links to style sheets or JS scripts, meta tags...
Features tour:
$resp->title = 'Document Title';
// generate a script tag
$resp->addJSLink( 'lib.js' );
// generate a script tag with inline code :
$resp->addJSCode( 'alert( "Hello world" ) )' );
// generate a <link>
$resp->addCSSLink('style.css');
// generate a <style>
$resp->addStyle('span', 'font-weight:bold;');
// Add a description meta tag:
$resp->addMetaDescription( 'description' );
// Add a keywords meta tag:
$resp->addMetaKeywords( 'jelix php framework' );
// Add the author:
$resp->addMetaAuthor('Laurent');
// change the meta generator name
$resp->addMetaGenerator('My Super App 1.0');
Note that addCSSLink()
and addJSLink()
can use an associative array argument specifying custom (X)HTML tag properties, for example:
$resp->addCSSLink(
'stylesheet.css',
array(
'title' => 'blue design',
'rel' => 'alternate stylesheet',
)
);
If you want to add custom content in the <head>
element, use addHeadContent()
:
$resp->addHeadContent('<link rel="alternate" type="application/rss+xml" title="Recent Changes" href="/feed.php" />')
It happens to require removal of parts of the generated headers (if you refuse to take the hand on third-party-module).
You should use method clearHtmlHeader()
for this:
// remove links to stylesheets done with addCSSLink(), and style tags from addStyle()
$resp->clearHtmlHeader( array( 'CSSLink', 'Styles' ) );
Acceptable array values are strings:
- CSSLink,
- Styles,
- JSLink,
- JSCode,
- Other.
Generate (X)HTML body ¶
jResponseHtml generates the (X)HTML <body>
tag, but you must control its contents and attributes.
To control its attributes:
$resp->bodyTagAttributes = array( 'onload'=>'bodyonload( )',
'class'=>'maincontent');
Control its contents with either:
- a template
- method
addContent( )
Using a template ¶
jResponseHtml provides a couple of properties:
$bodyTpl
, which value should be the template selector;body
, which contains a jTpl instance allowing control over template "settings".
For example :
$resp->bodyTpl = 'myapp~main';
$resp->body->assign( 'person','Guybrush Treepwood');
Contents generated by the template engine will be integrated in the (X)HTML body tags automatically.
To know more about templates, read chapter about templates.
It happens to require appending some arbitrary contents in addition to the (X)HTML body code generated with
method addContent()
:
- first argument is the string value to append to the (X)HTML body contents,
- second argument is a bool about the order :
true
if the first argument's string value should be placed before the templatefalse
if it should be placed after the template.
Note that it's set to false by default.
Example:
$resp->addContent( 'This text will be placed after the template' );
$resp->addContent( 'This text will be placed before the template', true);
It's possible to use this method to append contents from "zones", for example:
$resp->addContent( jZone::get( 'aModule~aZone'));
Using a main template and some "sub-templates" ¶
We often have a common template for all pages, and only few things change inside this common template, depending of the page. So you will have a first template for the common things, and all pages will define an other "sub-template" to generate specific things for the page. The result of this sub-template will be inserted into the main template.
You can do this work directly into all your controllers, with zones.
But there is a more convenient way to do it: you can define an object which inherits from jResponseHtml. In this object, you will define all common things. And then you declare this object as the default HTML view for all your actions.
Read the section: how to create a custom common response.
Not using templates ¶
Let bodyTpl
empty if you don't want to use a template for the (X)HTML body of the response, and use addContents()
as described in the previous paragraph of the documentation.
$rep->addContent('<p>content for my body</p>');
Other response parameters ¶
It's possible to control HTTP headers since jResponseHtml and jResponseBasicHtml inherit from jResponse, for the status code as well as for miscellaneous properties.
$resp->setHttpStatus( '404', 'Not Found' );
$resp->addHttpHeader( 'Date-modified', '...' );
If jResponseHtml's property $xhtmlContentType
is true : HTTP response's "Content-Type" will be application/xhtml+xml
. Note that the client-browser must support xHTML, or Content-Type text/html
is sent.
$resp->xhtmlContentType = true ;
Using plugins ¶
Since Jelix 1.3, jResponseHtml
and jResponseBasicHtml
have a plugin system. These plugins allow to add content or modify the response content automatically, on all HTML pages generated with these classes. Thus there is such plugins to show a debug bar, or to "minify" css style sheets or javascript files.
These plugins have the plugin type "htmlresponse", so they have to be stored in a htmlresponse/
directory inside a plugins repository. To activate them, you need to specify their name in the option plugins
in the section jResponseHtml
of the main configuration. Example:
[jResponseHtml]
plugins = debugbar, minify
Minifying css and javascript files ¶
Jelix provides Minify, which allow to concatenate and minify CSS and JS files. It improves performance during the load of the page.
In Jelix 1.2, this feature was natively implemented into the jResponseHtml
class, however, since Jelix 1.3, it is a plugin, and its configuration is a bit different.
To activate the plugin "minify", put its name into the plugins
option as indicated in the previous section. You have then some configuration options.
[jResponseHtml]
;concatenate and minify CSS and/or JS files :
minifyCSS = off # [on|off] : concatenate/minify CSS files
minifyJS = off # [on|off] : concatenate/minify JS files
; list of filenames (no path) which shouldn't be minified - coma separated :
minifyExcludeCSS = "file1.css,file2.css"
minifyExcludeJS = "jelix/wymeditor/jquery.wymeditor.js"
; bootstrap file for Minify. indicate a relative path to the basePath.
minifyEntryPoint = minify.php
First, with minifyCSS
and minifyJS
you activate the "minification". You can indicate files to NOT minify in minifyExcludeCSS
and minifyExcludeJS
. Keep the file name "jelix/wymeditor/jquery.wymeditor.js" in minifyExcludeJS
. Wymeditor doesn't like to be concatenated with other files.
Indicated path should be
- relative to the base path of the application (without a leading /)
- or relative to the domain name (with a leading /)
Don't indicate full URL (with http://
...), they are automatically excluded.
Second, you have to install a script minify.php
in www/
. Simply copy the file lib/jelix-scripts/templates/www/minify.php.tpl
into votre_appli/www/minify.php
. There are some options in this file you can set to configure Minify (read the documentation of Minify). If you want to choose an other name for this script, indicate its name into the option minifyEntryPoint
.