内容管理

作者:Reuven M. Lerner

在过去的几个月里,我们研究了 Mason,这是一个由 Jonathan Swartz 编写的 Web 开发系统,它结合了 Apache、mod_perl 和 HTML/Perl 模板。通常,Mason 与 Web 应用程序相关联,尤其是那些使用后端数据库并生成动态内容的应用程序。事实上,我发现 Mason 在我的咨询实践中是一个非常有用的工具,可以快速轻松地创建网站。

但是 Mason 的用途不仅仅是简单的服务器端 Web 应用程序。Mason 最有趣的应用程序之一是一组称为“Mason 内容管理器”或“Mason-CM”的组件。Mason-CM 提供基本的内容管理功能,首先是它能够将文件暂存到生产服务器,然后是内置的拼写检查、RCS 版本控制和 Mason 组件编辑支持。

虽然 Mason-CM 是用 Mason 编写的,因此需要 Apache、mod_perl 和相应的 Perl 模块,但它也可以很好地与仅使用 HTML 和图形图像的静态站点一起工作。事实上,我建议即使对 Mason 和 mod_perl 不感兴趣的网站所有者也应该看看 Mason 内容管理器,因为它在一个简单的免费软件包中提供了如此多的有用功能。

为什么选择内容管理?

随着网站变得越来越复杂,围绕它们的组织也变得越来越复杂。过去,专业网站通常是一个人的运营,而现在,即使是中小型网站,通常也至少有三个人:撰稿人/编辑、设计师和程序员。即使是这样一个小团队最终也会发现多个成员试图同时编辑同一个文件。这个问题多年前就通过版本控制系统(如 RCS 和 CVS)解决了——但这些工具是由程序员设计和为程序员设计的,对于设计师或编辑来说通常令人生畏。

此外,Web 提出了一些与传统软件世界中的开发不同的挑战。例如,软件传统上是编写、编译、测试和调试的,此时循环再次开始,直到软件发布。然而,Web 的工作方式不同。一旦 Web 文档层次结构中的 HTML 文件被编辑,它就会立即对 Internet 上的每个人可用。当有人发现需要快速修复的错误时,这是个好消息,这也意味着站点可以定期更新其内容,而无需经过漫长的过程。然而,这也意味着编辑文件的结果——无论是改进还是错误——都会立即对任何在错误的时间碰巧输入正确 URL 的人可用。

由于所有这些原因,大多数中大型网站现在都运行两台 Web 服务器。第一台服务器称为“暂存服务器”,是开发人员、编辑和设计师可以编写、编辑和测试他们对网站的更改的地方。只有在文件经过充分测试后,它们才会被发送到第二台 Web 服务器,即“生产服务器”。

当然,这两台服务器不必在单独的计算机上。它们只需要在某种程度上是分开的,以防止外部人员看到正在测试的内容,并确保暂存服务器和生产服务器具有平行的目录结构。

Mason-CM 是一组 Mason 组件,它可以让任何人相对容易地在自己的服务器上设置内容管理系统。用户界面并不美观,而且我在我的系统上安装它时遇到了一些小问题。但是,它非常充分地完成了工作,并使多人可以协同处理一个项目而不会互相干扰。

安装 Mason-CM

在安装 Mason-CM 之前,您需要拥有 Apache 的工作副本,其中安装了 mod_perl 和 Mason。(如果您需要安装 Mason 的帮助,请参阅过去三个月的“At the Forge”专栏。)此外,您还需要从 CPAN 下载并安装几个 Perl 模块,包括 MLDBM、Image::Size、URI::Escape 和 File::PathConvert。请确保在您的 Apache 配置文件 (httpd.conf) 中使用 PerlModule 指令导入这些模块,以增加各种 Apache 子进程之间共享的内存量。

Mason-CM 以 gzipped tar 文件的形式从 Mason 主页(请参阅“资源”)获取。该存档应解压缩到您的 Mason 组件根目录下的一个目录中。我选择将其放在 /usr/local/apache/mason/cm 中,其中 /usr/local/apache/mason 是我的 Mason 组件根目录。如果您已正确解压缩存档,则 /cm 目录应包含 READMEINSTALL 文件。我将介绍安装所需的所有步骤,但最好还是通读这些文件以防万一。

由于 Mason-CM 必须确保每个文件一次只能由一个用户编辑,并且由于内容管理系统应仅对授权用户可用,因此您必须使用 HTTP 身份验证来限制对 /cm 目录的访问。除非 Mason-CM 位于已密码保护的目录中,否则它将拒绝运行。

密码保护目录的最简单方法是在其中创建一个 .htaccess 文件。.htaccess 文件会覆盖其目录以及其下任何子目录的默认 Apache 配置设置。例如,这是我的内容管理系统的 .htaccess 文件

AuthName "Content Management System"
AuthType Basic
AuthUserFile /usr/local/apache/conf/staging-passwords
require valid-user

AuthName 指令定义了在提示用户输入密码时将向用户显示的字符串。(如果没有这样的字符串,用户可能很难记住哪个系统正在请求用户名和密码。)AuthUserFile 指令应指向包含用户名和加密密码的文件。

密码文件应位于 Web 文档根目录之外,以便用户无法使用 Web 浏览器检索它。要创建或编辑密码文件,您需要使用 “htpasswd” 程序,该程序默认安装在 /usr/local/apache/bin 中。

“require valid-user” 告诉 Apache,如果没有用户名和密码与 AuthUserFile 中的条目匹配,则用户将被拒绝访问该目录。

如果 .htaccess 文件没有任何效果,请检查 httpd.conf 中的 AllowOverride 指令。此指令指示哪些 Apache 配置选项可以被 .htaccess 文件覆盖。默认情况下,Apache 服务器配置为不允许 .htaccess 文件修改 AuthConfig 类型的指令。您可以通过将以下部分放在 httpd.conf 中来更改此设置

<Directory /usr/local/apache/mason/cm>
AllowOverride AuthConfig
</Directory>

最后,我发现在我的 Mason-CM 安装中有一个小错误。许多组件缺少 .html 后缀,这使得 Apache 难以或不可能将内容识别为 “text/html”。因此,即使 Mason-CM 组件以 HTML 格式的文本生成输出,我的浏览器也会将内容解释为未格式化的 ASCII。为了给 Apache 提供一些帮助,我使用 mod_perl “content_type” 方法显式设置了内容类型。以下 autohandler 放置在 /cm 目录中,自动将目录中每个文档的内容类型设置为 “text/html”

<% $m->call_next %>
<%init<
$r->content_type("text/html");
</%init>
因为我的 mason.pl 配置文件设置为忽略非文本文件,所以我可以确定以上操作不会意外地强制将 JPEG 和 PNG 图像渲染为 “text/html” 类型。
配置

Mason-CM 现在已就位。但是,我们需要 Apache 加载许多 Perl 模块才能使其工作。在您的 Mason 配置文件(我称之为 “mason.pl”,但 Mason 文档称之为 “handler.pl”)中,插入以下 Perl 代码块

{
   package HTML::Mason::Commands;
   use Fcntl;
   use MLDBM;<\n>
   use Image::Size;
   use URI::Escape;
   use File::PathConvert;
   use File::Copy;
   use File::Find;
   use IO::Handle;
   use IPC::Open2;
}

现在我们已经告诉 Apache 和 Mason 在哪里可以找到 Mason-CM,现在是时候配置 Mason-CM 本身了。几乎所有的配置都是通过修改 /cm 目录中的 cmConfig 组件来执行的。在撰写本文时,cmConfig 是使用旧式 Mason 接口编写的,对于我们这些从 0.80 版本开始使用 Mason 的人来说,这可能看起来有点陌生。例如,初始化块称为 <%perl_init> 而不是简单的 <%init>,并且一个组件使用 mc_comp 而不是 $m->comp 调用另一个组件。尽管如此,对于任何具有 Mason 最少经验的人来说,该组件应该相对容易识别和理解。

必须在 cmConfig 顶部设置的两个主要变量是 $CM_HOME$CM_DATA。(这些变量在 cmConfig 的默认版本的第 25 行定义,位于 <%perl_init> 部分的顶部。)第一个变量指的是 Mason-CM 的安装目录。第二个变量指的是 Mason-CM 可以存储有关其管理文件的信息的目录,例如锁定和版本控制信息。在我的系统上,我将它们定义如下

my $CM_HOME = '/usr/local/apache/mason/cm';
my $CM_DATA = '/usr/local/apache/cmdata';

这两个目录都必须存在,Mason-CM 才能工作。虽然 $CM_HOME 应该已经定义(因为 cmContent 应该在 $CM_HOME 内部),但您可能需要创建 $CM_DATA 目录。请注意,此目录与 Mason 数据目录不同,我通常将其放在 /usr/local/apache/masondata 中。

在 $CM_HOME 和 $CM_DATA 的定义之后是一个大型哈希,称为 %cm_config。%cm_config 中的键描述了不同的配置选项,值是这些选项的设置。在大多数情况下,默认选项可能就足够了;我们将只讨论您必须或应该更改的选项。

“admin” 键指的是 Mason-CM 管理员的电子邮件地址。管理员负责取消删除文件、解锁锁定的文件以及常规管理内容管理系统。默认情况下,它设置为 cm-admin,但您可以将该值更改为其他值。

定义分支

与 “branches” 键关联的值是一个数组引用,描述了版本控制系统上的各种 “分支”。虽然所有分支都必须位于 $CM_HOME 下,但这使得区分子站点成为可能。例如,报纸可能为新闻、体育和商业版块设置单独的分支。每个分支都由一个唯一的名称标识,后跟一个哈希引用,用于标识与该分支关联的不同特征。例如,以下是一个具有单个分支(称为 “Primary”)的网站的 “branches” 键的样子

branches => [
      Primary => {
          path =>'/usr/local/apache/htdocs/staging/content',
          trg_from => 'staging',
          trg_to => 'production',
          components => 0
      }
   ]

上面的分支将在 Mason-CM “分支选择器” 中显示为 “Primary”,并控制 /usr/local/apache/htdocs/staging/content 下的所有文档。确保命名目录不以 “/” 结尾,否则 Mason-CM 将因安全违规而失败。

“trg_from” 和 “trg_to” 键用于一个简单的替换,指示要将文档从暂存服务器移动到生产服务器,我们将字符串 “staging” 替换为字符串 “production”。(Mason-CM 将暂存过程称为 “触发”。)因此,内容最初放置在 /usr/local/apache/htdocs/staging/content 中,并暂存到目录 /usr/local/apache/htdocs/production/content 中。最后,我们通过将 “components” 键设置为 0 来指示此分支包含静态 HTML(而不是 Mason 组件)。

更复杂的站点可能会将分支设置为以下值

branches => [
        News => {
            path => '/usr/local/apache/htdocs/staging/news,
            trg_from => 'staging',
            trg_to => 'production',
            components => 1,
            hidden => 1
        },
        Business => {
            path => '/usr/local/apache/htdocs/staging/business,
            trg_from => 'staging',
            trg_to => 'production',
            components => 1,
            obj_dir => '/usr/local/apache/staging/obj',
            hidden => 1
}
]

上面的 Mason-CM 配置有两个分支,称为 “News” 和 “Business”。由于 “branches” 是一个数组引用而不是哈希引用,因此其元素保持其原始顺序。这意味着分支选择器将按照它们在上面的 branches 中输入的顺序显示分支。更改分支的显示顺序就像修改 branches 数组引用中元素的顺序一样容易。

如果我们使用上述系统设置分支,我们可以修改我们的 Apache 配置,使其接受任何以 /news 开头的 URL,并将其重写为 /production/news

Alias /news /usr/local/apache/htdocs/production/news

现在,暂存服务器通过 Web 浏览器隐藏起来。但是,我们可以配置我们的 Web 服务器,以便将对端口 8080 或我们选择的任何其他端口的所有请求定向到暂存服务器。

“hidden” 标签指示分支是否默认显示在分支选择器中。通常,所有分支都默认显示,并且对所有用户可用。任何用户都可以使用 Mason-CM 索引页面右上角的 “my.CM” 链接自定义分支列表,从而在其菜单中添加和删除分支。但是,默认情况下隐藏分支为新用户提供了内容管理系统的相对清晰的视图。

与 “Primary” 分支不同,“News” 和 “Business” 被定义为包含 Mason 组件。暂存组件与暂存静态 HTML 页面不同,因为 Mason-CM 会尝试编译组件并在实际允许其在生产服务器上之前测试其错误。这样,损坏的组件不会导致生产网站失败,而只会导致暂存服务器失败。如果我们想将编译后的 Mason 组件存储在特定目录中,我们可以使用 “obj_dir” 键指定该目录。

cmConfig 可以通过许多其他方式进行修改以自定义您的 Mason-CM。但是,一旦您配置了 $CM_HOME$CM_DATA 和分支,您就可以开始使用 Mason-CM。

索引页

要访问主 Mason-CM 界面,请将您的 Web 浏览器指向 $CM_HOME。在我的系统上,我打开了 URL https:///mason/cm/

由于此目录受密码保护,因此我必须输入用户名和密码。成功登录后,我看到了主 Mason-CM 索引屏幕。在很大程度上,索引页是一个基于 Web 的文件浏览器,允许您浏览各种已定义分支中的目录和子目录,打开文件进行读取和写入,以及按文件名或内容搜索文件。

索引屏幕很容易通过杂耍者的图片来识别。虽然您可以将其替换为您喜欢的任何图像(在 cmConfig 中设置 “juggler_src” 键),但该图像对于我们这些在网站上工作的人来说似乎相当合适!从 Mason-CM 中的任何位置单击此图像都会将您带回到此主索引页。

索引页的右侧是分支选择器,其中列出了在 cmConfig 中定义的分支。单击分支选择器中的链接允许您处理该特定分支的暂存。当前分支以与其他分支略有不同的背景颜色显示,因此您的当前位置应始终相当明显。

当前目录在屏幕中间的 “当前目录” 标题(和蓝色默认背景)中标识。当前目录路径的每个组件都是指向该路径的超链接,从而可以使用鼠标进行导航。要切换到子目录,只需单击其名称即可。或者,您可以使用屏幕中间的文本字段创建新的子目录。

在 “当前目录” 行上方是一个搜索系统。显然,我不是唯一一个在记不住特定文件存储在网站上的位置后又回到 grepfind 的人。Mason-CM 将这两个程序都放入一个易于理解的软件包中,即使是非 UNIX 用户也可以在当前分支中搜索文件。搜索支持 Perl 正则表达式,这意味着您可以按名称或内容以多种方式查找文件。但是,请注意您搜索的内容;Mason-CM 会很乐意在数百个文件中搜索复杂的正则表达式,即使执行需要很长时间。

在 “当前目录” 行下方是当前目录中可用文件的列表。每个文件都通过名称、上次修改日期、执行上次修改的人员以及文件的当前状态来标识。状态是 “staging”(表示它仅存在于暂存服务器上)、“prod”(文件在暂存服务器和生产服务器上是相同的)和 “modified”(文件同时存在于两个服务器上,但在保存服务器上已更改)。

您还可以使用文本字段和 “create” 按钮在现有文件列表之前创建一个新文件。不要将子目录创建按钮与文件创建按钮混淆;我修改了 “dirTable” 和 “fileTable” 组件中的按钮定义,以便它们分别显示 “create subdirectory” 和 “create file”。

查看和编辑文件

要查看文件的当前版本,请单击文件表中的文件名。HTML 源代码将显示在浏览器窗口的顶部。在页面底部,您可以要求查看 HTML 的渲染效果,在 80 列后换行文本(而不是逐字显示文本),或显示带有 HTML 源代码的行号。

您还可以使用原始但功能齐全的文本编辑器从 Mason-CM 中编辑文件。要编辑文件,请单击文件名旁边的 “edit” 链接。这将弹出一个 <textarea> 小部件,其中包含文件的内容。您可以通过在 <textarea> 字段中键入内容来修改文件内容,甚至可以使用页面顶部的文本字段复制或重命名文件。

这个编辑器几乎和能得到的一样原始,只有一组勉强可用的 Emacs 键绑定用于光标移动。但是,它可以让您轻松快速地进行修改,这当然是一个优势。它还集成到 Mason-CM 的其余部分中,采用大多数设计师和编辑都可以轻松理解的格式。

在编辑屏幕中,您可以从许多选项中进行选择

  • “save” 按钮更新文件,并返回到编辑屏幕。

  • “save and exit” 按钮将文件保存到磁盘,并返回到主 Mason-CM 索引页。

  • “save and render” 按钮显示文件生成的 HTML 输出,可用于预览特定页面或 Mason 组件的工作方式。

  • 最后,屏幕底部的 redraw 按钮可以调整 <textarea> 小部件的大小,调整其高度和宽度。

Mason-CM 使用锁定机制来确保一次只能有一个用户编辑文件。如果您正在编辑文件,则会在索引页顶部的红色框中注明。该框列出了您当前正在处理的文件,并提供了指向文件编辑器和 “unlock” 页面的链接。

如果您尝试编辑其他人正在编辑的文件,Mason-CM 将拒绝显示编辑屏幕。一旦文件被解锁,另一个用户将可以再次修改它。

暂存文件

一旦文件在暂存服务器上看起来工作正常,您必须将其移动到生产服务器。为此,请使用文件表左侧的复选框选择目录中的一个或多个文件。然后,单击页面底部的 “trigger” 按钮。文件将被复制到生产服务器,立即使其成为网站的 “当前” 副本。

您可以通过单击页面底部 “trigger” 按钮旁边的 “check all” 复选框来触发目录中的所有文件。当您创建了一个新目录并想一次使用所有项目时,这尤其有用。

如果有人碰巧修改了文件的生产版本,则可以 “反向触发” 该文件。这会将文件从生产服务器复制到暂存服务器。这是一个潜在的危险操作,不应掉以轻心;因此,Mason-CM 会在允许此类操作之前要求明确确认。

拼写检查

一旦您的基本 Mason-CM 功能正常工作,您可能需要尝试它包含的一些可选功能。也许最有趣的功能是拼写检查器,这是一个 Mason 组件,它使用 ispell 来检查文档的拼写。Mason 拼写检查器忽略 HTML 标签,因此您不必担心必须将 “href” 添加到字典中。

要启用拼写检查,请取消注释 %cm_config 中的 “ispell”、“main_dict” 和 “supp_dict” 键,在 cmConfig 中定义。它们默认被注释掉;在我的 Linux 系统上,我能够取消注释它们而无需进行任何修改

ispell      => '/usr/bin/ispell',
main_dict => '/usr/lib/ispell/english.hash',
supp_dict => "$CM_DATA/suppDict",

一旦您定义了这些键,Mason-CM 编辑器将自动包含一个 “spell check” 复选框。这意味着每次您单击 “save”、“save and render” 或 “save and exit” 时,都会对文档进行拼写检查。如果文档中的单词拼写错误,则一个小的 JavaScript 程序允许您选择一个备用词、忽略拼写错误或将该单词添加到字典中。Mason-CM 系统上的每个人都共享一个字典,这意味着如果一个用户将一个单词添加到字典中,其他人都会从中受益。(这也意味着,如果一个用户不小心将一个拼写错误的单词添加到字典中,每个人都会受苦,所以要小心!)

版本控制

Mason-CM 还支持使用 RCS 进行版本控制。这需要 mason.pl 导入 RCS 模块以及 Image::Size、URI::Escape 和 File::PathConvert。在此之后,从 cmConfig 中定义(或取消注释)以下行

rcs_bin => "/usr/bin",
rcs_files => "$CM_DATA/archive",

一旦 Mason-CM 看到这些值已定义,它就会在编辑页面的顶部添加一个 “version label” 文本字段。如果在将文档保存到磁盘时输入版本标签,则 RCS 将自动用于保留文件的旧版本和新版本。

此外,激活版本控制意味着文件列表将包含一个 “versions” 标签。单击此标签会弹出一个文档版本历史记录列表,并提供一个不错的 diff 界面以及检出旧版本的功能。当在较大的网站上工作时,版本控制几乎是必需的,因为错误几乎随时都可能潜入,而且通常使用稳定、较旧的版本比使用功能更多但不稳定的较新版本更重要。

除了拼写检查和 RCS 之外,Mason-CM 还包括许多其他功能:用户可以通过 HTTP 和 FTP 上传文件,管理员可以按目录限制用户访问。由于 Mason 是用一种简单的 Perl 方言编写的,因此添加其他功能应该不困难,例如暂存到其他计算机(而不是其他目录)以及暂存前的 HTML 验证。

结论

Mason 可能是创建网站的强大工具,但 Mason-CM 显示了此工具的多功能性。Mason-CM 证明 Mason 组件可以用于创建一种工具,该工具不会直接影响 Web 上生成的内容。Mason-CM 提供的各种工具给我留下了深刻的印象,虽然我不会在不久的将来放弃 GNU Emacs 作为我的首选编辑器,但我希望在我的许多客户的网站上使用 Mason-CM——包括那些使用 Mason 生成内容的网站,以及那些使用更简单、更低级工具的网站。

资源

Content Management
Reuven M. Lerner (reuven@lerner.co.il) 拥有一家咨询公司,专门从事 Web 和 Internet 技术,总部位于以色列莫迪因。当您阅读本文时,他应该(终于)完成了《Core Perl》的写作,该书将由 Prentice-Hall 出版。您可以通过电子邮件 reuven@lerner.co.il 或 ATF 主页 http://www.lerner.co.il/atf/ 与他联系。
加载 Disqus 评论