rails theme(参考typo)

最近学习一下typo,看typo的theme是怎样实现的,顺便把theme模块抽出来,以后编写rails应用(比如Blog),直接把代码COPY进去就可以.
1)修改routes.rb, add以下code:
map.with_options(:conditions => {:method => :get}) do |get|
  get.with_options(:controller => 'themes', :filename => /.*/, :conditions => {:method => :get}) do |theme|
      theme.connect 'stylesheets/theme/:filename', :action => 'stylesheets'
      theme.connect 'javascripts/theme/:filename', :action => 'javascript'
      theme.connect 'images/theme/:filename', :action => 'images'
  end
end

主要是由themes控制器来处理(读取)css、javascripts、image这些文件.
2)定义一个全局的静态实例,用来存储Theme
在environment.rb里添加:
@@stored_theme = nil

3)themes文件的位置:
在你的rails应用目录里mkdir一个themes文件,如图1:
其中dirtylicious,scribbish,standard_issue是三个不同的主题(Theme).
每个主题文件的布局像图1一样(以standard_issue):
由images(放图片),layouts(放模板),stylesheets(css文件),views(视图文件html)等文件组成.
4)定义一个Theme model(不与DB关联)
class Theme
  def initialize(name, path)
    @name, @path = name, path
  end

  def layout #模板文件,在layouts文件里,叫default.html.erb
    "../../themes/#{name}/layouts/default"
  end

  def self.find(name) #查找指定(name)的Theme
    self.new(name,theme_path(name))
  end

  def self.themes_root #所有theme的root
    RAILS_ROOT + "/themes"
  end

  def self.theme_path(name) #指定(name)theme的path
    themes_root + "/" + name
  end

  def self.theme_from_path(path) #查找指定(path)的Theme
    name = path.scan(/[-\w]+$/i).flatten.first
    self.new(name, path)
  end

  def self.find_all #查找所有Theme
    installed_themes.inject([]) do |array, path|
      array << theme_from_path(path) 
    end
  end

  def self.installed_themes #载入theme
    search_theme_directory
  end

  def self.search_theme_directory #读入
    glob = "#{themes_root}/[a-zA-Z0-9]*"
    Dir.glob(glob).select do |file|
      File.readable?("#{file}/about.markdown")
    end.compact
end

5)create themes controller由themes控制器来处理(读取)css、javascripts、image这些文件的位置:
class ThemesController < ApplicationController

  session :off

  def stylesheets
    render_theme_item(:stylesheets, params[:filename], 'text/css; charset=utf-8')
  end

  def javascript
    render_theme_item(:javascript, params[:filename], 'text/javascript; charset=utf-8')
  end

  def images
    render_theme_item(:images, params[:filename])
  end

  def error
    render :nothing => true, :status => 404
  end

  private

  def render_theme_item(type, file, mime = nil)
    mime ||= mime_for(file)
    if file.split(%r{[\\/]}).include?("..")
      return (render :text => "Not Found", :status => 404)
    end

    src = @@stored_theme.path + "/#{type}/#{file}"
    return (render :text => "Not Found", :status => 404) unless File.exists? src

    if perform_caching
      dst = "/#{page_cache_directory}/#{type}/theme/#{file}"
      FileUtils.makedirs(File.dirname(dst))
      FileUtils.cp(src, "#{dst}.#{$$}")
      FileUtils.ln("#{dst}.#{$$}", dst) rescue nil
      FileUtils.rm("#{dst}.#{$$}", :force => true)
    end

    send_file(src, :type => mime, :disposition => 'inline', :stream => true)
  end

  def mime_for(filename)
  	case filename.downcase
    	when /\.js$/
      	'text/javascript'
    	when /\.css$/
      	'text/css'
    	when /\.gif$/
      	'image/gif'
    	when /(\.jpg|\.jpeg)$/
      	'image/jpeg'
    	when /\.png$/
      	'image/png'
    	when /\.swf$/
      	'application/x-shockwave-flash'
    	else
      	'application/binary'
    end
  end

end

6)在Application.rb里定义current_theme helper方法:
helper_method :current_theme
def current_theme
  @@stored_theme ||= Theme.find(get_configuration('theme').value)
end
#get_configuration('theme').value 是获取存储在DataBase里面的当前Theme的名字(图2)

7)在Application.rb里定义theme_layout, setup_themer
def theme_layout #用于layout :theme_layout
  current_theme.layout
end
def setup_themer #设置视图文件(View) 读取路径
self.view_paths=::ActionController::Base.view_paths.dup.unshift("#{RAILS_ROOT}/themes/#{current_theme.name}/views")
end

8)编辑控制器:
class ArticlesController < ApplicationController
  before_filter :setup_themer
  layout :theme_layout

  def index
  ....
  end
  
  ....
end

9)总结
如果有新的theme文件,比如A,那么就mkdir一个A文件,并在A文件里面有图1结构,
然后放在Themes目录里,所有views文件就像平常一样编写,然后放到A文件的views里面,OK
如果要加载某个Theme的css或javascript文件,那么要在该Theme的模板文件(layouts/default.html.erb)定义:
<%= stylesheet_link_tag '/stylesheets/theme/application.css', :media => 'all' %>
<%= javascript_link_tag '/javascripts/theme/application.js'%>

OK

你可能感兴趣的:(JavaScript,css,Ruby,Rails,idea)