content_block_tools 0.4.6 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e547141a41ea1ed3c613e2ba8a8282fefd49f84ab64e2339c60a0f2d7acb2146
4
- data.tar.gz: 88018c79e26b77f59f9d154a4cd575763ac4f245a68b87631d96bfb4ac746263
3
+ metadata.gz: a8de300ea972686e97b1fcbe422979f9a3876060ae7e69d575b8270e65c0c509
4
+ data.tar.gz: 4db995f515fdbcb10c22695f03e74ba7d0d5c2f037b9870c52e274a54bee7674
5
5
  SHA512:
6
- metadata.gz: 79c0c6daa97869493fa5a82d79378ead1347ece9705f55d8cf8403234cfb153e615941f99d9964c07956e47999a48532b9d9fe5d57335b64ace4f28d2cf9d6b1
7
- data.tar.gz: e577a337138cf151795aa95d1d3f6e1a0ba30ba896e475f68e94adaf985351ec2967e7609b53e40992a59ff56b1f0548135587e01037ede80a04a418191d178f
6
+ metadata.gz: c74f391d6df0c5feee05dfbfafdb59576a99226029252c849a8a5714b44ea87a09fc54b4583e0de5424ccb9dfcc131d02c8477b309c3230c9536e8cb09e191df
7
+ data.tar.gz: b24e0e97e96edd7791cf586282c740feb13a2832a0d1c59234f93539e2b8b652851a387675a147703ac10ca041120c0ac150af803dad49e7cc6a1dcac5fc3dcc
data/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@
7
7
  useful summary for people upgrading their application, not a replication
8
8
  of the commit log.
9
9
 
10
+ ## 0.5.1
11
+
12
+ - Update dependencies
13
+ - Create a presenter for Contact Blocks ([30](https://github.com/alphagov/govuk_content_block_tools/pull/30))
14
+
15
+ ## 0.5.0
16
+
17
+ - Support Content ID aliases ([27](https://github.com/alphagov/govuk_content_block_tools/pull/27))
18
+
10
19
  ## 0.4.6
11
20
  - Remove noisy log ([25](https://github.com/alphagov/govuk_content_block_tools/pull/25))
12
21
 
@@ -27,7 +27,8 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_development_dependency "rake", "13.2.1"
29
29
  spec.add_development_dependency "rspec", "3.13.0"
30
- spec.add_development_dependency "rubocop-govuk", "5.0.3"
30
+ spec.add_development_dependency "rspec-html-matchers", "0.10.0"
31
+ spec.add_development_dependency "rubocop-govuk", "5.1.6"
31
32
 
32
33
  spec.add_dependency "actionview", ">= 6"
33
34
  end
@@ -36,13 +36,14 @@ module ContentBlockTools
36
36
  #
37
37
  # @!attribute [r] embed_code
38
38
  # The embed_code used for a block containing optional field name
39
- # @example
40
- # content_block_reference.embed_code #=> "{{embed:content_block_email_address:2b92cade-549c-4449-9796-e7a3957f3a86}}"
41
- # content_block_reference.embed_code #=> "{{embed:content_block_postal_address:2b92cade-549c-4449-9796-e7a3957f3a86/field_name}}"
42
- # @return [String]
39
+ # @example
40
+ # content_block_reference.embed_code #=> "{{embed:content_block_email_address:2b92cade-549c-4449-9796-e7a3957f3a86}}"
41
+ # content_block_reference.embed_code #=> "{{embed:content_block_postal_address:2b92cade-549c-4449-9796-e7a3957f3a86/field_name}}"
42
+ # @return [String]
43
43
  class ContentBlock < Data
44
44
  # A lookup of presenters for particular content block types
45
45
  CONTENT_PRESENTERS = {
46
+ "content_block_contact" => ContentBlockTools::Presenters::ContactPresenter,
46
47
  "content_block_email_address" => ContentBlockTools::Presenters::EmailAddressPresenter,
47
48
  "content_block_postal_address" => ContentBlockTools::Presenters::PostalAddressPresenter,
48
49
  "content_block_pension" => ContentBlockTools::Presenters::PensionPresenter,
@@ -1,5 +1,5 @@
1
1
  module ContentBlockTools
2
- ContentBlockReference = Data.define(:document_type, :content_id, :embed_code)
2
+ ContentBlockReference = Data.define(:document_type, :identifier, :embed_code)
3
3
 
4
4
  # Defines a reference pointer for a Content Block
5
5
  #
@@ -13,10 +13,12 @@ module ContentBlockTools
13
13
  # @return [String] the document type
14
14
  # @api public
15
15
  #
16
- # @!attribute [r] content_id
17
- # The content UUID for a block
16
+ # @!attribute [r] identifier
17
+ # The identifier for a block - can be a UUID or a slug. The UUID will refer to the `content_id` of a block
18
+ # within Publishing API, while the slug will refer to a block's Content ID alias.
18
19
  # @example
19
- # content_block_reference.id #=> "2b92cade-549c-4449-9796-e7a3957f3a86"
20
+ # content_block_reference.identifier #=> "2b92cade-549c-4449-9796-e7a3957f3a86"
21
+ # content_block_reference.identifier #=> "some-slug"
20
22
  # @return [String]
21
23
  #
22
24
  # @!attribute [r] embed_code
@@ -26,13 +28,22 @@ module ContentBlockTools
26
28
  # @return [String]
27
29
  class ContentBlockReference < Data
28
30
  # An array of the supported document types
29
- SUPPORTED_DOCUMENT_TYPES = %w[contact content_block_email_address content_block_postal_address content_block_pension].freeze
31
+ SUPPORTED_DOCUMENT_TYPES = %w[contact content_block_email_address content_block_postal_address content_block_pension content_block_contact].freeze
30
32
  # The regex used to find UUIDs
31
- UUID_REGEX = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/
33
+ UUID_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
34
+ # The regex used to find content ID aliases
35
+ CONTENT_ID_ALIAS_REGEX = /[a-z0-9-]+/
32
36
  # The regex to find optional field names after the UUID, begins with '/'
33
37
  FIELD_REGEX = /(\/[a-z0-9_\-\/]*)?/
34
38
  # The regex used when scanning a document using {ContentBlockTools::ContentBlockReference.find_all_in_document}
35
- EMBED_REGEX = /({{embed:(#{SUPPORTED_DOCUMENT_TYPES.join('|')}):#{UUID_REGEX}#{FIELD_REGEX}}})/
39
+ EMBED_REGEX = /({{embed:(#{SUPPORTED_DOCUMENT_TYPES.join('|')}):(#{UUID_REGEX}|#{CONTENT_ID_ALIAS_REGEX})#{FIELD_REGEX}}})/
40
+
41
+ # Returns if the identifier is an alias
42
+ #
43
+ # @return Boolean
44
+ def identifier_is_alias?
45
+ !identifier.match?(UUID_REGEX)
46
+ end
36
47
 
37
48
  class << self
38
49
  # Finds all content block references within a document, using `ContentBlockReference::EMBED_REGEX`
@@ -42,7 +53,7 @@ module ContentBlockTools
42
53
  def find_all_in_document(document)
43
54
  document.scan(ContentBlockReference::EMBED_REGEX).map do |match|
44
55
  ContentBlockTools.logger.info("Found Content Block Reference: #{match}")
45
- ContentBlockReference.new(document_type: match[1], content_id: match[2], embed_code: match[0])
56
+ ContentBlockReference.new(document_type: match[1], identifier: match[2], embed_code: match[0])
46
57
  end
47
58
  end
48
59
  end
@@ -1,11 +1,15 @@
1
1
  module ContentBlockTools
2
2
  module Presenters
3
3
  class BasePresenter
4
+ include ActionView::Context
4
5
  include ActionView::Helpers::TagHelper
5
6
 
6
7
  # The default HTML tag to wrap the presented response in - can be overridden in a subclass
7
8
  BASE_TAG_TYPE = :span
8
9
 
10
+ # A lookup of presenters for particular fields - can be overridden in a subclass
11
+ FIELD_PRESENTERS = {}.freeze
12
+
9
13
  # Returns a new presenter object
10
14
  #
11
15
  # @param [{ContentBlockTools::ContentBlock}] content_block A content block object
@@ -22,7 +26,7 @@ module ContentBlockTools
22
26
  # @return [string] A HTML representation of the content block
23
27
  def render
24
28
  content_tag(
25
- BASE_TAG_TYPE,
29
+ base_tag,
26
30
  content,
27
31
  class: %W[content-embed content-embed__#{content_block.document_type}],
28
32
  data: {
@@ -62,17 +66,28 @@ module ContentBlockTools
62
66
  ContentBlockTools.logger.warn("Content not found for content block #{content_block.content_id} and fields #{field_names}")
63
67
  content_block.embed_code
64
68
  else
65
- content
69
+ presenter = field_presenter || ContentBlockTools::Presenters::FieldPresenters::BasePresenter
70
+ presenter.new(content).render
66
71
  end
67
72
  end
68
73
 
69
74
  def field_names
70
- embed_code_match = ContentBlockReference::EMBED_REGEX.match(content_block.embed_code)
71
- if embed_code_match.present?
72
- all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
73
- all_fields&.split("/")&.map(&:to_sym)
75
+ @field_names ||= begin
76
+ embed_code_match = ContentBlockReference::EMBED_REGEX.match(content_block.embed_code)
77
+ if embed_code_match.present?
78
+ all_fields = embed_code_match[4]&.reverse&.chomp("/")&.reverse
79
+ all_fields&.split("/")&.map(&:to_sym)
80
+ end
74
81
  end
75
82
  end
83
+
84
+ def field_presenter
85
+ @field_presenter ||= field_names ? self.class::FIELD_PRESENTERS[field_names.last] : nil
86
+ end
87
+
88
+ def base_tag
89
+ field_names ? :span : self.class::BASE_TAG_TYPE
90
+ end
76
91
  end
77
92
  end
78
93
  end
@@ -0,0 +1,51 @@
1
+ module ContentBlockTools
2
+ module Presenters
3
+ class ContactPresenter < BasePresenter
4
+ include ActionView::Helpers::TextHelper
5
+
6
+ BASE_TAG_TYPE = :div
7
+
8
+ FIELD_PRESENTERS = {
9
+ email_address: ContentBlockTools::Presenters::FieldPresenters::Contact::EmailAddressPresenter,
10
+ }.freeze
11
+
12
+ private
13
+
14
+ def default_content
15
+ content_tag(:div, class: "contact") do
16
+ concat content_tag(:p, content_block.title, class: "govuk-body")
17
+ concat(email_addresses.map { |email_address| email_address_content(email_address) }.join.html_safe) if email_addresses.any?
18
+ concat(phone_numbers.map { |phone_number| phone_number_content(phone_number) }.join.html_safe) if phone_numbers.any?
19
+ end
20
+ end
21
+
22
+ def email_address_content(email_address)
23
+ content_tag(:p, class: "govuk-body govuk-!-margin-bottom-4") do
24
+ concat content_tag(:span, email_address[:title])
25
+ concat content_tag(:a,
26
+ email_address[:email_address],
27
+ class: "govuk-link",
28
+ href: "mailto:#{email_address[:email_address]}")
29
+ end
30
+ end
31
+
32
+ def phone_number_content(phone_number)
33
+ content_tag(:p, class: "govuk-body govuk-!-margin-bottom-4") do
34
+ concat content_tag(:span, phone_number[:title])
35
+ concat content_tag(:a,
36
+ phone_number[:telephone],
37
+ class: "govuk-link",
38
+ href: "tel:#{CGI.escape phone_number[:telephone]}")
39
+ end
40
+ end
41
+
42
+ def email_addresses
43
+ content_block.details[:email_addresses]&.values
44
+ end
45
+
46
+ def phone_numbers
47
+ content_block.details[:telephones]&.values
48
+ end
49
+ end
50
+ end
51
+ end
@@ -4,7 +4,10 @@ module ContentBlockTools
4
4
  private
5
5
 
6
6
  def content
7
- content_block.details[:email_address]
7
+ content_tag(:a,
8
+ content_block.details[:email_address],
9
+ class: "govuk-link",
10
+ href: "mailto:#{content_block.details[:email_address]}")
8
11
  end
9
12
  end
10
13
  end
@@ -0,0 +1,20 @@
1
+ module ContentBlockTools
2
+ module Presenters
3
+ module FieldPresenters
4
+ class BasePresenter
5
+ include ActionView::Context
6
+ include ActionView::Helpers::TagHelper
7
+
8
+ attr_reader :field
9
+
10
+ def initialize(field)
11
+ @field = field
12
+ end
13
+
14
+ def render
15
+ field
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module ContentBlockTools
2
+ module Presenters
3
+ module FieldPresenters
4
+ module Contact
5
+ class EmailAddressPresenter < BasePresenter
6
+ def render
7
+ content_tag(:a, field, class: "govuk-link", href: "mailto:#{field}")
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ContentBlockTools
4
- VERSION = "0.4.6"
4
+ VERSION = "0.5.1"
5
5
  end
@@ -3,7 +3,11 @@
3
3
  require "action_view"
4
4
  require "uri"
5
5
 
6
+ require "content_block_tools/presenters/field_presenters/base_presenter"
7
+ require "content_block_tools/presenters/field_presenters/contact/email_address_presenter"
8
+
6
9
  require "content_block_tools/presenters/base_presenter"
10
+ require "content_block_tools/presenters/contact_presenter"
7
11
  require "content_block_tools/presenters/email_address_presenter"
8
12
  require "content_block_tools/presenters/postal_address_presenter"
9
13
  require "content_block_tools/presenters/pension_presenter"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: content_block_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-12 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -37,20 +37,34 @@ dependencies:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
39
  version: 3.13.0
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec-html-matchers
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - '='
45
+ - !ruby/object:Gem::Version
46
+ version: 0.10.0
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.10.0
40
54
  - !ruby/object:Gem::Dependency
41
55
  name: rubocop-govuk
42
56
  requirement: !ruby/object:Gem::Requirement
43
57
  requirements:
44
58
  - - '='
45
59
  - !ruby/object:Gem::Version
46
- version: 5.0.3
60
+ version: 5.1.6
47
61
  type: :development
48
62
  prerelease: false
49
63
  version_requirements: !ruby/object:Gem::Requirement
50
64
  requirements:
51
65
  - - '='
52
66
  - !ruby/object:Gem::Version
53
- version: 5.0.3
67
+ version: 5.1.6
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: actionview
56
70
  requirement: !ruby/object:Gem::Requirement
@@ -92,7 +106,10 @@ files:
92
106
  - lib/content_block_tools/content_block.rb
93
107
  - lib/content_block_tools/content_block_reference.rb
94
108
  - lib/content_block_tools/presenters/base_presenter.rb
109
+ - lib/content_block_tools/presenters/contact_presenter.rb
95
110
  - lib/content_block_tools/presenters/email_address_presenter.rb
111
+ - lib/content_block_tools/presenters/field_presenters/base_presenter.rb
112
+ - lib/content_block_tools/presenters/field_presenters/contact/email_address_presenter.rb
96
113
  - lib/content_block_tools/presenters/pension_presenter.rb
97
114
  - lib/content_block_tools/presenters/postal_address_presenter.rb
98
115
  - lib/content_block_tools/version.rb
@@ -114,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
131
  - !ruby/object:Gem::Version
115
132
  version: '0'
116
133
  requirements: []
117
- rubygems_version: 3.6.5
134
+ rubygems_version: 3.6.8
118
135
  specification_version: 4
119
136
  summary: A suite of tools for working with GOV.UK Content Blocks
120
137
  test_files: []