IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Web development  >

用 Atom 注解 Web

实现全面的用户参与

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

英文原文

英文原文


级别: 中级

Uche Ogbuji, 合伙人, Zepheira, LLC
Eric Larson, 开发人员, BSG Alliance

2008 年 7 月 24 日

虽然您在网络博客和其他 Web 2.0 站点上见过读者评论,但是 Atom 协议允许以非常灵活的方式创建和管理这样的评论。通过实现灵活的 Web 注解,只需使用很少的新技术,就可以构建一种全新的 Web 应用程序。在本文中,您将学习如何为 Web 上几乎任何地方的任何东西创建注解管理系统。

Web 2.0 起源于几种推动力,其目的是使 Web 更有价值。推动力之一是实现 “读-写 Web”。在使用 Web 时,用户大多数时候仅仅是信息的读者。Web 上有少量发布者(写者)和大量读者。越来越多的人通过工具在 Web 上发布内容,但是他们通常只在他们能够控制的一些小区域中发布信息。许多人希望 Web 更加 “平衡”:贡献内容的人更多,用户能够在更广泛的范围发布信息。最重要的 Web 2.0 创新(例如网络博客、博客评论、wiki 和论坛)和资源或媒体共享站点(例如 del.icio.us、Flickr、YouTube 和 Digg)都促使 Web 向读-写 Web 发展。但是,还有进一步发展的空间。在本文中,我们要介绍一种精细但有效的方法,帮助扩展一般用户在 Web 上发布信息的空间。要想从本文获得最大的收益,您应该熟悉 Atom 语法和 Atom Publishing Protocol 的基本知识(参见 参考资料)。

简化 Web 页面评论

大家都熟悉网络博客和类似站点上的评论功能,我们以此为起点讨论 Web 注解。这些功能把文本片段与一个 URL 相关联,这个 URL 可以是博客文章、新闻稿、媒体资源等等。对于这种评论的输入有一定的限制(按照性质或来源分组)。一些文本片段仅仅是指向其他基本 URL 的指针,比如博客的 track-back 和 ping-back。图 1 给出一个取自 Sam Ruby 的 “Intertwingly” 博客的页面示例,其中有一篇文章、一条已经发表的评论和用来发表评论的表单。


图 1. 包含评论系统的博客
博客文章、评论和评论表单

它们仅仅是 URL 和关系

大多数这样的评论系统都在数据库中存储记录,并用专用代码在页面显示过程中获取记录。越来越多的系统为每个评论提供惟一的 URL(称为 “perma-links”),这是一个重要的步骤。如果考虑一下这些评论的抽象概念,它们基本上是一个 Web 资源、评论的目标页面和评论本身之间的关系。与 Web 资源一样,它们也有一个 URL。这是一个非常简单但强大的管理方式,可以通过一个简单的调整实现更强大的功能。我们不需要用数据库和代码存储和管理这些 Web 资源之间的关系,而是用一种标准的开放方式来表达关系。这样就可以跨系统查询和聚合评论;而且我们已经通过 Web 2.0 mash-up 体会到,如果 Web 发布者使用可共享的开放格式,就会大大扩展创造空间。

如果从更一般化的角度考虑这个问题,就会发现无限的可能性。与目标相关联的 Web 资源不一定非是简短的文本片段(比如评论)。它们可以是图像、声音、其他媒体以及其他博客文章(这个思想仅仅是 track-back 和 ping-back 的泛化),甚至是服务。为了以更传统的方式理解这个思想,考虑以下场景:当您把一个目标 URL 提交给 Digg 或 del.icio.us 这样的服务时,实际上相当于在评论中建立相同类型的 URL 关联。有时候,用户把一篇博客文章提交给 Digg,然后在博客上留下文本评论 “这篇文章真酷。我把它提交给 Digg 了”;从更一般化的角度考虑,这么做是多余的。博客文章与 Digg 服务之间的关联应该是透明的,就像评论与博客文章之间的关联一样。

“评论” 这个词太狭窄,不适合表达 “把任意 Web 资源与目标相关联” 这个广义思想。我们在这里讨论的实际上是 Web 注解,它更容易被发现和处理。实现这个目标的关键是采用确定的标准。Atom 标准组实际上已经提供了所需的许多功能。

通过 Atom 标准实现 Web 注解

通过为 Atom 条目提供上下文,Atom Threading Extension 扩展了核心 Atom 语法。简单地说,Atom Threading Extension 允许把一个条目或 feed 声明为对某一资源的响应或回复。因此可以为评论和线索式会话创建 feed。清单 1 是一个使用 Atom 和 Threading Extension 实现的博客文章评论。


清单 1. 用 Atom 和 Threading Extension 实现的博客文章评论
                
<entry xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0">
  <id>tag:eric@ionrock.org,2008-02-29:1-Annotations_and_Communcations</id>
  <title>Communication Reactions</title>
  <content type="text">
    One good use of annotations is tracking edits of some document!
  </content>
  <thr:in-reply-to
    rel="http://ionrock.org/blog/2008/01/10/Annotations_and_Communcations.atom"
    href="http://ionrock.org/blog/2008/01/10/Annotations_and_Communcations/"
    type="text/html" />
</entry>
    
    

注解只是评论的泛化。它可以是带一个 Web URL 和内容表示的任何东西,而不仅仅是文本片段。(实际上,没有任何 Web 表示的东西也可以作为注解,但这是另一篇文章的主题)。评论一般只在特定的上下文用法内有意义,但幸运的是,Atom Threading Extension 已经通过提供设置指针的方法支持更一般化的用法,同时保持上下文完全开放。





回页首


注解服务

Atom 语法提供一种用来表达 Web 注解的格式。Atom Publishing Protocol(AtomPub)提供一个用来构建注解服务的框架。在本文中,我们将开发一个注解服务器,它仅仅是一种有点儿特殊化的 AtomPub 服务器。惟一的额外要求是,Atom 条目要包含一个线索元素。为这个元素编制索引,供以后的查询使用。这个服务器的用途是提供一个用来存储注解的服务,可以根据编制了索引的引用查询这些注解。换句话说,可以请求服务器 “把与资源 X 相关的所有注解给我”,服务器会使用索引提供快速响应。以此为基础,可以进一步扩展服务,提供更方便的操作,支持更复杂的注解,但是本文只关注最简单的功能。

因为注解服务提供一个 AtomPub 接口,可以用一个 AtomPub 服务定义它的使用方法,见清单 2。


清单 2. 注解服务的 AtomPub 服务文档
                
<service xmlns="http://www.w3.org/2007/app"
         xmlns:a="http://www.w3.org/2005/Atom"
         xml:base="http://ionrock.org/annotations/">
  <workspace>
    <a:title>Annotations Collections</a:title>
      <collection href="comments/">
        <a:title>Comments for Ionrock.org</a:title>
        <accept>application/atom+xml;type=entry</accept>
      </collection>
   </workspace>

  <workspace>
    <a:title>Annotations Management</a:title>
    <collection href="manage/">
      <a:title>Manage Annotation Collections</a:title>
      <accept>application/atom+xml;type=entry</accept>
    </collection>
  </workspace>
</service>
    
    

在上面定义的服务中,有两个主要的工作空间。第一个工作空间是注解的集合。这个列表目前只包含 “comments” 集合,但是可以根据需要添加其他东西。为了便于实现这个目的,第二个工作空间 “Annotations Management” 有一个主集合,它定义哪些集合是可用的。如果请求 “manage” URL 上的 feed,只会找到一个描述 “comments” 集合的条目。

有了服务文档之后,就可以通过 AtomPub 接口使用注解服务了。还可以在这个 AtomPub 服务的基础上为注解服务构建一个管理应用程序。





回页首


创建评论界面

有了基本的注解服务之后,就可以考虑如何使用这个服务实现更特殊的评论用例。允许从任何 Web 页面向我们的服务提交评论。对于本文,假设客户机是 Web 浏览器,这可能会有点儿困难,因为使用传统的 Web 表单提交 Atom 条目并不很容易。一个解决方案是使用 XForms,但是 XForms 还未得到广泛接受,用户的系统可能无法处理 XForms。另一个方法是使用 JavaScript 将表单数据组合成有效的 Atom 条目(基本上采用 Ajax 方式)。尽管 JavaScript 可能比较容易实现,但是在受限制的系统上会造成问题。例如,社交站点允许使用 HTML,但是可能不允许使用 JavaScript。因此,最好的方法是使用简单的 HTML 表单和服务器端点,把表单数据转换为 Atom 条目并提交给注解服务端点。

为了便于找到表单的处理端点,我们在评论集合 feed 中添加一个链接。清单 3 是一个 Atom feed 片段示例。


清单 3. Atom feed 片段,包含一个评论表单端点

                
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>tag:ionrock.org:site-comments</id>
  <title>Ionrock dot org Web Log Comments</title>
  <link rel="comment-forms" href="http://ionrock.org/comments/forms/" />
  <entry>
   ...
  </entry>
</feed>
    
    

下一步是在要评论的页面上添加基本的表单。清单 4 是 HTML 表单代码。


清单 4. 用来提交评论的 HTML 表单代码
                
<form action="http://ionrock.org/comments/forms/" method="POST"
     name="annotation-service-comments">

  <fieldset>
    <legend>Leave a Comment</legend>
    <input type="hidden" name="thr-in-reply-to"
           value="http://ionrock.org/tutorials/pyxml/amara/Atom_Fun/"
    />
    <input type="hidden" name="atom-author-name" value="Uche Ogbuji" />
    <input type="hidden" name="atom-author-url"
           value="http://copia.ogbuji.net" />
    <label for="atom-title">Title<label>
    <input type="text" name="atom-title" />
    <label for="atom-content">Content</label>
    <textarea name="atom-content" rows="10" cols="30"></textarea>
    <input type="submit" name="submit" value="submit" />
  </fieldset>
</form>
    
    

我们按照一种非常简单的约定确定表单元素的名称。atom 前缀表示值最终将转换为 Atom 元素。- 分隔符后面的第一个字符串定义 Atom 元素。对于作者,Atom 定义一个 atom:author 元素,其中包含一个 atom:name 以及可选的 atom:urlatom:email。为了支持这个结构,只需在 author 后面使用另一个 - 分隔符,然后添加元素名。不使用这种约定的一个地方是 thr-in-reply-to,它定义 Atom Threading Extension 元素。我们喜欢更自然的名称,而且不希望用户认为命名约定是硬性的。

还要注意,作者信息包含在隐藏的输入中,而不是文本输入中。在这个示例中,假设在显示表单之前已经对用户进行过身份验证。例如,可以使用 Simple Registration Extension 和 OpenID 收集用户的基本信息。这样就可以在进行身份验证之后提供额外信息,并把信息发送给请求它的站点。也可以把作者信息的隐藏输入表单替换为文本输入表单。

有了表单之后,需要处理表单的提交。一种策略是收集所有表单值并按照约定选出我们需要的数据。但是在这里,只收集我们需要的数据似乎更好。这可以用任何语言实现,我们假设您知道如何获取表单输入并把表单数据转换为有效的 Atom 条目。最后,如果表单输入中缺少任何必需的元素,就通过适当的 HTTP 状态码将问题和相关的链接返回给原来的提交者,使他们能够纠正问题。





回页首


创建评论查询接口

评论提交功能已经实现了,现在需要一种使用评论的方法。对于这个示例,我们希望显示每个评论的标题、作者和内容。一个方法是通过 AtomPub 接口获取完整的评论 feed,然后寻找满足适当条件的条目。但是,这种方法并不理想,因为随着 feed 中评论数量的增加,每个请求所需的带宽和处理也会增加。解决方案是创建一个简单的查询接口,帮助控制带宽并简化处理。

考虑两个基本场景。在这两个场景中,查询参数都是注解的目标资源的 URL。在第一个场景中,所有 URL 实际上是到相同的基 URL 的路径。因此,可以直接在 URL 中使用路径来创建 URL 接口。例如:

# the annotated URL
http://ionrock.org/about/

# the annotation feed for the above URL
http://ionrock.org/comments/feed/about/
    
      

第二个场景中的 URL 可能与普通 URL 有很大的区别。每个注解的主机名、协议、端口号等都可能不一样。在这个场景中,最好使用一个查询字符串参数:

http://ionrock.org/comments/find_feed/?href=http://xml3k.org/Bright_Content
    

在这里,通过使用查询字符串参数,能够更灵活地寻找注解,同时不影响可读性。

建立了查询接口之后,就可以开始使用评论 feed 了。清单 5 是一个用 XSLT 编写的示例:


清单 5. 用来访问特定资源的评论注解的 XSLT 片段
                
<xsl:template name="get-comment-feed">
  <xsl:param name="comment-feed-url" />
  <xsl:variable name="atom-feed" select="document($comment-feed-url)" />

  <xsl:if test="$atom-feed/a:feed/a:entry">
    <xsl:apply-templates match="$atom-feed/a:feed/a:entry"
                         mode="comments" />
  </xsl:if>
</xsl:template>

<xsl:template match="a:entry" mode="comments">
  <div class="comment-entry">
    <h4><xsl:value-of select="a:title" /></h4>
    <xsl:copy-of select="a:content/xh:div" />
  </div>
</xsl:template>
    
    

这种模板很容易添加到客户端 XSLT 中。当然,也可以用 JavaScript 处理 feed。





回页首


扩展注解服务

很容易用 Atom 中的特性增加其他功能。可以用 atom:controlatom:draft 元素创建队列。还可以在同一个集合中提供 ping-back 或 track-back。还可以结合使用 atom:category 元素和自己定义的方案定义特定评论的特殊含义。例如,方案可以相对于页面中的锚:

<a id="section-3.4" name="section-3.4"/>
<h2>Section 3.4 - Handling Annotations with Atom</h2>
    
    

在 Atom 条目中,可以用下面的 atom:category 元素引用它:

<category scheme="http://ionrock.org/ns/dyntag/anchor/"
          value="section-3.4" />
    
    

通过使用这种简单的方法,可以对 Web 资源的不同部分应用注解。以 Atom 和 AtomPub 为基础,我们可以建立非常灵活的注解管理系统。





回页首


结束语

本文并没有提出全新的概念。几年前,W3C 已经在 Annotea 项目中研究过这种思想。我们的方法以现有的 Atom 语法和 Atom 协议为基础。我们给出的代码仅仅是一种可能的实现方式,您可以用许多不同的语言和库开发自己的实现。要点在于,通过使用 REST 式体系结构,很容易在现有的系统上进行扩展,而且一旦习惯于以这种方式考虑问题,您的注意力就不再局限于博客评论这样狭义的解决方案上了,而是更关注 Web 注解这样的广义思想。



参考资料

学习

获得产品和技术
  • 了解 Bright Content,这是一种按照 REST 原理构建的为博客等轻量应用程序设计的内容管理系统。


讨论


作者简介

Uche Ogbuji

Uche Ogbuji 是 Zepheira, LLC 的合伙人,这家公司专门提供下一代 Web 技术解决方案。Ogbuji 是 4Suite 的首席开发人员,这是一种用于 XML、RDF 和知识管理应用程序的开放源码平台;也是 Jacqard(用于 Web 团队开发的敏捷方法)和 Versa RDF 查询语言的首席开发人员。他是一位出生在尼日利亚的计算机工程师和技术作家,目前定居在科罗拉多的博尔德。可以通过他的博客 Copia 进一步了解 Ogbuji 先生。


Eric Larson 照片

Eric Larson 来自德克萨斯,他作为 BSG Alliance 的高级开发人员主要从事用 Python 和 Ruby 创建 REST 式的 Web 服务。他是 REST 式的 CMS Bright Content 的首席开发人员,还是 AmaraAkara XML/RDF 库的代码贡献者。Eric 很喜欢讨论 AtomPub。除了技术领域之外,Eric 还在摇滚乐队 Ume 里担任低音乐器手。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款