Вы смешиваете две разные функции Rails: частичные (используя render
) и макеты (используя yield
) .
Вы можете добавитьпохожая на рельсы версия любой из них (или обеих) для программы только на Haml.
Partials
В представлении rails вы можете использовать render :partial_name
, чтобы вызвать файл _partial_name.html.haml
визуализироваться в этой точке в содержащем представлении (фактически Rails позволяет вам использовать любой поддерживаемый язык шаблонов, и он найдет правильное расширение имени файла, но я остановлюсь только на Haml).Вне Rails render
недоступен, но его можно добавить довольно легко.
Простой метод render
просто найдет соответствующий файл haml, отобразит его и вернет html-строку для включения вparent:
def render(partial)
# assuming we want to keep the rails practice of prefixing file names
# of partials with "_"
Haml::Engine.new(File.read("_#{partial}.html.haml")).render
end
Первый аргумент Haml::Engine.render
- это объект области действия, который мы можем использовать для добавления методов, доступных внутри шаблона haml.По умолчанию Object.new
.Однако в простом случае, подобном этому, мы можем определить метод render
на верхнем уровне, и он будет доступен в области действия шаблона Haml.Мы просто помещаем наш метод render
в сценарий перед вызовом Haml::Engine.new(...).render
и вызываем его следующим образом в нашем шаблоне:
!!!
%html
%head
%title Hello
%body
=render :the_partial
Теперь файл _the_partial.html.haml
будет отображаться в соответствующей точкевыходных.
Локальные переменные
Мы можем сделать это еще дальше.Rails позволяет передавать в хеш локальных переменных в частичное.Haml также примет хэш переменных для передачи в качестве локальных переменных в качестве второго аргумента метода Haml render
.Поэтому, если мы расширим наш метод рендеринга, чтобы он выглядел следующим образом:
def render(partial, locals = {})
Haml::Engine.new(File.read("_#{partial}.html.haml")).render(Object.new, locals)
end
, мы можем использовать частичное, которое выглядит примерно так:
%p You passed in #{foo}
и вызвать его из нашего шаблона с помощью:
%body
=render :partial, :foo => "bar"
, который будет отображать
<body>
<p>You passed in bar</p>
</body>
Макеты
В Rails вы можете указать макет для ваших представлений, чтобы все ваши страницы могли иметь один и тот же заголовок, область менюи т. д. Это делается путем указания файла макета, внутри которого вы вызываете yield
, чтобы отобразить реальный вид.Макеты немного сложнее добавить в haml, но все еще можно сделать. Метод
Hamls render
также принимает блок, поэтому простое решение - визуализация файла макета и передача блока, который визуализируетфайл представления:
Haml::Engine.new(File.read("layout.html.haml")).render do
Haml::Engine.new(File.read("view.html.haml")).render
end
Это даст содержимое layout.html.haml
, отображаемое с содержимым view.html.haml
, отображаемое там, где файл макета содержит =yield
.
content_for
Rails немного более гибок, чем этот.Это позволяет вам вызывать yield
несколько раз в файле макета, называя конкретный регион в каждом случае, и указывать содержимое, которое будет добавлено в каждом регионе, используя метод content_for
в ваших представлениях.Итак, в вашем файле макета:
!!!
%html
%head
= yield :title
%body
=yield
и в вашем представлении:
-content_for :title do
%title Hello
%p
Here's a paragraph.
На самом деле Rails работает так, чтобы сначала визуализировать часть представления, сохраняя все различные разделы, а затемрендеринг макета, передача блока, который обеспечивает соответствующий блок всякий раз, когда yield
вызывается в макете.Мы можем повторить это с помощью небольшого вспомогательного класса, чтобы предоставить метод content_for
и отслеживать отрисованные фрагменты для каждого региона:
class Regions
def initialize
@regions_hash={}
end
def content_for(region, &blk)
@regions_hash[region] = capture_haml(&blk)
end
def [](region)
@regions_hash[region]
end
end
Здесь мы используем capture_haml
метод , чтобы получить обработанный хамл, не отправляя его прямо на выход.Обратите внимание, что это не захватывает безымянную часть представления.
Теперь мы можем использовать наш вспомогательный класс для визуализации окончательного результата.
regions = Regions.new
unnamed = Haml::Engine.new(File.read("view_named.html.haml")).render(regions)
output = Haml::Engine.new(File.read("layout_named.html.haml")).render do |region|
region ? regions[region] : unnamed
end
Теперь переменная output
содержитокончательный результат рендеринга.
Обратите внимание, что код здесь не обеспечивает всю гибкость, которая включена в rails, но, надеюсь, этого достаточно, чтобы показать вам, с чего начать настройку Haml в соответствии с вашими потребностями.