個性化頁面布局的設計思考與Rails初步實現
象博客,以及google的iGoogle,都可以個性化頁面布局---對頁面模塊增刪改,以及調整位置。這種效果是如何實現的呢?在我的項目中也面臨到
這個需求。我最初的解決方法是創建幾個典型的rhtml布局組合。但這遠遠不夠,而且不靈活,在形式上也不統一。于是我再次修改了設計,之后似乎可以基本
解決這個問題了。希望感興趣的朋友一起來討論。
這個設計其實很簡單,就是“引擎+配置“--主體頁面只定義一個rthml,可以把它看做頁面引擎,然后用一個配置文件指定了頁面所應具有的模塊和數據。 頁面模塊就象一個個裝有數據的盒子,通過“頁面引擎 + 配置文件”把這些盒子組合起來,象搭積木一樣。頁面引擎是各用戶共用的,配置文件是各用戶獨有的,這樣一裝配起來,就形成了用戶的個性化頁面。
剩下的重點就是怎么定義配置文件。首先是要劃清配置文件的責任界線----它只負責定義盒子里的數據,還有盒子的嵌套關系,而大小和位置等布局方面則全部交給CSS去負責。
上面是初步想法,下面看看具體實現,代碼僅供參考
以下是某個用戶的配置文件(我沒用XML,而是用YAML)。board_1是指ID=1這個欄目所用的配置定義。topContent是一個
這樣,以后想在頁面上增加刪除什么模塊,修改配置文件就行了。當然給用戶用,還必須得用AJAX來寫個GUI界面,總不能讓用戶手工去改配置文件吧。
這個設計其實很簡單,就是“引擎+配置“--主體頁面只定義一個rthml,可以把它看做頁面引擎,然后用一個配置文件指定了頁面所應具有的模塊和數據。 頁面模塊就象一個個裝有數據的盒子,通過“頁面引擎 + 配置文件”把這些盒子組合起來,象搭積木一樣。頁面引擎是各用戶共用的,配置文件是各用戶獨有的,這樣一裝配起來,就形成了用戶的個性化頁面。
剩下的重點就是怎么定義配置文件。首先是要劃清配置文件的責任界線----它只負責定義盒子里的數據,還有盒子的嵌套關系,而大小和位置等布局方面則全部交給CSS去負責。
上面是初步想法,下面看看具體實現,代碼僅供參考
以下是某個用戶的配置文件(我沒用XML,而是用YAML)。board_1是指ID=1這個欄目所用的配置定義。topContent是一個
<div>的id值,我把每個欄目的頁面分成topContent頂、sideContent邊(左或右由CSS決定)、primaryContent
主要、bottomContent底。topic是指添加一個模塊(盒子),顯示一個主題內容。和topic類似是還有顯示圖像的image、顯示主題列
表的topics、顯示分類列表的categories等等等等。它們各有不同的屬性值,比如topic模塊,它需要定指它的主題id,以及它所用的
view(topics/_show_hot.rhtml? or? topics/_show.rhtml等等)。
(雖然這個配置文件抽象得還不夠,但這樣子已經可以解決我的需要了,那就暫時這樣先了。)
template.yml
然后在controller里把配置文件讀入,再轉化成模型類。我把各個界面模塊看做一個個盒子Box
這是它的頂級Box
這是topic模塊的
這是Image模塊的
.....等 等, 其他的Box子類大同小異
然后在一個controller里把這些配置信息轉成Box模型類
最后是它頁面引擎(邏輯代碼和頁面代碼混在一起,比較丑陋)?
(雖然這個配置文件抽象得還不夠,但這樣子已經可以解決我的需要了,那就暫時這樣先了。)
template.yml
- board_2:??
- ??
- board_1:??
- -?topContent:??
- ??-?topic:??
- ??????topic_id:?7??
- ??????view:?topics/show_hot??
- -?sideContent:??
- ??-?image:??
- ??????url:?/images/news.jpg??
- ??-?categories:??
- ??????board:?5??
- ??????view:?tree??
- ??-?topics:??
- ??????board:?5??
- ??????per_page:?4??
- ??????view:?index_simple??
- ??-?topics:??
- ??????board:?6??
- -?primaryContent:??
- ??-?topics:??
- ??????board:?4??
- ??????view:?index??
- ??-?topic:??
- ??????topic_id:?7??
- ??????view:?util/box??
- ??
- board_3:??
然后在controller里把配置文件讀入,再轉化成模型類。我把各個界面模塊看做一個個盒子Box
這是它的頂級Box
ruby 代碼
- class?Box??
- ??attr_accessor?:html_id,?:view,?:boxes??
- ??def?initialize
- ????@boxes=[]??
- ??end??
- end??
這是topic模塊的
ruby 代碼
- class?TopicBox?<?Box??
- ??attr_accessor?:topic_id??
- end??
這是Image模塊的
ruby 代碼
- class?ImageBox?<?Box??
- ??attr_accessor?:url??
- end????
.....等 等, 其他的Box子類大同小異
然后在一個controller里把這些配置信息轉成Box模型類
ruby 代碼
- templates?=? YAML::load(File.read("public/uploads/#{user_id}/config/template.yml"))
- template?=?templates.find{|o|?o[0]=="board_#{@board.id}"?}??
- args?=?template[1]??
- ??
- @boxes?=?[]??
- args.each?do?|arg1_hash|??
- ??arg1_hash.each?do?|key1,?value1|??
- ????board_box?=?BoardBox.new??
- ????board_box.html_id?=?key1??
- ????@boxes?<<?board_box??
- ????value1.each?do?|arg2_hash|??
- ??????arg2_hash.each?do?|key2,?value2|??
- ????????case?key2??
- ????????when?'topics'??
- ??????????box?=?TopicsBox.new??
- ??????????box.board_id?=?value2['board']??
- ??????????box.per_page?=?value2['per_page']||2??
- ??????????box.view?=?value2['view']||'index_simple'??
- ??????????board_box.boxes?<<?box???
- ????????when?'categories'??
- ??????????box?=?CategoriesBox.new??
- ??????????box.board_id?=?value2['board']??
- ??????????box.view?=?value2['view']||'list'??
- ??????????board_box.boxes?<<?box???
- ????????when?'image'??
- ??????????box?=?ImageBox.new??
- ??????????box.url?=?value2['url']??
- ??????????board_box.boxes?<<?box???
- ????????when?'topic'??
- ??????????box?=?TopicBox.new??
- ??????????box.topic_id?=?value2['topic_id']??
- ??????????box.view?=?value2['view']||'util/box'??
- ??????????board_box.boxes?<<?box???
- ????????end??
- ??????end??
- ????end??
- ??end??
- end?
最后是它頁面引擎(邏輯代碼和頁面代碼混在一起,比較丑陋)
ruby 代碼
- <%?@boxes.each?do?|box1|?%>??
- "<%=box1.html_id%>">??/span>
- ??<%?box1.boxes.each?do?|box2|??
- ???????p1?box2.class.to_s??
- ??
- ??????case?box2.class.to_s??
- ??????when?'TopicsBox'??
- ????????board_id?=?box2.board_id??
- ????????if?board_id??
- ??????????board?=?Board.find(board_id)??
- ??????????topics?=?Topic.by_board_id(board_id,?:per_page?=>?box2.per_page)???
- ??????????%>??
- ??????????<%=?render(:partial?=>?"topics/#{box2.view}",?:locals?=>?{:title?=>board.title,?:topics?=>?topics?})%>??
- ????????<%end??
- ??????when?'CategoriesBox'??
- ????????board_id?=?box2.board_id??
- ????????if?board_id??
- ??????????board?=?Board.find(board_id)??
- ??????????categories?=?board.categories??
- ??????????%>??
- ??????????<%=?render?:partial?=>?"categories/#{box2.view}",?:locals?=>?{:board?=>board,?:categories?=>?categories?}?%>??
- ????????<%end%>??
- ??????<%when?'ImageBox'%>??
- ????????<%=?box_tag?:header=>false%>??
- ??????????<%=image_tag(box2.url,?:border?=>?0)?%>??
- ????????<%=?end_box_tag?%>??
- ??????<%when?'TopicBox'??
- ????????topic?=?Topic.find(box2.topic_id)?%>??
- ????????<%=render(:partial?=>?"#{box2.view}",?:locals?=>?{:title?=>topic.title,?:content?=>?topic.content,?:topic?=>?topic?})%>??
- ??????<%end??
- ??end%>?
這樣,以后想在頁面上增加刪除什么模塊,修改配置文件就行了。當然給用戶用,還必須得用AJAX來寫個GUI界面,總不能讓用戶手工去改配置文件吧。
posted on 2007-10-11 00:00 陳剛 閱讀(3582) 評論(0) 編輯 收藏 所屬分類: Rails&Ruby