制作"Commands"

---原作《网猴》 编译《搜狐》
现在我们来开始制作"Commands"。

首先在Dreamweaver 2/Configuration/Commands/目录下创建一个HTML文档,我们为此文件创建说明文档"convert library item to SSI.html"(将库条目转换为SSI.html),该说明会显示在"Commands"菜单中。我们让这个HTML文件的正文部分代码空着,这样该文件的HTML源代码会是下面这个样子:

<html>
<head>
<title>Covert library item to SSI</title>
</head>
<body>
</body>
</html>

根据此代码,我们知道目前它只是在"Commands"菜单中有一些显示信息,那么下面我们就来让这个"command"做些具体的事情。对于初学者来说,我想应该把任务设置的简单些,即要求该指令从主文本(假设主文本是一个库条目)任意选取某段信息,从库条目中寻找相应的存储路径,然后改变文档内容以便使库条目变为“服务器端包容”信息,具体指令请见下文。

Dreamweaver中库条目的句法是这个样子:

<!-- #BeginLibraryItem "/Library/testLibrary.lbi" -->

This is a library item< !-- #EndLibraryItem -->

在本例中,我们希望用来转换为“服务器端包容”的信息文件的路径就存储在第一行说明中,根据该说明,我们知道所有的库条目都存储在一个在网站根目录下的被称为"Library"的子目录中。经过"command"的修改,第一行就会变为:

<!--#include virtual=" /Library/testLibrary.lbi" -- >

我们要做的就是创建一个可以实现上述变化的函数,具体内容如下:
function convert_lbi_2_ssi(){
 var source = dreamweaver.getDocumentDOM("document")
.documentElement.outerHTML; var offs = dreamweaver.getSelection(); var lib = source.substring(offs[0], offs[1]); var libMatch = '<!-- #BeginLibraryItem "(\/Library\/.*lbi)" -->'; var path = lib.match(libMatch); var SSI = '<!--#include virtual="'+path[1]+'" -->'; var newSource = source.substring(0, offs[0])+SSI+source.
substring(offs[1]); dreamweaver.getDocumentDOM( "document" )
.documentElement.outerHTML = newSource; }
函数第一行内容较长,作用也很大。另外你会发现该说明以Dreamweaver对象做为开始,而任何以对象开始的信息都属于内部可扩展应用程序接口和外部通用JavaScript脚本两项内容的一个部分。Macromedia并非随意添加上述功能,而是为了更好地解决在编辑器环境下存在的一些问题。

我们遇到的第一个Dreamweaver对象实际上应用非常广泛,它填补了通用JavaScript脚本中一个巨大的漏洞。dreamweaver.getDocumentDOM()对象告诉函数查询我们正在编辑的内容,并获取它的文件对象模块(DOM)。这对于实现“包容”非常关键,如果没有这个步骤,你的脚本就会不听指挥地修改你正在编辑的DOM指令,而这是你目前还不希望看到的。

程序继续执行,当它发现了文档的文件对象模块,就会开始查找文档的基本信息。也许你会觉得这是一个重复的步骤,但实际上它正在描述你希望处理文件对象模块的哪个部分,而在本例中它指的是整个文档。

在描述行结尾,我们查看outerHTML属性,所有上述内容最终都归结为变量源,这时源文件会包含文档全部HTML代码的字符串。而既然我们已经把文档HMTL代码载入为一个变量,我们就可以开始对此进行操作了。

此时你的规范监督器可能会发现outerHTML属性其实是Dreamweaver从万维网联盟的标准演变而来的,并且与Internet Explorer 4中的Microsoft文件对象模块有一定的联系。万维网联盟的文件对象模块必须存在于根目录节点中,而在本例则指的是<HTML>置标符。当我们进行文件编辑时,我们经常会处理那些在<html>置标符之外的内容,如说明文档、服务器端处理指令等。

下一个说明也是一个经常会使用到的Dreamweaver指令。

dreamweaver.getSelection()函数会返回一组数列,来代表由用户选取的文本部分。getSelection()函数会返回两个数字:一个是从文本开始部分到选择开始部分的字符数,另一个是从文本开始部分到选择结尾部分的字符数。这两个数字被称为"offsets"(补偿值),它可以允许你对用户选择的文档部分执行"command"指令。

这个返回的补偿值被载入一个被称为"offs"的数列中,接着在var lib = source.substring(offs[0], offs[1])这一行,由用户选取的文本会被载入变量"var"中。

好了,现在我们已经拥有了用户选取的HTML代码,因为我们现在是在对库条目进行操作,因此Dreamweaver会将选择范围扩展到将所有库条目包括在内,所以让我们展开路径并将库中的文本进行改变,以便使它读起来象“服务器端包容”的格式。

因为Dreamweaver有内置JavaScript 1.2脚本编辑器,因此我们可以创建普通脚本表达方式(regex),这使工作简化为只需下面这个库条目的路径名即可完成任务。
<!-- #BeginLibraryItem "(\/Library\/.*lbi)" -->

如果你尚不清楚普通脚本表达方式,那么我告诉你上面一行内容的意思是在括号路径内查找与首置标符相符的信息,而在该括号内,它会在/Library/路径内查找相关信息,在此路径后,它会查找任何带有.lbi后缀的内容,这个后缀是Dreamweaver库文件的扩展名,此表达方式最后以说明置标符结尾。

请注意括号内集中了一些普通表达方式,从而使我们可以在今后进行参照。在本例中,我们实际只需记录下库条目的路径名。这样,我们就可以在“包容”中使用它了。

JavaScript脚本会返回一组相符的字符串,完全匹配的会显示在前面,接着是对括号内第一项内容的匹配信息。由于我们把匹配的普通表达方式置于一个叫做"path"的变量中,那么"path[0]"(注意我们处理的是数组)表示的是完全匹配信息: <!-- #BeginLibraryItem "/Library/testLibrary.lbi" -- >;而"path[1]"表示的是/Library/testLibrary.lbi中的信息。

为了创建SSI说明,SSI变量的内容就是 <!--#include virtual="'+path[1]+'" -->,接着我们来创建带有正确URL的正确句法,下面剩下的工作就是把该句法返回到文本中。为了实现这一点,我们需要再编写一至两条说明文档。

首先我们需要创建在新文档中需要的内容,让我们回到文本和补偿值的源代码中,我们希望把所有内容都保留在选择之前的模式下,即

(source.substring(0,offs[0])),以及保留选择之后的状态,即(source.substring(offs[1])。我们希望把SSI变量置于文本中部,所需JavaScript如下:

var newSource = source.substring(0, offs[0])+SSI+source.substring(offs[1]);

接着我们会把新源文件按照把它取出的相同方式再把它放回到文本中,采取的代码如下:

dreamweaver.getDocumentDOM("document").documentElement.outerHTML = newSource;

我们原本应该把这两项说明文档合并为一个,但由于文本的长度限制无法把它们合并为一个太长的编码。接下来保存文档并重新启动Dreamweaver编辑器,把一个库条目放入网页并选中该条目,进入"Commands"菜单并选择"Convert library item to SSI"(将库条目转换为服务器端包容模式)。这时会出现两种情况,一种是库条目会变为一个带有黄色护罩()的图标,或者如果你把默认服务器端包容(SSI)转换功能或我们Webmonkey提供的更加强大的扩展型服务器端包容(XSSI)转换功能打开后,你就不会看到文本中的变化。但实际上如果你查看文件源代码,就会注意到内容确实已经发生了变化。

恭喜你!你已经自己制作了第一个"command"。但别忘了下面还有更多的内容。