content_block_tools 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 342e7145710ce25e142f4b22f5b16ec7d974a205bd0f7ee2926c992b6687ebc0
4
+ data.tar.gz: 5a0df078972acd5e743b9b50bcd98d4297b0ac0f1a4f0b5d4f51962981012498
5
+ SHA512:
6
+ metadata.gz: 62f995e4d2520741e4a4cbe83a2e9083bbcbfd592a6acdc4352f7e27fdd964949bd90c1615965d70fa22dc93b62c5f0e9fccaa8a1de5ea5b444d37b08aaf4b92
7
+ data.tar.gz: 664d55f226662f74055c421409244ded66fd2b207c4915b7bbbd49593a2c7fc6c1e90043befed4302f51f7d4d3bfbe52d12d493c7bd560a8dbb369bb31541357
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ - package-ecosystem: "github-actions"
8
+ directory: "/"
9
+ schedule:
10
+ interval: daily
@@ -0,0 +1 @@
1
+ This repo is owned by the content modelling team. Please let us know in #govuk-publishing-content-modelling-dev when you raise any PRs.
@@ -0,0 +1,10 @@
1
+ on:
2
+ workflow_dispatch: {}
3
+ schedule:
4
+ - cron: '15 9 * * 1-5' # 9:15am UTC, Mon-Fri.
5
+
6
+ jobs:
7
+ autorelease:
8
+ uses: alphagov/govuk-infrastructure/.github/workflows/autorelease-rubygem.yml@main
9
+ secrets:
10
+ GH_TOKEN: ${{ secrets.GOVUK_CI_GITHUB_API_TOKEN }}
@@ -0,0 +1,44 @@
1
+ on: [push, pull_request, workflow_dispatch]
2
+
3
+ jobs:
4
+ codeql-sast:
5
+ name: CodeQL SAST scan
6
+ uses: alphagov/govuk-infrastructure/.github/workflows/codeql-analysis.yml@main
7
+ permissions:
8
+ security-events: write
9
+
10
+ dependency-review:
11
+ name: Dependency Review scan
12
+ uses: alphagov/govuk-infrastructure/.github/workflows/dependency-review.yml@main
13
+
14
+ # This matrix job runs the test suite against multiple Ruby versions
15
+ test_matrix:
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ ruby: [3.2, 3.3]
20
+ runs-on: ubuntu-latest
21
+ env:
22
+ GOVUK_CONTENT_SCHEMAS_PATH: vendor/publishing-api/content_schemas
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+ - name: Checkout Publishing API for content schemas
26
+ uses: actions/checkout@v4
27
+ with:
28
+ repository: alphagov/publishing-api
29
+ ref: main
30
+ path: vendor/publishing-api
31
+ - uses: ruby/setup-ruby@v1
32
+ with:
33
+ ruby-version: ${{ matrix.ruby }}
34
+ bundler-cache: true
35
+ - run: bundle exec rake
36
+
37
+ publish:
38
+ needs: test_matrix
39
+ if: ${{ github.ref == 'refs/heads/main' }}
40
+ permissions:
41
+ contents: write
42
+ uses: alphagov/govuk-infrastructure/.github/workflows/publish-rubygem.yml@main
43
+ secrets:
44
+ GEM_HOST_API_KEY: ${{ secrets.ALPHAGOV_RUBYGEMS_API_KEY }}
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ Gemfile.lock
13
+ /.DS_Store
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,3 @@
1
+ inherit_gem:
2
+ rubocop-govuk:
3
+ - config/default.yml
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.4
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ - We use the [GOV.UK versioning guidelines](https://docs.publishing.service.gov.uk/manual/publishing-a-ruby-gem.html#versioning).
4
+ - Mark breaking changes with `BREAKING:`. Be sure to include instructions on how applications should be upgraded.
5
+ - Include a link to your pull request.
6
+ - Don't include changes that are purely internal. The CHANGELOG should be a
7
+ useful summary for people upgrading their application, not a replication
8
+ of the commit log.
9
+
10
+ ## 0.1.0
11
+
12
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ ruby File.read(".ruby-version").strip unless ENV["CI"]
4
+
5
+ source "https://rubygems.org"
6
+
7
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2024 Crown Copyright (Government Digital Service)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # Content Block Tools
2
+
3
+ A suite of tools for working with GOV.UK Content Blocks
4
+
5
+ ## Installation
6
+
7
+ Install the gem
8
+
9
+ gem install content_block_tools
10
+
11
+ or add it to your Gemfile
12
+
13
+ gem "content_block_tools"
14
+
15
+ ## Usage
16
+
17
+ ### Finding embed code
18
+
19
+ To find embed code in a block of text, use `ContentBlockReference.find_all_in_document`:
20
+
21
+ ```ruby
22
+ content = "Hello - here is a embed code {{embed:content_block_email_address:be24ee44-b636-4a3e-b979-0da27b4a8e62}}"
23
+ ContentBlockReference.find_all_in_document(content)
24
+ # =>
25
+ #[#<data ContentBlockTools::ContentBlockReference
26
+ # document_type="content_block_email_address",
27
+ # content_id="be24ee44-b636-4a3e-b979-0da27b4a8e62",
28
+ # embed_code="{{embed:content_block_email_address:be24ee44-b636-4a3e-b979-0da27b4a8e62}}">]
29
+ ```
30
+
31
+ ### Rendering a content block
32
+
33
+ To render a content block, you can initialize the content block like so:
34
+
35
+ ```ruby
36
+ content_block = ContentBlockTools::ContentBlock.new(
37
+ document_type: "something",
38
+ content_id: "some uuid",
39
+ title: "Title",
40
+ details: { some: "hash"},
41
+ )
42
+ ```
43
+
44
+ Then call `render`:
45
+
46
+ ```ruby
47
+ content_block.render
48
+ #=> {HTML representation of content block}
49
+ ```
50
+
51
+ For more information, see the [Documentation](https://www.rubydoc.info/github/alphagov/content_block_tools)
52
+
53
+ ## License
54
+
55
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RuboCop::RakeTask.new
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: %i[rubocop spec]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'content_block_tools'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "content_block_tools/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "content_block_tools"
9
+ spec.version = ContentBlockTools::VERSION
10
+ spec.authors = ["GOV.UK Dev"]
11
+ spec.email = ["govuk-dev@digital.cabinet-office.gov.uk"]
12
+
13
+ spec.summary = "A suite of tools for working with GOV.UK Content Blocks"
14
+ spec.homepage = "https://github.com/alphagov/content_block_tools"
15
+ spec.license = "MIT"
16
+
17
+ spec.required_ruby_version = ">= 3.2"
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = %w[lib]
27
+
28
+ spec.add_development_dependency "rake", "13.2.1"
29
+ spec.add_development_dependency "rspec", "3.13.0"
30
+ spec.add_development_dependency "rubocop-govuk", "5.0.2"
31
+
32
+ spec.add_dependency "actionview", "7.2.2"
33
+ end
@@ -0,0 +1,52 @@
1
+ module ContentBlockTools
2
+ ContentBlock = Data.define(:content_id, :title, :document_type, :details)
3
+
4
+ # Defines a Content Block
5
+ #
6
+ # @api public
7
+ #
8
+ # @!attribute [r] content_id
9
+ # The content UUID for a block
10
+ # @example
11
+ # content_block.id #=> "2b92cade-549c-4449-9796-e7a3957f3a86"
12
+ # @return [String]
13
+ #
14
+ # @!attribute [r] title
15
+ # A title for the content block
16
+ # @example
17
+ # content_block.title #=> "Some title"
18
+ # @return [String]
19
+ # @api public
20
+ #
21
+ # @!attribute [r] document_type
22
+ # The document type of the content block - this will be used to work out which Presenter
23
+ # will be used to render the content block. All supported document_types are documented in
24
+ # {ContentBlockTools::ContentBlockReference::SUPPORTED_DOCUMENT_TYPES}
25
+ # @example
26
+ # content_block.document_type #=> "content_block_email_address"
27
+ # @return [String] the document type
28
+ # @api public
29
+ #
30
+ # @!attribute [r] details
31
+ # A hash that contains the details of the content block
32
+ # @example
33
+ # content_block.details #=> { email_address: "foo@example.com" }
34
+ # @return [Hash] the details
35
+ # @api public
36
+ class ContentBlock < Data
37
+ # A lookup of presenters for particular content block types
38
+ CONTENT_PRESENTERS = {
39
+ "content_block_email_address" => ContentBlockTools::Presenters::EmailAddressPresenter,
40
+ }.freeze
41
+
42
+ # Calls the appropriate presenter class to return a HTML representation of a content
43
+ # block. Defaults to {Presenters::BasePresenter}
44
+ #
45
+ # @return [string] A HTML representation of the content block
46
+ def render
47
+ CONTENT_PRESENTERS
48
+ .fetch(document_type, Presenters::BasePresenter)
49
+ .new(self).render
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,47 @@
1
+ module ContentBlockTools
2
+ ContentBlockReference = Data.define(:document_type, :content_id, :embed_code)
3
+
4
+ # Defines a reference pointer for a Content Block
5
+ #
6
+ # @api public
7
+ # @!attribute [r] document_type
8
+ # The document type of the content block - this will be used to work out which Presenter
9
+ # will be used to render the content block. All supported document_types are documented in
10
+ # {ContentBlockTools::ContentBlockReference::SUPPORTED_DOCUMENT_TYPES}
11
+ # @example
12
+ # content_block_reference.document_type #=> "content_block_email_address"
13
+ # @return [String] the document type
14
+ # @api public
15
+ #
16
+ # @!attribute [r] content_id
17
+ # The content UUID for a block
18
+ # @example
19
+ # content_block_reference.id #=> "2b92cade-549c-4449-9796-e7a3957f3a86"
20
+ # @return [String]
21
+ #
22
+ # @!attribute [r] embed_code
23
+ # The embed_code used for a block
24
+ # @example
25
+ # content_block_reference.embed_code #=> "{{embed:content_block_email_address:2b92cade-549c-4449-9796-e7a3957f3a86}}"
26
+ # @return [String]
27
+ class ContentBlockReference < Data
28
+ # An array of the supported document types
29
+ SUPPORTED_DOCUMENT_TYPES = %w[contact content_block_email_address].freeze
30
+ # 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})/
32
+ # The regex used when scanning a document using {ContentBlockTools::ContentBlockReference.find_all_in_document}
33
+ EMBED_REGEX = /({{embed:(#{SUPPORTED_DOCUMENT_TYPES.join('|')}):#{UUID_REGEX}}})/
34
+
35
+ class << self
36
+ # Finds all content block references within a document, using `ContentBlockReference::EMBED_REGEX`
37
+ # to scan through the document
38
+ #
39
+ # @return [Array<ContentBlockReference>] An array of content block references
40
+ def find_all_in_document(document)
41
+ document.scan(ContentBlockReference::EMBED_REGEX).map { |match|
42
+ ContentBlockReference.new(document_type: match[1], content_id: match[2], embed_code: match[0])
43
+ }.uniq
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,49 @@
1
+ module ContentBlockTools
2
+ module Presenters
3
+ class BasePresenter
4
+ include ActionView::Helpers::TagHelper
5
+
6
+ # The default HTML tag to wrap the presented response in - can be overridden in a subclass
7
+ BASE_TAG_TYPE = :span
8
+
9
+ # Returns a new presenter object
10
+ #
11
+ # @param [{ContentBlockTools::ContentBlock}] content_block A content block object
12
+ #
13
+ # @return [{ContentBlockTools::Presenters::BasePresenter}]
14
+ def initialize(content_block)
15
+ @content_block = content_block
16
+ end
17
+
18
+ # Returns a HTML representation of the content block wrapped in a base tag with
19
+ # a class and data attributes
20
+ # Calls the {#content} method, which can be overridden in a subclass
21
+ #
22
+ # @return [string] A HTML representation of the content block
23
+ def render
24
+ content_tag(
25
+ BASE_TAG_TYPE,
26
+ content,
27
+ class: %W[content-embed content-embed__#{content_block.document_type}],
28
+ data: {
29
+ content_block: "",
30
+ document_type: content_block.document_type,
31
+ content_id: content_block.content_id,
32
+ },
33
+ )
34
+ end
35
+
36
+ private
37
+
38
+ # The default representation of the content block - this can be overridden in a subclass
39
+ #
40
+ # @return [string] A representation of the content block to be wrapped in the base_tag in
41
+ # {#content}
42
+ def content
43
+ content_block.title
44
+ end
45
+
46
+ attr_reader :content_block
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module ContentBlockTools
2
+ module Presenters
3
+ class EmailAddressPresenter < BasePresenter
4
+ private
5
+
6
+ def content
7
+ content_block.details[:email_address]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ContentBlockTools
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view"
4
+ require "uri"
5
+
6
+ require "content_block_tools/presenters/base_presenter"
7
+ require "content_block_tools/presenters/email_address_presenter"
8
+
9
+ require "content_block_tools/content_block"
10
+ require "content_block_tools/content_block_reference"
11
+
12
+ require "content_block_tools/version"
13
+
14
+ module ContentBlockTools
15
+ class Error < StandardError; end
16
+ module Presenters; end
17
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: content_block_tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - GOV.UK Dev
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 13.2.1
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 13.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.13.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 3.13.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop-govuk
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 5.0.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 5.0.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: actionview
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 7.2.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 7.2.2
69
+ description:
70
+ email:
71
+ - govuk-dev@digital.cabinet-office.gov.uk
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".github/dependabot.yml"
77
+ - ".github/pull_request_template.md"
78
+ - ".github/workflows/autorelease.yml"
79
+ - ".github/workflows/ci.yml"
80
+ - ".gitignore"
81
+ - ".rspec"
82
+ - ".rubocop.yml"
83
+ - ".ruby-version"
84
+ - CHANGELOG.md
85
+ - Gemfile
86
+ - LICENSE.txt
87
+ - README.md
88
+ - Rakefile
89
+ - bin/console
90
+ - bin/setup
91
+ - content_block_tools.gemspec
92
+ - lib/content_block_tools.rb
93
+ - lib/content_block_tools/content_block.rb
94
+ - lib/content_block_tools/content_block_reference.rb
95
+ - lib/content_block_tools/presenters/base_presenter.rb
96
+ - lib/content_block_tools/presenters/email_address_presenter.rb
97
+ - lib/content_block_tools/version.rb
98
+ homepage: https://github.com/alphagov/content_block_tools
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '3.2'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubygems_version: 3.5.23
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: A suite of tools for working with GOV.UK Content Blocks
121
+ test_files: []