seiten 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/seiten/navigation.rb +10 -0
- data/lib/seiten/routes_helper.rb +79 -4
- data/lib/seiten/version.rb +1 -1
- data/lib/seiten.rb +5 -0
- data/test/dummy/app/controllers/guide/pages_controller.rb +5 -0
- data/test/dummy/config/locales/guide.de.yml +1 -0
- data/test/dummy/config/locales/guide.en.yml +1 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/test.log +8048 -0
- data/test/integration/localized_routes_test.rb +71 -0
- data/test/lib/seiten/i18n_navigation_test.rb +10 -0
- metadata +7 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6289826464b8f2c34c78a4d469fe26e0e772c79f67adf29f38dc3465c9d35ed6
|
|
4
|
+
data.tar.gz: fb131648fd8558fadf4e3b17f27aa1c24e4b4d4b59a13fcf0d173632c561c2a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b69aa165a103bd083dba0cb57c6c34078b139d56dba5a0e83679e4d654bd863e1e245d7dc247e429f6f3bf393818faa450f6c59fe9ad2255498e773427eb865c
|
|
7
|
+
data.tar.gz: '0643406590aa1ae9a182222163f903764807699d460cfa9652f3a56e235685bbb4c50e440701cae5a519f1f0a2afb5c5ba680ea41d74bf9098257737bd39242b'
|
data/lib/seiten/navigation.rb
CHANGED
|
@@ -32,6 +32,16 @@ module Seiten
|
|
|
32
32
|
page_collection
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
# The navigation's own title and slug, from I18n like its pages' (<i18n_scope>.<name>.title and
|
|
36
|
+
# .slug; the slug defaults to the parameterized title). Its localized routes start with the slug.
|
|
37
|
+
def title
|
|
38
|
+
I18n.t('title', scope: [Seiten.config[:i18n_scope], name], locale: locale, default: nil)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def slug
|
|
42
|
+
I18n.t('slug', scope: [Seiten.config[:i18n_scope], name], locale: locale, default: nil) || title&.parameterize
|
|
43
|
+
end
|
|
44
|
+
|
|
35
45
|
def pages=(pages_array)
|
|
36
46
|
page_collection.pages = pages_array.map { |page| page.navigation_id = id; page }
|
|
37
47
|
# return page_collection
|
data/lib/seiten/routes_helper.rb
CHANGED
|
@@ -1,15 +1,48 @@
|
|
|
1
1
|
class ActionDispatch::Routing::Mapper
|
|
2
|
+
# Routes a navigation's pages. Draw it after your other routes, which it would swallow.
|
|
3
|
+
#
|
|
4
|
+
# A navigation built in every locale from one file (config/navigations/help.yml) gets a route per
|
|
5
|
+
# locale, under the locale and the navigation's slug (its I18n title or slug, see
|
|
6
|
+
# Navigation#slug), to Help::PagesController#show, named help_page_<locale>:
|
|
7
|
+
#
|
|
8
|
+
# seiten :help # /en/help(/*slug), /de/hilfe(/*slug)
|
|
9
|
+
#
|
|
10
|
+
# Every page gets a link helper named after the navigation and its key, and the navigation one that
|
|
11
|
+
# takes a key; both link to the page in I18n.locale or the `locale:` option:
|
|
12
|
+
#
|
|
13
|
+
# help_account_manage_path # => "/en/help/your-account/manage-your-account"
|
|
14
|
+
# help_account_manage_url(locale: :de) # => "http://…/de/hilfe/dein-account/account-verwalten"
|
|
15
|
+
# help_page_path(page.key) # the same, for a key in a variable; unknown keys raise
|
|
16
|
+
# help_page_path # => "/en/help", the navigation's root
|
|
17
|
+
#
|
|
18
|
+
# `to:`, `as:` (of the navigation's helper) and `path:` (the same in every locale) replace the
|
|
19
|
+
# defaults, `prefix: false` names the page helpers without the navigation (account_manage_path), and
|
|
20
|
+
# `localized: false` draws one catch-all route instead.
|
|
21
|
+
#
|
|
22
|
+
# Other navigations get one catch-all route to seiten/pages#show (or `to:`) that sets
|
|
23
|
+
# params[:navigation_id] (except for the application navigation); `localized: true` routes them per
|
|
24
|
+
# locale too.
|
|
25
|
+
#
|
|
26
|
+
# seiten # /*slug, the application navigation
|
|
27
|
+
# scope(:help) { seiten :help }
|
|
2
28
|
def seiten(*resources)
|
|
3
29
|
options = resources.extract_options!
|
|
4
|
-
options
|
|
30
|
+
localized, path, prefix = options.extract!(:localized, :path, :prefix).values_at(:localized, :path, :prefix)
|
|
5
31
|
|
|
6
32
|
resources.each do |resource|
|
|
7
|
-
|
|
33
|
+
name = resource.to_s
|
|
34
|
+
|
|
35
|
+
if localized.nil? ? Seiten.i18n_navigation?(name) : localized
|
|
36
|
+
seiten_localized_routes(name, options.dup, path: path, prefix: prefix.nil? ? name : prefix)
|
|
37
|
+
next
|
|
38
|
+
end
|
|
8
39
|
|
|
40
|
+
resource_options = options.dup
|
|
41
|
+
resource_options[:to] ||= 'seiten/pages#show'
|
|
9
42
|
resource_options[:as] ||= resource == :application ? :seiten_page : "seiten_#{resource}_page"
|
|
10
43
|
|
|
11
|
-
resource_options[:defaults]
|
|
12
|
-
resource_options[:defaults][:navigation_id] =
|
|
44
|
+
resource_options[:defaults] = resource_options[:defaults].to_h.dup
|
|
45
|
+
resource_options[:defaults][:navigation_id] = name unless resource == :application
|
|
13
46
|
resource_options[:defaults][:slug] = ''
|
|
14
47
|
|
|
15
48
|
# NOTE: See https://github.com/rails/rails/issues/31228
|
|
@@ -18,4 +51,46 @@ class ActionDispatch::Routing::Mapper
|
|
|
18
51
|
get '(*slug)', **resource_options
|
|
19
52
|
end
|
|
20
53
|
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def seiten_localized_routes(name, options, path:, prefix:)
|
|
58
|
+
navigations = Seiten::Navigation.where(name: name)
|
|
59
|
+
raise ArgumentError, "No #{name} navigation in #{Seiten.config[:config_dir]}" if navigations.empty?
|
|
60
|
+
|
|
61
|
+
route = (options.delete(:as) || "#{name}_page").to_s
|
|
62
|
+
options = { to: "#{name}/pages#show", format: false, **options }
|
|
63
|
+
defaults = { **options.delete(:defaults).to_h, navigation_id: name, slug: '' }
|
|
64
|
+
|
|
65
|
+
navigations.each do |navigation|
|
|
66
|
+
locale_path = [navigation.locale, path || navigation.slug].compact_blank.join('/')
|
|
67
|
+
get "#{locale_path}(/*slug)", **options, as: "#{route}_#{navigation.locale}", defaults: defaults.merge(locale: navigation.locale)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
keys = navigations.first.pages.all.filter_map(&:key)
|
|
71
|
+
helpers = keys.map { |key| [prefix.presence, *key.split('.')].compact.join('_') }
|
|
72
|
+
duplicate = [route, *helpers].tally.find { |_, count| count > 1 }&.first
|
|
73
|
+
raise ArgumentError, "The #{name} navigation would define #{duplicate}_path twice" if duplicate
|
|
74
|
+
|
|
75
|
+
seiten_link_helper(route, name, route)
|
|
76
|
+
keys.zip(helpers).each { |key, helper| seiten_link_helper(helper, name, route, key) }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# <helper>_path and <helper>_url: the page with `page_key` (else the key given first, else the
|
|
80
|
+
# navigation's root) in the navigation of I18n.locale or the `locale:` option.
|
|
81
|
+
def seiten_link_helper(helper, navigation_name, route, page_key = nil)
|
|
82
|
+
@set.add_url_helper(helper, {}) do |*args|
|
|
83
|
+
options = args.extract_options!
|
|
84
|
+
key = page_key || args.first
|
|
85
|
+
locale = (options[:locale] || I18n.locale).to_s
|
|
86
|
+
|
|
87
|
+
navigation = Seiten::Navigation.find_by(name: navigation_name, locale: locale)
|
|
88
|
+
raise ArgumentError, "No #{navigation_name} navigation in #{locale}" unless navigation
|
|
89
|
+
|
|
90
|
+
page = navigation.pages.find_by(key: key.to_s) if key
|
|
91
|
+
raise ArgumentError, "No page #{key} in the #{navigation_name} navigation" if key && !page
|
|
92
|
+
|
|
93
|
+
{ use_route: "#{route}_#{locale}", slug: page&.slug.to_s, **options.except(:locale) }
|
|
94
|
+
end
|
|
95
|
+
end
|
|
21
96
|
end
|
data/lib/seiten/version.rb
CHANGED
data/lib/seiten.rb
CHANGED
|
@@ -80,6 +80,11 @@ module Seiten
|
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
# Whether the navigation is built in every locale from one file (config/navigations/<name>.yml).
|
|
84
|
+
def i18n_navigation?(name)
|
|
85
|
+
@i18n_files.key?(name.to_s)
|
|
86
|
+
end
|
|
87
|
+
|
|
83
88
|
# Drops the navigations built from I18n, so they're built again with the current translations
|
|
84
89
|
# (on every code or translation reload in development).
|
|
85
90
|
def reset_i18n_navigations!
|
data/test/dummy/config/routes.rb
CHANGED
|
File without changes
|