rails 3.1 макеты для конкретных шаблонов через шаблонный резольвер? - PullRequest
3 голосов
/ 29 сентября 2011

У меня довольно простой обработчик шаблонов, возвращающий шаблоны из базы данных:

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 Ответ

2 голосов
/ 16 августа 2012

Вы должны сделать что-то вроде этого:

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
      .
      .
      .

models / 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 таблицы базы данных в зависимости от погоды, в которой вы предпочитаете хранить шаблоны и макеты отдельно или вместе со следующими столбцами: заголовок, тело, путь, формат, языковой стандарт, обработчик, частичный

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...