Skip to content

Commit

Permalink
Add FAQPage schema
Browse files Browse the repository at this point in the history
What
----
This will be used on Guides to present the chapters in an improved way in
featured snippets.

Implemented as per: https://developers.google.com/search/docs/data-types/faqpage

Why
---
SEO improvement. It allows users to read more of the content in Google,
hopefully allowing them to make better decisions about whether to read more of
the content and thus shortening their journeys.

We will measure the effects of this change.
  • Loading branch information
sihugh committed Sep 4, 2019
1 parent 0e2ad75 commit 296f707
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
## Unreleased

* Fix components focus state spacing (PR #1054)
* Add FAQPage schema (PR #1087)

## 19.0.0

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module GovukPublishingComponents
module Presenters
class FaqPageSchema
attr_reader :page

def initialize(page)
@page = page
end

def structured_data
# http://schema.org/FAQPage
data = CreativeWorkSchema.new(@page).structured_data
.merge(main_entity)
data["@type"] = "FAQPage"
data
end

private

def main_entity
{
"mainEntity" => questions_and_answers
}
end

def questions_and_answers
page.parts.each_with_index.map do |part, index|
part_url = part_url(part, index)

{
"@type" => "Question",
"name" => part['title'],
"url" => part_url,
"acceptedAnswer" => {
"@type" => "Answer",
"url" => part_url,
"text" => part['body']
}
}
end
end

def part_url(part, index)
if index.zero?
page.canonical_url
else
page.canonical_url + "/" + part["slug"]
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ def content_item
def logo_url
local_assigns[:logo_url]
end

def parts
content_item.dig("details", "parts") || []
end
end
end
end
5 changes: 4 additions & 1 deletion lib/govuk_publishing_components/presenters/schema_org.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'govuk_publishing_components/presenters/machine_readable/page'
require 'govuk_publishing_components/presenters/machine_readable/article_schema'
require 'govuk_publishing_components/presenters/machine_readable/creative_work_schema'
require 'govuk_publishing_components/presenters/machine_readable/faq_page_schema'
require 'govuk_publishing_components/presenters/machine_readable/has_part_schema'
require 'govuk_publishing_components/presenters/machine_readable/is_part_of_schema'
require 'govuk_publishing_components/presenters/machine_readable/news_article_schema'
Expand All @@ -19,7 +20,9 @@ def initialize(page)
end

def structured_data
if page.schema == :article
if page.schema == :faq
FaqPageSchema.new(page).structured_data
elsif page.schema == :article
ArticleSchema.new(page).structured_data
elsif page.schema == :news_article
NewsArticleSchema.new(page).structured_data
Expand Down
37 changes: 37 additions & 0 deletions spec/lib/govuk_publishing_components/presenters/schema_org_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,43 @@
expect(structured_data['@type']).to eql("NewsArticle")
end

it "generates schema.org FAQPages" do
content_item = GovukSchemas::RandomExample.for_schema(frontend_schema: "guide") do |random_item|
random_item.merge(
"base_path" => "/how-to-train-your-dragon",
"details" => {
"parts" => [
{
"title" => "Overview",
"slug" => "overview",
"body" => "<p>First catch your dragon</p>"
},
{
"title" => "Insurance",
"slug" => "insurance",
"body" => "<p>Contact the Berk insurance bureau for more details.</p>"
}
]
}
)
end

structured_data = generate_structured_data(
content_item: content_item,
schema: :faq,
).structured_data

expect(structured_data['@type']).to eql("FAQPage")

q_and_a_pairs = structured_data['mainEntity']
expect(q_and_a_pairs.count).to eq(2)
expect(q_and_a_pairs.first["url"]).to eq("http://www.dev.gov.uk/how-to-train-your-dragon")
expect(q_and_a_pairs.second["url"]).to eq("http://www.dev.gov.uk/how-to-train-your-dragon/insurance")

expect(q_and_a_pairs.first["name"]).to eq("Overview")
expect(q_and_a_pairs.first["acceptedAnswer"]["text"]).to eq("<p>First catch your dragon</p>")
end

it "generates schema.org Person" do
content_item = GovukSchemas::RandomExample.for_schema(frontend_schema: "person")

Expand Down

0 comments on commit 296f707

Please sign in to comment.