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