Class: ContentBlockTools::ContentBlockReference
- Inherits:
-
Data
- Object
- Data
- ContentBlockTools::ContentBlockReference
- Defined in:
- lib/content_block_tools/content_block_reference.rb
Overview
Defines a reference pointer for a Content Block
Constant Summary collapse
- SUPPORTED_DOCUMENT_TYPES =
An array of the supported document types
%w[contact content_block_pension content_block_contact].freeze
- UUID_REGEX =
The regex used to find UUIDs
/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/- CONTENT_ID_ALIAS_REGEX =
The regex used to find content ID aliases
/[a-z0-9\-–—]+/- FIELD_REGEX =
The regex to find optional field names after the UUID, begins with ‘/’
/(\/[a-z0-9_\-–—\/]*)?/- EMBED_REGEX =
The regex used when scanning a document using find_all_in_document
/({{embed:(#{SUPPORTED_DOCUMENT_TYPES.join('|')}):(#{UUID_REGEX}|#{CONTENT_ID_ALIAS_REGEX})#{FIELD_REGEX}}})/
Instance Attribute Summary collapse
-
#document_type ⇒ String
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.
-
#embed_code ⇒ String
readonly
The embed_code used for a block.
-
#identifier ⇒ String
readonly
The identifier for a block - can be a UUID or a slug.
Class Method Summary collapse
-
.find_all_in_document(document) ⇒ Array<ContentBlockReference>
Finds all content block references within a document, using ‘ContentBlockReference::EMBED_REGEX` to scan through the document.
-
.from_match_data(match_data) ⇒ ContentBlockReference
private
Converts match data from a regex scan into a ContentBlockReference object.
-
.from_string(embed_code) ⇒ ContentBlockReference
Converts a single embed code string into a ContentBlockReference object.
Instance Method Summary collapse
-
#content_store_identifier ⇒ String
Returns the content store path for this content block reference.
-
#identifier_is_alias? ⇒ Boolean
Returns if the identifier is an alias.
Instance Attribute Details
#document_type ⇒ String (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 SUPPORTED_DOCUMENT_TYPES
29 30 31 32 33 34 35 36 37 38 39 40 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_reference.rb', line 29 class ContentBlockReference < Data # An array of the supported document types SUPPORTED_DOCUMENT_TYPES = %w[contact content_block_pension content_block_contact].freeze # The regex used to find UUIDs UUID_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ # The regex used to find content ID aliases CONTENT_ID_ALIAS_REGEX = /[a-z0-9\-–—]+/ # The regex to find optional field names after the UUID, begins with '/' FIELD_REGEX = /(\/[a-z0-9_\-–—\/]*)?/ # The regex used when scanning a document using {ContentBlockTools::ContentBlockReference.find_all_in_document} EMBED_REGEX = /({{embed:(#{SUPPORTED_DOCUMENT_TYPES.join('|')}):(#{UUID_REGEX}|#{CONTENT_ID_ALIAS_REGEX})#{FIELD_REGEX}}})/ # Returns if the identifier is an alias # # @return Boolean def identifier_is_alias? !identifier.match?(UUID_REGEX) end # Returns the content store path for this content block reference # # Constructs a path used to identify and retrieve the content block from the content store. # The path follows the format `/content-blocks/{document_type}/{identifier}`. # # @example # reference = ContentBlockReference.new(document_type: "content_block_contact", identifier: "some-slug", embed_code: "...") # reference.content_store_identifier # #=> "/content-blocks/content_block_contact/some-slug" # # @return [String] the content store path for this content block def content_store_identifier "/content-blocks/#{document_type}/#{identifier}" end class << self # Finds all content block references within a document, using `ContentBlockReference::EMBED_REGEX` # to scan through the document # # @return [Array<ContentBlockReference>] An array of content block references def find_all_in_document(document) document.scan(EMBED_REGEX).map do |match_data| ContentBlockReference.from_match_data(match_data) end end # Converts a single embed code string into a ContentBlockReference object # # Parses an embed code string using {EMBED_REGEX} to extract the document type, # identifier, and embed code, then creates a ContentBlockReference instance. # # @param embed_code [String] the embed code to parse # @example Parse an embed code with a UUID # ContentBlockReference.from_string("{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}") # #=> #<ContentBlockReference document_type="content_block_pension" identifier="2b92cade-549c-4449-9796-e7a3957f3a86" embed_code="{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"> # @example Parse an embed code with a slug # ContentBlockReference.from_string("{{embed:content_block_contact:some-slug}}") # #=> #<ContentBlockReference document_type="content_block_contact" identifier="some-slug" embed_code="{{embed:content_block_contact:some-slug}}"> # @return [ContentBlockReference] a new ContentBlockReference instance # @raise [InvalidEmbedCodeError] if the embed_code doesn't match {EMBED_REGEX} (match_data will be nil) # @see from_match_data def from_string() match_data = .match(/^#{EMBED_REGEX}$/) raise InvalidEmbedCodeError unless match_data ContentBlockReference.from_match_data(match_data.captures) end # Converts match data from a regex scan into a ContentBlockReference object # # This method is used internally by {find_all_in_document} and {from_string} to create # ContentBlockReference instances from regex match data. It normalizes the match data # by replacing en/em dashes with double/triple dashes (which can occur due to Kramdown's # markdown parsing) before creating the object. # # @param match_data [MatchData, Array] the match data from scanning with {EMBED_REGEX} # Expected to contain: [full_match, document_type, identifier, field] # @example Creating from match data # match_data = "{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}".match(EMBED_REGEX) # ContentBlockReference.from_match_data(match_data) # #=> #<ContentBlockReference document_type="content_block_pension" identifier="2b92cade-549c-4449-9796-e7a3957f3a86" embed_code="{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"> # @return [ContentBlockReference] a new ContentBlockReference instance # @api private # @see find_all_in_document # @see from_string # @see prepare_match def from_match_data(match_data) match = prepare_match(match_data) ContentBlockTools.logger.info("Found Content Block Reference: #{match}") ContentBlockReference.new(document_type: match[1], identifier: match[2], embed_code: match[0]) end private # This replaces an en / em dashes in content block references with double or triple dashes. This can occur # because Kramdown (the markdown parser that Govspeak is based on) replaces double dashes with en dashes and # triple dashes with em dashes def prepare_match(match) [ match[0], match[1], replace_dashes(match[2]), match[3], ] end def replace_dashes(value) value&.gsub("–", "--") &.gsub("—", "---") end end end |
#embed_code ⇒ String (readonly)
The embed_code used for a block
29 30 31 32 33 34 35 36 37 38 39 40 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_reference.rb', line 29 class ContentBlockReference < Data # An array of the supported document types SUPPORTED_DOCUMENT_TYPES = %w[contact content_block_pension content_block_contact].freeze # The regex used to find UUIDs UUID_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ # The regex used to find content ID aliases CONTENT_ID_ALIAS_REGEX = /[a-z0-9\-–—]+/ # The regex to find optional field names after the UUID, begins with '/' FIELD_REGEX = /(\/[a-z0-9_\-–—\/]*)?/ # The regex used when scanning a document using {ContentBlockTools::ContentBlockReference.find_all_in_document} EMBED_REGEX = /({{embed:(#{SUPPORTED_DOCUMENT_TYPES.join('|')}):(#{UUID_REGEX}|#{CONTENT_ID_ALIAS_REGEX})#{FIELD_REGEX}}})/ # Returns if the identifier is an alias # # @return Boolean def identifier_is_alias? !identifier.match?(UUID_REGEX) end # Returns the content store path for this content block reference # # Constructs a path used to identify and retrieve the content block from the content store. # The path follows the format `/content-blocks/{document_type}/{identifier}`. # # @example # reference = ContentBlockReference.new(document_type: "content_block_contact", identifier: "some-slug", embed_code: "...") # reference.content_store_identifier # #=> "/content-blocks/content_block_contact/some-slug" # # @return [String] the content store path for this content block def content_store_identifier "/content-blocks/#{document_type}/#{identifier}" end class << self # Finds all content block references within a document, using `ContentBlockReference::EMBED_REGEX` # to scan through the document # # @return [Array<ContentBlockReference>] An array of content block references def find_all_in_document(document) document.scan(EMBED_REGEX).map do |match_data| ContentBlockReference.from_match_data(match_data) end end # Converts a single embed code string into a ContentBlockReference object # # Parses an embed code string using {EMBED_REGEX} to extract the document type, # identifier, and embed code, then creates a ContentBlockReference instance. # # @param embed_code [String] the embed code to parse # @example Parse an embed code with a UUID # ContentBlockReference.from_string("{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}") # #=> #<ContentBlockReference document_type="content_block_pension" identifier="2b92cade-549c-4449-9796-e7a3957f3a86" embed_code="{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"> # @example Parse an embed code with a slug # ContentBlockReference.from_string("{{embed:content_block_contact:some-slug}}") # #=> #<ContentBlockReference document_type="content_block_contact" identifier="some-slug" embed_code="{{embed:content_block_contact:some-slug}}"> # @return [ContentBlockReference] a new ContentBlockReference instance # @raise [InvalidEmbedCodeError] if the embed_code doesn't match {EMBED_REGEX} (match_data will be nil) # @see from_match_data def from_string() match_data = .match(/^#{EMBED_REGEX}$/) raise InvalidEmbedCodeError unless match_data ContentBlockReference.from_match_data(match_data.captures) end # Converts match data from a regex scan into a ContentBlockReference object # # This method is used internally by {find_all_in_document} and {from_string} to create # ContentBlockReference instances from regex match data. It normalizes the match data # by replacing en/em dashes with double/triple dashes (which can occur due to Kramdown's # markdown parsing) before creating the object. # # @param match_data [MatchData, Array] the match data from scanning with {EMBED_REGEX} # Expected to contain: [full_match, document_type, identifier, field] # @example Creating from match data # match_data = "{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}".match(EMBED_REGEX) # ContentBlockReference.from_match_data(match_data) # #=> #<ContentBlockReference document_type="content_block_pension" identifier="2b92cade-549c-4449-9796-e7a3957f3a86" embed_code="{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"> # @return [ContentBlockReference] a new ContentBlockReference instance # @api private # @see find_all_in_document # @see from_string # @see prepare_match def from_match_data(match_data) match = prepare_match(match_data) ContentBlockTools.logger.info("Found Content Block Reference: #{match}") ContentBlockReference.new(document_type: match[1], identifier: match[2], embed_code: match[0]) end private # This replaces an en / em dashes in content block references with double or triple dashes. This can occur # because Kramdown (the markdown parser that Govspeak is based on) replaces double dashes with en dashes and # triple dashes with em dashes def prepare_match(match) [ match[0], match[1], replace_dashes(match[2]), match[3], ] end def replace_dashes(value) value&.gsub("–", "--") &.gsub("—", "---") end end end |
#identifier ⇒ String (readonly)
The identifier for a block - can be a UUID or a slug. The UUID will refer to the ‘content_id` of a block within Publishing API, while the slug will refer to a block’s Content ID alias.
29 30 31 32 33 34 35 36 37 38 39 40 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_reference.rb', line 29 class ContentBlockReference < Data # An array of the supported document types SUPPORTED_DOCUMENT_TYPES = %w[contact content_block_pension content_block_contact].freeze # The regex used to find UUIDs UUID_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ # The regex used to find content ID aliases CONTENT_ID_ALIAS_REGEX = /[a-z0-9\-–—]+/ # The regex to find optional field names after the UUID, begins with '/' FIELD_REGEX = /(\/[a-z0-9_\-–—\/]*)?/ # The regex used when scanning a document using {ContentBlockTools::ContentBlockReference.find_all_in_document} EMBED_REGEX = /({{embed:(#{SUPPORTED_DOCUMENT_TYPES.join('|')}):(#{UUID_REGEX}|#{CONTENT_ID_ALIAS_REGEX})#{FIELD_REGEX}}})/ # Returns if the identifier is an alias # # @return Boolean def identifier_is_alias? !identifier.match?(UUID_REGEX) end # Returns the content store path for this content block reference # # Constructs a path used to identify and retrieve the content block from the content store. # The path follows the format `/content-blocks/{document_type}/{identifier}`. # # @example # reference = ContentBlockReference.new(document_type: "content_block_contact", identifier: "some-slug", embed_code: "...") # reference.content_store_identifier # #=> "/content-blocks/content_block_contact/some-slug" # # @return [String] the content store path for this content block def content_store_identifier "/content-blocks/#{document_type}/#{identifier}" end class << self # Finds all content block references within a document, using `ContentBlockReference::EMBED_REGEX` # to scan through the document # # @return [Array<ContentBlockReference>] An array of content block references def find_all_in_document(document) document.scan(EMBED_REGEX).map do |match_data| ContentBlockReference.from_match_data(match_data) end end # Converts a single embed code string into a ContentBlockReference object # # Parses an embed code string using {EMBED_REGEX} to extract the document type, # identifier, and embed code, then creates a ContentBlockReference instance. # # @param embed_code [String] the embed code to parse # @example Parse an embed code with a UUID # ContentBlockReference.from_string("{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}") # #=> #<ContentBlockReference document_type="content_block_pension" identifier="2b92cade-549c-4449-9796-e7a3957f3a86" embed_code="{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"> # @example Parse an embed code with a slug # ContentBlockReference.from_string("{{embed:content_block_contact:some-slug}}") # #=> #<ContentBlockReference document_type="content_block_contact" identifier="some-slug" embed_code="{{embed:content_block_contact:some-slug}}"> # @return [ContentBlockReference] a new ContentBlockReference instance # @raise [InvalidEmbedCodeError] if the embed_code doesn't match {EMBED_REGEX} (match_data will be nil) # @see from_match_data def from_string() match_data = .match(/^#{EMBED_REGEX}$/) raise InvalidEmbedCodeError unless match_data ContentBlockReference.from_match_data(match_data.captures) end # Converts match data from a regex scan into a ContentBlockReference object # # This method is used internally by {find_all_in_document} and {from_string} to create # ContentBlockReference instances from regex match data. It normalizes the match data # by replacing en/em dashes with double/triple dashes (which can occur due to Kramdown's # markdown parsing) before creating the object. # # @param match_data [MatchData, Array] the match data from scanning with {EMBED_REGEX} # Expected to contain: [full_match, document_type, identifier, field] # @example Creating from match data # match_data = "{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}".match(EMBED_REGEX) # ContentBlockReference.from_match_data(match_data) # #=> #<ContentBlockReference document_type="content_block_pension" identifier="2b92cade-549c-4449-9796-e7a3957f3a86" embed_code="{{embed:content_block_pension:2b92cade-549c-4449-9796-e7a3957f3a86}}"> # @return [ContentBlockReference] a new ContentBlockReference instance # @api private # @see find_all_in_document # @see from_string # @see prepare_match def from_match_data(match_data) match = prepare_match(match_data) ContentBlockTools.logger.info("Found Content Block Reference: #{match}") ContentBlockReference.new(document_type: match[1], identifier: match[2], embed_code: match[0]) end private # This replaces an en / em dashes in content block references with double or triple dashes. This can occur # because Kramdown (the markdown parser that Govspeak is based on) replaces double dashes with en dashes and # triple dashes with em dashes def prepare_match(match) [ match[0], match[1], replace_dashes(match[2]), match[3], ] end def replace_dashes(value) value&.gsub("–", "--") &.gsub("—", "---") end end end |
Class Method Details
.find_all_in_document(document) ⇒ Array<ContentBlockReference>
Finds all content block references within a document, using ‘ContentBlockReference::EMBED_REGEX` to scan through the document
68 69 70 71 72 |
# File 'lib/content_block_tools/content_block_reference.rb', line 68 def find_all_in_document(document) document.scan(EMBED_REGEX).map do |match_data| ContentBlockReference.from_match_data(match_data) end end |
.from_match_data(match_data) ⇒ ContentBlockReference
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Converts match data from a regex scan into a ContentBlockReference object
This method is used internally by find_all_in_document and from_string to create ContentBlockReference instances from regex match data. It normalizes the match data by replacing en/em dashes with double/triple dashes (which can occur due to Kramdown’s markdown parsing) before creating the object.
114 115 116 117 118 |
# File 'lib/content_block_tools/content_block_reference.rb', line 114 def from_match_data(match_data) match = prepare_match(match_data) ContentBlockTools.logger.info("Found Content Block Reference: #{match}") ContentBlockReference.new(document_type: match[1], identifier: match[2], embed_code: match[0]) end |
.from_string(embed_code) ⇒ ContentBlockReference
Converts a single embed code string into a ContentBlockReference object
Parses an embed code string using EMBED_REGEX to extract the document type, identifier, and embed code, then creates a ContentBlockReference instance.
89 90 91 92 93 94 |
# File 'lib/content_block_tools/content_block_reference.rb', line 89 def from_string() match_data = .match(/^#{EMBED_REGEX}$/) raise InvalidEmbedCodeError unless match_data ContentBlockReference.from_match_data(match_data.captures) end |
Instance Method Details
#content_store_identifier ⇒ String
Returns the content store path for this content block reference
Constructs a path used to identify and retrieve the content block from the content store. The path follows the format ‘/content-blocks/#document_type/#identifier`.
59 60 61 |
# File 'lib/content_block_tools/content_block_reference.rb', line 59 def content_store_identifier "/content-blocks/#{document_type}/#{identifier}" end |
#identifier_is_alias? ⇒ Boolean
Returns if the identifier is an alias
44 45 46 |
# File 'lib/content_block_tools/content_block_reference.rb', line 44 def identifier_is_alias? !identifier.match?(UUID_REGEX) end |