### Movable Type 模版

- MOVABLE TYPE 模版

- 模版和卷标哲学
- 卷标种类
- 卷标语法
- 卷标属性
- 情境的重要性
- 技术信息

# MOVABLE TYPE 模版

## 模版和卷标哲学

在 Movable Type 的模版卷标背后，有两个主要的概念：

- 情境是决定能否使用特定卷标的关键。

- 容器卷标代表著清单及条件，而变数卷标则代表著变数替换。

这两点都会在后面详加描述。对于其它出版管理系统的使用者、也就是那些更熟悉其它模版卷标的人来说，这里有一些内部模型差异的注意事项：

- Blogger
  Movable Type 的模版卷标跟 Blogger 的精神很像。在 Blogger 里，你用 `<Blogger>` 卷标来围绕文章项目清单；然后你可以用 `<$Blog*$>` 卷标来代表变数替换。

  把这个模型转成 Movable Type 相当容易。

  `<Blogger>` 卷标和 `</Blogger>` 卷标分别被换成 `<MTEntries>` 卷标及 `</MTEntries>` 卷标。

  `<$Blog*$>` 卷标被换成名称很像的 `<$MTEntry*$>` 卷标。

  当然， Movable Type 的模版卷标比 Blogger 的还要多些，不过他们的内部模型非常地相似。

- Greymatter
  Greymatter 的模版卷标用了和 Movable Type 不同的内部模型；举例来说，当你想要在 Greymatter 的索引页面里插入你所有文章项目的清单时，你得插入 `{{logbody}}` 卷标。然后你还得自订两个其它模版 -- `Index Entry Template: Standard Entries` 和 `Index Entry Template: Extended Entries` -- 来调整每一个文章项目在你的索引页面上的样式。

  要把这样的模型转换成 Movable Type ，大概是像这样：

  `{{logbody}}` 卷标会被一个 `<MTEntries>` 容器所取代。

  `Index Entry Template: Standard Entries` 和 `Index Entry Template: Extended Entries` 的组成组件会被混合起来，形成 `<MTEntries>` 卷标和 `</MTEntries>` 卷标之间的组成组件。任何你祇想要在延伸文章项目出现的组成元素，都应该被包在 `<MTEntryIfExtended>` 容器里。当然，你还要把 Greymatter 的变数替换卷标换成相对应的 Movable Type 卷标。

为什么 Movable Type 用了现在出现于模版里的内部模型呢？有两个原因：

1. 最主要的原因是灵活度的考量。你可以用 `<MTEntries>` 卷标来表示你任何文章项目的清单，并且可以透过各种不同的手段，把这份清单变成任何你想要的样子。跟 Greymatter 的方法比较一下，后者的 `{{logbody}}` 卷标总是被完全相同的组成组件所定义样式的文章项目清单所取代：这些组成组件是两个 `Index Entry Templates` 模版的其中一个。

2. 你可以少盯一些模版，而且可以在一个模版里就组出整个页面的板面安排。 Greymatter 的方法通常会把一个页面拆成许多小片段，每一个小片段都是一个模版。在 Movable Type 的模版系统中，所有的组成组件都放在同一个地方，并且透过容器卷标来决定是否要囊括或重复。

（请注意上面这一段并不是在指责 Greymatter 的不是，我们祇不过是要试著描绘出两者的不同，并解释为什么我们选择了现在所用的这一套。）

## 卷标种类

Movable Type 模版是由许多特别的卷标，并嵌入标准纯文字（或 HTML 在此也有可能）的片段。这一些卷标的集合可以分成两群 -- 容器和变数：

- 容器卷标
  有些 MT 卷标是『容器』卷标，里面可能装有被称为子模版的东西；其实就是一些文字片段和 MT 卷标，然后被包在另外两个 MT 卷标：容器的开头和容器的结尾之间。举例来说，如果有个叫做 `<MTFoo>` 的卷标，那么你也许会在你的模版里看到下列的组成组件：

      <MTFoo>
      Foo bar
      </MTFoo>

  这个容器的开头卷标和结尾卷标看起来都很像标准的 HTML 卷标。

  容器卷标可能代表著一份清单或者是一种条件。

  如果容器代表著一份清单 -- 例如像是 `<MTEntries>` 卷标 -- 容器内的子模版会套用在清单上的每一项。举例来说，如果你用了一个 `<MTEntries>` 卷标，那么在 <MTEntries> 卷标和 </MTEntries> 卷标间的组成组件就会套用在清单上的每一则文章项目。

  如果容器代表著一种条件 -- 例如像是 `<MTEntryIfExtended>` 卷标 -- 那么开头卷标和结尾卷标间的组成组件就祇有当条件吻合时才会显示。举例来说，在 `<MTEntryIfExtended>` 的情况下，条件考验著是否文章项目有延伸的部分（『更多文字』）。

- 变数卷标
  所有的非容器卷标通通都是单纯的变数替换卷标。他们其实是信息动态片段的位置保留器。举例来说， `<$MTEntryTitle$>` 卷标会被以文章项目的标题代换掉。

## 卷标语法

所有的 Movable Type 卷标都被包在小于和大于符号之间，就跟 HTML 卷标一样。你可以选择在这些标志里插入 `$` ，就像这样：

    <$MTEntryBody$>

透过这个技巧，你就能够迅速地判断某个卷标到底是 HTML 卷标还是 Movable Type 卷标。

这个 `$` 是选用性的；惯例上所有的预设模版和文件里都会把变数卷标加上 `$` ，但是并不会加进容器卷标里。一部份的原因是因为你不该在容器卷标的结尾卷标里用这个 `$` ，否则系统就会找不到结尾卷标。

## 卷标属性

有些 Movable Type 卷标会透过属性来修改他们的预设作用。卷标属性的作用就跟 HTML 卷标的属性很像：他们是一连串的 `name="value"` 配对，以空白隔开。举例来说：

    <MTEntries author="Foo" category="Bar">

（要知道这里到底发生了些甚么事，请翻阅 `<MTEntries>` 文件。）

属性的值必须被包在引号中；否则就无法被正确地解读。当你在卷标中加入 `$` 时，必须把这个字符放在卷标的开始之后、结束之前；然后当你要在这样的卷标中加入卷标属性时，你得把这些属性放在卷标结尾的 `$` 字符之前。举例来说：

    <$MTEntryDate format="%B %e, %Y"$>

被各个 Movable Type 卷标所支持的属性，会跟著这些卷标被列出。

## 情境的重要性

大部分的 Movable Type 卷标都是仰赖情境的，这表示这些卷标祇应该在适当的情境中被使用。

情境通常都是由附近的模版或者是附近的容器卷标所决定的：举例来说，模版组成组件若被放在 `<MTEntries>` 卷标里、在`单篇`汇整页面里、在`评论清单`模版里或者在`评论预览`模版里的时候，就是在文章项目情境里。因为这样，所以在这些情境中使用 `<$MTEntryTitle$>` 卷标或 `<MTComments>` 容器时才有意义。

## 技术信息

以下这些技术信息说明了模版如何被解读后再建造成输出页面。

第一步是把进来的模版拆成若干零件，每一个零件都是一个卷标（像是 `<$MTEntryText$>` 或 `<MTEntries>` 之类的）或可以被直接插入的原始文字区块。有些卷标是容器，像是 `<MTEntries>` -- 这些卷标一定要包含开启卷标和关闭卷标，然后介于其间的组成组件也一样被拆解成若干零件，再储存于容器之下。

第二步是取得这些零件以及文章项目、文章项目清单、评论、评论清单之类的 -- 基本上就是某种内容 -- 然后再建造出最后输出的页面。一般说来这个最后的页面会是 HTML ，不过显然系统本身并没有这样的限制（别忘了， RSS 串联模版早就装进来啦）。

卷标自己本身并没有写死在分析程序（把文字编译成零件的对象）里；每一次分析程序找到一个卷标后，它就会内容对象有关卷标的类别为何、是否是个容器之类的。然后这个卷标就会增加到零件清单里。

同样地这些卷标也不是写死在用来建造最后输出的对象（其本质是转译程序）里。这个对象也会跟内容对象沟通；对于每一个他所处理的对象，都会有一个匿名的副例程 -- 该副例程已经被以其创造之上的内容对象注祇过 -- 被唤起。这个副例程会传回一整块输出，然后直接插入最后的输出里。

Copyright © 2001-2003 Six Apart. All Rights Reserved.