module Munge module Helper module Rendering def render(item, engines: nil, data: {}, content_override: nil) content = content_override || item.content renderers = tilt_renderer_list(item, engines) mdata = merged_data(item.frontmatter, data) render_string(content, data: mdata, engines: renderers) end def layout(item_or_string, data: {}, &block) layout_item = resolve_layout(item_or_string) renderers = tilt_renderer_list(layout_item, nil) mdata = merged_data(layout_item.frontmatter, data) render_string(layout_item.content, data: mdata, engines: renderers, &block) end def render_string(content, data: {}, engines: []) inner = if block_given? yield end engines .inject(content) do |output, engine| template = engine.new { output } if inner template.render(self, data) { inner } else template.render(self, data) end end end def render_with_layout(item, content_engines: nil, data: {}, content_override: nil) inner = render(item, engines: content_engines, data: data, content_override: content_override) mdata = merged_data(item.frontmatter, data) if item.layout layout(item.layout, data: mdata) do inner end else inner end end private def merged_data(*data) hash_with_string_and_symbol_keys = data.inject(@global_data) do |merged, datum| merged.merge(datum) end hash_with_string_and_symbol_keys .each_with_object({}) do |(key, value), memo| memo[key.to_sym] = value end end def resolve_layout(item_or_string) if item_or_string.is_a?(String) @layouts[item_or_string] else item_or_string end end def tilt_renderer_list(item, preferred_engine) if preferred_engine tilt_renderers_from_preferred(preferred_engine) else tilt_renderers_from_path(item.relpath) end end def tilt_renderers_from_path(path) ::Tilt.templates_for(path) end def tilt_renderers_from_preferred(preferred_engines) preferred = if preferred_engines.is_a?(Array) preferred_engines.flatten.join(".") else preferred_engines end ::Tilt.templates_for(preferred) end end end end