content_block_tools 1.0.3 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/content_block_tools/base_component.rb +13 -0
  3. data/app/components/content_block_tools/contact_component.html.erb +18 -0
  4. data/app/components/content_block_tools/contact_component.rb +29 -0
  5. data/app/components/content_block_tools/contacts/address_component.html.erb +5 -0
  6. data/app/components/content_block_tools/contacts/address_component.rb +42 -0
  7. data/app/components/content_block_tools/contacts/contact_link_component.html.erb +12 -0
  8. data/app/components/content_block_tools/contacts/contact_link_component.rb +19 -0
  9. data/app/components/content_block_tools/contacts/email_address_component.html.erb +12 -0
  10. data/app/components/content_block_tools/contacts/email_address_component.rb +28 -0
  11. data/app/components/content_block_tools/contacts/telephone_component.html.erb +32 -0
  12. data/app/components/content_block_tools/contacts/telephone_component.rb +51 -0
  13. data/lib/content_block_tools/content_block.rb +85 -12
  14. data/lib/content_block_tools/engine.rb +8 -0
  15. data/lib/content_block_tools/presenters/field_presenters/contact/{email_address_presenter.rb → email_presenter.rb} +1 -1
  16. data/lib/content_block_tools/version.rb +1 -1
  17. data/lib/content_block_tools.rb +5 -11
  18. metadata +49 -19
  19. data/lib/content_block_tools/presenters/base_presenter.rb +0 -138
  20. data/lib/content_block_tools/presenters/block_presenters/base_presenter.rb +0 -21
  21. data/lib/content_block_tools/presenters/block_presenters/contact/address_presenter.rb +0 -42
  22. data/lib/content_block_tools/presenters/block_presenters/contact/block_level_contact_item.rb +0 -34
  23. data/lib/content_block_tools/presenters/block_presenters/contact/contact_link_presenter.rb +0 -41
  24. data/lib/content_block_tools/presenters/block_presenters/contact/email_address_presenter.rb +0 -50
  25. data/lib/content_block_tools/presenters/block_presenters/contact/telephone_presenter.rb +0 -83
  26. data/lib/content_block_tools/presenters/contact_presenter.rb +0 -40
  27. data/lib/content_block_tools/presenters/pension_presenter.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50436aeb5d432fa7ec6ebabbe8cee19e432bb56cd3fe28bd8ede33a4bbbd73c0
4
- data.tar.gz: 4893df6d56a576411107110e9b3f4c1458798df3ec2575362fab5fd48bf714b8
3
+ metadata.gz: fb006e7903ec6cae4253ae9332308c42accf3f4e424da21e3bdb3d5ce2efe89c
4
+ data.tar.gz: 5cfd7df4e3bfa56fcd4b1333e7d09d0ab26b71de12cc6e8f7f13855493d5d6c6
5
5
  SHA512:
6
- metadata.gz: eb3677c3386cb06b584ded27945d938c29e36f35ce424c4a3697eb5b25cf17c4ee6d75b8f197d3ca154bf925ef44bb64df5def7cd75e8592313d9353095fdd22
7
- data.tar.gz: 34debefd7c42b20635fba94cf0a2b924bb61d6ccc53fa8a5e0f53cde7d9d4ae42469ede2a4526c021145424dd7091f2f3d979d4c06ddc3f21fcc4b6da5bb563d
6
+ metadata.gz: 4d084a5f1684a8189d3b38db0d8df0a453e461b7c96aba6612493a326232312593de5fb0ec97402141c8865862fd36b09c6ff7bfca5796c287aedce4b2e93e40
7
+ data.tar.gz: ddf80b36ba7d6292219afb73df52a6df83b04640c8a2befec36054e9382cd34d5b6b573de844e67dfdbe91d3f17fa72ec8cba3df12d0c40d1112dcaee3576eb0
@@ -0,0 +1,13 @@
1
+ module ContentBlockTools
2
+ class BaseComponent < ViewComponent::Base
3
+ def render
4
+ render_in(view_context)
5
+ end
6
+
7
+ private
8
+
9
+ def view_context
10
+ ActionView::Base.new(ActionView::LookupContext.new([]), {}, nil)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ <div class="vcard">
2
+ <p class="fn org content-block__title"><%= content_block.title %></p>
3
+
4
+ <% if block_type.present? && content_block.details[:description] %>
5
+ <%= render_govspeak(content_block.details[:description]) %>
6
+ <% end %>
7
+
8
+ <% if block_type.nil? %>
9
+ <% BLOCK_TYPES.each do |block_type| %>
10
+ <% content_by_block_type[block_type].each do |item| %>
11
+ <p class="content-block__subtitle"><%= item[:title] %></p>
12
+ <%= component_for_block_type(block_type).new(item:).render.html_safe %>
13
+ <% end %>
14
+ <% end %>
15
+ <% else %>
16
+ <%= component_for_block_type(block_type).new(item: item_to_render).render.html_safe %>
17
+ <% end %>
18
+ </div>
@@ -0,0 +1,29 @@
1
+ module ContentBlockTools
2
+ class ContactComponent < ContentBlockTools::BaseComponent
3
+ BLOCK_TYPES = %i[addresses email_addresses telephones contact_links].freeze
4
+
5
+ def initialize(content_block:, block_type: nil, block_name: nil)
6
+ @content_block = content_block
7
+ @block_type = block_type
8
+ @block_name = block_name
9
+ end
10
+
11
+ private
12
+
13
+ attr_reader :content_block, :block_type, :block_name
14
+
15
+ def component_for_block_type(block_type)
16
+ "ContentBlockTools::Contacts::#{block_type.to_s.singularize.camelize}Component".constantize
17
+ end
18
+
19
+ def content_by_block_type
20
+ @content_by_block_type ||= content_block.details.keys.map { |key|
21
+ [key, content_block.details[key]&.values]
22
+ }.to_h
23
+ end
24
+
25
+ def item_to_render
26
+ content_block.details.dig(block_type, block_name)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ <p class="adr content-block__body">
2
+ <%= lines.map { |field, value| address_line(field, value) }.join(",<br />").html_safe %>
3
+ </p>
4
+
5
+ <%= render_govspeak(item[:description]) if item[:description].present? %>
@@ -0,0 +1,42 @@
1
+ module ContentBlockTools
2
+ module Contacts
3
+ class AddressComponent < ContentBlockTools::BaseComponent
4
+ include ContentBlockTools::Govspeak
5
+
6
+ def initialize(item:)
7
+ @item = item
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :item
13
+
14
+ def lines
15
+ address_parts.map { |attribute|
16
+ next if item[attribute].blank?
17
+
18
+ [attribute, item[attribute]]
19
+ }.compact.to_h
20
+ end
21
+
22
+ def address_parts
23
+ %i[recipient street_address town_or_city state_or_county postal_code country]
24
+ end
25
+
26
+ def address_line(field, value)
27
+ content_tag(:span, value, { class: class_for_field_name(field) })
28
+ end
29
+
30
+ def class_for_field_name(field_name)
31
+ {
32
+ recipient: "organization-name",
33
+ street_address: "street-address",
34
+ town_or_city: "locality",
35
+ state_or_county: "region",
36
+ postal_code: "postal-code",
37
+ country: "country-name",
38
+ }[field_name]
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,12 @@
1
+ <ul class="content-block__list">
2
+ <li>
3
+ <a href="<%= item[:url] %>" class="url content-block__link">
4
+ <%= link_text %>
5
+ </a>
6
+ </li>
7
+ <% if item[:description] %>
8
+ <li>
9
+ <%= render_govspeak(item[:description]) %>
10
+ </li>
11
+ <% end %>
12
+ </ul>
@@ -0,0 +1,19 @@
1
+ module ContentBlockTools
2
+ module Contacts
3
+ class ContactLinkComponent < ContentBlockTools::BaseComponent
4
+ include ContentBlockTools::Govspeak
5
+
6
+ def initialize(item:)
7
+ @item = item
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :item
13
+
14
+ def link_text
15
+ item[:label] || item[:url]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ <ul class="content-block__list">
2
+ <li>
3
+ <a href="<%= "mailto:#{item[:email_address]}#{query_params}" %>" class="email content-block__link">
4
+ <%= link_text %>
5
+ </a>
6
+ </li>
7
+ <% if item[:description] %>
8
+ <li>
9
+ <%= render_govspeak(item[:description]) %>
10
+ </li>
11
+ <% end %>
12
+ </ul>
@@ -0,0 +1,28 @@
1
+ module ContentBlockTools
2
+ module Contacts
3
+ class EmailAddressComponent < ContentBlockTools::BaseComponent
4
+ include ContentBlockTools::Govspeak
5
+
6
+ def initialize(item:)
7
+ @item = item
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :item
13
+
14
+ def query_params
15
+ params = {
16
+ subject: item[:subject],
17
+ body: item[:body],
18
+ }.compact.map { |k, v| "#{k}=#{v}" }.join("&")
19
+
20
+ "?#{params}" if params.present?
21
+ end
22
+
23
+ def link_text
24
+ item[:label] || item[:email_address]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ <% if item[:description] %>
2
+ <%= render_govspeak(item[:description], root_class: "content-block__body") %>
3
+ <% end %>
4
+
5
+ <ul class="content-block__list">
6
+ <% item[:telephone_numbers].each do |number| %>
7
+ <li>
8
+ <span><%= number[:label] %>: </span>
9
+ <span class="tel"><%= number[:telephone_number] %></span>
10
+ </li>
11
+ <% end %>
12
+ </ul>
13
+
14
+ <% if show_video_relay_service? %>
15
+ <%= render_govspeak(video_relay_service_content) %>
16
+ <% end %>
17
+
18
+ <% if show_bsl_guidance? %>
19
+ <%= render_govspeak(bsl_guidance[:value], root_class: "content-block__body") %>
20
+ <% end %>
21
+
22
+ <% if show_opening_hours? %>
23
+ <%= render_govspeak(opening_hours[:opening_hours], root_class: "content-block__body") %>
24
+ <% end %>
25
+
26
+ <% if show_call_charges? %>
27
+ <p class="content-block__body">
28
+ <a href="<%= call_charges[:call_charges_info_url] %>" class="content-block__link">
29
+ <%= call_charges[:label] %>
30
+ </a>
31
+ </p>
32
+ <% end %>
@@ -0,0 +1,51 @@
1
+ module ContentBlockTools
2
+ module Contacts
3
+ class TelephoneComponent < ContentBlockTools::BaseComponent
4
+ include ContentBlockTools::Govspeak
5
+
6
+ def initialize(item:)
7
+ @item = item
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :item
13
+
14
+ def video_relay_service
15
+ @video_relay_service ||= item[:video_relay_service] || {}
16
+ end
17
+
18
+ def show_video_relay_service?
19
+ video_relay_service[:show].present?
20
+ end
21
+
22
+ def video_relay_service_content
23
+ "#{video_relay_service[:prefix]} #{video_relay_service[:telephone_number]}"
24
+ end
25
+
26
+ def bsl_guidance
27
+ @bsl_guidance ||= item[:bsl_guidance] || {}
28
+ end
29
+
30
+ def show_bsl_guidance?
31
+ bsl_guidance[:show].present?
32
+ end
33
+
34
+ def opening_hours
35
+ @opening_hours ||= item[:opening_hours] || {}
36
+ end
37
+
38
+ def show_opening_hours?
39
+ opening_hours[:show_opening_hours].present?
40
+ end
41
+
42
+ def call_charges
43
+ @call_charges ||= item[:call_charges] || {}
44
+ end
45
+
46
+ def show_call_charges?
47
+ call_charges[:show_call_charges_info_url].present?
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,6 +1,4 @@
1
1
  module ContentBlockTools
2
- ContentBlock = Data.define(:content_id, :title, :document_type, :details, :embed_code)
3
-
4
2
  # Defines a Content Block
5
3
  #
6
4
  # @api public
@@ -40,25 +38,100 @@ module ContentBlockTools
40
38
  # content_block_reference.embed_code #=> "{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"
41
39
  # content_block_reference.embed_code #=> "{{embed:content_block_contact:2b92cade-549c-4449-9796-e7a3957f3a86/field_name}}"
42
40
  # @return [String]
43
- class ContentBlock < Data
44
- # A lookup of presenters for particular content block types
45
- CONTENT_PRESENTERS = {
46
- "content_block_contact" => ContentBlockTools::Presenters::ContactPresenter,
47
- "content_block_pension" => ContentBlockTools::Presenters::PensionPresenter,
48
- }.freeze
41
+ class ContentBlock
42
+ include ActionView::Helpers::TagHelper
43
+
44
+ CONTENT_BLOCK_PREFIX = "content_block_".freeze
45
+
46
+ attr_reader :content_id, :title, :embed_code
47
+
48
+ def initialize(content_id:, title:, document_type:, details:, embed_code:)
49
+ @content_id = content_id
50
+ @title = title
51
+ @document_type = document_type
52
+ @details = details
53
+ @embed_code = embed_code
54
+ end
49
55
 
50
56
  # Calls the appropriate presenter class to return a HTML representation of a content
51
57
  # block. Defaults to {Presenters::BasePresenter}
52
58
  #
53
59
  # @return [string] A HTML representation of the content block
54
60
  def render
55
- CONTENT_PRESENTERS
56
- .fetch(document_type, Presenters::BasePresenter)
57
- .new(self).render
61
+ content_tag(
62
+ base_tag,
63
+ content,
64
+ class: %W[content-block content-block--#{document_type}],
65
+ data: {
66
+ content_block: "",
67
+ document_type: document_type,
68
+ content_id: content_id,
69
+ embed_code: embed_code,
70
+ },
71
+ )
58
72
  end
59
73
 
60
74
  def details
61
- to_h[:details].deep_symbolize_keys
75
+ @details.deep_symbolize_keys
76
+ end
77
+
78
+ def document_type
79
+ @document_type.delete_prefix(CONTENT_BLOCK_PREFIX)
80
+ end
81
+
82
+ private
83
+
84
+ def base_tag
85
+ rendering_block? ? :div : :span
86
+ end
87
+
88
+ def content
89
+ field_names.present? ? field_or_block_content : component.new(content_block: self).render
90
+ rescue NameError
91
+ title
92
+ end
93
+
94
+ def field_or_block_content
95
+ content = details.dig(*field_names)
96
+ case content
97
+ when String
98
+ field_presenter(field_names.last).new(content).render
99
+ when Hash
100
+ component.new(content_block: self, block_type: field_names.first, block_name: field_names.last).render
101
+ else
102
+ ContentBlockTools.logger.warn("Content not found for content block #{content_id} and fields #{field_names}")
103
+ embed_code
104
+ end
105
+ end
106
+
107
+ def rendering_block?
108
+ !field_names.present? || details.dig(*field_names).is_a?(Hash)
109
+ end
110
+
111
+ def component
112
+ "ContentBlockTools::#{document_type.camelize}Component".constantize
113
+ end
114
+
115
+ def field_presenter(field)
116
+ "ContentBlockTools::Presenters::FieldPresenters::#{document_type.camelize}::#{field.to_s.camelize}Presenter".constantize
117
+ rescue NameError
118
+ ContentBlockTools::Presenters::FieldPresenters::BasePresenter
119
+ end
120
+
121
+ def field_names
122
+ @field_names ||= begin
123
+ embed_code_match = ContentBlockReference::EMBED_REGEX.match(embed_code)
124
+ if embed_code_match.present?
125
+ all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
126
+ all_fields&.split("/")&.map do |item|
127
+ is_number?(item) ? item.to_i : item.to_sym
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ def is_number?(item)
134
+ Float(item, exception: false)
62
135
  end
63
136
  end
64
137
  end
@@ -1,7 +1,15 @@
1
+ require "rails/engine"
2
+ require "view_component"
3
+ require "view_component/version"
4
+
1
5
  module ContentBlockTools
2
6
  class Engine < ::Rails::Engine
3
7
  isolate_namespace ContentBlockTools
4
8
 
9
+ config.autoload_paths = %W[
10
+ "#{root}/app/components"
11
+ ]
12
+
5
13
  initializer "content_block_tools.assets" do
6
14
  if defined? Rails.application.config.assets
7
15
  Rails.application.config.assets.paths += %w[
@@ -2,7 +2,7 @@ module ContentBlockTools
2
2
  module Presenters
3
3
  module FieldPresenters
4
4
  module Contact
5
- class EmailAddressPresenter < BasePresenter
5
+ class EmailPresenter < BasePresenter
6
6
  def render
7
7
  content_tag(:a, field, class: "govuk-link", href: "mailto:#{field}")
8
8
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ContentBlockTools
4
- VERSION = "1.0.3"
4
+ VERSION = "1.1.1"
5
5
  end
@@ -7,17 +7,7 @@ require "govspeak"
7
7
  require "content_block_tools/helpers/govspeak"
8
8
 
9
9
  require "content_block_tools/presenters/field_presenters/base_presenter"
10
- require "content_block_tools/presenters/field_presenters/contact/email_address_presenter"
11
-
12
- require "content_block_tools/presenters/block_presenters/base_presenter"
13
- require "content_block_tools/presenters/block_presenters/contact/address_presenter"
14
- require "content_block_tools/presenters/block_presenters/contact/contact_link_presenter"
15
- require "content_block_tools/presenters/block_presenters/contact/email_address_presenter"
16
- require "content_block_tools/presenters/block_presenters/contact/telephone_presenter"
17
-
18
- require "content_block_tools/presenters/base_presenter"
19
- require "content_block_tools/presenters/contact_presenter"
20
- require "content_block_tools/presenters/pension_presenter"
10
+ require "content_block_tools/presenters/field_presenters/contact/email_presenter"
21
11
 
22
12
  require "content_block_tools/content_block"
23
13
  require "content_block_tools/content_block_reference"
@@ -30,6 +20,10 @@ module ContentBlockTools
30
20
  class Error < StandardError; end
31
21
  module Presenters; end
32
22
 
23
+ module Components
24
+ module Contacts; end
25
+ end
26
+
33
27
  class << self
34
28
  attr_writer :logger
35
29
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: content_block_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
@@ -24,33 +24,33 @@ dependencies:
24
24
  - !ruby/object:Gem::Version
25
25
  version: 13.3.0
26
26
  - !ruby/object:Gem::Dependency
27
- name: rspec
27
+ name: rspec-html-matchers
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 3.13.1
32
+ version: 0.10.0
33
33
  type: :development
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 3.13.1
39
+ version: 0.10.0
40
40
  - !ruby/object:Gem::Dependency
41
- name: rspec-html-matchers
41
+ name: rspec-rails
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - '='
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 0.10.0
46
+ version: '0'
47
47
  type: :development
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '='
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 0.10.0
53
+ version: '0'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: rubocop-govuk
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -93,6 +93,34 @@ dependencies:
93
93
  - - '='
94
94
  - !ruby/object:Gem::Version
95
95
  version: 10.6.1
96
+ - !ruby/object:Gem::Dependency
97
+ name: rails
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: view_component
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '='
115
+ - !ruby/object:Gem::Version
116
+ version: 4.0.1
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '='
122
+ - !ruby/object:Gem::Version
123
+ version: 4.0.1
96
124
  email:
97
125
  - govuk-dev@digital.cabinet-office.gov.uk
98
126
  executables: []
@@ -102,22 +130,24 @@ files:
102
130
  - README.md
103
131
  - app/assets/stylesheets/blocks/_contact.scss
104
132
  - app/assets/stylesheets/content_block_tools.scss
133
+ - app/components/content_block_tools/base_component.rb
134
+ - app/components/content_block_tools/contact_component.html.erb
135
+ - app/components/content_block_tools/contact_component.rb
136
+ - app/components/content_block_tools/contacts/address_component.html.erb
137
+ - app/components/content_block_tools/contacts/address_component.rb
138
+ - app/components/content_block_tools/contacts/contact_link_component.html.erb
139
+ - app/components/content_block_tools/contacts/contact_link_component.rb
140
+ - app/components/content_block_tools/contacts/email_address_component.html.erb
141
+ - app/components/content_block_tools/contacts/email_address_component.rb
142
+ - app/components/content_block_tools/contacts/telephone_component.html.erb
143
+ - app/components/content_block_tools/contacts/telephone_component.rb
105
144
  - lib/content_block_tools.rb
106
145
  - lib/content_block_tools/content_block.rb
107
146
  - lib/content_block_tools/content_block_reference.rb
108
147
  - lib/content_block_tools/engine.rb
109
148
  - lib/content_block_tools/helpers/govspeak.rb
110
- - lib/content_block_tools/presenters/base_presenter.rb
111
- - lib/content_block_tools/presenters/block_presenters/base_presenter.rb
112
- - lib/content_block_tools/presenters/block_presenters/contact/address_presenter.rb
113
- - lib/content_block_tools/presenters/block_presenters/contact/block_level_contact_item.rb
114
- - lib/content_block_tools/presenters/block_presenters/contact/contact_link_presenter.rb
115
- - lib/content_block_tools/presenters/block_presenters/contact/email_address_presenter.rb
116
- - lib/content_block_tools/presenters/block_presenters/contact/telephone_presenter.rb
117
- - lib/content_block_tools/presenters/contact_presenter.rb
118
149
  - lib/content_block_tools/presenters/field_presenters/base_presenter.rb
119
- - lib/content_block_tools/presenters/field_presenters/contact/email_address_presenter.rb
120
- - lib/content_block_tools/presenters/pension_presenter.rb
150
+ - lib/content_block_tools/presenters/field_presenters/contact/email_presenter.rb
121
151
  - lib/content_block_tools/version.rb
122
152
  - node_modules/govuk-frontend/README.md
123
153
  - node_modules/govuk-frontend/dist/govuk-prototype-kit/functions.js
@@ -1,138 +0,0 @@
1
- module ContentBlockTools
2
- module Presenters
3
- class BasePresenter
4
- include ActionView::Context
5
- include ActionView::Helpers::TagHelper
6
-
7
- # The default HTML tag to wrap the presented response in - can be overridden in a subclass
8
- BASE_TAG_TYPE = :span
9
-
10
- # A lookup of presenters for particular fields - can be overridden in a subclass
11
- FIELD_PRESENTERS = {}.freeze
12
-
13
- # A lookup of presenters for particular blocks - can be overridden in a subclass
14
- BLOCK_PRESENTERS = {}.freeze
15
-
16
- def self.has_embedded_objects(*object_types)
17
- @embedded_objects = object_types
18
-
19
- object_types.each do |object_type|
20
- define_method(object_type) do
21
- embedded_objects_of_type(object_type)
22
- end
23
- end
24
- end
25
-
26
- # Returns a new presenter object
27
- #
28
- # @param [{ContentBlockTools::ContentBlock}] content_block A content block object
29
- #
30
- # @return [{ContentBlockTools::Presenters::BasePresenter}]
31
- def initialize(content_block)
32
- @content_block = content_block
33
- end
34
-
35
- # Returns a HTML representation of the content block wrapped in a base tag with
36
- # a class and data attributes
37
- # Calls the {#content} method, which can be overridden in a subclass
38
- #
39
- # @return [string] A HTML representation of the content block
40
- def render
41
- content_tag(
42
- base_tag,
43
- content,
44
- class: %W[content-block content-block--#{document_type}],
45
- data: {
46
- content_block: "",
47
- document_type: document_type,
48
- content_id: content_block.content_id,
49
- embed_code: content_block.embed_code,
50
- },
51
- )
52
- end
53
-
54
- private
55
-
56
- attr_reader :content_block
57
-
58
- # The default representation of the content block - this can be overridden in a subclass
59
- # by overriding the content, default_content or content_for_fields methods
60
- #
61
- # @return [string] A representation of the content block to be wrapped in the base_tag in
62
- # {#content}
63
- def content
64
- ContentBlockTools.logger.info("Getting content for content block #{content_block.content_id}")
65
- field_names.present? ? content_for_field_names : default_content
66
- end
67
-
68
- def default_content
69
- content_block.title
70
- end
71
-
72
- def content_for_field_names
73
- if field_or_block_content.blank?
74
- ContentBlockTools.logger.warn("Content not found for content block #{content_block.content_id} and fields #{field_names}")
75
- return content_block.embed_code
76
- end
77
-
78
- field_or_block_presenter.new(field_or_block_content, rendering_context: :field_names, content_block:).render
79
- end
80
-
81
- def field_names
82
- @field_names ||= begin
83
- embed_code_match = ContentBlockReference::EMBED_REGEX.match(content_block.embed_code)
84
- if embed_code_match.present?
85
- all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
86
- all_fields&.split("/")&.map do |item|
87
- is_number?(item) ? item.to_i : item.to_sym
88
- end
89
- end
90
- end
91
- end
92
-
93
- def is_number?(item)
94
- Float(item, exception: false)
95
- end
96
-
97
- def field_or_block_content
98
- @field_or_block_content ||= field_names.any? ? content_block.details.deep_symbolize_keys.dig(*field_names) : nil
99
- end
100
-
101
- def rendering_block?
102
- field_or_block_content.is_a?(Hash)
103
- end
104
-
105
- def field_or_block_presenter
106
- @field_or_block_presenter ||= if rendering_block?
107
- block_presenter || ContentBlockTools::Presenters::BlockPresenters::BasePresenter
108
- else
109
- field_presenter || ContentBlockTools::Presenters::FieldPresenters::BasePresenter
110
- end
111
- end
112
-
113
- def field_presenter
114
- @field_presenter ||= field_names ? self.class::FIELD_PRESENTERS[field_names.last] : nil
115
- end
116
-
117
- def block_presenter
118
- @block_presenter ||= field_names ? self.class::BLOCK_PRESENTERS[field_names.first] : nil
119
- end
120
-
121
- def base_tag
122
- field_names ? field_or_block_presenter::BASE_TAG_TYPE : self.class::BASE_TAG_TYPE
123
- end
124
-
125
- def embedded_objects_of_type(type)
126
- content_block.details.fetch(type, {}).values
127
- end
128
-
129
- def embedded_objects
130
- self.class.instance_variable_get("@embedded_objects")
131
- end
132
-
133
- def document_type
134
- content_block.document_type.delete_prefix("content_block_")
135
- end
136
- end
137
- end
138
- end
@@ -1,21 +0,0 @@
1
- module ContentBlockTools
2
- module Presenters
3
- module BlockPresenters
4
- class BasePresenter
5
- include ActionView::Context
6
- include ActionView::Helpers::TextHelper
7
- include ContentBlockTools::Govspeak
8
-
9
- BASE_TAG_TYPE = :span
10
-
11
- attr_reader :item
12
-
13
- def initialize(item, **_args)
14
- @item = item
15
- end
16
-
17
- def render; end
18
- end
19
- end
20
- end
21
- end
@@ -1,42 +0,0 @@
1
- require_relative "./block_level_contact_item"
2
-
3
- module ContentBlockTools
4
- module Presenters
5
- module BlockPresenters
6
- module Contact
7
- class AddressPresenter < ContentBlockTools::Presenters::BlockPresenters::BasePresenter
8
- include ContentBlockTools::Presenters::BlockPresenters::Contact::BlockLevelContactItem
9
-
10
- def render
11
- wrapper do
12
- output = []
13
-
14
- output << content_tag(:p, class: "adr content-block__body") do
15
- %i[recipient street_address town_or_city state_or_county postal_code country].map { |field|
16
- next if item[field].blank?
17
-
18
- content_tag(:span, item[field], { class: class_for_field_name(field) })
19
- }.compact_blank.join(",<br/>").html_safe
20
- end
21
-
22
- output << render_govspeak(item[:description]) if item[:description].present?
23
-
24
- output.join.html_safe
25
- end
26
- end
27
-
28
- def class_for_field_name(field_name)
29
- {
30
- recipient: "organization-name",
31
- street_address: "street-address",
32
- town_or_city: "locality",
33
- state_or_county: "region",
34
- postal_code: "postal-code",
35
- country: "country-name",
36
- }[field_name]
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,34 +0,0 @@
1
- module ContentBlockTools
2
- module Presenters
3
- module BlockPresenters
4
- module Contact
5
- module BlockLevelContactItem
6
- BASE_TAG_TYPE = :div
7
-
8
- def initialize(item, content_block:, rendering_context: :block, **_args)
9
- @item = item
10
- @content_block = content_block
11
- @rendering_context = rendering_context
12
- end
13
-
14
- def wrapper(&block)
15
- content_tag(:div) do
16
- concat title
17
- concat yield block
18
- end
19
- end
20
-
21
- def title
22
- if @rendering_context == :field_names
23
- content_tag(:p,
24
- @content_block.title,
25
- class: "content-block__title")
26
- else
27
- content_tag(:p, item[:title], class: "content-block__subtitle")
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,41 +0,0 @@
1
- require_relative "./block_level_contact_item"
2
-
3
- module ContentBlockTools
4
- module Presenters
5
- module BlockPresenters
6
- module Contact
7
- class ContactLinkPresenter < ContentBlockTools::Presenters::BlockPresenters::BasePresenter
8
- include ContentBlockTools::Presenters::BlockPresenters::Contact::BlockLevelContactItem
9
-
10
- def render
11
- wrapper do
12
- content_tag(:ul, class: "content-block__list") do
13
- concat link
14
- concat description if item[:description]
15
- end
16
- end
17
- end
18
-
19
- def link
20
- content_tag(:li) do
21
- content_tag(:a,
22
- link_text,
23
- class: "url content-block__link",
24
- href: item[:url])
25
- end
26
- end
27
-
28
- def link_text
29
- item[:label] || item[:url]
30
- end
31
-
32
- def description
33
- content_tag(:li) do
34
- render_govspeak(item[:description])
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,50 +0,0 @@
1
- require_relative "./block_level_contact_item"
2
-
3
- module ContentBlockTools
4
- module Presenters
5
- module BlockPresenters
6
- module Contact
7
- class EmailAddressPresenter < ContentBlockTools::Presenters::BlockPresenters::BasePresenter
8
- include ContentBlockTools::Presenters::BlockPresenters::Contact::BlockLevelContactItem
9
-
10
- def render
11
- wrapper do
12
- content_tag(:ul, class: "content-block__list") do
13
- concat email
14
- concat description if item[:description].present?
15
- end
16
- end
17
- end
18
-
19
- def email
20
- content_tag(:li) do
21
- concat content_tag(:a,
22
- link_text,
23
- class: "email content-block__link",
24
- href: "mailto:#{item[:email_address]}#{query_params}")
25
- end
26
- end
27
-
28
- def query_params
29
- params = {
30
- subject: item[:subject],
31
- body: item[:body],
32
- }.compact.map { |k, v| "#{k}=#{v}" }.join("&")
33
-
34
- "?#{params}" if params.present?
35
- end
36
-
37
- def link_text
38
- item[:label] || item[:email_address]
39
- end
40
-
41
- def description
42
- content_tag(:li) do
43
- render_govspeak(item[:description])
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,83 +0,0 @@
1
- require_relative "./block_level_contact_item"
2
-
3
- module ContentBlockTools
4
- module Presenters
5
- module BlockPresenters
6
- module Contact
7
- class TelephonePresenter < ContentBlockTools::Presenters::BlockPresenters::BasePresenter
8
- include ContentBlockTools::Presenters::BlockPresenters::Contact::BlockLevelContactItem
9
-
10
- def render
11
- wrapper do
12
- content_tag(:div) do
13
- concat description if item[:description].present?
14
- concat number_list
15
- concat video_relay_service
16
- concat bsl_details
17
- concat opening_hours
18
- concat call_charges_link
19
- end
20
- end
21
- end
22
-
23
- def description
24
- render_govspeak(item[:description], root_class: "content-block__body")
25
- end
26
-
27
- def number_list
28
- content_tag(:ul, class: "content-block__list") do
29
- item[:telephone_numbers].each do |number|
30
- concat number_list_item(number)
31
- end
32
- end
33
- end
34
-
35
- def number_list_item(number)
36
- content_tag(:li) do
37
- concat content_tag(:span, "#{number[:label]}: ")
38
- concat content_tag(:span, number[:telephone_number], { class: "tel" })
39
- end
40
- end
41
-
42
- def video_relay_service
43
- video_relay_service = item[:video_relay_service] || {}
44
-
45
- if video_relay_service[:show]
46
- content = "#{video_relay_service[:prefix]} #{video_relay_service[:telephone_number]}"
47
- render_govspeak(content, root_class: "content-block__body")
48
- end
49
- end
50
-
51
- def bsl_details
52
- bsl_guidance = item[:bsl_guidance] || {}
53
-
54
- render_govspeak(bsl_guidance[:value], root_class: "content-block__body") if bsl_guidance[:show]
55
- end
56
-
57
- def opening_hours
58
- opening_hours = item[:opening_hours] || {}
59
-
60
- render_govspeak(opening_hours[:opening_hours], root_class: "content-block__body") if opening_hours[:show_opening_hours]
61
- end
62
-
63
- def opening_hours_list_item(item)
64
- content_tag(:li, "#{item[:day_from]} to #{item[:day_to]}, #{item[:time_from]} to #{item[:time_to]}")
65
- end
66
-
67
- def call_charges_link
68
- call_charges = item[:call_charges] || {}
69
-
70
- if call_charges[:show_call_charges_info_url]
71
- content_tag(:p) do
72
- concat content_tag(:a,
73
- call_charges[:label],
74
- class: "content-block__link",
75
- href: call_charges[:call_charges_info_url])
76
- end
77
- end
78
- end
79
- end
80
- end
81
- end
82
- end
83
- end
@@ -1,40 +0,0 @@
1
- module ContentBlockTools
2
- module Presenters
3
- class ContactPresenter < BasePresenter
4
- include ActionView::Helpers::TextHelper
5
- include ContentBlockTools::Govspeak
6
-
7
- BASE_TAG_TYPE = :div
8
-
9
- FIELD_PRESENTERS = {
10
- email_address: ContentBlockTools::Presenters::FieldPresenters::Contact::EmailAddressPresenter,
11
- }.freeze
12
-
13
- BLOCK_PRESENTERS = {
14
- addresses: ContentBlockTools::Presenters::BlockPresenters::Contact::AddressPresenter,
15
- telephones: ContentBlockTools::Presenters::BlockPresenters::Contact::TelephonePresenter,
16
- email_addresses: ContentBlockTools::Presenters::BlockPresenters::Contact::EmailAddressPresenter,
17
- contact_links: ContentBlockTools::Presenters::BlockPresenters::Contact::ContactLinkPresenter,
18
- }.freeze
19
-
20
- has_embedded_objects :addresses, :email_addresses, :telephones, :contact_links
21
-
22
- private
23
-
24
- def default_content
25
- content_tag(:div, class: "vcard") do
26
- concat content_tag(:p, content_block.title, class: "fn org content-block__title")
27
- concat render_govspeak(content_block.details[:description]) if content_block.details[:description]
28
- embedded_objects.each do |object|
29
- items = send(object)
30
- concat(items.map { |item| presenter_for_object_type(object).new(item, content_block:).render }.join.html_safe)
31
- end
32
- end
33
- end
34
-
35
- def presenter_for_object_type(type)
36
- "ContentBlockTools::Presenters::BlockPresenters::Contact::#{type.to_s.singularize.underscore.camelize}Presenter".constantize
37
- end
38
- end
39
- end
40
- end
@@ -1,11 +0,0 @@
1
- module ContentBlockTools
2
- module Presenters
3
- class PensionPresenter < BasePresenter
4
- private
5
-
6
- def default_content
7
- content_block.title
8
- end
9
- end
10
- end
11
- end