summaryrefslogtreecommitdiff
path: root/app/helpers/social_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/helpers/social_helper.rb')
-rw-r--r--app/helpers/social_helper.rb53
1 files changed, 49 insertions, 4 deletions
diff --git a/app/helpers/social_helper.rb b/app/helpers/social_helper.rb
index d6932a2f..e43f5a5c 100644
--- a/app/helpers/social_helper.rb
+++ b/app/helpers/social_helper.rb
@@ -92,11 +92,14 @@ module SocialHelper
92 @page&.published_at&.iso8601 92 @page&.published_at&.iso8601
93 end 93 end
94 94
95 # request.path rather than a routing helper: it is already the locale's 95 # The address of the version actually being served, not of the URL that
96 # own canonical form -- unprefixed for German, /en/ for English -- and 96 # was requested. So /de/updates/foo points at /updates/foo, and a page
97 # dropping the query string is what makes it canonical. 97 # with no English translation requested under /en/ points at the German
98 # URL rather than claiming to be an English page. The query string is
99 # dropped, which is what makes it canonical.
98 def og_canonical_url 100 def og_canonical_url
99 og_absolute_url(request.path) 101 locale = @page&.persisted? ? og_locale_key : I18n.locale
102 og_locale_url(locale)
100 end 103 end
101 104
102 def og_locale 105 def og_locale
@@ -104,6 +107,48 @@ module SocialHelper
104 OG_LOCALES[I18n.default_locale.to_sym]) 107 OG_LOCALES[I18n.default_locale.to_sym])
105 end 108 end
106 109
110 # Locales that can appear in a URL. Cccms::LOCALES will replace this when
111 # the set_locale allowlist lands; :root is in available_locales but is not
112 # a language.
113 def og_url_locales
114 I18n.available_locales - [:root]
115 end
116
117 # The request path with any locale prefix stripped, so a locale-specific
118 # URL can be rebuilt from it. /en/updates/foo, /de/updates/foo and
119 # /updates/foo all reduce to /updates/foo.
120 def og_bare_path
121 pattern = og_url_locales.join("|")
122 request.path.sub(%r{\A/(?:#{pattern})(?=/|\z)}, "").presence || "/"
123 end
124
125 # Absolute URL for this page in one locale. The default locale is
126 # unprefixed, matching default_url_options, so /updates/foo is the
127 # canonical German address and /de/updates/foo is a duplicate of it.
128 def og_locale_url(locale)
129 locale = locale.to_sym
130 locale = I18n.default_locale unless og_url_locales.include?(locale)
131
132 path = og_bare_path
133 return og_absolute_url(path) if locale == I18n.default_locale
134
135 og_absolute_url(path == "/" ? "/#{locale}" : "/#{locale}#{path}")
136 end
137
138 # One entry per locale in which the page genuinely has a translation,
139 # including a self-reference, which Google requires. A locale with no
140 # translation is omitted: /en/ would render German content through the
141 # fallback chain, which is not an English version of the page. With only
142 # one translation there is nothing to declare.
143 def og_hreflang_alternates
144 return [] unless @page&.persisted?
145
146 locales = @page.translated_locales.map(&:to_sym) & og_url_locales
147 return [] if locales.size < 2
148
149 locales.sort.map { |locale| [locale.to_s, og_locale_url(locale)] }
150 end
151
107 # Only locales in which this page genuinely has a translation, so a 152 # Only locales in which this page genuinely has a translation, so a
108 # crawler is not told about a variant that would fall back. 153 # crawler is not told about a variant that would fall back.
109 def og_locale_alternates 154 def og_locale_alternates