From 81d4bb778fd115b16bc8d9598d7d34cb2e314dcc Mon Sep 17 00:00:00 2001 From: Guillaume Grossetie Date: Tue, 11 Feb 2020 00:11:17 +0100 Subject: [PATCH] Use content_for and yield_content to remove code duplication --- templates/helpers.rb | 63 +++++++++++++++++++++++++++++++- templates/section.html.slim | 73 +++++++++++++++---------------------- 2 files changed, 92 insertions(+), 44 deletions(-) diff --git a/templates/helpers.rb b/templates/helpers.rb index 43230261..79305fc9 100644 --- a/templates/helpers.rb +++ b/templates/helpers.rb @@ -130,8 +130,69 @@ def section_title(sec = self) def resolve_content @content_model == :simple ? %(

#{content}

) : content end - #-- + # Capture nested template content and register it with the specified key, to + # be executed at a later time. + # + # This method must be invoked using the control code directive (i.e., -). By + # using a control code directive, the block is set up to append the result + # directly to the output buffer. (Integrations often hide the distinction + # between a control code directive and an output directive in this context). + # + # key - The Symbol under which to save the template block. + # opts - A Hash of options to control processing (default: {}): + # * :append - A Boolean that indicates whether to append this block + # to others registered with this key (default: false). + # * :content - String content to be used if template content is not + # provided (optional). + # block - The template content (in Slim template syntax). + # + # Examples + # + # - content_for :body + # p content + # - content_for :body, append: true + # p more content + # + # Returns nothing. + def content_for key, opts = {}, &block + @content = {} unless defined? @content + (opts[:append] ? (@content[key] ||= []) : (@content[key] = [])) << (block_given? ? block : lambda { opts[:content] }) + nil + end + + # Checks whether deferred template content has been registered for the specified key. + # + # key - The Symbol under which to look for saved template blocks. + # + # Returns a Boolean indicating whether content has been registered for this key. + def content_for? key + (defined? @content) && (@content.key? key) + end + + # Evaluates the deferred template content registered with the specified key. + # + # When the corresponding content_for method is invoked using a control code + # directive, the block is set up to append the result to the output buffer + # directly. + # + # key - The Symbol under which to look for template blocks to yield. + # opts - A Hash of options to control processing (default: {}): + # * :drain - A Boolean indicating whether to drain the key of blocks + # after calling them (default: true). + # + # Examples + # + # - yield_content :body + # + # Returns nothing (assuming the content has been captured in the context of control code). + def yield_content key, opts = {} + if (defined? @content) && (blks = (opts.fetch :drain, true) ? (@content.delete key) : @content[key]) + blks.map {|b| b.call }.join + end + nil + end + #-- end # More custom functions can be added in another namespace if required diff --git a/templates/section.html.slim b/templates/section.html.slim index f21e6316..dbe04c35 100644 --- a/templates/section.html.slim +++ b/templates/section.html.slim @@ -33,32 +33,38 @@ - if attr? 'background-color' - data_background_color = attr 'background-color' -/ RENDERING -/ render parent section of vertical slides set -- if @level == 1 && !vertical_slides.empty? - section - / TODO: try to get rid of duplication w/ standalone slide section - section(id=(titleless ? nil : id) - class=roles - data-transition=(attr 'transition') - data-transition-speed=(attr 'transition-speed') - data-background-color=data_background_color - data-background-image=data_background_image - data-background-size=(data_background_size || attr('background-size')) - data-background-repeat=(data_background_repeat || attr('background-repeat')) - data-background-transition=(data_background_transition || attr('background-transition')) - data-background-position=(data_background_position || attr('background-position')) - data-background-iframe=(attr "background-iframe") - data-background-video=(attr "background-video") - data-background-video-loop=((attr? 'background-video-loop') || (option? 'loop')) - data-background-video-muted=((attr? 'background-video-muted') || (option? 'muted')) - data-background-opacity=(attr "background-opacity") - data-state=(attr 'state')) +- parent_section_with_vertical_slides = @level == 1 && !vertical_slides.empty? - - unless hide_title - h2=section_title +- content_for :section + section(id=(titleless ? nil : id) + class=roles + data-transition=(attr 'transition') + data-transition-speed=(attr 'transition-speed') + data-background-color=data_background_color + data-background-image=data_background_image + data-background-size=(data_background_size || attr('background-size')) + data-background-repeat=(data_background_repeat || attr('background-repeat')) + data-background-transition=(data_background_transition || attr('background-transition')) + data-background-position=(data_background_position || attr('background-position')) + data-background-iframe=(attr "background-iframe") + data-background-video=(attr "background-video") + data-background-video-loop=((attr? 'background-video-loop') || (option? 'loop')) + data-background-video-muted=((attr? 'background-video-muted') || (option? 'muted')) + data-background-opacity=(attr "background-opacity") + data-state=(attr 'state')) + - unless hide_title + h2=section_title + - if parent_section_with_vertical_slides - (blocks - vertical_slides).each do |block| =block.convert + - else + =content.chomp + +/ RENDERING +/ render parent section of vertical slides set +- if parent_section_with_vertical_slides + section + - yield_content :section - vertical_slides.each do |subsection| =subsection.convert @@ -69,23 +75,4 @@ h level=(@level) =title =content.chomp - else - section(id=(titleless ? nil : id) - class=roles - data-transition=(attr 'transition') - data-transition-speed=(attr 'transition-speed') - data-background-color=data_background_color - data-background-image=data_background_image - data-background-size=(data_background_size || attr('background-size')) - data-background-repeat=(data_background_repeat || attr('background-repeat')) - data-background-transition=(data_background_transition || attr('background-transition')) - data-background-position=(data_background_position || attr('background-position')) - data-background-iframe=(attr "background-iframe") - data-background-video=(attr "background-video") - data-background-video-loop=((attr? 'background-video-loop') || (option? 'loop')) - data-background-video-muted=((attr? 'background-video-muted') || (option? 'muted')) - data-background-opacity=(attr "background-opacity") - data-state=(attr 'state')) - - - unless hide_title - h2=section_title - =content.chomp + - yield_content :section