From 6419a8cadb1f67687d08a5b69c6ff3660ca153d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Eckerstr=C3=B6m?= Date: Sat, 16 May 2026 17:53:41 +0200 Subject: [PATCH] Redirect page slugs with spaces to underscore form When visiting a slug containing a literal space (e.g. /Foo Bar, URL-encoded as /Foo%20Bar), 301-redirect to the canonical underscore slug so the browser address bar matches the stored slug. Improves SEO and avoids the previous 302 detour through /new/. Fixes #54 --- lib/controllers/page_controller.rb | 3 +++ test/integration/app_not_logged_in_test.rb | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/lib/controllers/page_controller.rb b/lib/controllers/page_controller.rb index 03a1bbeb..4390ece9 100644 --- a/lib/controllers/page_controller.rb +++ b/lib/controllers/page_controller.rb @@ -215,6 +215,9 @@ def restrict_concealed(page) end get '/:slug' do + if params[:slug].include?(" ") + redirect "/#{params[:slug].tr(' ', '_')}", 301 + end @page = Page .select(:id, :slug, :title, :concealed, :revision, :updated_on, :compiled_content, :author_id) .eager_graph(:author) diff --git a/test/integration/app_not_logged_in_test.rb b/test/integration/app_not_logged_in_test.rb index a530dc55..1fdf5a39 100644 --- a/test/integration/app_not_logged_in_test.rb +++ b/test/integration/app_not_logged_in_test.rb @@ -88,6 +88,13 @@ def test_nonexistent_page assert_equal "/new/#{random_slug}", URI(redirect_location).path end + def test_page_with_space_in_slug_redirects_to_underscore + get "/foo%20bar" + + assert_equal 301, last_response.status + assert_equal "/foo_bar", URI(last_response["Location"]).path + end + def test_new get "/new"