本手册由zengl开源网的站长提供 首页:www.zengl.com Server Side Integration 服务端集成 This document offers some guidelines that must be considered when developing server side integrati...
本手册由zengl开源网的站长提供 首页:www.zengl.com
This document offers some guidelines that must be considered when developing server side integration for FCKeditor (alias Server Side Integration Pack). There are a few points of integration that every server side technology should have to be completely ready for FCKeditor. These are the main features:
该文档提供了当开发服务端集成FCKeditor的时候要遵循的准则(也就是开发服务端集成包的时候)。下面是每个服务端技术要考虑的要点:
This document will present the basic (minimum) features the integration must accomplish to. Any other feature is a welcome surplus. The scope of this document is to provide a generic pattern in the way the editor can have a homogeneous programming style even when being used from different languages.
这个文档将描述集成语言所要完成的基本功能。任何其他的功能都是次要。这篇文档主要提供使用不同语言来加载编辑器时的通用编程模式。
This is the main integration feature needed. It makes it possible to create an instance of FCKeditor in a page using the desired server side language. Object oriented programming (OOP) should be used wherever is possible. The Integration Pack should offer this functionality to the end user programmer:
这是所需的最主要的功能。这样才能使用所需的编程语言在页面中创造一个FCKeditor的实例,尽可能的使用面向对象技术,服务端的集成开发包需要给终端编程者提供下面的功能:
Suppose the editor instance is called "MyEditor". For compatible browsers the Integration Pack should output HTML like this: 假设编辑器的实例名为“MyEditor” 。对于兼容的浏览器,集成包必须输出如下所示的类似的代码:
<div> <input type="hidden" id="MyEditor" name="MyEditor" value="initial value (HTML encoded) "> <input type="hidden" id="MyEditor___Config" value="Key1=Value1&Key2=Value2&... (Key/Value:HTML encoded)"> <iframe id="MyEditor___Frame" src="/fckeditor/editor/fckeditor.html?instancename=myeditor&toolbar=default" width="100%" height="200" frameborder="no" scrolling="no"></iframe> </div> |
While non compatible browsers should get: 对于非兼容的浏览器则输出如下:
<div> <textarea name="MyEditor" rows="4" cols="40" style="WIDTH: 100%; HEIGHT: 200px" wrap="virtual">initial value (HTML encoded)</textarea> </div> |
The Integration pack should usually offer a main class, called "FCKeditor", in a file called "fckeditor.ext" placed in the root of the editor's distribution package. To be able to use the class the end user should just include a "link" to that file and then easily create an instance of it. Obviously this is the common scenario for scripting languages. Other languages should just reflect this behaviour in the best way possible.
集成包通常需要提供一个主类,叫做"FCKeditor" ,可以将该类放到"fckeditor.ext"里(该文件的ext扩展名为相关的服务端编程语言),然后将该文件放到编辑器发行包的根目录下。这样终端 用户只需要包含这个文件的链接,就可以轻松的创建编辑器的实例了,这是脚本语言的最常见的方式,其他的语言可以以最佳的方式来实现这一行为。
This is the basic structure of the FCKeditor Class: FCKeditor 类 的基本结构:
The implementation should be based on the Javascript implementation (see fckeditor.js file). See "JavaScript Integration" for a complete explanation of the class elements.
这些服务端集成包的实现可以参考 fckeditor.js文件里的js实现方式。
The editor gives the end user the flexibility to create a custom file browser that can be integrated with it. This is a powerful feature, because every case is a different case and so different and specific problems must be solved. In any case, the editor package offers a default implementation of the File Browser so the user has a ready to use software without having to develop anything.
以前提到过,编辑器允许终端用户创建一个自定义的文件浏览器,并且可以加载该自定义的浏览器。这个功能的强大之处就在于它可以满足不同应用程序的各种需求。同时,编辑器又给用户提供了一个默认的文件浏览器,这样用户也可以不用进行任何开发就可以直接使用该文件浏览器。
On prior versions, a sample File Browser was available for each server side technology supported by the editor. The problem with that approach was that each sample had a different implementation and worked completely different from each other. And worst, on some of them were really poor.
在以前的版本中,每种服务端语言对应的文件浏览器都是不同的,这样导致每个程序都有不同的实现方式,工作的效果也大相径庭,有时,工作效果还很糟糕。
To solve those problems the current version offers a unique interface that can be used by all server side languages. The interface was developed completely on Javascript DHTML and the integration is available by XML. In this way the developer that wants to integrate with it doesn't have to be worried about the presentation layer of it.
在当前的版本中提供了一种唯一的接口方式,这样所有的服务端语言都与同一个接口进行交互,该接口是使用JAVASCRIPT DHTML开发的,并且支持XML 。这样开发端就只用专注于自己的连接器的服务端实现即可,不用担忧客户端显示层的工作效果。
The following image shows how the File Browser Integration works: 下面这幅图显示了文件浏览器集成的工作原理(前面提到过!):
The "Connector" is the main file to be developed in this case regarding the server side integration with the File Browser. The following tasks must be done by the Connector:
在本例中,"Connector" 是服务端编程语言所关注的主要文件,他负责与客户端的文件浏览器接口的通信。他需要完成以下的任务:
All requests are simply made by the File Browser using the normal HTTP channel. The request info is always passed by QueryString in the URL that uses the following format:
文件浏览器所产生的所有请求都使用普通的HTTP协议。请求的信息是通过URL中的查询字符串来传递的。通常是下面这样的查询格式:
connector.ext?Command=CommandName&Type=ResourceType&CurrentFolder=FolderPath //ext为服务端编程语言的扩展 |
● CommandName - is the command the Connector must execute. For now there are four commands that must be handled: "GetFolders", "GetFoldersAndFiles", "CreateFolder" and "FileUpload".
这个CommandName是告诉连接器必须执行的命令。目前有四个命令必须要实现的: "GetFolders" , "GetFoldersAndFiles" , "CreateFolder" 和 "FileUpload" 分别是 获取目录列表,获取目录以及文件的列表,创建目录 和 文件上传 四个命令。
#p#文件浏览器#e#
● ResourceType - the File Browser is used on many parts of the editor, like the Link and Image dialog boxes and in the future Flash and Multimedia dialogs. So to separate each "Resource Type" the following type names are used: "File", "Image", "Flash" and "Media".
ResourceType(资源类型):文件浏览器在编辑器的许多部分都使用到了,像链接和图像对话框中,以及未来的 Flash 和多媒体对话框中 (原著针对2.5版的,2.6.5版已经有flash对话框),所以要区分每种资源类型,可以使用下面四个类型名:"File" , “Image” , "Flash" 以及 "Media" 。
● FolderPath - represents the path of the current folder visible in the File Browser. This path is not the final URL path for that folder, but it is relative to the Resource Type folder. The final folder is composed by: "Configured User Files Path" + "Resource Type" + "Folder Path". For example, the Folder Path "/Docs/Test/" of resources type "Image" could correspond to the following URL path: "/UserFiles/Image/Docs/Test/".
FolderPath (目录路径)用于设置相对于资源目录的文件路径,通过配置文件中设置的 "UserFilePath" 路径 +"ResourceType" 资源类型名 + “FolderPath”资源相对路径 ,就可以得到要访问的最终的目录 比如,FolderPath设为"/Docs/Test/" , ResourceType 为 "Image" , 配置中的 "UserFilePath" 为 默认的"/UserFiles/" ,那么最终的URL路径就是 "/UserFiles/Image/Docs/Test/" 。
◎ The Folder Path must begin and finish with a slash ("/"). If those slashes are missing, the server connector must append them before processing the request.
这个相对路径 FolderPath 前后都要有斜线 “/” 。如果丢失斜线,那么服务端的连接器必须在处理请求之前加上他们。
◎ The developer is encouraged to make an easy and secure way to configure the "Server Path" folder available to the end user. For example, for the ASP.NET Connector the user can use the global Web.config file to set which folder to use. The default key for this is "FCKeditor:UserFilesPath". In case of absent configuration the Connector must use the "/userfiles/" folder. The Connector should also automatically create the folder if it doesn't already exist.
建议开发者为终端用户创建一种简便安全的配置 "服务端访问路径" 的方式。例如,对应ASP.NET连接器,用户可以使用全局的 Web.config 文件来设置要访问的目录。默认的配置选项是"FCKeditor.UserFilesPath" 。同时连接器里关于该配置的默认值必须是 "/userfiles/" 目录。如果该目录不存在,那么连接器还要负责自动创建该目录。
NOTE: Please try to let any configuration setting to be done outside the editor package directory. In this way it is easy to the end user to handle future editor updates (just replacing the entire directory with the new version). 注意:请尽可能的让所有的配置设置都在编辑器的安装目录外完成。这样,可以方便终端用户升级新版本的编辑器(只需用新版本的文件覆盖安装目录即可,不需要 重新进行配置)。
All Connector responses have the same base XML structure, like this: 所有连接器的响应都有一个相同的XML结构,类似下面的内容:
<?xml version="1.0" encoding="utf-8" ?>
<Connector command="RequestedCommandName" resourceType=" RequestedResourceType">
<CurrentFolder path="CurrentFolderPath" url="CurrentFolderUrl" />
<Error number="ErrorNumber" text="CustomErrorMessage" />
<!-- Here goes all specific command data -->
</Connector>
Some important things must be considered when building the response: 下面是创建响应时必须考虑的地方:
● The response encoding must be set to "application/xml" and UTF-8. 响应的编码必须设置为 "application/xml" 和 UTF-8 。
● The "Cache-Control" HTTP header must be set to "no-cache". This is needed because the browsers usually cache the requests for XML files and this is not wanted in this case.
"Cache-Control" HTTP 头信息必须设置为 "no-cache" 。 这是必需的,因为浏览器经常会缓存请求中的XML文件,但这不是我们想要的。
● The Path and the URL must always start and finish with a slash (/). 路径和URL 必须在前后使用斜线 "/" 封闭起来。
The value of the "number" attribute of the <error> tag is always checked when receiving response. The data is processed only if the "ErrorNumber" value is equals to "0" (zero). Any other value will popup an error message box to the user. 在<error>标签中的 "number" 属性的值(错误号)会在客户端接口接收响应时进行检查。只有当 "ErrorNumber" 错误号为0时,XML中的数据才会被处理,任何其他的值都会弹出一个错误消息框。
Each command may implement its set of default errors based on the number. For example the "CreateFolder" command sends a "101" error if the folder already exists.
当要执行的命令发生错误时会针对不同的错误产生相关的错误号。例如,当文件已经存在时,"CreateFolder"(创建目录)命令就会发送 一个 "101" 的错误。
The special error number "1" (one) is reserved for "custom error messages". When processing this error, the File Browser will look for the value of the "text" attribute of the <error> tag and show and alert box with that text. 在所有的错误号中 "1" 是预留的错误号,可以通过这个错误号来自定义错误消息。当处理进程处理该错误时,文件浏览器就会查询 <error>标签中的"text" 属性的值,然后 通过 alert 对话框 显示出text里的消息。
For security reasons, it is recommended to the connectors to not be active by default, but to use some configuration system for its activation. In this way we can prevent the use of the connector by others (hackers) on cases were the user doesn't even know that connectors exist. For this, we recommend the connectors implementations to return a custom error message with more information regarding it. Something like this:
考虑到安全性问题,建议连接器默认不激活,只有通过一些指定的配置来激活。这样就可以防止骇客通过连接器进行的攻击。在没有激活的情况下可以通过返回一个自定义的错误消息来告知用户,类似下面的响应输出:
<?xml version="1.0" encoding="utf-8" ?> <Connector><Error number="1" text="This connector is disabled. Please check the "editor/filemanager/browser/default/connectors/php/config.php" file" /></Connector> |
The current File Browser version has 3 commands that wait for XML responses and 1 command that waits for HTML.
在当前的文件浏览器版本中有3个命令是用于接收XML响应的,还有一个命令是用于接收HTML的。
Gets the list of the children folders of a folder. 获取一个目录中的子目录列表信息
● Sample request: 请求示例:
connector.ext?Command=GetFolders&Type=File&CurrentFolder=/Samples/Docs/ |
● Sample response: 响应示例:
<?xml version="1.0" encoding="utf-8" ?> <Connector command="GetFolders" resourceType="File"> <CurrentFolder path="/Samples/Docs/" url="/UserFiles/File/Samples/Docs/" /> //里面的path 和 url 都是前后以斜线封闭的!这点值得注意。 <Folders> <Folder name="Documents" /> <Folder name="Files" /> <Folder name="Other Files" /> <Folder name="Related" /> </Folders> </Connector> |
Gets the list of the children folders and files of a folder. 获取一个目录中的子目录和文件列表信息:
● Sample request: 请求示例:
connector.ext?Command=GetFoldersAndFiles&Type=File&CurrentFolder=/Samples/Docs/ |
● Sample response: 响应示例:
<?xml version="1.0" encoding="utf-8" ?> <Connector command="GetFoldersAndFiles" resourceType="File"> <CurrentFolder path="/Samples/Docs/" url="/UserFiles/File/Samples/Docs/" /> <Folders> <Folder name="Documents" /> <Folder name="Files" /> <Folder name="Other Files" /> <Folder name="Related" /> </Folders> <Files> <File name="XML Definition.doc" size="14" /> <File name="Samples.txt" size="5" /> <File name="Definition.txt" size="125" /> <File name="External Resources.drw" size="840" /> <File name="Todo.txt" size="2" /> </Files> </Connector> |
The file size must be expressed as KBytes (KB). 这里的文件大小是以 KBytes (KB) 为单位的。
Creates a child folder. 创建一个子目录:
● Sample request: 请求示例:
connector.ext?Command=CreateFolder&Type=File&CurrentFolder=/Samples/Docs/&NewFolderName=FolderName //这里还有个 NewFolderName 查询参数告诉服务器要创建的文件名 |
● Sample response: 响应示例:
<?xml version="1.0" encoding="utf-8" ?> <Connector command="CreateFolder" resourceType="File"> <CurrentFolder path="/Samples/Docs/" url="/UserFiles/File/Samples/Docs/" /> <Error number="0" /> </Connector> |
Possible Error Numbers are: 可能的错误号为:
● 0 : No Errors Found. The folder has been created. "0" 表示没有发现错误。这个目录创建好了。
● 101 : Folder already exists. 101表示目录已经存在。
● 102 : Invalid folder name. 无效的目录名。
● 103 : You have no permissions to create the folder. 103 表示你没有创建目录的权限。
● 110 : Unknown error creating folder. 110 未知的错误。
Adds a file in a folder. 在目录中添加一个文件。
This is a special command that doesn't require a XML response. A common "multipart/form-data" post goes with the request. The posted file is named "NewFile".
这个命令不需要XML响应,通常以"multipart/form-data"的表单方式上传数据,上传的文件就是添加的新文件。
In the case a file with the same name already exists, the Connector must automatically rename it adding a progressive number suffix. For example, if the posted file is named "Test.doc", the names to be used, in order, are: "Test(1).doc", "Test(2).doc", Test(3).doc"... and so on.
如果在服务器端存在一个同名的文件,那么连接器必须自动在名字后面添加一个递增的数字来与同名文件区分开来。例如,如果上传的文件名字 是"Test.doc" ,在服务端已经存在同名的文件时,上传的文件会按顺序被命名为 "Test(1).doc" , "Test(2).doc" ,Test(3).doc 等等。
● Sample request: 请求示例:
connector.ext?Command=FileUpload&Type=File&CurrentFolder=/Samples/Docs/
● Sample response (simple HTML): 响应示例(就是一个HTML):
<script type="text/javascript">
window.parent.OnUploadCompleted( 'ErrorNumber', 'FileUrl', 'FileName', 'CustomMessage' ) ;
</script>
The "OnUploadCompleted" is a JavaScript function that is called to expose the upload result. The possible values are:
"OnUploadCompleted" 这个js脚本函数用于显示上传结果。可能的结果为:
● OnUploadCompleted( 0 ) : no errors found on the upload process. OnUploadCompleted( 0 ) 表示上传过程中没有发现错误。
● OnUploadCompleted( 1, , , 'Reason' ) : the upload filed because of "Reason". OnUploadCompleted( 1, , , 'Reason' ) 表示自定义上传后需要显示的错误信息。
● OnUploadCompleted( 201, ,'FileName(1).ext' ) : the file has been uploaded successfully, but its name has been changed to "FileName(1).ext".
OnUploadCompleted( 201, ,'FileName(1).ext' ) 表示文件虽然上传成功了,但是由于服务器存在同名文件,所以上传的文件被重命名为 "FileName(1).ext"。
● OnUploadCompleted( 202 ) : invalid file. 无效的文件类型。
其实这些参数的含义可以直接到js脚本里查看该函数的定义就一目了然了,比如,在fck_image.js文件中,该函数的定义如下:
function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg ) { // Remove animation window.parent.Throbber.Hide() ; GetE( 'divUpload' ).style.display = '' ; switch ( errorNumber ) { case 0 : // No errors 没错误 alert( 'Your file has been successfully uploaded' ) ; break ; case 1 : // Custom error 自定义错误信息 alert( customMsg ) ; return ; case 101 : // Custom warning 自定义警告信息 alert( customMsg ) ; break ; case 201 : //存在同名文件。 alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ; break ; case 202 : //无效的文件类型 alert( 'Invalid file type' ) ; return ; case 203 : //安全错误,可能你没有上传的权限。 alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ; return ; case 500 : //连接器被禁用 alert( 'The connector is disabled' ) ; break ; default : //未知错误,显示错误号。 alert( 'Error on file upload. Error number: ' + errorNumber ) ; return ; } sActualBrowser = '' ; SetUrl( fileUrl ) ; GetE('frmUpload').reset() ; } |
All connectors available in the editor package can be found at the following folder: "editor/filemanager/connectors". Each server side language has its own folder there, with the Connector file inside it. To choose which connector to use, the end-user just edits the configuration file fckconfig.js or the custom Configuration File and modifies the following key (in this case for the Link Dialog box in PHP):
编辑器中所有的连接器都可以在"editor/filemanager/connectors" 目录中找到。每个服务端语言都有自己的目录,里面存放着相应的连接器文件。要选择使用哪个连接器,可以在配置文件fckconfig.js 或自定义的配置文件中修改下面的配置选项(这里以PHP的Link超链接对话框为例):
FCKConfig.LinkBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Connector=../../connectors/php/connector.php ; |
The user can even write his custom Connector and point the LinkBrowserURL to it, like "?Connector=/MyFolder/MyConnector.php" for example. See:
当然用户可以自己写个自定义的连接器,然后将LinkBrowserURL 配置指向自己的连接器 ,比如"?Connector=/MyFolder/MyConnector.php" 。通过下面的链接可以获得更多的信息:
● LinkBrowserURL ● ImageBrowserURL ● FlashBrowserURL
for further information
The "Image Properties", "Link Properties" and "Flash Properties" dialog windows provide a way to quickly upload a file to the server. This feature works much like the "FileUpload" command of the File Browser Connector.
在编辑器的"图像属性" ,"超链接属性" 和 "flash属性"对话框窗口中都提供了一种快速上传文件到服务器的方式。这个功能和 文件浏览器的连接器的 "FileUpload" 文件上传命令很相似。
The implementation must provide a URL where the editor will POST the file to be uploaded. The "Uploader" will then process the file, making the necessary security checks, and return a simple "HTML" with a script that confirms the upload success or failure. The posted file is named "NewFile".
实现者必须提供一个编辑器上传文件时需要的URL地址。然后,"Uploader"服务端的上传处理器就会处理上传过来的文件,并对该文件做必要的安全检查,然后返回一个HTML的js脚本程序,通过脚本函数告诉用户上传是否成功。这个上传的文件就是新加的文件。
The "Uploader" must return a simple <script> tag with a script that calls the "window.parent.OnUploadCompleted" function. This is the response template:
上传处理器返回的脚本程序包含在<script>标签中,通过调用 "window.parent.OnUploadCompleted" 函数来反馈用户。下面是个响应的例子:
<script type="text/javascript">
window.parent.OnUploadCompleted( 'ErrorNumber', 'FileUrl', 'FileName', 'CustomMessage' );
</script>
The "OnUploadCompleted" function expects the following parameters: 这个函数和上面提到到 "OnUploadCompleted" 函数是一样的。他的参数如下:
● ErrorNumber: indicates the success or failure of the upload processing. The following values are valid:
第一个参数 ErrorNumber错误号 ,可用的值为:
● 0: File sucessfuly uploade. 0 表示文件上传成功
● 1: Custom error. In this case the "CustomMessage" parameter value is displayed to the user in an alert box.
1表示自定义错误。在本例中 "CustomMessage" 参数的值会在alert警告框中显示出来。
● 201: The file has been successfully uploaded, but a file with the same name already exists. So the file has been renamed to the value present in the "FileName" parameter. 201表示服务端有个同名的文件,所以会对上传的 文件进行重命名。
● 202: Invalid file type (usually for security reason). 202表示无效的文件类型。
● 203: Not enough permission to write in the server. 203表示用户在服务端没有写权限。
● FileUrl: the final URL to load the uploaded file. 第二个参数 FileUrl 表示要加载该上传文件时所对应的最终URL,通过该URL就可以访问刚上传的文件。
● FileName: see the error number "201". 第三个参数FileName 对应 "201" 错误号,表示重命名后该上传文件最终的文件名。
● CustomMessage: see the error number "1". 第四个参数 CustomMessage 对应 "1" 错误号,即自定义的错误信息。
The easiest way for the end user to understand how to use the editor is to see it in action. So it's important to make available samples that clearly show how to use it.
如果想让终端用户清楚具体如何使用编辑器,最好的方式就是做些示例,所以在写完服务端集成包后,需要写些可用的示例让用户清楚的知道如何使用它。
The developers are invited to create samples similar to that available for the Javascript Integration Pack. Please take a look at the _samples/html folder. All files must be put together in a folder under the _samples folder.
开发者可以参照Javascript集成包的示例,可以查看 _samples/html 目录。所有的示例文件必须集中放置到 _samples 目录中的一个子目录内。
All samples should post the posted data to a single page that shows that data. The Javascript integration module uses an ASP file, called sampleposteddata.asp, that does that (just because JavaScript doesn't handle posted data). That file can be used as a reference for a custom implementation. Please use the same file name, like sampleposteddata.ext.
所有的示例都需要有一个处理编辑器上传数据的简单页面。像 javascript集成模块就使用的是一个 名为sampleposteddata.asp 的ASP 文件,开发者所做的处理页面可以参考这个asp文件,自定义的处理页面请使用和刚刚提到的asp文件相同的名字 像 sampleposteddata.ext (ext为服务端开发语言对应的扩展名)。
OK ,本章结束。休息休息哈
如果本文有翻译不周的地方,或有其他方面的评论,可以到下方发表评论。