Class: Integral::ContentRenderer

Inherits:
Object
  • Object
show all
Defined in:
lib/integral/content_renderer.rb

Overview

Handles the rendering of dynamic content (Widgets) within static HTML A widget could be used to list recent articles from the blog, featured content from a list, etc

Example Widget Markup <p class=‘integral-widget’ data-widget-type=‘recent_posts’ data-widget-value-tagged=‘sweet-tag’>

Constant Summary collapse

PLACEHOLDER_SELECTOR =

Markup defining a widget

'p.integral-widget'.freeze

Class Method Summary collapse

Class Method Details

.render(raw_html) ⇒ String

Renders WYSIWYG html, converting any widget placeholders to dynamic content



26
27
28
29
30
31
32
33
34
35
# File 'lib/integral/content_renderer.rb', line 26

def self.render(raw_html)
  html = Nokogiri::HTML(raw_html)
  html.css(self::PLACEHOLDER_SELECTOR).each do |placeholder|
    widget_type = placeholder.attributes['data-widget-type']&.value

    placeholder.replace(render_widget(widget_type, widget_options(placeholder.attributes)))
  end

  html.css('body').inner_html.html_safe
end

.render_widget(type, options) ⇒ String

Renders a specific widget using the provided options



56
57
58
59
60
61
62
63
64
# File 'lib/integral/content_renderer.rb', line 56

def self.render_widget(type, options)
  widget = widgets.find { |w| w[0] == type }

  return widget_not_available_message unless widget.present?

  widget[1].constantize.render(options)
rescue StandardError => error
  respond_with_widget_error(error)
end

.respond_with_widget_error(error) ⇒ Object

Handles widget errors



67
68
69
70
71
# File 'lib/integral/content_renderer.rb', line 67

def self.respond_with_widget_error(error)
  Rails.logger.error(error.message)

  '<!-- Error rendering widget -->'
end

.widget_not_available_messageString



74
75
76
# File 'lib/integral/content_renderer.rb', line 74

def self.widget_not_available_message
  '<!-- Widget not available -->'
end

.widget_options(placeholder_attributes) ⇒ Hash

Parse placeholder attributes to find any widget options



42
43
44
45
46
47
48
# File 'lib/integral/content_renderer.rb', line 42

def self.widget_options(placeholder_attributes)
  options = {}
  keys = placeholder_attributes.keys.select { |key| key.starts_with?('data-widget-value-') }

  keys.each { |key| options[key.remove('data-widget-value-').to_sym] = placeholder_attributes[key].value }
  options
end

.widgetsArray



12
13
14
15
16
17
18
19
# File 'lib/integral/content_renderer.rb', line 12

def self.widgets
  widgets = [
    ['recent_posts', 'Integral::Widgets::RecentPosts'],
    ['swiper_list', 'Integral::Widgets::SwiperList']
  ]

  widgets.concat Integral.additional_widgets
end