您知道 Microsoft Internet Explorer 5.5 具有編輯 HTML 的內(nèi)置支持嗎?我一直想有一個基于 XML 的好工具來做聯(lián)機(jī)討論,和新聞組差不多,但是結(jié)構(gòu)性更強(qiáng),好讓我能輕松地添加新的功能。 我一直希望這類工具中能有這些功能:
唯一的問題是如何做好多信息文本編輯。我的朋友 Jonathan Marsh 開發(fā)了一個棒極了的原型。一旦 IE 5.5 給我解決了多信息文本編輯的問題,我就能根據(jù)朋友的原型把下面這些放在一起: ![]() 圖 1:原型 XML 討論列表 每個頂級討論線索是一個可以展開和折疊的層次結(jié)構(gòu)。它使用 Cookie 來記憶您在哪里。這樣,您回到討論時,還會回到同樣的位置。 分級您也可以看到用戶分級功能;在上面的圖里,選定的張貼內(nèi)容也是最受歡迎的張貼。最多可以分 4 級。要對消息進(jìn)行分級,用戶只需要在標(biāo)題 RATE THIS MESSAGE 旁邊單擊鏈接,網(wǎng)頁會將分級信息發(fā)布到服務(wù)器,并顯示新的平均值。它還可以做很多事情。最棒的是:它非常容易使用,而且速度足夠快,這樣用戶才會真正去用。 編輯單擊 REPLY 的時候,詳細(xì)信息框架將進(jìn)入 HTML 多信息文本編輯器,如下圖所示: ![]() 圖 2:多信息文本編輯器接口 實際上,IE 5.5 的內(nèi)置編輯器還有很多這里沒有提到的功能。使用工具欄、彈出式菜單和您擁有的其他控件,您可以隨心所欲地創(chuàng)建內(nèi)容更加豐富的用戶界面。其實,這段代碼是從另一篇 MSDN 文章上獲得的:定位和編輯(英文)。 開始和所有基于 XML 的 Web 服務(wù)一樣,首先要為包含消息線索索引的論壇設(shè)計一個簡單的架構(gòu)。在這里,我決定使用傳統(tǒng)的文檔類型定義 (DTD): <!ELEMENT discussion (title, threads*)> <!ELEMENT title (#PCDATA)> <!ELEMENT threads (message*)> <!ELEMENT message (subject, body, author, posted, rating, replies)> <!ELEMENT replies (message*)> <!ATTLIST message id CDATA #REQUIRED> <!ELEMENT subject (#PCDATA)> <!ELEMENT body EMPTY> <!ATTLIST body src CDATA #REQUIRED> <!ELEMENT subject (#PCDATA)> <!ELEMENT author EMPTY> <!ATTLIST author name CDATA #IMPLIED email CDATA #IMPLIED> <!ELEMENT rating EMPTY> <!ATTLIST rating users CDATA #IMPLIED average CDATA #IMPLIED> 這段代碼會捕獲線索化討論的層次結(jié)構(gòu),在這個結(jié)構(gòu)中,消息包含了答復(fù),答復(fù)又包含了更多的消息,等等。每個張貼內(nèi)容的主體都存儲在獨立的 XHTML 文件中,而 <body> 元素的 src 屬性確定了文件的位置。 這個索引存儲在論壇目錄里名為 index.xml 的文件中。您將此目錄作為一個稱作 root 的 URL 參數(shù)提供給 discuss.asp 網(wǎng)頁。例如,上面的網(wǎng)頁是使用以下的 URL 顯示的: http://localhost/xdiscuss/discuss.asp?root=userdata 這樣,同一個論壇 Web 應(yīng)用程序可以用來維護(hù)站點上任意數(shù)量的獨立論壇。例如,我有一個論壇討論這個應(yīng)用程序本身(就是上面那個),另一個則用來討論我正在開發(fā)的產(chǎn)品的新功能。 管理在服務(wù)器的論壇目錄中,還有一個名為 admin.xml 的文件,其中包含了允許刪除張貼內(nèi)容的用戶名稱和電子郵件別名: <admin> <user> <name>clovett</name> <permission>all</permission> </user> <user> <name>jmarsh</name> <permission>all</permission> </user> </admin> 現(xiàn)在,唯一的一個權(quán)限是“All”。很顯然,可以用很多方法來擴(kuò)展這個列表。如果能用一個用戶界面來維護(hù)這個管理消息,那也是個好辦法。 源代碼您下載源代碼時,將看到以下文件:
上面的 XSL 轉(zhuǎn)換器是 http://www./1999/XSL/Transform(英文)轉(zhuǎn)換器,同時使用了由 MSXML 3.0 提供的 msxsl:script 擴(kuò)展。 設(shè)計![]() 圖 3:總體消息流 上圖說明了本應(yīng)用程序的總體消息流:index.xml 文件高速緩存在 ASP 應(yīng)用程序范圍中,以獲得更好的性能,該文件還會不時保存到磁盤中,以免丟失所作的更改。這些由共享 ASP 腳本 common.asp 以及 global.asa 和 unload.asp 共同管理。 頂級大綱框架由 outline.asp 生成。outline.asp 運行一個服務(wù)器端 XSL 轉(zhuǎn)換器以過濾出用戶想看的消息(基于分級進(jìn)行)。然后,它將篩選后的索引內(nèi)容發(fā)送至客戶端,內(nèi)容中附加的 outline.xsl 轉(zhuǎn)換器將執(zhí)行客戶端 XSL 轉(zhuǎn)換,以生成 DHTML 用戶界面。 當(dāng)您從大綱中選擇消息時,底部的詳細(xì)消息框架將顯示 message.asp 的運行結(jié)果。message.asp 從指定的論壇中找到指定消息并返回消息的詳細(xì)信息,同時通過附加的 detail.xsl 轉(zhuǎn)換器建立詳細(xì)信息 DHTML 用戶接口。 在詳細(xì)信息視圖中,您可以刪除調(diào)用 delete.asp 的消息,并檢查您是否具有管理員權(quán)限,或者答復(fù)這個消息。Reply.asp 建立模板消息,并使用 reply.xsl 轉(zhuǎn)換器來顯示多信息文本編輯器。從編輯器視圖上,您可以將答復(fù)張貼到 post.asp 腳本,它將有關(guān)您消息的信息添加到共享索引,并將消息主體保存到服務(wù)器上的單獨文件中。 一些技巧從包含的源代碼數(shù)目中,您可以看出這并不僅僅是一個小練習(xí)。它開始通過服務(wù)器上的 JScript ASP 代碼、十分復(fù)雜的 XML 轉(zhuǎn)換器和技巧性的 DHTML 客戶端 UI 代碼來拓寬維護(hù)能力方面的限制。其中技巧性最強(qiáng)的一些是: 縮進(jìn) - 使用稱作 padding-left 的 CSS 樣式生成大綱視圖的縮進(jìn)。根據(jù) <message> 元素的嵌套深度計算該樣式的值。此計算在 outline.xsl 轉(zhuǎn)換器中執(zhí)行,使用以下 XPath 表達(dá)式: padding-left:<xsl:value-of select="count(ancestor::message)"/>em; 本地時間 - 服務(wù)器在 post.asp 中生成消息的時間戳記,并將其保存為通用協(xié)調(diào)時間,通用協(xié)調(diào)時間是指定日期與 1970 年 1 月 1 日午夜之間的差(按毫秒計算)。使用 JScript Date() 對象的 getUTC* 方法完成這一功能。在客戶端,多種 XSL 轉(zhuǎn)換器使用 Date 對象的 getTimezoneOffset 方法將時間調(diào)回本地時間,并使用 toLocaleString 顯示為本地化字符串。這些工作由 XSL/T 轉(zhuǎn)換器中的 msxsl:script 塊完成。 多論壇支持 - 一個論壇應(yīng)用程序,可用于參加同一服務(wù)器上的多個論壇。您可以使用“Root”URL 參數(shù)選擇論壇,每個論壇的 index.xml 文件被高速緩存在應(yīng)用程序范圍中。為了管理所有論壇,使用了另一個動態(tài)生成的、自由線索的 XML 文檔對象來維護(hù)所有載入論壇的主控列表。這樣,當(dāng)在 global.asa 中引發(fā) Application_OnEnd 事件時,commmon.asp 中的 Unload() 方法可以找到所有載入的論壇,并將其全部卸載。 展開/折疊 - 大綱視圖實際上是一個只有一行的表。要實現(xiàn)層次結(jié)構(gòu)的展開/折疊,HTML 中需要包含足夠的信息,以便 DHTML 腳本代碼指出各行之間的父子層次結(jié)構(gòu)。它的實現(xiàn)方式是:通過 outline.xsl 轉(zhuǎn)換器,在每個 <TR> 元素上生成 id、thread、parent 和 depth expando 屬性。這些值按 XPath 父子關(guān)系來生成,非常巧妙。在 expand.js 中將使用這一 HTML 信息實現(xiàn)展開/折疊功能。當(dāng)前的展開狀態(tài)也被維護(hù)并保存在 Cookie 中,以便您回來時它還能保持原來的展開狀態(tài)。通過維護(hù)當(dāng)前展開消息的消息 ID 列表可以實現(xiàn)這一功能。 下一步是什么?這時,要添加下面的新功能將會相當(dāng)容易:
|
|