summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-28 00:02:55 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-28 00:02:55 +0200
commiteca95f90de3de7c6507fc529e00e1e36f136a234 (patch)
treec2ad60e1c3f7ff7969da2e004b245f662a32df4c
parent7605ececf7055e6da28eb54160324356c5dfe31c (diff)
Let editors manage menu titles in both locales
-rw-r--r--app/controllers/menu_items_controller.rb6
-rw-r--r--app/models/menu_item.rb6
-rw-r--r--app/views/menu_items/edit.html.erb3
-rw-r--r--app/views/menu_items/new.html.erb3
-rw-r--r--config/locales/de.yml2
-rw-r--r--config/locales/en.yml2
-rw-r--r--test/controllers/menu_items_controller_test.rb42
-rw-r--r--test/controllers/page_translations_controller_test.rb2
8 files changed, 56 insertions, 10 deletions
diff --git a/app/controllers/menu_items_controller.rb b/app/controllers/menu_items_controller.rb
index b095c8df..8b4e636e 100644
--- a/app/controllers/menu_items_controller.rb
+++ b/app/controllers/menu_items_controller.rb
@@ -19,7 +19,9 @@ class MenuItemsController < ApplicationController
19 end 19 end
20 20
21 def create 21 def create
22 if MenuItem.create( menu_item_params ) 22 @menu_item = MenuItem.new( menu_item_params )
23
24 if @menu_item.save
23 redirect_to menu_items_path 25 redirect_to menu_items_path
24 else 26 else
25 render :new 27 render :new
@@ -58,6 +60,6 @@ class MenuItemsController < ApplicationController
58 private 60 private
59 61
60 def menu_item_params 62 def menu_item_params
61 params.require(:menu_item).permit(:node_id, :path, :position, :type, :title, :type_id) 63 params.require(:menu_item).permit(:node_id, :path, :position, :titles => {})
62 end 64 end
63end 65end
diff --git a/app/models/menu_item.rb b/app/models/menu_item.rb
index 7769b7fa..b8df9ddb 100644
--- a/app/models/menu_item.rb
+++ b/app/models/menu_item.rb
@@ -3,11 +3,17 @@ class MenuItem < ApplicationRecord
3 default_scope -> { where(:type => "MenuItem") } 3 default_scope -> { where(:type => "MenuItem") }
4 4
5 translates :title 5 translates :title
6 validates :title, presence: true
6 7
7 acts_as_list :scope => :type 8 acts_as_list :scope => :type
8 9
9 before_save :determine_type_id 10 before_save :determine_type_id
10 11
12 def titles=(values)
13 values.each do |locale, value|
14 Globalize.with_locale(locale) { self.title = value.to_s.strip.presence }
15 end
16 end
11 17
12 private 18 private
13 19
diff --git a/app/views/menu_items/edit.html.erb b/app/views/menu_items/edit.html.erb
index 0652dc78..2bd65575 100644
--- a/app/views/menu_items/edit.html.erb
+++ b/app/views/menu_items/edit.html.erb
@@ -15,8 +15,7 @@
15 <div class="layout_row_label"><%= MenuItem.human_attribute_name(:path) %></div> 15 <div class="layout_row_label"><%= MenuItem.human_attribute_name(:path) %></div>
16 <div class="layout_row_content"><%= f.text_field :path %></div> 16 <div class="layout_row_content"><%= f.text_field :path %></div>
17 17
18 <div class="layout_row_label"><%= MenuItem.human_attribute_name(:title) %></div> 18 <%= render "title_fields", :menu_item => @menu_item %>
19 <div class="layout_row_content"><%= f.text_field :title %></div>
20 19
21 <div class="layout_row_label"></div> 20 <div class="layout_row_label"></div>
22 <div class="layout_row_content"><%= f.submit t("admin.common.update") %></div> 21 <div class="layout_row_content"><%= f.submit t("admin.common.update") %></div>
diff --git a/app/views/menu_items/new.html.erb b/app/views/menu_items/new.html.erb
index 713ac967..08872ec0 100644
--- a/app/views/menu_items/new.html.erb
+++ b/app/views/menu_items/new.html.erb
@@ -13,8 +13,7 @@
13 <div class="layout_row_label"><%= MenuItem.human_attribute_name(:path) %></div> 13 <div class="layout_row_label"><%= MenuItem.human_attribute_name(:path) %></div>
14 <div class="layout_row_content"><%= f.text_field :path %></div> 14 <div class="layout_row_content"><%= f.text_field :path %></div>
15 15
16 <div class="layout_row_label"><%= MenuItem.human_attribute_name(:title) %></div> 16 <%= render "title_fields", :menu_item => @menu_item %>
17 <div class="layout_row_content"><%= f.text_field :title %></div>
18 17
19 <div class="layout_row_content"><%= f.submit t("admin.common.create") %></div> 18 <div class="layout_row_content"><%= f.submit t("admin.common.create") %></div>
20<% end %> 19<% end %>
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 30e2f1b5..7253d1e4 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -638,6 +638,8 @@ de:
638 title: "Menüeintrag hinzufügen" 638 title: "Menüeintrag hinzufügen"
639 edit: 639 edit:
640 title: "Menüeintrag bearbeiten" 640 title: "Menüeintrag bearbeiten"
641 title_fields:
642 falls_back: "Menu-Title leer lassen, fall-back nach deutsch"
641 643
642 layouts: 644 layouts:
643 application: 645 application:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index f76dfecb..b21008f7 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -455,6 +455,8 @@ en:
455 title: "Add Menu Item" 455 title: "Add Menu Item"
456 edit: 456 edit:
457 title: "Edit Menu Item" 457 title: "Edit Menu Item"
458 title_fields:
459 falls_back: "Menu item title falls back to German if empty"
458 460
459 flash: 461 flash:
460 common: 462 common:
diff --git a/test/controllers/menu_items_controller_test.rb b/test/controllers/menu_items_controller_test.rb
index c47467a3..15a7b30b 100644
--- a/test/controllers/menu_items_controller_test.rb
+++ b/test/controllers/menu_items_controller_test.rb
@@ -1,8 +1,44 @@
1require 'test_helper' 1require 'test_helper'
2 2
3class MenuItemsControllerTest < ActionController::TestCase 3class MenuItemsControllerTest < ActionController::TestCase
4 # Replace this with your real tests. 4 def create_menu_item(title = "Ausgangstitel")
5 test "the truth" do 5 item = MenuItem.new(:path => "/menu_title_test")
6 assert true 6 item.titles = { I18n.default_locale.to_s => title }
7 item.save!
8 item
9 end
10
11 test "updating stores a title per locale" do
12 login_as :quentin
13 item = create_menu_item
14
15 patch :update, params: { :id => item.id,
16 :menu_item => { :titles => { "de" => "Transparenz", "en" => "Transparency" } } }
17
18 assert_equal "Transparenz", item.reload.translations.find_by(:locale => "de").title
19 assert_equal "Transparency", item.translations.find_by(:locale => "en").title
20 end
21
22 test "blanking a non-default title falls back to the default locale" do
23 login_as :quentin
24 item = create_menu_item
25 patch :update, params: { :id => item.id,
26 :menu_item => { :titles => { "de" => "Transparenz", "en" => "Transparency" } } }
27
28 patch :update, params: { :id => item.id,
29 :menu_item => { :titles => { "de" => "Transparenz", "en" => "" } } }
30
31 item.reload
32 assert_equal "Transparenz", Globalize.with_locale(:en) { item.title }
33 end
34
35 test "a blank default title is rejected" do
36 login_as :quentin
37 item = create_menu_item
38 patch :update, params: { :id => item.id,
39 :menu_item => { :titles => { "de" => "" } } }
40
41 assert_response :success # re-rendered :edit, not a redirect
42 assert_not_equal "", item.reload.translations.find_by(:locale => "de").title
7 end 43 end
8end 44end
diff --git a/test/controllers/page_translations_controller_test.rb b/test/controllers/page_translations_controller_test.rb
index 7484a203..31eefe84 100644
--- a/test/controllers/page_translations_controller_test.rb
+++ b/test/controllers/page_translations_controller_test.rb
@@ -30,7 +30,7 @@ class PageTranslationsControllerTest < ActionController::TestCase
30 node = Node.root.children.create!(:slug => "translations_exit_test") 30 node = Node.root.children.create!(:slug => "translations_exit_test")
31 node.lock_for_editing!(users(:quentin)) 31 node.lock_for_editing!(users(:quentin))
32 32
33 patch :update, params: { :node_id => node.id, :translation_locale => "en", :page => { :title => "x" }, :commit => "Save + Unlock + Exit" } 33 patch :update, params: { :node_id => node.id, :translation_locale => "en", :page => { :title => "x" }, :unlock_exit => "1" }
34 34
35 assert_nil node.reload.lock_owner 35 assert_nil node.reload.lock_owner
36 assert_redirected_to node_path(node) 36 assert_redirected_to node_path(node)