Class: ContentBlockTools::ContentBlock

Inherits:
Object
  • Object
show all
Includes:
ActionView::Helpers::TagHelper
Defined in:
lib/content_block_tools/content_block.rb

Overview

Defines a Content Block

Defined Under Namespace

Classes: UnknownComponentError

Constant Summary collapse

CONTENT_BLOCK_PREFIX =
"content_block_".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content_id:, title:, document_type:, details:, embed_code:) ⇒ ContentBlock

Returns a new instance of ContentBlock.



49
50
51
52
53
54
55
# File 'lib/content_block_tools/content_block.rb', line 49

def initialize(content_id:, title:, document_type:, details:, embed_code:)
  @content_id = content_id
  @title = title
  @document_type = document_type
  @details = details
  @embed_code = embed_code
end

Instance Attribute Details

#content_idString (readonly)

The content UUID for a block

Examples:

content_block.id #=> "2b92cade-549c-4449-9796-e7a3957f3a86"

Returns:

  • (String)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/content_block_tools/content_block.rb', line 41

class ContentBlock
  include ActionView::Helpers::TagHelper
  class UnknownComponentError < StandardError; end

  CONTENT_BLOCK_PREFIX = "content_block_".freeze

  attr_reader :content_id, :title, :embed_code

  def initialize(content_id:, title:, document_type:, details:, embed_code:)
    @content_id = content_id
    @title = title
    @document_type = document_type
    @details = details
    @embed_code = embed_code
  end

  # Calls the appropriate presenter class to return a HTML representation of a content
  # block. Defaults to {Presenters::BasePresenter}
  #
  # @return [string] A HTML representation of the content block
  def render
    (
      base_tag,
      content,
      class: %W[content-block content-block--#{document_type}],
      data: {
        content_block: "",
        document_type: document_type,
        content_id: content_id,
        embed_code: embed_code,
      },
    )
  end

  def details
    @details.deep_symbolize_keys
  end

  def document_type
    @document_type.delete_prefix(CONTENT_BLOCK_PREFIX)
  end

private

  def base_tag
    rendering_block? ? :div : :span
  end

  def content
    field_names.present? ? field_or_block_content : component.new(content_block: self).render
  rescue UnknownComponentError
    title
  end

  def field_or_block_content
    content = details.dig(*field_names)
    case content
    when String
      field_presenter(field_names.last).new(content).render
    when Hash
      component.new(content_block: self, block_type: field_names.first, block_name: field_names.last).render
    else
      ContentBlockTools.logger.warn("Content not found for content block #{content_id} and fields #{field_names}")
      embed_code
    end
  end

  def rendering_block?
    !field_names.present? || details.dig(*field_names).is_a?(Hash)
  end

  def component
    "ContentBlockTools::#{document_type.camelize}Component".constantize
  rescue NameError
    raise UnknownComponentError
  end

  def field_presenter(field)
    "ContentBlockTools::Presenters::FieldPresenters::#{document_type.camelize}::#{field.to_s.camelize}Presenter".constantize
  rescue NameError
    ContentBlockTools::Presenters::FieldPresenters::BasePresenter
  end

  def field_names
    @field_names ||= begin
      embed_code_match = ContentBlockReference::EMBED_REGEX.match(embed_code)
      if embed_code_match.present?
        all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
        all_fields&.split("/")&.map do |item|
          is_number?(item) ? item.to_i : item.to_sym
        end
      end
    end
  end

  def is_number?(item)
    Float(item, exception: false)
  end
end

#detailsHash (readonly)

A hash that contains the details of the content block

Examples:

content_block.details #=> { email_address: "foo@example.com" }

Returns:

  • (Hash)

    the details



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/content_block_tools/content_block.rb', line 41

class ContentBlock
  include ActionView::Helpers::TagHelper
  class UnknownComponentError < StandardError; end

  CONTENT_BLOCK_PREFIX = "content_block_".freeze

  attr_reader :content_id, :title, :embed_code

  def initialize(content_id:, title:, document_type:, details:, embed_code:)
    @content_id = content_id
    @title = title
    @document_type = document_type
    @details = details
    @embed_code = embed_code
  end

  # Calls the appropriate presenter class to return a HTML representation of a content
  # block. Defaults to {Presenters::BasePresenter}
  #
  # @return [string] A HTML representation of the content block
  def render
    (
      base_tag,
      content,
      class: %W[content-block content-block--#{document_type}],
      data: {
        content_block: "",
        document_type: document_type,
        content_id: content_id,
        embed_code: embed_code,
      },
    )
  end

  def details
    @details.deep_symbolize_keys
  end

  def document_type
    @document_type.delete_prefix(CONTENT_BLOCK_PREFIX)
  end

private

  def base_tag
    rendering_block? ? :div : :span
  end

  def content
    field_names.present? ? field_or_block_content : component.new(content_block: self).render
  rescue UnknownComponentError
    title
  end

  def field_or_block_content
    content = details.dig(*field_names)
    case content
    when String
      field_presenter(field_names.last).new(content).render
    when Hash
      component.new(content_block: self, block_type: field_names.first, block_name: field_names.last).render
    else
      ContentBlockTools.logger.warn("Content not found for content block #{content_id} and fields #{field_names}")
      embed_code
    end
  end

  def rendering_block?
    !field_names.present? || details.dig(*field_names).is_a?(Hash)
  end

  def component
    "ContentBlockTools::#{document_type.camelize}Component".constantize
  rescue NameError
    raise UnknownComponentError
  end

  def field_presenter(field)
    "ContentBlockTools::Presenters::FieldPresenters::#{document_type.camelize}::#{field.to_s.camelize}Presenter".constantize
  rescue NameError
    ContentBlockTools::Presenters::FieldPresenters::BasePresenter
  end

  def field_names
    @field_names ||= begin
      embed_code_match = ContentBlockReference::EMBED_REGEX.match(embed_code)
      if embed_code_match.present?
        all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
        all_fields&.split("/")&.map do |item|
          is_number?(item) ? item.to_i : item.to_sym
        end
      end
    end
  end

  def is_number?(item)
    Float(item, exception: false)
  end
end

#document_typeString (readonly)

The document type of the content block - this will be used to work out which Presenter will be used to render the content block. All supported document_types are documented in ContentBlockTools::ContentBlockReference::SUPPORTED_DOCUMENT_TYPES

Examples:

content_block.document_type #=> "content_block_pension"

Returns:

  • (String)

    the document type



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/content_block_tools/content_block.rb', line 41

class ContentBlock
  include ActionView::Helpers::TagHelper
  class UnknownComponentError < StandardError; end

  CONTENT_BLOCK_PREFIX = "content_block_".freeze

  attr_reader :content_id, :title, :embed_code

  def initialize(content_id:, title:, document_type:, details:, embed_code:)
    @content_id = content_id
    @title = title
    @document_type = document_type
    @details = details
    @embed_code = embed_code
  end

  # Calls the appropriate presenter class to return a HTML representation of a content
  # block. Defaults to {Presenters::BasePresenter}
  #
  # @return [string] A HTML representation of the content block
  def render
    (
      base_tag,
      content,
      class: %W[content-block content-block--#{document_type}],
      data: {
        content_block: "",
        document_type: document_type,
        content_id: content_id,
        embed_code: embed_code,
      },
    )
  end

  def details
    @details.deep_symbolize_keys
  end

  def document_type
    @document_type.delete_prefix(CONTENT_BLOCK_PREFIX)
  end

private

  def base_tag
    rendering_block? ? :div : :span
  end

  def content
    field_names.present? ? field_or_block_content : component.new(content_block: self).render
  rescue UnknownComponentError
    title
  end

  def field_or_block_content
    content = details.dig(*field_names)
    case content
    when String
      field_presenter(field_names.last).new(content).render
    when Hash
      component.new(content_block: self, block_type: field_names.first, block_name: field_names.last).render
    else
      ContentBlockTools.logger.warn("Content not found for content block #{content_id} and fields #{field_names}")
      embed_code
    end
  end

  def rendering_block?
    !field_names.present? || details.dig(*field_names).is_a?(Hash)
  end

  def component
    "ContentBlockTools::#{document_type.camelize}Component".constantize
  rescue NameError
    raise UnknownComponentError
  end

  def field_presenter(field)
    "ContentBlockTools::Presenters::FieldPresenters::#{document_type.camelize}::#{field.to_s.camelize}Presenter".constantize
  rescue NameError
    ContentBlockTools::Presenters::FieldPresenters::BasePresenter
  end

  def field_names
    @field_names ||= begin
      embed_code_match = ContentBlockReference::EMBED_REGEX.match(embed_code)
      if embed_code_match.present?
        all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
        all_fields&.split("/")&.map do |item|
          is_number?(item) ? item.to_i : item.to_sym
        end
      end
    end
  end

  def is_number?(item)
    Float(item, exception: false)
  end
end

#embed_codeString (readonly)

The embed_code used for a block containing optional field name

Examples:

content_block_reference.embed_code #=> "{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"
content_block_reference.embed_code #=> "{{embed:content_block_contact:2b92cade-549c-4449-9796-e7a3957f3a86/field_name}}"

Returns:

  • (String)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/content_block_tools/content_block.rb', line 41

class ContentBlock
  include ActionView::Helpers::TagHelper
  class UnknownComponentError < StandardError; end

  CONTENT_BLOCK_PREFIX = "content_block_".freeze

  attr_reader :content_id, :title, :embed_code

  def initialize(content_id:, title:, document_type:, details:, embed_code:)
    @content_id = content_id
    @title = title
    @document_type = document_type
    @details = details
    @embed_code = embed_code
  end

  # Calls the appropriate presenter class to return a HTML representation of a content
  # block. Defaults to {Presenters::BasePresenter}
  #
  # @return [string] A HTML representation of the content block
  def render
    (
      base_tag,
      content,
      class: %W[content-block content-block--#{document_type}],
      data: {
        content_block: "",
        document_type: document_type,
        content_id: content_id,
        embed_code: embed_code,
      },
    )
  end

  def details
    @details.deep_symbolize_keys
  end

  def document_type
    @document_type.delete_prefix(CONTENT_BLOCK_PREFIX)
  end

private

  def base_tag
    rendering_block? ? :div : :span
  end

  def content
    field_names.present? ? field_or_block_content : component.new(content_block: self).render
  rescue UnknownComponentError
    title
  end

  def field_or_block_content
    content = details.dig(*field_names)
    case content
    when String
      field_presenter(field_names.last).new(content).render
    when Hash
      component.new(content_block: self, block_type: field_names.first, block_name: field_names.last).render
    else
      ContentBlockTools.logger.warn("Content not found for content block #{content_id} and fields #{field_names}")
      embed_code
    end
  end

  def rendering_block?
    !field_names.present? || details.dig(*field_names).is_a?(Hash)
  end

  def component
    "ContentBlockTools::#{document_type.camelize}Component".constantize
  rescue NameError
    raise UnknownComponentError
  end

  def field_presenter(field)
    "ContentBlockTools::Presenters::FieldPresenters::#{document_type.camelize}::#{field.to_s.camelize}Presenter".constantize
  rescue NameError
    ContentBlockTools::Presenters::FieldPresenters::BasePresenter
  end

  def field_names
    @field_names ||= begin
      embed_code_match = ContentBlockReference::EMBED_REGEX.match(embed_code)
      if embed_code_match.present?
        all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
        all_fields&.split("/")&.map do |item|
          is_number?(item) ? item.to_i : item.to_sym
        end
      end
    end
  end

  def is_number?(item)
    Float(item, exception: false)
  end
end

#titleString (readonly)

A title for the content block

Examples:

content_block.title #=> "Some title"

Returns:

  • (String)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/content_block_tools/content_block.rb', line 41

class ContentBlock
  include ActionView::Helpers::TagHelper
  class UnknownComponentError < StandardError; end

  CONTENT_BLOCK_PREFIX = "content_block_".freeze

  attr_reader :content_id, :title, :embed_code

  def initialize(content_id:, title:, document_type:, details:, embed_code:)
    @content_id = content_id
    @title = title
    @document_type = document_type
    @details = details
    @embed_code = embed_code
  end

  # Calls the appropriate presenter class to return a HTML representation of a content
  # block. Defaults to {Presenters::BasePresenter}
  #
  # @return [string] A HTML representation of the content block
  def render
    (
      base_tag,
      content,
      class: %W[content-block content-block--#{document_type}],
      data: {
        content_block: "",
        document_type: document_type,
        content_id: content_id,
        embed_code: embed_code,
      },
    )
  end

  def details
    @details.deep_symbolize_keys
  end

  def document_type
    @document_type.delete_prefix(CONTENT_BLOCK_PREFIX)
  end

private

  def base_tag
    rendering_block? ? :div : :span
  end

  def content
    field_names.present? ? field_or_block_content : component.new(content_block: self).render
  rescue UnknownComponentError
    title
  end

  def field_or_block_content
    content = details.dig(*field_names)
    case content
    when String
      field_presenter(field_names.last).new(content).render
    when Hash
      component.new(content_block: self, block_type: field_names.first, block_name: field_names.last).render
    else
      ContentBlockTools.logger.warn("Content not found for content block #{content_id} and fields #{field_names}")
      embed_code
    end
  end

  def rendering_block?
    !field_names.present? || details.dig(*field_names).is_a?(Hash)
  end

  def component
    "ContentBlockTools::#{document_type.camelize}Component".constantize
  rescue NameError
    raise UnknownComponentError
  end

  def field_presenter(field)
    "ContentBlockTools::Presenters::FieldPresenters::#{document_type.camelize}::#{field.to_s.camelize}Presenter".constantize
  rescue NameError
    ContentBlockTools::Presenters::FieldPresenters::BasePresenter
  end

  def field_names
    @field_names ||= begin
      embed_code_match = ContentBlockReference::EMBED_REGEX.match(embed_code)
      if embed_code_match.present?
        all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
        all_fields&.split("/")&.map do |item|
          is_number?(item) ? item.to_i : item.to_sym
        end
      end
    end
  end

  def is_number?(item)
    Float(item, exception: false)
  end
end

Instance Method Details

#renderstring

Calls the appropriate presenter class to return a HTML representation of a content block. Defaults to Presenters::BasePresenter

Returns:

  • (string)

    A HTML representation of the content block



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/content_block_tools/content_block.rb', line 61

def render
  (
    base_tag,
    content,
    class: %W[content-block content-block--#{document_type}],
    data: {
      content_block: "",
      document_type: document_type,
      content_id: content_id,
      embed_code: embed_code,
    },
  )
end