Skip to content

Commit 542c3e4

Browse files
committed
Add JSON-LD structured data helpers
1 parent 1e32636 commit 542c3e4

File tree

6 files changed

+91
-0
lines changed

6 files changed

+91
-0
lines changed

app/helpers/better_together/application_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module BetterTogether
66
# platform configurations, and navigation items.
77
module ApplicationHelper # rubocop:todo Metrics/ModuleLength
88
include MetricsHelper
9+
include StructuredDataHelper
910

1011
# Returns the base URL configured for BetterTogether.
1112
def base_url
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# frozen_string_literal: true
2+
3+
module BetterTogether
4+
# Helper methods for rendering JSON-LD structured data for schema.org
5+
module StructuredDataHelper
6+
def structured_data_tag(data)
7+
return if data.blank?
8+
9+
tag.script(type: 'application/ld+json') do
10+
raw(Array.wrap(data).to_json)
11+
end
12+
end
13+
14+
def platform_structured_data(platform)
15+
{
16+
'@context': 'https://schema.org',
17+
'@type': 'WebSite',
18+
name: platform.name,
19+
url: platform.url
20+
}
21+
end
22+
23+
def community_structured_data(community)
24+
data = {
25+
'@context': 'https://schema.org',
26+
'@type': 'Organization',
27+
name: community.name,
28+
url: community_url(community)
29+
}
30+
data[:description] = community.description.to_plain_text if community.respond_to?(:description) && community.description.present?
31+
if community.logo.attached?
32+
attachment = community.respond_to?(:optimized_logo) ? community.optimized_logo : community.logo
33+
data[:logo] = rails_storage_proxy_url(attachment)
34+
end
35+
data
36+
end
37+
38+
def event_structured_data(event)
39+
data = {
40+
'@context': 'https://schema.org',
41+
'@type': 'Event',
42+
name: event.name,
43+
startDate: event.starts_at&.iso8601,
44+
endDate: event.ends_at&.iso8601,
45+
url: event_url(event)
46+
}
47+
data[:description] = event.description.to_plain_text if event.respond_to?(:description) && event.description.present?
48+
data[:location] = event.location.to_s if event.respond_to?(:location) && event.location.present?
49+
data.compact
50+
end
51+
end
52+
end

app/views/better_together/events/show.html.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
<%= @resource.name %> | <%= resource_class.model_name.human.pluralize %>
33
<% end %>
44

5+
<% content_for :structured_data do %>
6+
<%= structured_data_tag(event_structured_data(@event)) %>
7+
<% end %>
8+
59
<div class="container-fluid mb-3 px-0">
610
<div class="event-header position-relative">
711
<!-- Cover Image Section -->

app/views/layouts/better_together/application.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
<title><%= (yield(:page_title) + ' | ') if content_for?(:page_title) %><%= host_platform.name %></title>
1212
<%= open_graph_meta_tags %>
1313
<%= seo_meta_tags %>
14+
<%= structured_data_tag([platform_structured_data(host_platform), community_structured_data(host_community)]) %>
15+
<%= yield(:structured_data) if content_for?(:structured_data) %>
1416
<meta name="color-scheme" content="light dark">
1517
<meta name="viewport" content="width=device-width, initial-scale=1.0">
1618
<%= csrf_meta_tags %>

app/views/layouts/better_together/turbo_native.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
<title><%= (yield(:page_title) + ' | ') if content_for?(:page_title) %><%= host_platform.name %></title>
1212
<%= open_graph_meta_tags %>
1313
<%= seo_meta_tags %>
14+
<%= structured_data_tag([platform_structured_data(host_platform), community_structured_data(host_community)]) %>
15+
<%= yield(:structured_data) if content_for?(:structured_data) %>
1416
<meta name="color-scheme" content="light dark">
1517
<meta name="viewport" content="width=device-width, initial-scale=1.0">
1618
<%= csrf_meta_tags %>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe BetterTogether::StructuredDataHelper, type: :helper do
6+
let(:platform) { build(:platform, name: 'Platform', url: 'https://example.com') }
7+
let(:event) { BetterTogether::Event.new(name: 'Event', starts_at: Time.zone.parse('2024-01-01 12:00:00')) }
8+
9+
before do
10+
allow(helper).to receive(:event_url).and_return('https://example.com/events/event')
11+
end
12+
13+
describe '#structured_data_tag' do
14+
it 'wraps JSON-LD data in a script tag' do
15+
data = platform_structured_data(platform)
16+
html = structured_data_tag(data)
17+
expect(html).to include('application/ld+json')
18+
expect(html).to include('Platform')
19+
end
20+
end
21+
22+
describe '#event_structured_data' do
23+
it 'includes event properties' do
24+
data = event_structured_data(event)
25+
expect(data[:name]).to eq('Event')
26+
expect(data[:url]).to eq('https://example.com/events/event')
27+
expect(data[:startDate]).to eq('2024-01-01T12:00:00Z')
28+
end
29+
end
30+
end

0 commit comments

Comments
 (0)