Пользовательские переменные в Rails вид именем


По умолчанию Rails может найти представления с форматом, языковым стандартом и языком шаблона в имени файла (поэтому я могу создать index.de.json.erb)

Можно ли добавить другой, пользовательский параметр к имени файла представления?

Я хотел бы передать текущий поддомен, так что http://foo.example.com/ будет отображать index.foo.html.erb, а http://bar.example.com/ будет отображать index.bar.html.erb (оба с index.html.erb резервным вариантом).

2 5

2 ответа:

Разрешающий шаблон, используемый для поиска представлений, может содержать только переменные, зарегистрированные в классе ActionView::LookupContext. Поэтому первым шагом является регистрация новой переменной (subdomain) в классе LookupContext. Вы должны сделать это в инициализаторе:

ActionView::LookupContext.register_detail(:subdomain) do
  ['default_subdomain']
end

Теперь LookupContext знает о subdomain, его можно включить в разрешающий паттерн. Более подробно об изменении разрешающего паттерна см. ActionView::FileSystemResolver документация , но по существу вы должны включить следующее, также в инициализаторе:

ActionController::Base.view_paths = ActionView::FileSystemResolver.new(
  Rails.root.join('app', 'views'),
  ':prefix/:action{.:locale,}{.:subdomain,}{.:formats,}{.:handlers,}'
)

Эта модель в конечном итоге передается Dir.glob (после замены переменных :*). Шаблон glob {.:subdomain,} означает "либо .:subdomain, либо ничего", что обеспечивает запасной вариант для файла представления без поддомена, если файл с поддоменом не найден.

Последним шагом является обновление вашего ApplicationController для передачи поддомена в LookupContext:

class ApplicationController < ActionController::Base
  def details_for_lookup
    {:subdomain => [request.subdomain]}
  end
end

(этот ответ был в основном вычислен путем чтения исходного кода, некоторые из эти особенности не документированы. Он был испытан с рельсами 3.2.5)

Я не думаю, что вам нужен пользовательский обработчик здесь. Вы не выполняете некоторую подготовку ваших шаблонов, но вам просто нужно, чтобы ваши шаблоны стали специфичными для домена.

Я бы хотел сделать что-то вроде этого:

# in ApplicationController:
  before_filter :set_view_paths

  def set_view_paths
    self.class.view_paths = Rails.root.join('app', 'views', controller_name, request.subdomain)
  end
Затем вы должны поместить шаблоны для домена foo в папки foo каждого пути views/controller_name.

Также проверьте append/prepend_view_path документация , Чтобы разрешить дефолты в случае отсутствия представления домена.