`
liuqiang
  • 浏览: 164357 次
  • 性别: Icon_minigender_1
  • 来自: 华东
社区版块
存档分类
最新评论

利用rails轻松建立个性化主页门户

    博客分类:
  • Ruby
阅读更多

      简单来说,个性化主页就是结合了各种小模块和网络信息的个人主页。与传统网站的区别是:用户可以非常自由地控制其内容(通过RSS,email等等),内容会更适合用户口味并且使用查看也非常方便,由于有了ajax技术,所以更像是一个桌面软件。例如http://www.netvibes.com/就提供了比较酷的个性化主页服务。
总的来说主要有以下几个特点:

1 页面中的内容是一个个小模块,其内容来自于其他站点或者服务 

2 用户可以根据自己的喜好通过拖拽随意摆放这些小模块

3 用户可以添加自己感兴趣的小模块

4  用户可以删除任意已添加的小模块

5 用户可以改变自己的页面风格以及布局。

用rails解决这些问题显得极为简洁,为了简化说明,这里不考虑用户权限,如下:

 

1 在主应用(也就是提供主页服务的系统)建立模块加载机制和代理转发功能(依据dlee翻译的《ajax模式与最佳实践》最后一章的MVC模式),在这里简化下就是一个user有N个page,一个page有N列,一列有N个模块。建立模型如下:

class User < ActiveRecord::Base
   has_many :pages
 end

class Page < ActiveRecord::Base
   has_many :columns
   belongs_to :user
 end

class Column < ActiveRecord::Base
   has_many :cells
   belongs_to :page
end

class Cell < ActiveRecord::Base
      belongs_to :column
end
#在后台发起向其他系统调用服务,当然可以带有一些查询参数比如username已取得和该用户相关的模块内容。
def show
    @cell = Cell.find params[:id]
     Net::HTTP.start(@cell.url,@cell.port) do |http|
        response = http.get('#{@cell.path}', 'Accept' => 'text/xml')
     end
     render :text => @response.body
 end

#其他系统处理请求并返回,返回结果可以是html/xml/rss/flash/js等等,这里暂用字符串文本代替。
def show
     render :text => "ok"
 end

其中需要说明的是:cells表中应存有name、来源URl、port、path,name表示改模块的名字,URl的作用是记录该cell的内容来自于哪个外部站点的rest服务,port指定外部站点的端口,path指定服务的路径。

 

2 利用rails内置的ajax功能处理拖拽,代码如下:

#为简明起见,取id为1的 page,当然也可以根据user来取page
def index 
    @page = Page.find 1
    @columns = @page.columns
end

 

  <%= javascript_include_tag :defaults %>
<table id="table_<%= @page.id %>" align="center">
      <tr id="tr_<%= @page.id %>">
        <% for column in @page.columns %>           
          <td id="td_<%= column.id %>" style="height:auto;word-break:break-all;vertical-align:top;">       
            <% for cell in column.cells %>            
                <div id="cell_<%= cell.id %>" class="cell">
                    正在载入……
            </div>       
            <% end %>
          </td>
        <% end %>
      </tr>
    </table>

     <% for column in @page.columns %>
        <%= sortable_element "td_#{column.id}",  
          :url => { :action => "sort" , :column_id => column.id } , 
          :dropOnEmpty => true ,   
          :tag => "div" ,
          :containment => [
           #一个页面最多可以支持4列,总之把page的所有column设置为拖拽容器即可。
       "td_#{@page.columns[0].id}" ,
          "td_#{@page.columns[1].id}" , 
          "td_#{@page.columns[2].id}" ,
          "td_#{@page.columns[3].id}"
        ] , :constraint => false %>    
      <% end %>
    <% end %>

 异步地为每个小模块加载内容

 

<script>
window.onload = function(){
<% for column in @page.columns %>                 
      <% for cell in column.cells %>   
                new Ajax.Updater('cell_<%= cell.id %>',
                '/Cell/show/<%= cell.id %>',
                {asynchronous:true,evalScripts:true,method:'get'});
      <% end %>
<% end %>
}
<script>

 

后台处理排序

def sort
    @column = Column.find params[:column_id]
    td_index = "td_" + @column.id.to_s 
    list = params[td_index] 
    list.each_with_index { |id,idx| 
      cell = Cell.find id
      cell.column = @column
      cell.row_index = idx.to_i
      cell.save
    } 
end

 

3 向页面添加模块,这里默认向页面的第一列添加,添加模块的div可以做成弹出的浮动div形式。

   <div>
        <% for cell in @cells %>
              <%= link_to_remote cell.name , :update => "td_#{@page.columns[0].id}" , :mothod => :get ,
:url => {:action => "add_cell" , :page_id => @page.id , :id => cell.id} ,:position => "top"  %>
         <% end %> 
  </div>

 后台代码如下:

def add_Cell
    @page = Page.find params[:page_id]
     #获取该页面的第一列,column_index表示改列的列标
    @column = Column.find :first , :conditions => ["page_id=? and column_index=?" , @page.id , 1]
      @cell = Cell.find params[:id]
      @cell.column = @column
      @cell.row_index =  0#row_index 表示该模块在一列中的位置
    @cell.save
end

 

 4 删除模块

#在这里简单的删除该cell记录,前台直接隐藏该cell的div再向后台发送ajax请求。
def delete_cell
    Cell.delete params[:id]
end

 

5 关于设置主题和列数,这个用ajax实现比较容易也比较常见,在此不做解释了。

 

6 这里仅提供了一个思路,很多地方可以完善和扩展,比如在现实中column和cell应为多对多的关系,这里简化为一对多,这个方案已经过简单的扩展和测试,效果还不错。

 

分享到:
评论
1 楼 open2ye 2008-07-05  
照片真吓人.

相关推荐

    RailsSpace

    此外,还会涉及到如何利用Rails的内置工具来简化这些任务。 ##### 2.4 单元测试入门 第五章“Getting started with testing”引导读者进入测试驱动开发的世界。本章首先介绍了测试的重要性,并逐步指导读者如何为...

    Ruby+Rails+社交+进阶教程5

    同时,使用`feed` gem或自定义实现可以生成用户个性化的消息流。 4. **私信系统**:私信是社交网络中的重要通信工具。我们可以创建`Message`模型,包含发送者、接收者、内容等字段,并建立一对多关联,让用户能够...

    服务器自动化任务解决方案 Huginn.zip

    用户可以根据需求自由组合和定制这些Agent,实现个性化的自动化流程。 例如,你可以创建一个HTTP Agent来定期检查某个新闻网站的更新,接着用Regex Extractor Agent解析文章标题,再通过Slack Agent将新文章推送到...

    关于网上书店建站策划书模板.rar

    6. 个性化推荐:根据用户的浏览和购买历史,提供个性化的书籍推荐。 四、技术选型 1. 前端框架:可以选择React、Vue或Angular等现代前端框架,提供良好的用户体验。 2. 后端开发:可采用Node.js、Django、Ruby on ...

    myBlog:尝试建立个人博客

    6. **域名与托管**:购买一个个性化的域名(如yourname.com)可以让博客更具专业性。同时,选择合适的托管服务,如GitHub Pages、Netlify或Vercel,可以免费或低成本地发布你的博客。 7. **SEO优化**:为了让更多人...

    whukxggx.github.io

    如果需要对博客进行个性化定制,可以修改样式表、布局文件或添加自定义功能的JavaScript代码。 总之,"whukxggx.github.io" 是一个基于GitHub Pages的博客项目,它体现了开源精神和Web开发技术的结合,让用户能够...

    pusher-whos-in

    Fork 功能允许用户复制原项目到自己的 GitHub 账户,以便进行个性化修改和开发。 6. **本地网络**: 本地网络通常指局域网(LAN),在这个项目中,可能是指在同一局域网内的设备可以互相看到彼此的在线状态。这可能...

    Grails基础教程

    Web 2.0时代的到来标志着互联网应用进入了一个全新的阶段,这一时期的应用更加注重用户体验、实时交互及个性化服务。Web 2.0的核心理念包括用户生成内容、社会网络、开放API等,这要求开发工具能够更好地支持敏捷...

Global site tag (gtag.js) - Google Analytics