Skip to content

Commit

Permalink
Add hardcoded FAQPage schema for voting-in-the-uk
Browse files Browse the repository at this point in the history
We think that the voting intents around this page mean that users will benefit
from a more curated schema.  This is intended to be a one of a kind for now,
and is obviously time sensitive, hence the somewhat blunt approach.

I've added a couple of light touch tests to ensure that they aren't broken
inadvertently.

We'll be keeping the content in the yaml file in step with the published
content until we find a better approach.
  • Loading branch information
sihugh committed Oct 25, 2019
1 parent c430de9 commit 540e56e
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 1 deletion.
2 changes: 2 additions & 0 deletions app/presenters/content_item_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class ContentItemPresenter
attr_reader :content_item,
:requested_content_item_path,
:base_path,
:slug,
:title,
:description,
:schema_name,
Expand All @@ -21,6 +22,7 @@ def initialize(content_item, requested_content_item_path = nil)
@content_item = content_item
@requested_content_item_path = requested_content_item_path
@base_path = content_item["base_path"]
@slug = @base_path.delete_prefix("/") if @base_path
@title = content_item["title"]
@description = content_item["description"]
@schema_name = content_item["schema_name"]
Expand Down
69 changes: 69 additions & 0 deletions app/presenters/machine_readable/yaml_faq_page_schema_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
module MachineReadable
class YamlFaqPageSchemaPresenter
attr_reader :content_item, :config_file

def self.configured?(content_item)
File.exist?(config_path(content_item))
end

def self.config_path(content_item)
CONFIG_PATH.join(content_item.slug + ".yml").to_s
end

def initialize(content_item)
@content_item = content_item
@config_file = YAML.load_file(YamlFaqPageSchemaPresenter.config_path(content_item))
end

def structured_data
# http://schema.org/FAQPage
{
"@context" => "http://schema.org",
"@type" => "FAQPage",
"headline" => config_file["title"],
"description" => config_file["preamble"],
"publisher" => {
"@type" => "Organization",
"name" => "GOV.UK",
"url" => "https://www.gov.uk",
"logo" => {
"@type" => "ImageObject",
"url" => logo_url,
},
},
}
.merge(main_entity)
end

private

CONFIG_PATH = Rails.root.join("config/machine_readable/").freeze

def main_entity
{
"mainEntity" => questions_and_answers,
}
end

def questions_and_answers
config_file["faqs"].each_with_index.map do |faq|
{
"@type" => "Question",
"name" => faq["question"],
"acceptedAnswer" => {
"@type" => "Answer",
"text" => faq["answer"],
},
}
end
end

def logo_url
image_url("govuk_publishing_components/govuk-logo.png")
end

def image_url(image_file)
ActionController::Base.helpers.asset_url(image_file, type: :image)
end
end
end
4 changes: 3 additions & 1 deletion app/views/content_items/guide_single.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
) %>
<% end %>

<% if MachineReadable::YamlFaqPageSchemaPresenter.configured?(@content_item) %>
<script type="application/ld+json">
<%= raw MachineReadable::GuideFaqPageSchemaPresenter.new(@content_item).structured_data.to_json %>
<%= raw MachineReadable::YamlFaqPageSchemaPresenter.new(@content_item).structured_data.to_json %>
</script>
<% end %>

<% content_for :simple_header, true %>

Expand Down
84 changes: 84 additions & 0 deletions config/machine_readable/voting-in-the-uk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
title: "How to vote"
preamble: >
<p>You need to <a href="/register-to-vote">register to vote</a> before you can vote in UK elections or referendums.</p>
<p>If you’re eligible, you can vote in person on the day of the election at a named polling station. You can also apply for a postal or proxy vote instead.</p>
faqs:
- question: Ways of voting
answer: >
<p>You can vote:</p>
<ul>
<li><a href="/voting-in-the-uk/voting-in-person">in person at a polling station</a></li>
<li><a href="/voting-in-the-uk/postal-voting">by post</a></li>
<li>by asking someone else to vote for you (<a href="/voting-in-the-uk/voting-by-proxy">voting by proxy</a>)</li>
</ul>
<p>You cannot vote online in any elections.</p>
- question: Eligibility to vote
answer: >
<p>You can vote when you’re:</p>
<ul>
<li>18 years old in England, Wales and Northern Ireland</li>
<li>16 years old in Scottish Parliament and local elections (and other elections when you’re 18)</li>
</ul>
- question: Voting in person
answer: >
<p>You vote in person at a polling station (usually in a public building, such as a school or local hall).</p>
<h2 id="your-poll-card">Your poll card</h2>
<p>You’ll be sent a poll card just before an election telling you when to vote and at which polling station. You can only vote at the polling station location on your card.</p>
<p>If you have not received a poll card but think you should, contact your local <a href="/get-on-electoral-register">Electoral Registration Office</a>.</p>
<p>You can still vote if you’ve lost your card.</p>
- question: When you can vote
answer: >
<p>Polling stations are open from 7am to 10pm on the day of the election (‘polling day’).</p>
- question: ID you need to bring
answer: >
<p>If you live in England, Wales or Scotland you do not need to bring any identification to vote.</p>
<p>You will need to show <a rel="external" href="http://www.eoni.org.uk/Electoral-Identity-Card/Electoral-Identity-Card-FAQs#q34">photo ID to vote in Northern Ireland</a> (your passport, driving licence, Electoral Identity Card or certain kinds of Translink Smartpass).</p>
- question: Voting by post
answer: >
<p>You must <a href="/government/publications/apply-for-a-postal-vote">apply for a postal vote</a> if you want to vote by post, for example if:</p>
<ul>
<li>you’re away from home</li>
<li>you’re abroad and want to vote in England, Scotland or Wales</li>
</ul>
<p>You do not need to give a reason unless you’re voting in Northern Ireland.</p>
- question: Voting by proxy
answer: >
<p>If you’re unable to vote in person you can ask someone to vote on your behalf. This is called a proxy vote.</p>
<p>You can only apply for a proxy vote under certain circumstances, including:</p>
<ul>
<li>being away on polling day</li>
<li>having a medical issue or disability</li>
<li>not being able to vote in person because of work or military service</li>
</ul>
<h2 id="how-to-apply-for-a-proxy-vote">How to apply for a proxy vote</h2>
<p><a href="/government/collections/proxy-voting-application-forms">Apply for a proxy vote</a> using a paper form. You need to send it to your local Electoral Registration Office.</p>
<p>Usually, you need to apply for a proxy vote at least 6 working days before election day if you want to vote in England, Scotland or Wales.</p>
<p>There’s a different form to <a rel="external" href="http://www.eoni.org.uk/Vote/Voting-by-post-or-proxy">apply to vote by proxy in Northern Ireland</a>. Apply at least 14 working days before election day.</p>
- question: Voting from abroad
answer: >
<p>If you’re abroad on election day you need to make arrangements in advance. Apply to vote by proxy if the election is less than 2 weeks away and you have not made the arrangements yet.</p>
<p>How you vote when you’re abroad depends on:</p>
<ul>
<li>whether you’ll be abroad temporarily or living abroad</li>
<li>where you want to vote</li>
</ul>
<h2 id="if-youll-be-abroad-temporarily">If you’ll be abroad temporarily</h2>
<p>You can vote by post or proxy if you’ll be abroad temporarily on election day, for example on holiday or a work trip.</p>
<h3 id="voting-in-england-scotland-or-wales">Voting in England, Scotland or Wales</h3>
<p>You can arrange:</p>
<ul>
<li>to <a href="/voting-in-the-uk/postal-voting">vote by post</a></li>
<li>for someone else to vote for you (<a href="/voting-in-the-uk/voting-by-proxy">vote by proxy</a>)</li>
</ul>
<p>Your postal ballot will be sent to the address you’ve chosen no earlier than 16 days before the election. You need to return your ballot before 10pm on polling day.</p>
<h3 id="voting-in-northern-ireland">Voting in Northern Ireland</h3>
<p>There’s a different process to <a rel="external" href="http://www.eoni.org.uk/Vote/Voting-by-post-or-proxy">apply to vote by post or proxy if you live in Northern Ireland</a> and will be abroad temporarily on election day.</p>
<p>If you vote by post you must return your ballot before going abroad (you cannot post it from outside the UK).</p>
32 changes: 32 additions & 0 deletions test/integration/guide_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,38 @@ class GuideTest < ActionDispatch::IntegrationTest
assert_nil faq_schema
end

# The schema config is in /config/machine_readable/voting-in-the-uk.yml
test "voting in the UK guide shows hard coded FAQ schema" do
setup_and_visit_voting_guide

faq_schema = find_structured_data(page, "FAQPage")
q_and_as = faq_schema["mainEntity"]

assert_equal faq_schema["@type"], "FAQPage"
assert_equal faq_schema["headline"], "How to vote"
assert_equal faq_schema["description"], "<p>You need to <a href=\"/register-to-vote\">register to vote</a> before you can vote in UK elections or referendums.</p> <p>If you’re eligible, you can vote in person on the day of the election at a named polling station. You can also apply for a postal or proxy vote instead.</p>\n"

assert_equal 8, q_and_as.count
end

test "voting in the UK guide shows all chapters on a single page" do
content_item = setup_and_visit_voting_guide
part_titles = content_item["details"]["parts"].map { |part| part["title"] }

part_titles.each do |part_title|
assert page.has_css? "h1", text: part_title
end
end

def setup_and_visit_voting_guide
@content_item = get_content_example("guide").tap do |item|
item["base_path"] = "/voting-in-the-uk"
item["content_id"] = "9315bc67-33e7-42e9-8dea-e022f56dabfa"
content_store_has_item(item["base_path"], item.to_json)
visit_with_cachebust(item["base_path"])
end
end

def setup_and_visit_part_in_guide
@content_item = get_content_example("guide").tap do |item|
chapter_path = "#{item['base_path']}/key-stage-1-and-2"
Expand Down

0 comments on commit 540e56e

Please sign in to comment.