Customizing the Document with Joomla! 1.5: Part 2

Exclusive offer: get 50% off this eBook here
Joomla! 1.5 Development Cookbook

Joomla! 1.5 Development Cookbook — Save 50%

Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes

$26.99    $13.50
by James Kennard | September 2009 | Cookbooks Joomla! MySQL Content Management Open Source PHP

Read Part One of Customizing the Document with Joomla! 1.5 here.

Creating a PDF in a component

This recipe explains how to create a PDF view in a Joomla! MVC component. Adding PDF views is a relatively quick process, and it significantly improves the functionality of a component.

Getting ready

Like any other view format, we must create a new JView subclass to create a PDF view. This should be located in the corresponding view's folder and the file should be named view.pdf.php. For example, for the myview view in the mycomponent component, we create the components/com_mycomponent/views/myview/view.pdf.php file, in which we place the MycomponentViewMyview class, which extends JView.

How to do it...

The first thing we do is override the display() method in order to change the PDF document. We modify the document using the mutator methods. The first method changes the document title, this is the title normally shown in the title bar of the PDF viewer.

$document->setTitle($title);

The next method changes the filename. This is especially useful if the user is likely to save the file, as this will be the default name the user is prompted to save the file as.

$document->setName($filename);

The next method sets the document description, sometimes referred to as the subject. This should only be a very brief description of the document.

$document->setDescription($description);

The next method sets the document metadata. Currently, only keywords are supported. It is possible to set other metadata, but it will not be used in the document.

$document->setMetaData('keywords', $keywords);

So far, all of the methods do not print anything to the body of the PDF itself. The next method adds a common header to every page. Note that the header text itself is not formatted.

$document->setHeader("My PDF Document TitlenMy Subtitle");

Lastly, we can add content to the main body of the PDF document. We achieve this in the normal way by simply outputting the content.

echo 'This is my PDF! ';

The outputted data can be formatted using some basic HTML tags. The following tags are supported:

Type

Tags

Format

<b>, <u>, <i>, <strong>, <em>, <sup>, <sub>, <small>, <font>

Heading

<h1>, <h2>, <h3>, <h4>, <h5>, <h6>

Indentation

<blockquote>

Linked

<a>, <img>

List

<ol>, <ul>, <li>

Spacing

<p>, <br>, <hr>

Table

<table>, <tr>, <td>, <th>

Joomla! 1.5 Development Cookbook Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes
Published: September 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

See also

For information about working with other document types, refer to the remaining recipes in this article—Creating an RSS or Atom feed in a component, Outputting a RAW document from a component, and Using a custom JDocument in a component (PHP 5 only).

Creating an RSS or Atom feed in a component

This recipe describes how to create an RSS (Really Simple Syndication) or Atom (RFC 4287) feed.

Getting ready

Like any other view format, we must create a new JView subclass to create a feed view. This should be located in the corresponding view's folder and the file should be named view.feed.php. For example, for the myview view in the mycomponent component, we create the components/com_mycomponent/views/myview/view.feed.php file. Here, we place the MycomponentViewMyview class, which extends JView.

How to do it...

Unlike the other document formats, the feed document does not handle direct output. To modify the feed, we must tell the document object everything we want to do. We start by modifying the document itself. At the very least, we need to set the title of the document.

// get the document
$document =& JFactory::getDocument();
// set the feed title
$document->setTitle('My Feed');

There are other things we might want to set in the feed using the JDocumentFeed::set() method. For example, we can set the copyright notice.

// set the feed title
$document->set('copyright', '(c) 2009 Packt Publishing');

Next, we add the items to the document we want to appear in the feed. To do this, we need to iterate over the data we are adding. In each iteration, we create a new JFeedItem object and add it to the document. The following example assumes that $currentRecord is the current object we are using to create a feed item:


// create new item
$item = new JFeedItem();
// set the required feed item data
$item->set('title', $currentRecord->name);
$item->set('link', $currentRecord->url);
$item->set('description', $currentRecord->description);

Once we have created a new JFeedItem object, we must add it to the document.

// add the feed item
$document->addItem($item);

How it works...

The values we can set in the document using the JDocumentFeed::set() method are detailed in the following table. The RSS and Atom columns show how these values are used by Joomla! to create the RSS and Atom feeds respectively. Note that these do not necessarily correspond to the RSS and Atom requirements. For more information, refer to http://www.rssboard.org/rss-specification and http://www.ietf.org/rfc/rfc5023.txt.

Name

Description

RSS

Atom

category

Category to which the channel belongs

OPTIONAL

NO

copyright

Copyright notice

OPTIONAL

NO

docs

URI to documentation describing the format(1)

OPTIONAL

NO

editor

Name of the managing editor

OPTIONAL (2)

OPTIONAL

editorEmail

Email address of the managing editor

NO

OPTIONAL

image

Object of the JFeedImage type that defines an image associated with the feed

OPTIONAL

NO

lastBuildDate

Date when the feed was last built

IGNORED (3)

NO

pubDate

Date when the channel was last published

OPTIONAL

NO

rating

PICS rating; refer to http://www.w3.org/PICS/

OPTIONAL

NO

skipDays (4)

Days of the week when an aggregating client-client that combines several feeds-should not bother updating the feed

OPTIONAL

NO

skipHours (5)

Hours when an aggregating client-client that combines several feeds-should not bother updating the feed

OPTIONAL

NO

syndicationURL

Automatically generated URI to Atom feed

IGNORED

IGNORED

ttl

Maximum number of minutes to cache feed

OPTIONAL

NO (6)

webmaster

Email address of the webmaster

OPTIONAL

NO

 

  1. For RSS this should be http://www.rssboard.org/rss-specification
  2. For RSS this should be the email address of the managing editor
  3. Last build date is always now (unless cached)
  4. In the string form SaturdaySunday
  5. In the string form nn+1
  6. Atom uses HTTP caching, for more information refer to the Controlling client caching of responses recipe earlier in this article

Items in the feed are represented as JFeedItem objects. The following table describes values in these objects that we can set. The RSS and Atom columns show how these values are used by Joomla! to create the RSS and Atom feed items respectively. Note that again these do not necessarily correspond to the RSS and Atom requirements. For more information, refer to http://www.rssboard.org/rss-specification and http://www.ietf.org/rfc/rfc5023.txt.

Name

Description

RSS

Atom

author

Name or email of the user who created the item (1)

OPTIONAL

OPTIONAL

authorEmail

Email address of the user who created the item

NO

NO

category

Name of category in which the item resides

OPTIONAL

NO

comments

URI of the page where comments about the item are available

OPTIONAL

NO

description

Description of the item, for example introduction text to a content item

REQUIRED

OPTIONAL

date (2)

Date when the item was published

OPTIONAL

OPTIONAL

enclosure

Object of the JFeedEnclosure type that defines a related media object, for example an MPEG

OPTIONAL

OPTIONAL

guid

Globally Unique Identifier (3)

OPTIONAL

NO

link

URI to the full story

REQUIRED

REQUIRED

pubDate

see date instead

NO

NO

source

RSS channel to which the item belongs

NO (4)

NO

title

Name or title of the feed item

REQUIRED

REQUIRED

  1. For Atom this should be an email address, for RSS this should be a username
  2. This is not technically part of JFeedItem, but the document renderers use this instead of pubDate
  3. Usually easiest to use the URI for the item
  4. Not yet implemented

There's more...

Creating feeds is all well and good, but there is little point in creating them unless the users know how to access them. The following RSS icon was created by Mozilla and has since been accepted as the standardized feed icon for RSS 1.0, RSS 2.0, and Atom 1.0 feeds. For more information, refer to http://www.mozilla.org/foundation/feed-icon-guidelines/

Customizing the Document with Joomla! 1.5: Part 2

The first place we tend to add links to feeds is in the content of a web page. When we do this, we need only create a normal hyperlink with a few extra attributes. Those attributes are rel and type, and they should be used as shown in the following code snippet:

<a rel="alternate"
type="application/rss+xml"
href="<?php echo $rssLink; ?>">Feed</a>

Most modern browsers are capable of displaying a feed icon in one of their toolbars if the web site informs the browser that there is an alternative way of viewing the current content as a feed. For example, if we browse to the Joomla! announcements page in Firefox, a feed icon appears in the address bar.

Customizing the Document with Joomla! 1.5: Part 2

To tell a browser about feeds, we must add a <link> tag to the document header. To do this, we use the JDocumentHTML::addHeadLink() method. Note that this only works for HTML documents.

// get the document
$document =& JFactory::getDocument();
// add the link tag
$attribs = array("type" => "application/rss+xml",
"title" => "My RSS Feed");
$document->addHeadLink($rssLink, "alternate", "rel", $attribs);

The previous example deals explicitly with RSS. Ideally, we should also add an Atom link. This will allow the user to choose his or her preferred format. This will output something like this:


<link href="rss.xml"
rel="alternate"
type="application/rss+xml"
title="My RSS Feed" />

See also

For information about working with other document types, refer to the previous recipe Creating a PDF in a component and the remaining recipes in this article, Outputting a RAW document from a component and Using a custom JDocument in a component (PHP 5 only).

Outputting a RAW document from a component

This recipe explains how to output a document other than an HTML, PDF, or Feed document. For the purposes of this recipe, we will output a text file.

How to do it...

To output a raw document, we must specify the format in the request. For example:

http://example.org/index.php?option=com_mycomponent&format=text

The next stage is to create a JView subclass capable of handing the format text. The view name must be view.text.php. This should be located in the relevant view folder. For example, for the myview view in the mycomponent component, the file will be located in components/com_mycomponent/views/myview/. The file must contain the MycomponentViewMyview class, which extends JView.

/**
* Text view class
*/
class MycomponentViewMyview extends JView {
}

In this class, we override the JView::display() method. In this method, we change the MIME type of the response and we output the response.

/**
* Text view class
*/
class MycomponentViewMyview extends JView {
/**
* Display the view
*
* @param string $tpl template file (not used)
*/
function display($tpl = null) {
// get the document
$document =& JFactory::getDocument();
// set the MIME type
$document->setMimeEncoding('text/plain');
// get the item we want to display
$item =& $this->get('Data');
// output the text file
echo $item->title . "nn" . $item->text;
}
}

How it works...

Selecting the format in the request determines the type of document. The table in the article introduction describes each of the document types. In this instance, we are invoking JDocumentRaw by using a format value that none of the other JDocument classes can handle.

By default, the JDocumentRaw class uses a MIME type of text/html. It is perfectly safe to change this to suit the data we are returning to the browser. In the example, we set the MIME type as text/plain.

Outputting data in a RAW document is no different from any other view. We simply throw out the data exactly as we want it to be sent in the response.

There's more...

It can be useful to instruct the browser to download the response as opposed to displaying it inline. We can achieve this by changing the disposition of the response body.

// change disposition of this MIME part
JResponse::setHeader('Content-Disposition', 'attachment');

We can use the static JResponse::setHeader() method to replace or add any MIME headers to the response. For more information, refer to the official Joomla! API site at http://api.joomla.org

See also

For information about working with other document types, refer to the previous two recipes Creating a PDF in a component and Creating an RSS or Atom feed in a component, and refer to the next recipe Using a custom JDocument in a component (PHP 5 only).

 

Using a custom JDocument in a component (PHP 5 only)

This recipe explains how to create and use a custom JDocument in a component. For he purposes of this recipe, we will create a JDocument class to handle JSON-RPC.

How to do it...

We start by creating a new JDocument class. We will create a class named JDocumentJSONRPC. Although the location of this class is unimportant, if we are following the normal Joomla! way of doing things, the best place to put this is probably in the classes folder in the root of the component's administrative folder. We begin by defining the class. The class extends the abstract JDocument class.

/**
* JDocumentJSONRPC class, provides an easy interface to
* display a JSON RPC response.
*/
class JDocumentJSONRPC extends JDocument {
/**
* Class constructor
*
* @param array $options Associative array of options
*/
function __construct($options = array()) {
// let the parent class do its bit
parent::__construct($options);
// set the MIME type
$this->setMimeEncoding("application/json");
}
}

A JSON-RPC response is always an object, and it always contains jsonrpc, id, and result or error. The value of jsonrpc is static, so we will ignore that for now and add the rest to our class.

var $_id = 0;
var $_result = null;
var $_error = null;

For each of these we supply a mutator that will allow us to set the values.

/**
* Sets the repsonse ID. This value should always be equal
* to the incoming request ID.
*
* @param int $id Response ID
* @access public
*/
function setId($id) {
$this->_id = intval($id);
}
/**
* Sets the result of the procedure call.
*
* @param mixed $result Procedure call result
* @access public
*/
function setResult($result) {
// flush the error, we don't need it any more
$this->_error = null;
// define the result
$this->_result = $result;
}
/**
* Sets the error
*
* @param int $code Error code
* @param string $message Error message
* @access public
*/
function setError($code, $message) {
// flush the result, we don't need it any more
$this->_result = null;
// define the error object
$this->_error = new stdClass();
$this->_error->code = intval($code);
$this->_error->message = (string)$message;
}

The last method we add is where the magic occurs. The JDocument::render() method is used to generate the output from the request, and the method returns that output as a string. We need to override this method in order to create our JSON-RPC response.

function render($cache = false, $params = array()) {
// create the response object
$response = new stdClass();
$response->jsonrpc = "2.0";
$response->id = $this->_id;
// set the error or result
// these are always mutually exclusive
if (is_object($this->_error)) {
$response->error = $this->_error;
} else {
$response->result = $this->_result;
}
// let the parent deal with the headers
parent::render($cache, $params);
// return the JSON-RPC response
return json_encode($response);
}

We're nearly there! Only one thing is left to do. Joomla! is built such that the document object is always created from one of the core JDocument classes. What we need to do is replace the current Joomla! document object with an instance of our JDocumentJSONRPC class.

$document =& JFactory::getDocument();
$document = new JDocumentJSONRPC();

We are now ready to start using our custom JDocument! For example, we could set an error.

$document->setError(-32601, 'Procedure not found.');

This will produce the following:

{"jsonrpc":"2.0","id":0,"error":{"code":-32601,"message":"Procedure
not found."}}

Or on a more positive note, we might have something like this:

$result = "Joomla! 1.5 Cookbook";
$document->setResult($result);

This will produce the following:


{"jsonrpc":"2.0","id":0,"result":"Joomla! 1.5 Cookbook"}

How it works...

Jumping in and replacing the Joomla! document object is obviously something that we won't find in the normal Joomla! documentation, especially because it requires PHP 5. But that doesn't make it unadvisable. The much anticipated translation tool Nooku, from Joomlatools, uses exactly the same approach to deal with the DBO.

Of course, we must replace the document object as early as possible. Failure to do so could result in unexpected behavior. In fact, the best time and place to do this is at the start of the component's root file. Here's an example:

// use the format request value to check for document type
if (JRequest::getCmd("format") == "jsonrpc") {
// get the class
require_once($pathToJDocumentJSONRPC_Class);
// replace the document
$document =& JFactory::getDocument();
$document = new JDocumentJSONRPC();
}

Notice how we use the format request value. This is the same value that is used to normally determine the JDocument class we want to use. It also happens to mean that the document we are replacing will be of the type JDocumentRAW.

There's more...

Our example explicitly uses JSON-RPC. So, is there a way we can use the example class in the real world? Indeed there is. But one thing is missing—there is no parsing of the JSON-RPC request.

JS ON-RPC can accept POST and GET requests. However, POST is the preferred format. The following example function getJSON_RPC_Request() deals with the POST request data by reading it from php://input and decoding it. The example also checks to make sure the request data is valid.

/**
* Decodes JSON-RPC POST request data
*
* @return mixed request object or false on fail
*/
function getJSON_RPC_Request() {
// only deals with POST requests
if (JRequest::getVar('REQUEST_METHOD', null, 'SERVER') != 'POST')
{
$document->setError(-32600, 'Invalid Request.');
return false;
}
// get raw POST data and decode
$rawRequest = file_get_contents('php://input');
$request = json_decode($rawRequest);
// check request was successfully decoded
if ($request == null) {
$document->setError(-32700, 'Parse Error.');
return false;
}
// check request is an object
if (!is_object($request)) {
$document->setError(-32600, 'Invalid Request.');
return false;
}
// check the request object is valid
$vars = get_object_vars($request);
if (!array_key_exists('method', $vars) ||
!array_key_exists('jsonrpc', $vars)) {
$document->setError(-32600, 'Invalid Request.');
return false;
}
// set the response ID if an ID was provided
if (array_key_exists('id', $vars)) {
$document->setId($request->id);
}
// all done!
return $request;
}



This ultimately results in a $request object that defines what we should be doing. If an error has been set in the document, we know that we should not attempt to continue because the request is illegal.

See also

For information about working with other document types, refer to the previous three recipes—Creating a PDF in a component, Creating an RSS or Atom feed in a component, and Outputting a RAW document from a component.

Summary

This article discusses the ways in which we can modify the response by working with the Joomla! document object. Joomla! uses a JDocument object to handle response data. Because JDocument is abstract, the Joomla! document object will always be a subtype of JDocument.

[ 1 | 2 ]

If you have read this article you may be interested to view :

 

Joomla! 1.5 Development Cookbook Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes
Published: September 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


James Kennard

James Kennard is a computer programmer. He has worked with various PHP and MySQL applications, since 2002. He quickly discovered Mambo/Joomla! because of its flexible extension manager. James currently maintains one open-source Joomla! component, which has been translated into over fifteen languages. Moreover, he has plans to build two more open-source components. Examples of his work can be found on his personal website www.webamoeba.co.uk.

Books From Packt

Symfony 1.3 web application development
Symfony 1.3 web application development

Zend Framework 1.8 Web Application Development
Zend Framework 1.8 Web Application Development

Papervision3D Essentials
Papervision3D Essentials

Joomla! 1.5 SEO
Joomla! 1.5 SEO

Joomla! 1.5x Customization: Make Your Site Adapt to Your Needs
Joomla! 1.5x Customization: Make Your Site Adapt to Your Needs

Pentaho Reporting 3.5 for Java Developers
Pentaho Reporting 3.5 for Java Developers

Drupal 6 Site Blueprints
Drupal 6 Site Blueprints

Ext JS 3.0 Cookbook
Ext JS 3.0 Cookbook

Your rating: None Average: 5 (1 vote)

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
h
n
R
C
Y
S
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software