Home 文章 Servlet/JSP ????????????????????? Web ????????????????????????

feedsky
抓虾
google reader
my yahoo
????????????????????? Web ???????????????????????? E-mail
User Rating: / 0
PoorBest 
作者是 Administrator   
2008-06-21 21:35:22

后端开发人员必须要应对的一个棘手问题就是 HTML。在我的从业生涯中,我发现很少有开发人员特别热衷于编写和修改前端代码,这些工作对于向站点的访问者展示特定的输出而言非常必要。尽管这不太容易又有点单调乏味,但有些时候还是十分有必要的。很多开发人员都习惯于编写中间层和数据库代码,但却非常不愿意触及 HTML 和 CSS 所带来的前端的格式化、表、标记列表、属性和样式等。

常用的缩写词
  • CSS:级联样式表
  • HTML:超文本标记语言
  • XML:可扩展标记语言
  • XHTML:可扩展超文本标记语言
  • XSL:可扩展样式表语言

尽管极力想要成功处理 HTML,但很多 Web 站点在每次需要新的站点感观时无一例外地都要重写。要为站点重新设计皮肤,很多时候既费时又费力 — 尤其是当站点的代码已经相当一段时间没有被碰过的时候。

更糟糕的是,随着 Web 2.0 的出现,很多开发人员都对开发应采取何种方案颇感困惑。我们知道合适的方案必须是要提前计划好的(提供可靠的设计和架构),但由于预算和期限的问题,我们常常不得不牺牲质量。除非在下一次再次更新站点的外观时,您或您的客户均不在意从头制作 Web 站点,否则就必须确保代码整洁、最优化并在前端使用了最严格的代码编写技术以便为过渡到 Web 2.0(包括 Asynchronous JavaScript™ + XML,Ajax)打下稳固的基础。

此外,如果开发的 Web 站点有一个受数据驱动的组件,那么进行内容更改可能会更简单一些 — 可以使用一种基于 Web 的方式修改 Web 站点的内容,而不必在每次想要增加站点内容时都必须要修改实际的页面本身。本文讨论了上述问题以及这些问题的解决方法。

注意:本文使用的源代码均可在本文下面的 参考资料 一节找到。

典型的架构方式

本文讨论了编写整洁、最优化和严格代码背后的一些概念,尤其强调了在开发 Web 站点模板时要使用这些技术。首先,我将深入讨论一下这些概念,然后再向您展示如何将这些概念付诸实践来使用模板构建 Web 站点,模板有时又称为皮肤(skin)

图 1 所示,一个 Web 站点常常会被分成几个互相连接的块,比如保存客户有用数据的数据库以及站点的配置信息。数据库经常由组件和对象访问,而组件和对象又由另一层代码调用,这一层通常就是所谓的中间层。中间层是从浏览器发出的请求所途经的第一站。此请求通常是在用户单击某个动作时触发的。


图 1. 一个典型的架构
一个典型的架构

服务器处理了请求之后,响应(包括文本和图形)会以几种方式返回给浏览器,包括:

  • 纯 XML
  • XHTML
  • HTML
  • XML/XSL 组合
  • XHTML/CSS 组合

不恰当地格式化内容

现在格式化数据和图形的最常见方式是在 HTML 表内构造和组织所返回的内容。很多时候,这些数据都会通过标记和内联样式在所返回的 HTML 内被格式化。典型的代码应类似于 清单 1


清单 1. 一个不好的内容格式化示例
                
<table width="703" height="100%"  border="0" cellpadding="0" cellspacing="0">
	<tr>
		<td  colspan="5">&nbsp;</td>
	</tr>
	<tr>
		<td>&nbsp;</td>
		<td align="right">
			<img  src="/images/top_left_border.jpg"
		width="40"  height="26" /></td>
		<td  width="100%" height="26"  background="images/top_border.jpg" />
		<td  align="left">
			<img src="/images/top_right_border.jpg"
		width="36" height="26" /></td>
		<td style="line-height:20px;  color: red">
			<strong>
				This is some content that will be shown to site visitors
			</strong></td>
	</tr>

此段代码打破了 HTML 编码的所有规则和最佳实践。首先,它使将来维护和进一步修改文件变得十分困难,因为在每次打开文件时,都必须重新熟悉布局和样式,这会浪费很多时间。浪费时间的结果就是客户不满意,因为每次编写或修改代码的费用都是客户担负的。

第二,您永远不可能重新设计皮肤来为站点提供不同的观感。如果您试图这么做,那么最终毫无例外地都会抬高成本。

恰当地格式化内容

一种较好的做法是将所有格式化从此文件转到 CSS 文件。清单 2 给出了使用严格 XHTML 编码技术的一个 HTML 文件。如果仔细研究此段代码,就会发现对比 HTML 而言,它更像是 XML 代码(这种看法可能是对的)。


清单 2. 处理 XHTML 内容的一种较好的做法
                
<body>
  <div id="container">
    <div  id="header">
      <div  id="logo"><span></span></div>
        <div  id="search_area">
        <?php  mosLoadModules( 'user4' ); ?>
      </div>

      <div  id="flash_banner">
        <?php  mosLoadModules( 'user3' ); ?>
      </div>
    </div>

    <div  id="menu_bar">
      <?php  mosLoadModules( 'user5' ); ?>
    </div>

    <div  id="left_sidebar">
      <?php  mosLoadModules( 'left' ); ?>
    </div>

    <div id="content_top">
      <?php  mosMainBody(); ?>
    </div>

    <div  id="footer_area">
      <div  id="footer_left_corner">
        <span></span>
      </div>

      <div  id="footer_menu">
        <?php  mosLoadModules( 'user6' ); ?>
      </div>

      <div  id="footer_right_corner">
        <span></span>
      </div>
    </div>

  </div>

  <div id="signature">
    <span>Designed  and Powered By
      <a  href="http://www.axsyshosting.com" target="_blank">Axsys  Hosting</a>
    </span>
  </div>

</body>

清单 2 中的例子基于的是我为我的一个客户编写的模板(我稍候会详细介绍有关模板的内容),该模板是针对一个基于 Joomla 的站点设计的。清单 3 中展示了一个 CSS 文件,可用来将上述代码转变成 “美丽的事物”。


清单 3. 为 XHTML 文件提供格式化的 CSS 文件
                
body {
    text-align:  center; /* center hack */
    margin: 0px;
    font-family:  verdana;
  }

html {
  background:  #102a43 url(../images/background.jpg) 0 0 repeat-x;
  }

#container {
  display: block;
  background-color:  #e7eaf2;
  background-attachment:scroll;
  width: 849px;
  margin: 0 auto;
  text-align:  left;
  overflow:hidden;
  }

/* Header, Logo, Search Area, Cart Info, and Flash Banner */
#header {
  float: left;
  width: 849px;
  height: 242px;
  margin: 0px;
  padding: 0px;
  }

#logo {
  float: left;
  background:  #8f1b1b url(../images/site_logo.jpg)  no-repeat top left;
  width: 358px;
  height: 242px;
  margin: 0px;
  padding: 0px;
  }

/* Search Area */
#search_area {
  background:  #1a212c url(../images/search_box_bkgd.jpg) no-repeat top left;
  float: left;
  width: 263px;
  height: 32px;
  margin: 0px;
  padding: 0px;
  }

#search_area input.inputbox {
  float: left;
  margin: 0px;
  margin-top: 6px;
  margin-left:  15px;
  overflow:visible;
  height:15px;
  width:210px;
  padding: 0px;
  }

#flash_banner {
  float: left;
  background:  #bbc2d2 no-repeat top left;
  width: 491px;
  height: 170px;
  margin: 0px;
  padding: 0px;
  overflow:hidden;
  border:none;
  text-align:left;
  }

/* Menu Bar */
#menu_bar {
  float: left;
  background:  url(../images/menu_bar.jpg) 0 0 repeat-x;
  height: 33px;
  }

我认为这项技术并不是什么全新的技术。它存在的时间已经很长了,但经常被误认为是 “无关紧要的装饰物”,只有在时间允许时方可尝试一用。实际上,此技术是整个 Web 站点 —Zen Garden— 的全部主题,该站点专门提供了这样一个页面,该页面由很多将 CSS 作为格式化 XHTML 页面的惟一 手段的开发人员重新设计外观。请注意观察由来自全世界的开发人员开发并贡献出来的独立 CSS 文件的数量。这些都是轻松优雅地重新设计 Web 站点皮肤的很好的例子。理解了这些概念之后,就能很容易地使用它来为自己的站点制作模板了。

不用表获得想要的外观

所有这些设计都有一个共性:它们在没有动用令人头痛的表的情况下实现了想要的外观和布局,这之前,很多开发人员都依赖表获得理想的 Web 站点的布局。HTML 出现之初,在需要将数据以类似电子数据表的行列形式呈现的时候,几乎所有人都认为只有使用表才可以达到这一目的。否则,就应该考虑使用其他手段,比如 CSS 定位或浮动块。

开发模板

使用这种技术,不仅可以更改文本的字体、大小和颜色,而且还可以更改内容的放置和布局 — 在某些情况下 — 甚至可以将内容从纯文本更改为赏心悦目的图形。此技术可被应用到几乎各类站点(各种框架 —从 Microsoft® .NET 应用程序到 LAMP 应用程序再到 Java™ 应用程序)。

让我举一个例子说明。我目前接触到一个客户,他想要让主索引页能够提供一组 “外观和感觉” 的选项以供站点的访问者选择。用户所做的选择决定了站点的外观(例如放置、颜色和字体)。通过将此值提供给未来主页,我就确保了该主页能够动态带回正确的 CSS 文件。这可以用任何一种语言实现,但为了展示的目的,我给出了使用 PHP 实现此目的的过程。您可以访问和查看此代码的一个工作示例,链接可以在本文的 参考资料 部分找到。

首先,需要一个索引文件,可调用此文件来显示颜色(或模板)选项。如下所示的代码恰好能实现这一目的:

<body>
<h1>Template Article
</h1>
<ol>
  <li><a  href="home-page.php?template=blue">Blue  Appearance</a></li>
  <li><a  href="home-page.php?template=red">Red  Appearance</a></li>
  <li><a  href="home-page.php?template=green">Green  Appearance</a></li>
</ol>
</body>

正如您所见,作者们提供了完整链接,可将参数值传递给主页。此值被称为 template,但其名称是随意的,可以是任何想要的名字。在主页内,需要检索模板的值、存储该值并用它来调入(summon)请求模板(或 CSS)文件。如下所示的是实现的方法:

<?php
  $template =  $_GET["template"];
?>
<link href="<?php echo $template; ?>.css"  rel="stylesheet" type="text/css" />

模板值成为想要用来格式化内容的 CSS 文件的名称。您基本上可以将响应视为一个综合了内容(和任何图形)和样式及格式的漏斗。图 2 给出了一个综合了这些概念的概念性展示。


图 2. 格式化了的 XHTML 的展示
格式化了的 XHTML

现在,我们来看看您想要格式化的内容。清单 4 给出了一个没有样式的 XHTML 文件。它所提供的元素可完全使用 CSS 进行格式化。


清单 4. XHTML 文件
                
<body>
<h1>Template Article</h1>

<div id="paragraph1">As a developer, one of the worst things you have to contend with
on a daily basis is HTML. In my career, I haven't met too many developers who enjoy
writing or modifying the front-end code, which is absolutely necessary in order to
present any kind of output to your website's visitors. However difficult it may be, it
is nonetheless necessary. Most developers feel comfortable writing the middle tier
and database code, but loathe to deal with front-end formatting, tables, and the list
of tags, attributes, and styles that come along when dealing with HTML and its handsome
cousin, CSS.</div>

<div id="paragraph2">Even if you manage to tango with HTML at a successful level, most
websites are entirely rewritten each time a new look and feel is desired. To reskin the
site is just too expensive and confusing most of the time, especially if the site's
code has sat untouched for awhile.</div>

<p><a href="index.html">return to index page</a></p>

</body>

此文件只包含能提供结构给 XHTML 的元素,以便能轻松地使用 CSS 访问这些块。这里的规则是您应该在 XHTML 内有足够多的分区以便能够正确地重新布置和样式化内容。在本例中,使用了一个标题、两个 <div> 标记和一个链接。了解了如何使用 PHP 选择合适的 CSS 文件之后,让我们来看看这种技术所带来的输出,如 图 3 所示。


图 3. 使用了不同模板的相同主页
使用了不同模板的相同主页

如您所见,虽然调用的是同一主页,但不同的链接得到的该主页看起来却截然不同。这种转变是 CSS 以及在结果发送给浏览器之前的前端编码的结果。要让此技术发挥作用的关键是 <style> 标记,该标记在被发送到浏览器做进一步处理之前可被动态操纵。 清单 5 给出了蓝色样式化所需的样式表,清单 6 给出了红色处理所需的样式表,而 清单 7 则给出了绿色样式处理所需的样式表。


清单 5. 提供蓝色观感的 CSS 文件
                
body {
	background-color:  #33CCFF;
}

a {
	display: block;
	float:right;
	color: blue;
}

h1 {
	font-family:  Verdana, Arial, Helvetica, sans-serif;
	font-size:    18px;
	color:        #000099;
}

#paragraph1 {
	font-family:  "Times New Roman", Times, serif;
	font-size:    12px;
	color:        #0000FF;
}

#paragraph2 {
	margin:       20px;
	font-family:  Geneva, Arial, Helvetica, sans-serif;
	font-size:    14px;
	color:        #3366CC;
	text-decoration:  underline;
}


清单 6. 实现红色外观的 CSS 文件
                
body {
	background-color: #FFCCCC;
}

a {
	display: block;
	float:right;
	color: red;
}

h1 {
	float: right;
	font-family: Georgia, "Times New Roman", Times, serif;
	font-size:   22px;
	color:       #FF0000;
}

#paragraph1 {
	margin:      60px;
	font-family: "Century Gothic", Verdana, Arial, Tahoma;
	font-size:   9px;
	color:       #FF0033;
}

#paragraph2 {
	font-family: Geneva, Arial, Helvetica, sans-serif;
	font-size:   10px;
	color:		 #CC0033;
	text-transform: lowercase;
	font-style:  italic;
}


清单 7. 实现绿色格式化的 CSS 文件
                
body {
	background-color: #CCFFCC;
}

a {
	display: block;
	float:left;
	color: green;
}

h1 {
	position: absolute;
	left: 80px;
	top: 275px;
	font-family: Georgia, "Times New Roman", Times, serif;
	font-size:   22px;
	color: #006600;
}

#paragraph1 {
	float: right;
	margin: 30px;
	font-family: "Courier New", Courier, monospace;
	font-size:   11px;
	color: #00CC66;
}

#paragraph2 {
	float: left;
	position:absolute;
	display: block;
	left: 0px;
	top: 0px;
	margin: 10px;
	font-family: Geneva, Arial, Helvetica, sans-serif;
	font-size:  11px;
	color:  #66CC99;
	font-style: italic;
}

此主页包含一个 <h1> 部分、由 <div> 标记包围的两个参数以及一个 <a> 标记。所有这些元素以及主体均使用 CSS 修改。

请注意各种样式表间存在几个差异。其中的一些差异会更改元素的外观,而其他的几个差异则会修改颜色、字体、文本样式和背景。

在为自己的站点开发模板时应该注意的另一个问题是应该创建文件夹层次结构来很好地维护模板的各个部分。比如,如果模板需要图片,就可以将这些图片放到模板的图片文件夹当中。图 4 给出了文件夹层次结构的一个例子。


图 4. 模板的文件夹层次结构
模板的文件夹层次结构

添加数据驱动功能

了解了如何为 Web 站点创建模板之后,我们将要在本文结束之前添加最后一个功能:数据驱动。创建数据驱动的 Web 站点需要为您的站点创建一个管理模块。如果不需要对 Web 站点做变更,很多客户都看不到这样做的价值所在。一旦需要变更,即使是做很小的内容更改,他们都需要再次求助于开发人员。长此以往,客户的拥有成本就会增加。这对开发人员是件好事,对于客户则不然。

我经常这样讲给我自己的客户听并努力说服他们让我为其 Web 站点构建一个管理模块(也被称为 管理控制台),然后培训他们该如何自己操作管理控制台。这就让我的客户可以自己进行一些细微的内容修改,而不用等到我有时间才能为他们提供这类帮助。而且,建立管理控制台的费用要远比 Web 站点的整个生命周期内的内容更改费用低。

一个管理控制台既可以简单到只有几个页面来执行管理工作,也可以复杂到一个充满特性和功能的完整的 Web 站点来让客户能够定制内容甚至图像。图 5 展示了一个简单的管理控制台是如何被用来处理 Template Article Web 站点的数据的。


图 5. Admin Web 页面
Admin web 页面

我为最终的这个 Web 站点中的每个部分创建了所有的字段。如果我修改这些字段中的值并提交该表单,数据就会存储于服务器以备实际的 Web 站点日后访问。而且,我采用何种存储介质并不重要。它可以是一个很简单的文件(正如我在本例中所使用的)、一个数据库、一个 XML 文件或是 Web 站点需要的任何其他东西。

接下来,我要向您介绍我是如何为此 admin Web 页面创建代码的。此外,还会给出 Submit 按钮背后的代码。同样地,出于展示的目的,我使用 PHP 创建此页面的内容,如 清单 8 所示。


清单 8. 我的 admin 页面
                
<?php
	require_once("config.php");
?>

<body>
<h1>Template Article - Admin</h1>
<form id="form" name="form" method="post" action="admin.php">
	<input type="hidden" name="store" value="true" />
	<label>Heading:
		<input type="text" name="HEADING" id="heading" value="<?php echo
 HEADING; ?>"/>
	</label>

	<p>&nbsp;</p>
		<label>Paragraph 1:
			<textarea name="PARAGRAPH1" id="paragraph1" cols="45" rows="5">
				<?php echo PARAGRAPH1; ?>
			</textarea>
		</label>

	<p>
		<label>Paragraph 2
			<textarea name="PARAGRAPH2" id="paragraph2" cols="45" rows="5">
				<?php echo PARAGRAPH2; ?>
			</textarea>
		</label>
	</p>

	<p>
		<label>
			<input type="submit" name="button" id="button" value="Submit" />
		</label>

		<label>
			<input type="reset" name="button2" id="button2" value="Reset" />
		</label>
	</p>

</form>
</body>

要获得这个页面的在线版本,请参见 参考资料 中的链接。

代码的开始部分是一个文件,该文件包含了 <heading><paragraph><paragraph> 的定义。同样地,此数据的源可以是您所能想象得到的任何东西。为了简便起见,我选择使用包含数据的一个 PHP 文件。我每次将所发布的数据提交回服务器时,此文件都会重新创建。<form> 标记包含指回相同脚本的一个地址。我之所以可以这样做是因为此文件的顶部包含 if 语句,该语句可以检查潜在的输入字段 store 是否存在,而这永远被设置为 True。 清单 9 给出了此 PHP 文件的其余代码,这些代码实际上位于文件的顶部。


清单 9. admin 页面的其余部分
                
<?php
    if($_POST['store'] == 'true') {
      $config =  "<?php\n";
      foreach( $_POST  as $key => $value ) {
         $config  .= "define (\"$key\", \"$value\");\n";
    }
    $config .=  "?>";

    if ($fp =  fopen("config.php", "w")) {
        fputs($fp,  $config, strlen($config));
        fclose  ($fp);
    }
    else {
        echo  'Problem occurred while trying to save data into config.php';
        return  false;
    }
}
?>

现在,为了使用存储在 config.php 内的数据,我需要对主页做一些修改。清单 10 提供了主页所使用的新代码。


清单 10. 新主页使用了数据驱动功能
                
<body>
  <h1><?php echo HEADING; ?></h1>
  <div id="paragraph1"><?php echo PARAGRAPH1; ?></div>
  <div id="paragraph2"><?php echo PARAGRAPH2; ?></div>
  <p><a href="index.html">return to index page</a></p>
</body>

新主页让人立即耳目一新的是代码的显著缩减。数据也不再是直接放入 XHTML 文件,而是保存在其他地方再利用代码片段带入此页面。现在,XHTML 页面成了集成站点各个部分的地方。它包含页面的各个部分,不过没有任何实际内容或样式。

为了获得完整的概念,可以参看包含数据的 config.php 文件,如 清单 11 所示。


清单 11. config.php
                
<?php
define ("HEADING", "Template Article");

define ("PARAGRAPH1", "As a developer, one of the worst things you have to contend
with on a daily basis is HTML. In my career, I haven't met too many developers that enjoy
writing or modifying the front-end code, which is absolutely necessary in order to
present any kind of output to your website's visitors. However difficult it may be, it is
nonetheless necessary. Most developers feel comfortable writing the middle tier and
database code, but loathe to deal with front-end formatting, tables, and the list of
tags, attributes, and styles that come along when dealing with HTML and its handsome
cousin, CSS.");

define ("PARAGRAPH2", "Even if you manage to tango with HTML at a successful level,
most websites are entirely rewritten each time a new look and feel is desired. To reskin
the site is just too expensive and confusing most of the time, especially if the site's
code has sat untouched for a while.");
?>

正如您所想,配置文件(或数据库,如果您选择数据库进行保存)可用于 Web 站点需要实现的任何事情。不仅可以保存语言信息(比如标题和段落),还可以保存图形、格式、样式等等。有无限可能。基于配置值,还可以更改站点以支持不同的语言。

结束语

Web 站点开发人员需要考虑布局和格式化其 Web 站点的各种可能方式。继续使用内联样式和表来创建 Web 页面变得十分困难并且成本昂贵。若提前计划,您可以实际构建非常有助于模板或可重设皮肤的系统的 Web 站点。

如今已经存在几种技术来协助开发人员实现基于模板的站点。例如,PHP 具有一个流行的模板,名为 Smarty Template Engine,我非常推崇(参见 参考资料)。其他的语言也有类似技术。为 Web 站点(尤其是可由大众访问的站点)使用基于模板的系统的好处是可以由您提供内容和后端功能,由他人提供格式和样式。更好的是,如果是与设计团队一同开发,团队之间就可以很好地协同工作,而不会相互交叉和影响,因为现在可以真正地将 Web 站点的各个组成块分成多个文件,这些文件可随时集中在一起。

添加数据驱动的元素让 Web 站点能够更加灵活、让非专业技术人员或 Web 站点的所有者也能对站点内容(文本和图形)进行更改。而这一点是大多数内容管理系统的基础所在。



参考资料

学习

获得产品和技术


最近更新 ( 2008-06-21 21:35:22 )
 
Java家,