Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ajax In Action (2006).pdf
Скачиваний:
63
Добавлен:
17.08.2013
Размер:
8.36 Mб
Скачать

100CHAPTER 3

Introducing order to Ajax

object and partly populate it with our search criteria. Because the object model is included from a separate file, we can reuse it for other searches, too. The XML View is generated against the object model now as well. Our next refactoring step is to separate the format of the XML from the process of generating it.

3.4.3Separating content from presentation

Our View code is still rather tangled up with the object, inasmuch as the XML format is tied up in the object-parsing code. If we’re maintaining several pages, then we want to be able to change the XML format in only one place and have that apply everywhere. In the more complex case where we want to maintain more than one format, say one for short and detailed listings for display to customers and another for the stock-taking application, then we want to define each format only once and provide a centralized mapping for them.

Template-based systems

One common approach to this is a template language, that is, a system that accepts a text document containing some special markup notation that acts as a placeholder for real variables during execution. PHP, ASP, and JSP are themselves templating languages of sorts, written as web page content with embedded code, rather than the code with embedded content seen in a Java servlet or traditional CGI script. However, they expose the full power of the scripting language to the page, making it easy to tangle up business logic and presentation.

In contrast, purpose-built template languages, such as PHP Smarty and Apache Velocity (a Java-based system, ported to .NET as NVelocity), offer a more limited ability to code, usually limiting control flow to simple branching (for example, if) and looping (for example, for, while) constructs. Listing 3.9 shows a PHP Smarty template for generating our XML.

Listing 3.9 PHP Smarty template for our XML output

<?xml version="1.0" encoding="UTF-8" ?> <garments>

{section name=garment loop=$garments}

<garment id="{$garment.id}" title="{$garment.title}"> <description>{$garment.description}</description> <price>{$garment.price}</price>

{if count($garment.getColors())>0} <colors>

{section name=color loop=$garment.getColors()} <color>$color->name</color>

{/section}

</colors>

Web server MVC

101

 

 

{/if}

</garment>

{/section}

</garments>

The template expects to see an array variable garments, containing Garment objects, as input. Most of the template is emitted from the engine verbatim, but sections inside the curly braces are interpreted as instructions and are either substituted for variable names or treated as simple branch and loop statements. The structure of the output XML document is more clearly readable in the template than when tangled up with the code, as in the body of listing 3.7. Let’s see how to use the template from our page.

Using the revised view

We’ve moved the definition of our XML format out of our main page into the Smarty template. As a result, now the main page needs only to set up the template engine and pass in the appropriate data. Listing 3.10 shows the changes needed to do this.

Listing 3.10 Using Smarty to generate the XML

<?php

header("Content-type: application/xml"); include "garment_business_objects.inc"; include "smarty.class.php";

$garment=new DataObjects_Garment; $garment->category = $_GET["cat"]; $number_of_rows = $garment->find(); $smarty=new Smarty; $smarty->assign('garments',$garments); $smarty->display('garments_xml.tpl'); ?>

Smarty is very concise to use, following a three-stage process. First, we create a Smarty engine. Then, we populate it with variables. In this case, there is only one, but we can add as many as we like—if the user details were stored in session, we could pass them in, for example, to present a personalized greeting through the template. Finally, we call display(), passing in the name of the template file.

We’ve now achieved the happy state of separating out the View from our search results page. The XML format is defined once and can be invoked in a few lines of code. The search results page is tightly focused, containing only the

102CHAPTER 3

Introducing order to Ajax

information that is specific to itself, namely, populating the search parameters and defining an output format. Remember that we dreamed up a requirement earlier to be able to swap in alternative XML formats on the fly? That’s easy with Smarty; we simply define an extra format. It even supports including templates within other templates if we want to be very structured about creating minor variations.

Looking back to the opening discussion about the Model-View-Controller pattern, we can see that we’re now implementing it quite nicely. Figure 3.8 provides a visual summary of where we are.

The Model is our collection of domain objects, persisted to the database automatically using our ORM. The View is the template defining the XML format. The Controller is the “search by category” page, and any other pages that we care to define, that glue the Model and the View together.

This is the classic mapping of MVC onto the web application. We’ve worked through it here in the web server tier of an Ajax application that serves XML documents, but it’s easy to see how it could also apply to a classic web application serving HTML pages.

Depending on the technologies you work with, you’ll encounter variations on this pattern, but the principle is the same. J2EE enterprise beans abstract the Model and Controller to the point where they can reside on different servers.

.NET “code-behind” classes delegate the Controller role to page-specific objects, whereas frameworks such as Struts define a “front controller” that intercepts and routes all requests to the application. Frameworks such as Apache Struts have worked this down to a fine art, refining the role of the Controller to route the user between pages, as well as applying at the single-page level. (In an Ajax application, we might do this in the JavaScript.) But in all cases, the mapping is

Server

Controller

PHP

Web browser

Smarty

View

Model

Figure 3.8

MVC as it is commonly applied in the web application. The web page/servlet acts as the Controller and first queries the Model to get the relevant data. It then passes this data to the template file (the View), which generates the content to be forwarded to the user. Note that this is a read-only situation. If we were modifying the Model, the flow of events would differ slightly, but the roles would remain the same.