这个 共分 5 部分的系列文章 向您介绍了如何使用 Perl 和 Apache 构建一个照片共享网站,从而访问 Amazon 的 Simple Storage Service (S3) 和 SimpleDB。在这最后一期文章中,我们将考察完整 mod_perl 站点的模板,包括一个用于索引的模板、三个用于上传的模板(通用模板、S3 表单和 URL 添加物)、一个用于浏览照片和评论的模板,以及一个用于递归式地浏览(即遍历浏览)照片评论的模板。
在最后一期文章中,我们将了解完整的 mod_perl 站点(这一次将讨论模板;代码库位于 功能丰富的 Perl:Perl 和 Amazon 云,第 4 部分)。我再一次鼓励您阅读源代码。该站点是功能性的,但是许多细节都没有在本系列中详细介绍,我希望您能理解这些细节或者了解还存在疑问的地方。您可以通过书店或搜索引擎查找信息。
|
特别是,设置一个完整的 mod_perl 站点并使用 Template Toolkit 是非常广泛的主题,并且已经介绍过许多次,因此这里不再解释。最佳学习途径就是了解每一个问题和难点,直到网站可以正常运行。本系列将给出可以使网站正常运行所需的所有内容 — 但是需要由您来将所有内容结合起来。
和此前的文章一样,我将使用 share.lifelogs.com 作为域名。当在您自己的环境中使用时,应根据需要修改它。
index.tmpl
我们将按照从上而下的顺序讨论模板(policy.tmpl 在 第 4 部分 已作讨论)。有关 Template Toolkit 语法的解释,见 参考资料 小节。我将解释比较复杂的部分。
index.tmpl 是一个简单的 HTML 页面。这里惟一需要注意的是所有 URI 都是相关的,因此这个模板和其他所有模板都可以用于任何域。
清单 1. index.tmpl,简单的 HTML
<html> <head> <title>Share Pictures</title> </head> <body> <h1>Share Pictures</h1> You can <a href="/upload">upload or add images</a> or <a href="/browse">browse images and comments</a>. <address> Contact <a href="mailto:tzz@bu.edu">Ted Zlatanov</a> if you have lots of money you're trying to get out of Nigeria. The breath is <strike>baited</strike>bated. </address> </body> </html> |
upload.tmpl
现在,我们将了解一个优秀的模板,它集合了 JavaScript、HTML 和 Template Toolkit 语言。如果这还不能让 Web 设计师激动不已的话,那么我不知道还有什么能够拥有这种魔力。
清单 2. 足以让 Web 设计人员激动不已的 upload.tmpl
<html> <head> <title>Upload Page For [% username %]</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js" type="text/javascript"></script> </head> <body> <script language="JavaScript"> function OnSubmitForm() { var form = $('uploader'); var file = form['file']; var ct = form['Content-Type']; var name = form['name'].value; if (!name || name.length < 1) { alert("Sorry, you can't upload without a name."); return false; } var filename = ''+$F(file); var f = filename.toLowerCase(); // always compare against the lowercase version if (!navigator['mimeTypes']) { alert("Sorry, your browser can't tell us what type of file you're uploading."); return false; } var type = $A(navigator.mimeTypes).detect(function(m) { // does any of the suffixes match? return m.type.length > 3 && m.type.match('/') && $A(m.suffixes.split(',')).detect(function(suffix) { return f.match('\.' + suffix.toLowerCase() + ' |
上传页面展示了两个上传对话框。它们都可以添加照片,但是第二个对话框更加简单。在第二个对话框中,用户填入照片的 URL 和名称,这些内容随后被 POST 到 /urluploaded,后者正是 urluploaded.tmpl。在显示该模板时,将自动调用图像参数处理程序。用户名从服务器获得并且是一个隐藏了表单的 POST 参数。
第一个表单非常复杂。幸运的是,可以阅读本系列的 第 2 部分,其中解释了有关 S3 上传的所有内容,因此您应当不会感到陌生。
对第 2 部分的 s3form.pl(包含在 下载 小节)的主要修改包括:
- success_action_redirect 将用户名和照片名作为参数传递。策略被修改为只需要字符串中截至用户名的一部分,但是不包括用户名。
- 策略和签名从服务器传递。
- AWS 访问和秘密密匙被放到 env 散列中从服务器传递。
- OnSubmitForm 函数需要一个名称并将其作为参数添加到 success_action_redirect 表单字段并转义(注意,在决定 MIME 类型之前 需要用到名称,但是名称只有在对表单执行 POST 前被添加到 URL。)
- 如果没有找到 MIME 类型,OnSubmitForm 函数就会失败,允许用户指定他们自己的类型。
s3uploaded.tmpl
在 S3 上传中将使用该模板。
清单 3. 在上传中使用 s3uploaded.tmpl 模板
[% success = params.result %] <html> <head> <title>[% IF success %]Successful[% ELSE %]Unsuccessful[% END %] Upload Page For [% params.user %]</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> [% IF success %]Congratulations[% ELSE %]Sorry[% END %], [% params.user %]. You have [% IF success %]successfully[% ELSE %]unsuccessfully[% END %] uploaded [% params.key %] to S3 bucket [% params.bucket %] named [% params.name %].<p> (etag is [% params.etag %] but I doubt you care.) <p> [% IF success %] <a href="http://[% params.bucket %].s3.amazonaws.com/[% params.key %]"> Your new upload is probably here. Let's see if it displays already. <img src="http://[% params.bucket %].s3.amazonaws.com/[% params.key %]"> </a> [% END %] <p> You can now go back to <a href="/upload">uploading</a> or <a href="/">the main page</a>. </body> </html> |
通过一些复杂的 Template Toolkit IF-ELSE 结构和 result 参数,页面可以处理成功的和不成功的上传。成功上传的关键在于添加了 SimpleDB;如果掌握了这点,那么就能够始终成功地将照片上传到 S3。在 SimpleDB 故障时从 S3 取回照片留给读者作为练习。
urluploaded.tmpl
该模板用于 URL 添加。
清单 4. urluploaded.tmpl 实现代码重用
[% success = params.result %] <html> <head> <title>[% IF success %]Successful[% ELSE %]Unsuccessful[% END %] URL add Page For [% params.user %]</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> [% IF success %]Congratulations[% ELSE %]Sorry[% END %], [% params.user %]. You have [% IF success %]successfully[% ELSE %]unsuccessfully[% END %] added [% params.url %] named [% params.name %].<p> <p> [% IF success %] <a href="[% params.url %]"> The URL you added is, perhaps, visible here. <img src="[% params.url %]"> </a> [% END %] <p> You can now go back to <a href="/upload">uploading</a> or <a href="/">the main page</a>. </body> </html> |