Skip to content

Commit

Permalink
Merge pull request #4247 from alphagov/landing-pages-backend-scaffold
Browse files Browse the repository at this point in the history
Landing pages backend scaffold
  • Loading branch information
richardTowers authored Oct 8, 2024
2 parents 7d02592 + f194508 commit b906d6d
Show file tree
Hide file tree
Showing 25 changed files with 552 additions and 2 deletions.
34 changes: 34 additions & 0 deletions app/controllers/landing_page_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class LandingPageController < ContentItemsController
private

# SCAFFOLDING: can be removed when basic content items are available
# from content-store
def request_content_item(_base_path)
GdsApi.content_store.content_item(request.path).to_h
rescue StandardError
fake_data
end

# SCAFFOLDING: can be removed when basic content items are available
# from content-store
def fake_data
{
"base_path" => request.path,
"title" => "Landing Page",
"description" => "A landing page example",
"locale" => "en",
"document_type" => "landing_page",
"schema_name" => "landing_page",
"publishing_app" => "whitehall",
"rendering_app" => "frontend",
"update_type" => "major",
"details" => {},
"routes" => [
{
"type" => "exact",
"path" => request.path,
},
],
}
end
end
45 changes: 45 additions & 0 deletions app/helpers/block_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module BlockHelper
def tab_items_to_component_format(tab_items)
tab_items.map do |ti|
{
id: ti["id"],
label: ti["label"],
content: sanitize("<p class=\"govuk-body-m\">#{ti['content']}</p>"),
}
end
end

def column_class_for_equal_columns(number_of_columns)
case number_of_columns
when 1
"govuk-grid-column"
when 2
"govuk-grid-column-one-half"
when 3
"govuk-grid-column-one-third"
else
"govuk-grid-column-one-quarter"
end
end

def column_class_for_assymetric_columns(number_of_columns, column_size)
case number_of_columns
when 3
case column_size
when 1
"govuk-grid-column-one-third"
when 2
"govuk-grid-column-two-thirds"
end
when 4
case column_size
when 1
"govuk-grid-column-one-quarter"
when 2
"govuk-grid-column-two-quarters"
when 3
"govuk-grid-column-three-quarters"
end
end
end
end
11 changes: 11 additions & 0 deletions app/models/block/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Block
class Base
attr_reader :id, :type, :data

def initialize(block_hash)
@data = block_hash
@id = data["id"]
@type = data["type"]
end
end
end
5 changes: 5 additions & 0 deletions app/models/block/columns_layout.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Block
class ColumnsLayout < Block::LayoutBase
alias_method :columns, :blocks
end
end
11 changes: 11 additions & 0 deletions app/models/block/layout_base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Block
class LayoutBase < Block::Base
attr_reader :blocks

def initialize(block_hash)
super(block_hash)

@blocks = data["blocks"].map { |subblock_hash| BlockFactory.build(subblock_hash) }
end
end
end
26 changes: 26 additions & 0 deletions app/models/block/two_column_layout.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Block
class TwoColumnLayout < Block::LayoutBase
attr_reader :left, :right, :theme
alias_method :columns, :blocks

def initialize(block_hash)
super(block_hash)

@left = columns[0]
@right = columns[1]
@theme = data["theme"]
end

def left_column_size
theme == "two_thirds_one_third" ? 2 : 1
end

def right_column_size
theme == "one_third_two_thirds" ? 2 : 1
end

def total_columns
left_column_size + right_column_size
end
end
end
12 changes: 12 additions & 0 deletions app/models/block_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class BlockFactory
def self.build(block_hash)
block_class(block_hash["type"]).new(block_hash)
end

def self.block_class(type)
klass = "Block::#{type.camelize}".constantize
klass.ancestors.include?(Block::Base) ? klass : Block::Base
rescue StandardError
Block::Base
end
end
7 changes: 5 additions & 2 deletions app/models/content_item_factory.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
class ContentItemFactory
def self.build(content_hash)
content_item_class(content_hash).new(content_hash)
content_item_class(content_hash["document_type"]).new(content_hash)
end

def self.content_item_class(_content_hash)
def self.content_item_class(document_type)
klass = document_type.camelize.constantize
klass.superclass == ContentItem ? klass : ContentItem
rescue StandardError
ContentItem
end
end
27 changes: 27 additions & 0 deletions app/models/landing_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class LandingPage < ContentItem
attr_reader :blocks

ADDITIONAL_CONTENT_PATH = "lib/data/landing_page_content_items".freeze

def initialize(content_store_response)
if content_store_response.dig("details", "blocks")
super(content_store_response)
else
super(content_store_response.deep_merge(load_additional_content(content_store_response["base_path"])))
end

@blocks = (@content_store_response.dig("details", "blocks") || []).map { |block_hash| BlockFactory.build(block_hash) }
end

private

# SCAFFOLDING: can be removed (and reference above) when full content items
# including block details are available from content-store
def load_additional_content(base_path)
file_slug = base_path.split("/").last.gsub("-", "_")
filename = Rails.root.join("#{ADDITIONAL_CONTENT_PATH}/#{file_slug}.yaml")
return { "details" => {} } unless File.exist?(filename)

{ "details" => YAML.load(File.read(filename)) }
end
end
4 changes: 4 additions & 0 deletions app/views/landing_page/blocks/_big_number.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<%= render "govuk_publishing_components/components/big_number", {
number: block.data["number"],
label: block.data["label"],
} %>
5 changes: 5 additions & 0 deletions app/views/landing_page/blocks/_columns_layout.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="govuk-grid-row">
<% block.columns.each do |column| %>
<div class="<%= column_class_for_equal_columns(block.columns.count) %>"><%= render "landing_page/blocks/#{column.type}", block: column %></div>
<% end %>
</div>
4 changes: 4 additions & 0 deletions app/views/landing_page/blocks/_govspeak.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<%= render "govuk_publishing_components/components/govspeak", {
} do %>
<%= block.data["content"].html_safe %>
<% end %>
3 changes: 3 additions & 0 deletions app/views/landing_page/blocks/_tabs.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= render "govuk_publishing_components/components/tabs", {
tabs: tab_items_to_component_format(block.data["tab_items"]),
} %>
8 changes: 8 additions & 0 deletions app/views/landing_page/blocks/_two_column_layout.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="govuk-grid-row">
<div class="<%= column_class_for_assymetric_columns(block.total_columns, block.left_column_size) %>">
<%= render "landing_page/blocks/#{block.left.type}", block: block.left %>
</div>
<div class="<%= column_class_for_assymetric_columns(block.total_columns, block.right_column_size) %>">
<%= render "landing_page/blocks/#{block.right.type}", block: block.right %>
</div>
</div>
9 changes: 9 additions & 0 deletions app/views/landing_page/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

<div class="landing-page">
<% @content_item.blocks.each do |block| %>
<%= render "landing_page/blocks/#{block.type}", block: %>
<% end %>
<% if @content_item.blocks.empty? %>
Warning: No blocks specified for this page
<% end %>
</div>
9 changes: 9 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@

get "/foreign-travel-advice", to: "travel_advice#index", as: :travel_advice

scope "/landing-page" do
get "/", to: "landing_page#show"
get "/*any", to: "landing_page#show"
end

# Accounts
get "/sign-in", to: "help#sign_in"
get "/sign-in/redirect", to: "sessions#create"
Expand Down Expand Up @@ -59,6 +64,10 @@
get "/find-licences/:slug/:authority_slug", to: "licence_transaction#authority", as: "licence_transaction_authority"
get "/find-licences/:slug/:authority_slug/:interaction", to: "licence_transaction#authority_interaction", as: "licence_transaction_authority_interaction"

constraints FormatRoutingConstraint.new("landing_page") do
get ":slug", to: "landing_page#show"
end

# Simple Smart Answer pages
constraints FormatRoutingConstraint.new("simple_smart_answer") do
get ":slug/y(/*responses)" => "simple_smart_answers#flow", :as => :smart_answer_flow
Expand Down
43 changes: 43 additions & 0 deletions lib/data/landing_page_content_items/landing_page.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
blocks:
- type: govspeak
content: |
<h2>Here's a heading</h2>
<p>Here's some content!</p>
<p>Here's some more content</p>
<ul>
<li>What?</li>
<li>When?</li>
</ul>
<a href="/landing-page/sub-page-1">Visit sub-page 1</a>
- type: tabs
id: landing-pages-item-selector
tab_items:
- id: tab-1
label: Item 1
content: Here's the content for item one
- id: tab-2
label: Item 2
content: Here's the content for item two
- type: govspeak
content: <p>Here's some more content!</p>
- type: two_column_layout
theme: two_thirds_one_third
blocks:
- type: govspeak
content: <p>Left content!</p>
- type: govspeak
content: <p>Right content!</p>
- type: govspeak
content: <h2>Statistics</h2>
- type: columns_layout
blocks:
- type: big_number
number: £75m
label: amount of money that looks big
- type: big_number
number: 100%
label: increase in the number of big_number components added to the columns at this point
- type: big_number
number: £43
label: Cost of a cup of coffee in Covent Garden

5 changes: 5 additions & 0 deletions lib/data/landing_page_content_items/sub_page_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blocks:
- type: govspeak
content: |
<h2>Sub Page 1</h2>
<a href="/landing-page">Back to main landing page</a>
43 changes: 43 additions & 0 deletions spec/fixtures/landing_page.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
blocks:
- type: govspeak
content: |
<h2>Here's a heading</h2>
<p>Here's some content!</p>
<p>Here's some more content</p>
<ul>
<li>What?</li>
<li>When?</li>
</ul>
<a href="/landing-page/sub-page-1">Visit sub-page 1</a>
- type: tabs
id: landing-pages-item-selector
tab_items:
- id: tab-1
label: Item 1
content: Here's the content for item one
- id: tab-2
label: Item 2
content: Here's the content for item two
- type: govspeak
content: <p>Here's some more content!</p>
- type: two_column_layout
theme: two_thirds_one_third
blocks:
- type: govspeak
content: <p>Left content!</p>
- type: govspeak
content: <p>Right content!</p>
- type: govspeak
content: <h2>Statistics</h2>
- type: columns_layout
blocks:
- type: big_number
number: £75m
label: amount of money that looks big
- type: big_number
number: 100%
label: increase in the number of big_number components added to the columns at this point
- type: big_number
number: £43
label: Cost of a cup of coffee in Covent Garden

Loading

0 comments on commit b906d6d

Please sign in to comment.