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 ¶
jResponseBasicHtml
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.
There is also an other variable, $BASEPATH (since Jelix 1.4.1), containing the base path of the application, and that could be useful for your style sheets or other static resources.
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_US" lang="en_US">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
<title>Hello From Jelix !</title>
<link type="text/css" href="<?php echo $BASEPATH; ?>mystyles.css" rel="stylesheet" />
<?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 = jApp::coord()->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 of 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');
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>');
Adding CSS style sheets, javascript files, images... ¶
You probably saw above an example about the use of addJSLink()
and
addCSSLink()
. These methods allow you to link some CSS style sheets and
javascript files to your HTML page.
addJSLink()
and addCSSLink()
accept as first argument the URL of a
JS file or CSS file. Since most of URL of your application are "virtual" (the URL of
"actions" do not corresponds to a static file), you cannot indicate an URL for your CSS/JS
files, relative to the URL page (except if you really know what you do,
but it will not be very easy). You should then indicate an absolute URL (most of
time without the domain name).
Your CSS/JS files can be stored into the www/ directory of your application or in the www/ directory of a module.
If it is stored into the www/ directory of your application, and if this directory
in the "documentRoot" of the application, then just indicate its path with a leading /
.
For instance, if you want to link to yourapp/www/css/mystyles.css
, then you should do:
$resp->addCSSLink('/css/mystyles.css');
However, if www/
is not the document root, or if your module is supposed to be
used by other applications, or if the application can be installed in some different
configuration, it is better to add the "base path" of the web site:
$resp->addCSSLink(jApp::config()->urlengine['basepath'].'css/mystyles.css');
If you want a link to a CSS/JS file of the lib/jelix-www/
directory, you can use the jelixWWWPath
property:
$resp->addJSLink(jApp::config()->urlengine['jelixWWWPath'].'js/tooltip.js');
If the CSS/JS file is stored into a module, then you cannot use a direct URL, but
have to indicate the URL of a specific action of the module Jelix, which is jelix~www:getfile
.
You should give two parameters, targetmodule
and file
. The first one indicate the module where
CSS/JS files are stored, and the second one the path to the file inside the www/
directory of the module. For example, if you want a link to the file mymodule/www/css/mystyles.css
:
$resp->addCSSLink(jUrl::get('jelix~www:getfile', array('targetmodule=>'mymodule', 'file'=>'css/mystyles.css')));
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',
)
);
All previous example about the retrieval of URLs of CSS files, work with JS files, images files
and any other ressources stored into the www/
directory of an application, a module or into
the jelix-www directory.
You can also use same principle directly in a template:
{* in the www/ of the application *}
{meta_html css '/css/mystyles.css'}
{meta_html css $j_basepath.'css/mystyles.css'}
{* in the jelix-www/ *}
{meta_html js $j_jelixwww.'js/tooltip.js'}
{* in the www/ of a module *}
{meta_htmlmodule css 'mymodule', 'css/mystyles.css'}
{* link to an image *}
<img src="{jurl 'jelix~www:getfile', array('targetmodule=>'mymodule', 'file'=>'img/mypicture.png')}" />
See chapter about templates to know more about these features.
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 ¶
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.
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
.
minifyExcludeCSS = "file1.css,file2.css"
- minifyExcludeJS = "jquery.wymeditor.js" +minifyExcludeJS = "jelix/wymeditor/jquery.wymeditor.js"
; bootstrap file for Minify. indicate a relative path to the basePath.
minifyEntryPoint = minify.php
</code>