首页 HTML5 Dive Into HTML5:可扩展性(续)

Dive Into HTML5:可扩展性(续)

0 1

完整的 People 例子

顺便提一句,我们上一节演示的例子并不完整。我们的确可以为 people 编写一个 microdata 词典,并且真正使用这个词典。下面看看我们究竟要如何去做。

最简单的集成 microdata 的方式是在你的个人主页的“关于”页面。你应该有一个“关于”页面,不是吗?如果没有,你可以扩展一下我们这里给出的这个简单的“关于”页面的例子。

我们首先来看一下没有添加 microdata 属性的原始页面:

<section>
    <img width="204" height="250"
         src="http://diveintohtml5.org/examples/2000_05_mark.jpg"
         alt="[Mark Pilgrim, circa 2000]">
    <h1>Contact Information</h1>
    <dl>
        <dt>Name</dt>
            <dd>Mark Pilgrim</dd>
        <dt>Position</dt>
            <dd>Developer advocate for Google, Inc.</dd>
        <dt>Mailing address</dt>
            <dd>
                100 Main Street<br>
                Anytown, PA 19999<br>
                USA
            </dd>
    </dl>
    <h1>My Digital Footprints</h1>
    <ul>
        <li>
            <a href="http://diveintomark.org/">weblog</a>
        </li>
        <li>
            <a href="http://www.google.com/profiles/pilgrim">Google profile</a>
        </li>
        <li>
            <a href="http://www.reddit.com/user/MarkPilgrim">Reddit.com profile</a>
        </li>
        <li>
            <a href="http://www.twitter.com/diveintomark">Twitter</a>
        </li>
    </ul>
</section>

你需要注意的第一件事是,声明你要使用的词典,以及你需要添加的属性的作用域。你可以通过在包含实际数据的最外层元素上添加itemtypeitemscope属性来达到这一目的。本例中,这个元素就是<section>

<section itemscope itemtype="http://data-vocabulary.org/Person">

现在,你可以开始定义位于 http://data-vocabulary.org/Person 的词典了。但是这都是些什么属性呢?我们可以使用浏览器打开这个链接。microdata 标准并不要求这么做,但是这的确是一个最佳实践。毕竟,如果你希望开发人员真正使用你的 microdata 词典,你就应当很好的做文档。还有什么地方比在词典 URL 本身更好的呢?

词典属性说明
name名字
nickname昵称
photo图像链接
title头衔,例如金融经理
role角色,例如收银员
url网页链接,比如个人主页
affiliation与这个人相关联的组织的名字,比如作为该组织的一个员工
friend定义被描述人与另外一个人的社会关系
contact定义被描述人与另外一个人的社会关系
acquaintance定义被描述人与另外一个人的社会关系
address这个人的位置。可以有 street-address、locality、region、postal-code 和 country-name 子属性

“关于”页面的第一个是我的一张照片。显然,我们使用<img>元素。为了声明这个<img>元素是我的个人照片,我们需要给<img>添加itemprop="photo"

<img itemprop="photo" width="204" height="250"
     src="http://diveintohtml5.org/examples/2000_05_mark.jpg"
     alt="[Mark Pilgrim, circa 2000]">

microdata 属性值在哪里呢?就在那里,src属性。回忆一下我们前面介绍的 HTML5 microdata 数据模型,<img>元素的值是src属性。每一个<img>元素都有 src 属性——否则只会显示一个破损的占位图——src通常是一个 URL。看到了吗?如果你正确使用 HTML,microdata 很简单。

另外,<img>元素并不是页面中的独立元素。它是<section>的子元素,而<section>则是我们刚刚声明了itemscope属性的。Microdata 会重用页面上元素的父子关系,从而定义 microdata 属性的作用域。用日常语言来说,也就是,“<section>代表一个人。任何<section>元素的子元素定义的 microdata 属性都是这个人的属性。”你可以将<section>元素当做一个句子的主语。itemprop属性就是句子的谓语,比如“照片是在...”。microdata 属性值就是句子的宾语。

这个人【<section itemscope itemtype="...">得出】

照片是在【由<img itemprop="photo">得出】

http://diveintohtml5.org/examples/2000_05_mark.jpg 【由<img src>属性得出】

主语仅仅需要定义一次,通过在最外层的<section>元素上增加itemscopeitemtype属性。动词通过在<img>元素上添加itemprop="photo"而来。句子的宾语不需要特殊的标记,因为 HTML5 microdata 数据模型定义了<img>的属性值就是其src属性。

我们继续来看下一个标记,<h1><dl>列表。<h1><dl>都不需要标记 microdata。并不是 HTML 的每一部分都需要 microdata 属性。Microdata 是关于属性自身,而不是包围着属性的那些标记或者头。<h1> 不是属性,仅仅是一个 header。类似的,<dt>中的“Name”也不是一个属性,仅仅是标签。

<h1>Contact Information</h1>
<dl>
    <dt>Name</dt>
    <dd>Mark Pilgrim</dd>

那么,真正的数据是什么?真正的数据在<dd>标记中,这才是我们需要添加itemprop属性的地方。那么我们需要什么属性呢?答案是name属性。属性值是什么?是<dd>标签的文本。那这些文本需要标记吗?HTML5 microdata 数据模型说,不需要!<dd>不需要特殊处理,所以属性值就是标记的文本。

<dd itemprop="name">Mark Pilgrim</dd>

我们用日常用语怎么说?“这个人的名字是 Mark Pilgrim”。好了,继续。

下面两个属性就有点技巧性了。这是我们的原始代吗:

<dt>Position</dt>
<dd>Developer advocate for Google, Inc.</dd>

查看一下 Person 词典的定义,“Developer advocate for Google, Inc.” 这段文本应该分属于两个属性:title (“Developer advocate”)和 affiliation(“Google, Inc.”)。那么我们该怎么办呢?简单的回答是,没办法。microdata 没有任何办法将一段文本分割成两个独立的属性。你不能说“这段文本前18个字符是一个 microdata 属性,后12个字符是另外一个属性。”

但这种设计并不是一种损失。设想一下,你希望将“Developer advocate”和“Google, Inc.”设置为不同的样式。CSS也做不到这一点。那你该怎么做?首先是使用标记将这段文本进行分割,比如<span>,然后对每一个<span>添加不同的 CSS 规则。

这个技术在 microdata 中也是非常有用的。这里有两个不同的信息:title和affiliation。如果你将每一部分使用<span>包围起来,那么就可以将每一个<span>声明称一个独立的 microdata 属性。

<dt>Position</dt>
<dd><span itemprop="title">Developer advocate</span> for
<span itemprop="affiliation">Google, Inc.<span></dd>

好了!现在,“这个人的头衔是‘Developer advocate’,受雇于 Google, Inc.”。两句话,两个 microdata 属性。虽然多了一些标记,但是是值得的。

同样的技术对于街道地址也是适用的。Person 词典定义了两个地址属性,而这个值是一个 microdata item。也就是说,它有着自己的词典(http://data-vocabulary.org/Address),有自己的属性。Address 词典定义了5个属性:street-address,locality,region,postal-code和country-name。

如果你是一个程序员,你应该很熟悉对象及其属性的点运算符。看一下这种关系:

  • Person
  • Person.address
  • Person.address.street-address
  • Person.address.locality
  • Person.address.region
  • Person.address.postal-code
  • Person.address.country-name

在这个例子中,完整的接到信息出现在一个<dd>元素中。(再一次强调,<dt>仅仅是说明文字的标签,在 microdata 中不担任任何有语义的角色。)使用 address 属性也很简单,在<dd>标记添加itemprop属性即可。

<dt>Mailing address</dt>
<dd itemprop="address">

但是记住,address 属性自己也是 microdata item,这意味着我们需要为它添加itemscopeitemtype属性。

<dt>Mailing address</dt>
<dd itemprop="address" itemscope
    itemtype="http://data-vocabulary.org/Address">

我们以前都见过这种东西了,只不过当时是在顶层元素。<section>元素定义了itemtypeitemscope<section>元素的所有定义了 microdata 属性的子元素都“属于”同一个词典。但这是我们第一个见到嵌套范围——在已有的词典中(<section> 元素)定义新的itemtypeitemscope<dd>元素)。这种嵌套类似 HTML DOM。<dd>元素有一系列子元素,所有这些都属于定义在<dd>上的词典的范围中。一旦<dd>元素使用了</dd>关闭,作用域才会回到父元素(在这里就是<section>)定义的词典。

Address 属性遇到了我们刚刚遇到的 title 和 affiliation 的同样的问题。我们有一大段文本,但是不能将它分割成五个 microdata 属性。解决办法也是一样的:使用<span>包围起来每一部分,然后为每一个<span>声明microdata属性。

<dd itemprop="address" itemscope
     itemtype="http://data-vocabulary.org/Address">
    <span itemprop="street-address">100 Main Street</span><br>
    <span itemprop="locality">Anytown</span>,
    <span itemprop="region">PA</span>
    <span itemprop="postal-code">19999</span>
    <span itemprop="country-name">USA</span>
</dd>
</dl>

我们来读一下:“这个人有一个邮箱地址。街道部分是‘100 Main Street’,地区是‘Anytown’,行政区是‘PA’,邮编‘19999’,国家名字‘USA’”。很简单吧。

Q:这个邮箱地址格式是 US 所特有的吗?

A:不是。Address 词典中定义的属性具有一般意义,足以描述世界上大多数邮箱地址。并不是所有地址每一个属性都会有值,但这也没关系。有些地址可能需要不止一行,不过也没问题。例如,如果你的邮箱地址有街道信息和门牌号,那么 street-address 子属性可能会是下面的:

<p itemprop="address" itemscope
   itemtype="http://data-vocabulary.org/Address">
    <span itemprop="street-address">
        100 Main Street
        Suite 415
    </span>
...
</p>

我们的页面上还有另外的东西:URL 列表。Person 词典对此有一个属性,称为 url。url 属性可以是任何值。(你可能会以为它必须是一个 URL。)我强调这一点,是想说明,url 属性的定义并不那么完备。这个属性可以是你所希望关联到这个 Person 的任何 URL:博客、相册,或者 Facebook 或 Twitter 的账号。

另一个值得注意的是,一个 Person 可以有多个 url 属性。从技术上说,任意属性都可以有多个。但是目前为止我们还没有接触到这一点。例如,你可以有两个 photo 属性,每一个指向不同的 URL。这里,我要列出四个不同的 URL:博客,Google 个人页面,Reddit 个人页面和 Twitter 账户。在 HTML 中,我们有一个链接的列表:四个<a>元素,每一个都在一个<li>元素中。在 microdata,每一个<a>元素都有一个itemprop="url"属性。

<h1>My Digital Footprints</h1>
<ul>
    <li>
        <a href="http://diveintomark.org/"
           itemprop="url">weblog</a>
    </li>
    <li>
        <a href="http://www.google.com/profiles/pilgrim"
           itemprop="url">Google profile</a>
    </li>
    <li>
        <a href="http://www.reddit.com/user/MarkPilgrim"
           itemprop="url">Reddit.com profile</a>
    </li>
    <li>
        <a href="http://www.twitter.com/diveintomark"
           itemprop="url">Twitter</a>
    </li>
</ul>

根据 HTML5 microdata 数据模型,<a>元素有特殊处理。microdata 属性值取其href属性,而不是文本。每一个链接的文本被 microdata 处理器自动忽略。因此我们说,“这个人有一个 URL 是 http://diveintomark.org/,另一个是 http://www.google.com/profiles/pilgrim.,一个是 http://www.reddit.com/user/MarkPilgrim,另外一个是 http://www.twitter.com/diveintomark。”

Google Rich Snippets 简介

下面我们再来说说,“为什么要这么做?”我们像前面那样添加一大堆语义,就是为了添加语义吗?不要冤枉我,我只是想好好利用 web 新特性。但为什么是 microdata?

现在有两类应用程序可以直接或者通过扩展使用 HTML5 microdata:

  1. Web browsers
  2. Search engines

对于浏览器,HTML5 定义了一系列 DOM API,用于导出页面上的 microdata 条目、属性以及属性值。在2011年2月左右,还没有浏览器支持这个API,一点支持都没有。所以,我们的讨论基本到此为止了,或者说必须要等到有浏览器支持客户端 API。

另一个主要应用是搜索引擎。搜索引擎拿来一个人的 microdata 属性能干什么?想象一下,搜索引擎可以整合一些结构化数据并且显示出来,而不是简单地罗列一堆数据。全名、工作头衔、雇主,甚至是简历照片。这些引起你的注意了吗?好吧,我承认引起我的注意了。

Google 使用 Rich Snippets 程序支持 microdata 程序。当 Google 的网络爬虫处理你的页面时,会发现来自http://data-vocabulary.org/Person 的 microdata 属性。Google 甚至提供了一个工具,让你自己看看它是如何“看到”你的 microdata 属性的。我们使用它可以测试一下我们页面的 microdata,其输出应该是这样子的:

Item
Type: http://data-vocabulary.org/person
photo = http://diveintohtml5.org/examples/2000_05_mark.jpg
name = Mark Pilgrim
title = Developer advocate
affiliation = Google, Inc.
address = Item( 1 )
url = http://diveintomark.org/
url = http://www.google.com/profiles/pilgrim
url = http://www.reddit.com/user/MarkPilgrim
url = http://www.twitter.com/diveintomark

Item 1
Type: http://data-vocabulary.org/address
street-address = 100 Main Street
locality = Anytown
region = PA
postal-code = 19999
country-name = USA

所有的都在这里了:photo 属性来自<img src>,所有四个 URL 来自<a href>列表,甚至 address 对象(在“Item 1” 中列出)及其子属性。

Google 是怎么使用这些信息呢?那取决于它自己的实现。没有硬性要求规定 microdata 属性如何被显示,或者是它们该不该被显示。如果有人搜索 “Mark Pilgrim”,而 Google 又决定这个 “about” 页面应该作为结果页面,那么,Google 就会使用从这个页面获取的 microdata 属性来显示搜索结果:

第一行,“About Mark Pilgrim”,之处页面的标题,来自 <title> 元素。这并不奇怪,Google 对每一个页面都会这么做。但是第二行有一个直接来自 microdata 属性的完整的信息。“Anytown PA” 是邮箱地址的一部分,这是使用 http://data-vocabulary.org/Address 词典定义的。“Developer advocate” 和 “Google, Inc.” 来自 http://data-vocabulary.org/Person 词典的两个属性(title 和 affiliation)。

这的确很令人吃惊。你并没有做什么特殊的操作,搜索引擎就直接给你显示出来带有你个人信息的页面了。仅仅花10分钟添加几个HTML属性,你就能有这待遇了!

Q:我按你说的做了,但我的 Google 搜索结果页面还是原来那样,怎么回事?

A:“Google 并不保证页面上的标记一定会被用到搜索结果页面。”但是即使 Google 没有使用你的 microdata 数据描述你的页面,另外的搜索引擎可能也会用。就像 HTML5 的其他部分,microdata 是一个开放的标准,任何人都可以实现。你的工作就是提供更多的信息,让世界上其他工作去拿你的数据干点什么吧。这或许让你有些不解,也算是一种分工吧~

发表评论

关于我

devbean

devbean

豆子,生于山东,定居南京。毕业于山东大学软件工程专业。软件工程师,主要关注于 Qt、Angular 等界面技术。

主题 Salodad 由 PenciDesign 提供 | 静态文件存储由又拍云存储提供 | 苏ICP备13027999号-2