smarty ajax冲突,Ajax 与 smarty

Ajax and Smarty, Part 1: Develop Ajax applications with

Smarty

Build Ajax applications using PHP, the Smarty template

engine, and the jQuery framework

Andrei Cioroianu, Senior Developer and Consultant,

Devsphere

Andrei Cioroianu is the founder of Devsphere, a provider of Java

EE development and Web 2.0/Ajax consulting services. He's been

using Java and Web technologies since 1997 and has 12 years of

professional experience in solving complex technical problems and

managing the full life cycle of commercial products, custom

applications, and open-source frameworks. You can reach Andrei

through the contact form at www.devsphere.com.

Summary: Smarty is a PHP template

engine that lets you separate the business logic from the

presentation in your Web applications. Smarty currently has no

built-in Asynchronous JavaScript and XML (Ajax) support, but its

plug-in architecture lets you extend it easily and use it together

with JavaScript frameworks, such as jQuery. This series describes

how to use Smarty in Ajax applications, how to create Smarty

plug-ins, and how to improve the code quality of your Web

applications, making the code more readable and easier to

maintain.

Date: 27 Apr 2010

Level:  Intermediate

PDF: A4 and Letter (46KB | 14 pages)Get Adobe®

Reader®

Also available in:

Korean

Russian

Japanese

Activity: 14986 views

Comments:

Average rating from 7 votes (You rated this 5 stars)

You'll also learn how to build a form that has two versions, one

letting the user enter data in the input fields and the other using

hidden fields and presenting the data in a non-editable manner. By

clicking a button, the user can switch between the two versions of

the form, submitting the data to the server with Ajax and

retrieving the HTML content that is needed to update the page. In

addition, the form would still work if JavaScript was disabled in

the Web browser.

The last section of the article contains instructions for

configuring Smarty and the sample application. This process is a

bit complicated if your server or workstation has SELinux enabled.

The extra commands are a small price to pay for the enhanced

security provided by SELinux. You'll find this information useful

for any Web application that has to modify its public files, such

as content management systems and Web sites that allow their users

to upload content. No matter if you use Smarty, a popular CMS, or a

custom-built system, you'll run into the same configuration

problems related to SELinux as soon as your code tries to modify

the Web files. This article shows how to solve them, using the

restorecon, chcon, and setsebool commands of Linux®.

In this section, learn how to build Smarty templates that

produce the responses for the Ajax requests. You can use any of the

common formats, such as JSON, XML, or HTML. The Smarty syntax was

designed primarily for HTML, which makes it very suitable for XML

as well. However, it is a bit harder to build JSON responses with

Smarty because template constructs use { and } in their syntax,

which means you'll have to escape these two characters when they

are used by JSON. You'll see, however, that it is possible to

change the Smarty delimiters to avoid this syntax conflict. You'll

also learn how to create custom modifiers and functions that are

registered to the Smarty framework so that you can use them in your

templates.

Let's start with a simple example (shown in Listing 1) that

generates an XML response that can be consumed by an Ajax client.

First of all, the PHP code should set the content type and the

no-cache headers, which ensure that the Web browser won't cache the

Ajax responses. If you haven't used Smarty before, here is a quick

explanation of what the demo_xml.php file is doing. It includes the

Smarty class with require, creates a new instance of this class,

sets its compilation and debugging flags, creates two variables

named root_attr and elem_data with assign(), and then invokes a

Smarty template named demo_xml.tpl with display(), which will

generate the XML response.

header("Content-Type: text/xml");

header("Cache-Control: no-cache");

header("Pragma: no-cache");

require 'libs/Smarty.class.php';

$smarty = new Smarty;

$smarty->compile_check = true;

$smarty->debugging = false;

$smarty->force_compile = 1;

$smarty->assign("root_attr", "<

abc & def >");

$smarty->assign('elem_data', array("111", "222",

"333"));

$smarty->display('demo_xml.tpl');

?>

The demo_xml.tpl template (see Listing 2) produces a

element that has an attribute

whose value is retrieved from the root_attr variable created in the

demo_xml.php file. The , ", ' and

& characters are replaced with

<, >, ",

', and &, respectively,

using the escape modifier of Smarty. Within the root element, the

template uses the {section} function of Smarty to iterate over the

elements of the elem_data array, which is the second variable

assigned in the demo_xml.php file. For each element of the array,

the demo_xml.tpl template generates an XML element containing the

value retrieved from the array.

attr="{$root_attr|escape}">

{section

name="d" loop=$elem_data}

{$elem_data[d]|escape}

{/section}

Listing 3 contains the XML output produced by the demo_xml.php

file and the demo_xml.tpl template.

111

222

333

The demo_json.php file (shown in Listing 4) sets the no-cache

headers, and creates and configures the Smarty object just like the

example in Listing 3. In addition, it defines two functions named

json_modifier() and json_function(), which call json_encode() of

PHP. The two functions are registered to Smarty so that they can be

used in templates, as you'll see later in this section. After that,

the demo_json.php file creates a few Smarty variables of various

types: a string, a number, a boolean, and an array. Then, the PHP

example executes the demo_json.tpl template to produce the JSON

response.

header("Content-Type: application/json");

header("Cache-Control: no-cache");

header("Pragma: no-cache");

require 'libs/Smarty.class.php';

$smarty = new Smarty;

$smarty->compile_check = true;

$smarty->debugging = false;

$smarty->force_compile = 1;

function json_modifier($value) {

return

json_encode($value);

}

function json_function($params, &$smarty) {

return

json_encode($params);

}

$smarty->register_modifier('json',

'json_modifier');

$smarty->register_function('json',

'json_function');

$smarty->assign('str', "a\"b\"c");

$smarty->assign('num', 123);

$smarty->assign('bool', false);

$smarty->assign('arr', array(1,2,3));

$smarty->display('demo_json.tpl');

?>

Instead of registering the plug-ins (such as modifiers or

functions) to Smarty, you can follow some special naming convention

described in the Smarty documentation (see Resources). You can then place your code in a plug-ins

directory so that your Smarty modifiers and functions can be used

in any Web page of the application.

Because both JSON and Smarty use { and } in their syntax, you

must use {ldelim} and {rdelim} in your Smarty templates to generate

the { and } characters of the JSON response. You can also place {

and } between {literal} and {/literal}. As you'll see in another

example, it is possible to change the Smarty delimiters to avoid

this inconvenience.

The demo_json.tpl template (see Listing 5) uses the json

modifier to encode the values of the four variables that are set in

the demo_json.php file. This is useful, for example, to escape the

quotes and other special characters such as tabs and new lines in a

string. Smarty will call the json_modifier() function from the

demo_json.php file each time the template uses |json. The json

modifier must be preceded by the @ character so that the array

variable can be passed to json_modifier(). Without the @ character,

the modifier function would be called for each element of the

array.

The {json ... } construct from the demo_json.tpl template is

translated to a call to json_function() of the demo_json.php file.

The function gets the attributes from the template as an array

named params that is passed to json_encode(), which returns a JSON

representation of the PHP associative array.

{ldelim}

s: {$str|json},

n: {$num|json},

b: {$bool|json},

a: {$arr|@json},

o: {json os=$str on=$num ob=$bool oa=$arr},

z: {literal}{ x: 1, y: 2 }{/literal}

{rdelim}

Listing 6 contains the JSON output produced by the demo_json.php

file and the demo_json.tpl template.

{

s: "a\"b\"c",

n: 123,

b: false,

a: [1,2,3],

o: {"os":"a\"b\"c","on":123,"ob":false,"oa":[1,2,3]},

z: { x: 1, y: 2 }

}

To avoid the use of {ldelim} and {rdelim} in Smarty templates,

you can change the Smarty delimiters as shown in Listing 7.

$smarty->left_delimiter =

'

$smarty->right_delimiter =

'%>';

The template from Listing 8 generates the JSON response, using

the delimiters in the

Smarty constructs.

{

s: ,

n: ,

b: ,

a: ,

o:

%>,

z: { x: 1, y: 2 }

}

The example from this section shows how to use Smarty to

generate HTML content that is retrieved with Ajax. In addition, the

Web page has an HTML form whose data is submitted with Ajax to the

server, using the jQuery framework. If JavaScript is disabled in

the Web browser, the form still works properly and Smarty is still

used to produce the content on the server.

The demo_form.tpl template (see Listing 9) contains an HTML form

whose fields may be editable or not depending on the value of a

variable named edit_mode. This variable is set in the PHP code

invoking the template, as you'll see later in this section. The

value of edit_mode is also stored in a hidden field of the

form.

name="demo_form">

value="{if $edit_mode}true{else}false{/if}">

cellspacing="0">

...

Listing 10 shows the first field of the form, which is an input

box if edit_mode is true or a hidden field if edit_mode is false.

In the latter case, the non-editable value of the field is included

in the output with {$smarty.post.demo_text|escape}. When the user

submits the editable form, the demo_text parameter contains the

user's input. When the form is not editable, the parameter is still

present, thanks to the hidden field. Therefore, it is possible to

obtain the value of the post parameter with $smarty.post.demo_text

whether the form is editable or not.

Demo

Text:

{if $edit_mode}

value="{$smarty.post.demo_text|escape}">

{else}

value="{$smarty.post.demo_text|escape}">

{$smarty.post.demo_text|escape}

{/if}

The next input field of the form is a checkbox (see Listing 11).

In the editable version of the form, the input element has the

checked attribute only if the demo_checkbox parameter is present.

Similarly, the non-editable version of the form contains the hidden

form element only if the submitted form data contains the post

parameter named demo_checkbox.

Demo

Checkbox:

{if $edit_mode}

{if $smarty.post.demo_checkbox}checked{/if}>

{else}

{if $smarty.post.demo_checkbox}

value="On">

{/if}

{if $smarty.post.demo_checkbox}On{else}Off{/if}

{/if}

The following row of the form's table contains three radio

buttons (see Listing 12). The template's code determines which

radio button should be selected by comparing each button's value

with the demo_radio parameter. The non-editable form uses a hidden

input field to store the parameter's value and shows that value to

the user with $smarty.post.demo_radio.

Demo

Radio:

{if $edit_mode}

{if $smarty.post.demo_radio ==

'1'}checked{/if}>1

{if

$smarty.post.demo_radio == '2'}checked{/if}>2

{if $smarty.post.demo_radio ==

'3'}checked{/if}>3

{else}

value="{$smarty.post.demo_radio|escape}">

{$smarty.post.demo_radio|escape}

{/if}

The options of a form list are generated in a loop with

{section}, as shown in Listing 13. The current index of the loop is

assigned to a template variable named demo_counter, which is

compared with the value of the option element being generated to

determine if the option should be selected.

Demo

Select:

{if $edit_mode}

size="1">

{section name="demo_section" start=10 loop=100 step="10"}

{assign var="demo_counter"

value=$smarty.section.demo_section.index}

$demo_counter}

selected{/if} value="{$demo_counter}">

{$demo_counter}

{/section}

{else}

value="{$smarty.post.demo_select|escape}">

{$smarty.post.demo_select|escape}

{/if}

The submit button has a different label (Save or Edit) depending

on the value of the edit_mode flag (see Listing 14). The onclick

attribute contains a call to a JavaScript function named

submitDemoForm(). As you'll see later in the article, this function

uses Ajax to submit the form's data to the server and returns false

so the Web browser doesn't submit the same data one more time in

response to the button's click. If JavaScript is disabled, however,

submitDemoForm() won't be called, and the Web browser does submit

the form to the server. Therefore, the form will work properly no

matter if JavaScript is enabled or disabled.

 

{if $edit_mode}Save{else}Edit{/if}

The demo_page.tpl file (see Listing 15) contains two

elements, one for jQuery and

the other for the JavaScript file of the sample application. The

page template includes the form template within a

element, using the {include}

function of Smarty.

Demo

{include file="demo_form.tpl"}

The demo_html.php file (shown in Listing 16) acts as a bridge

between Ajax and Smarty, handling the Ajax requests and using

Smarty to generate the Ajax responses with the demo_form.tpl

template, which is invoked only if an Ajax header is present. This

header is set in the JavaScript code, as you'll see in the

following sub-section. The code uses the demo_page.tpl template if

the Ajax header is missing, which means that either this is the

initial page request made by the Web browser or JavaScript is

disabled. After each request the value of the edit_mode flag is

inverted to alternate the editable form and its non-editable

version.

header("Cache-Control: no-cache");

header("Pragma: no-cache");

require 'libs/Smarty.class.php';

$smarty = new Smarty;

$smarty->compile_check = true;

$smarty->debugging = false;

$smarty->force_compile = 1;

$edit_mode = @($_REQUEST['edit_mode'] == "true");

$smarty->assign("edit_mode", !$edit_mode);

$ajax_request = @($_SERVER["HTTP_AJAX_REQUEST"] == "true");

$smarty->display($ajax_request ? 'demo_form.tpl'

: 'demo_page.tpl');

?>

The submitDemoForm() function (see Listing 17) is called when

the form's button is clicked. It sends the form's data to the

server with jQuery, using the POST method and the same URL used by

the Web form. The form's data is encoded as a string using the

serialize() API of jQuery. The beforeSend() function, which is

called by jQuery before sending the Ajax request, is used in this

example to set the Ajax-Request header that is needed on the server

side to identify the Ajax requests. The success() function is

called when the Ajax response is received. This callback inserts

the response's content into the

element of the Web page.

function submitDemoForm() {

var form

= $("form[name=demo_form]");

$.ajax({

type: "POST",

url: form.action ? form.action : document.URL,

data: $(form).serialize(),

dataType: "text",

beforeSend: function(xhr) {

xhr.setRequestHeader("Ajax-Request", "true");

},

success: function(response) {

$("#demo_div").html(response);

}

});

return

false;

}

After unzipping the sample application, you should see a

directory named ajaxsmarty that contains the PHP files, a

JavaScript file, and fours sub-directories: cache, configs,

templates and templates_c. The templates directory contains the

Smarty templates of the sample application. The other three

sub-directories are empty.

Download the latest stable release of Smarty (see Resources) and unzip it. (The sample application was tested

with Smarty 2.6.25.) Next, copy the libs sub-directory of Smarty

into the ajaxsmarty directory, which is the main directory of the

sample application.

Upload or copy the ajaxsmarty directory (containing both the

sample application and Smarty's libs) into the html directory of

Apache. If you're using a Web hosting company for your server,

SELinux may be disabled because it would probably generate too many

support calls. If you are testing the application on your own Linux

installation, chances are SELinux is enabled, and you might get the

following error when requesting a PHP file from your browser:

"SELinux is preventing the httpd from using potentially mislabeled

files." The solution is to run the command from Listing 18 as

root.

restorecon -R -v /var/www/html/ajaxsmarty

At this point, you should be able to open into your browser

http://localhost/ajaxsmarty/, which shows three links. If you click

one of them you'll get the following Smarty error in the Web

browser: "Fatal error: Smarty error: unable to write to

$compile_dir '/var/www/html/ajaxsmarty/templates_c'. Be sure

$compile_dir is writable by the Web server user. in

/var/www/html/ajaxsmarty/libs/Smarty.class.php on line 1113"

The above error happens because the Smarty setup is not yet

complete. You must give the Web server user permissions to write

into the templates_c and cache directories. The right way to do

that is to change their owner as shown in Listing 19. Note that the

apache user name and the server's html directory might be different

on your computer.

chown apache:apache /var/www/html/ajaxsmarty/templates_c

chown apache:apache /var/www/html/ajaxsmarty/cache

If you don't have root access, you could change the write

permissions of templates_c and cache instead of using chown. You

should be able to do that using your FTP client, or you can use the

chmod command with the 777 parameter. Allowing any user to write

into those folders is not a very good idea, but it might be your

only immediate option if you cannot use chown. If your Web server

is public, you should contact the server administrator.

If SELinux is enabled on your computer, you might still get one

of the following errors in the browser: "SELinux prevented httpd

reading and writing access to http files." or "SELinux is

preventing httpd (httpd_t) write to ./templates_c

(public_content_rw_t)." The solution is to run the commands from

Listing 20 as root.

chcon -t public_content_rw_t

/var/www/html/ajaxsmarty/templates_c

chcon -t public_content_rw_t /var/www/html/ajaxsmarty/cache

setsebool -P allow_httpd_anon_write=1

The setsebool command with the allow_httpd_anon_write parameter

must be executed only once. It allows the httpd daemon to write

files in the directories labeled public_content_rw_t.

In this article, you learned how to build Smarty templates that

produce JSON, XML, and HTML responses for the Ajax requests, how to

use Smarty to build an Ajax form that still works if JavaScript is

disabled in the Web browser, and how to configure Smarty on Linux

machines that have SELinux enabled.

Description

Name

Size

Download method

Sample application for this article

ajaxsmarty_part1_src.zip

5KB

Learn

The Smarty

manual contains everything you need to know about Smarty.

Take a look at this sample

application based on Smarty.

"Separate

form and function in PHP applications with Smarty"

(developerWorks, July 2007) is an introduction to Smarty provided

by developerWorks.

The jQuery framework

complements Smarty, adding the needed JavaScript capabilities, such

as Ajax.

The developerWorks Web development zone

is packed with tools and information for Web 2.0 development.

The developerWorks Ajax resource center

contains a growing library of Ajax content as well as useful

resources to get you started developing Ajax applications

today.

Get products and technologies

Download Smarty and start using it

today.

Discuss

Take a look at the official Smarty forum.

Andrei Cioroianu is the

founder of Devsphere, a provider of Java EE development and Web

2.0/Ajax consulting services. He's been using Java and Web

technologies since 1997 and has 12 years of professional experience

in solving complex technical problems and managing the full life

cycle of commercial products, custom applications, and open-source

frameworks. You can reach Andrei through the contact form at

www.devsphere.com.

Report abuse

Thank you. This entry has been flagged for moderator

attention.

Report abuse

Report abuse submission failed. Please try again

later.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值