rails 3.1模板特定布局通过模板解析器?

时间:2011-09-28 22:20:45

标签: ruby-on-rails templates ruby-on-rails-3.1

我有一个非常直接的模板解析器从数据库返回模板:

class MyResolver < ActionView::PathResolver
  def query path, details, formats
    template = MyTemplate.find_by_path path
    ...
    ActionView::Template.new template.source, identifier, handler, details
  end
end

那部分效果很好......我无法弄清楚如何告诉rails使用与从数据库中提取的模板相关联的布局(即template.layout_name或其他一些)。

class MyResolver < ActionView::PathResolver
  def query path, details, formats
    template = MyTemplate.find_by_path path
    layout template.layout_name # ??? yes? no?
    ActionView::Template.new template.source, identifier, handler, details
  end
end

我可以在上面的查询方法中调用设置布局吗?我不应该返回一个ActionView :: Template,而是返回我的Template类,其中包含相应的AV :: T方法,然后覆盖渲染堆栈的其他部分并使用template.layout_name吗?

1 个答案:

答案 0 :(得分:2)

你必须做这样的事情:

pages_controller.rb:

class PagesController < ApplicationController

      prepend_view_path PageTemplate::Resolver.instance

      def render_page
        #Some logic to retrieve the @site & @current_page records....
        render :layout => @site.layout.path, :template => @current_page.template.path
      end
      .
      .
      .

模型/ page_template.rb:

class Resolver < ActionView::Resolver
    require "singleton"
    include Singleton

    def find_templates(name, prefix, partial, details)
      if prefix.empty?
          #If this is not a layout, look it up in the views table and pass that record to the init function
          initialize_template('Template', record)
        end
      elsif prefix === 'layouts'
        #If this is a layout, look it up in the layouts table and pass that record to the init function
        initialize_template('Layout', record)
        end
      end
    end

    # Initialize an ActionView::Template object based on the record found.
    def initialize_template(type, record)
      source = record.body
      identifier = "#{type} - #{record.id} - #{record.path.inspect}"
      handler = ActionView::Template.registered_template_handler(record.handler)

      details = {
          :format => Mime[record.format],
          :updated_at => record.updated_at,
          :virtual_path => virtual_path(record.path, record.partial)
      }

      ActionView::Template.new(source, identifier, handler, details)
    end

    # Make paths as "users/user" become "users/_user" for partials.
    def virtual_path(path, partial)
      return path unless partial
      if index = path.rindex("/")
        path.insert(index + 1, "_")
      else
        "_#{path}"
      end
    end
end

当然这可以重构一下,但这是一般的想法。您还需要1或2个数据库表,具体取决于您希望单独存储模板和布局的天气或与以下列一起存储:标题,正文,路径,格式,区域设置,处理程序,部分

希望有所帮助!