seiten 1.0.2 → 1.2.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/page.rb +33 -1
- data/lib/seiten/railtie.rb +3 -0
- data/lib/seiten/routes_helper.rb +1 -1
- data/lib/seiten/version.rb +1 -1
- data/lib/seiten.rb +64 -6
- data/test/dummy/config/initializers/new_framework_defaults.rb +0 -4
- data/test/dummy/config/locales/guide.de.yml +13 -0
- data/test/dummy/config/locales/guide.en.yml +14 -0
- data/test/dummy/config/navigations/guide.yml +7 -0
- data/test/dummy/log/test.log +11304 -42632
- data/test/dummy/tmp/local_secret.txt +1 -0
- data/test/integration/navigation_test.rb +4 -6
- data/test/lib/seiten/html/helpers_test.rb +4 -3
- data/test/lib/seiten/i18n_navigation_test.rb +47 -0
- data/test/lib/seiten/page_translation_test.rb +64 -0
- metadata +19 -12
- data/test/dummy/log/development.log +0 -1716
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '09cdd9e8323ed21cafe0eb5f92544ee05a8e78bc86b421a0fb2bfc6c865ecd8b'
|
|
4
|
+
data.tar.gz: f9860ca8c46a06a36136a992e078be502c81fba45373c5feae6682a5fb431e8e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ab559c9fb74b3373ddb9b31485dd4d78b56bcab9dbd1c1e863bafcf0a60c1a4cfb502728ea763db6e7b81ca9b1ff9d3c17d529fcf5b7b8c0bf226cca5316e6d
|
|
7
|
+
data.tar.gz: 4525be586db9bba6d0c8b1589d7297680b411523874c4fae5ed73dbb3ebff0445a65c7a27c22c65612c29c2dd525a30de5c845482c2cafef044824c8e7acc426
|
data/lib/seiten/page.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Seiten
|
|
4
4
|
class Page
|
|
5
|
-
attr_accessor :navigation_id, :id, :parent_id, :title, :slug, :refer, :data, :html_options
|
|
5
|
+
attr_accessor :navigation_id, :id, :parent_id, :title, :slug, :refer, :key, :data, :html_options
|
|
6
6
|
attr_writer :layout
|
|
7
7
|
|
|
8
8
|
# initialize Page object with attributes
|
|
@@ -13,6 +13,7 @@ module Seiten
|
|
|
13
13
|
@title = options[:title]
|
|
14
14
|
@slug = options[:slug]
|
|
15
15
|
@refer = options[:refer]
|
|
16
|
+
@key = options[:key]&.to_s
|
|
16
17
|
@layout = options[:layout]
|
|
17
18
|
@data = options[:data].each_with_object({}){|(k,v), h| h[k.to_sym] = v} if options[:data]
|
|
18
19
|
@data ||= {}
|
|
@@ -71,6 +72,37 @@ module Seiten
|
|
|
71
72
|
end
|
|
72
73
|
end
|
|
73
74
|
|
|
75
|
+
# The page's place in its navigation tree: the index among its siblings, from the root down
|
|
76
|
+
# (e.g. [2, 0] for the first child of the third top-level page).
|
|
77
|
+
def position
|
|
78
|
+
@position ||= (parent ? parent.position : []) + [navigation.pages.where(parent_id: parent_id).index(self)]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# The same page in the navigation of the same name in another locale: the page at the same
|
|
82
|
+
# position, or, for a page with a `key`, the page with the same key. Nil when there is none.
|
|
83
|
+
def translation(locale)
|
|
84
|
+
locale = locale.to_s
|
|
85
|
+
return self if locale == navigation.locale
|
|
86
|
+
|
|
87
|
+
other = Seiten::Navigation.find_by(name: navigation.name, locale: locale)
|
|
88
|
+
return unless other
|
|
89
|
+
|
|
90
|
+
if key
|
|
91
|
+
other.pages.find_by(key: key)
|
|
92
|
+
else
|
|
93
|
+
page = other.pages.all.find { |candidate| candidate.position == position }
|
|
94
|
+
page unless page&.key
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# This page in every locale that has it, by locale (including its own).
|
|
99
|
+
def translations
|
|
100
|
+
Seiten::Navigation.where(name: navigation.name).each_with_object({}) do |other, translations|
|
|
101
|
+
page = translation(other.locale)
|
|
102
|
+
translations[other.locale] = page if page
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
74
106
|
# get children of page
|
|
75
107
|
def children
|
|
76
108
|
navigation.pages.where(parent_id: id)
|
data/lib/seiten/railtie.rb
CHANGED
data/lib/seiten/routes_helper.rb
CHANGED
|
@@ -15,7 +15,7 @@ class ActionDispatch::Routing::Mapper
|
|
|
15
15
|
# NOTE: See https://github.com/rails/rails/issues/31228
|
|
16
16
|
resource_options[:constraints] ||= ->(req) { req.path.exclude? 'rails/active_storage' }
|
|
17
17
|
|
|
18
|
-
get '(*slug)', resource_options
|
|
18
|
+
get '(*slug)', **resource_options
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
data/lib/seiten/version.rb
CHANGED
data/lib/seiten.rb
CHANGED
|
@@ -21,6 +21,7 @@ module Seiten
|
|
|
21
21
|
config_dir: File.join('config', 'navigations'),
|
|
22
22
|
pages_dir: File.join('app', 'pages'),
|
|
23
23
|
root_page: 'home',
|
|
24
|
+
i18n_scope: 'navigations',
|
|
24
25
|
default_layout: 'application',
|
|
25
26
|
html: {
|
|
26
27
|
navigation: {
|
|
@@ -45,6 +46,9 @@ module Seiten
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
@navigations = []
|
|
49
|
+
@i18n_files = {}
|
|
50
|
+
@i18n_navigations = nil
|
|
51
|
+
@i18n_lock = Mutex.new
|
|
48
52
|
|
|
49
53
|
class << self
|
|
50
54
|
def config
|
|
@@ -52,6 +56,7 @@ module Seiten
|
|
|
52
56
|
end
|
|
53
57
|
|
|
54
58
|
def navigations
|
|
59
|
+
build_i18n_navigations unless @i18n_navigations
|
|
55
60
|
@navigations
|
|
56
61
|
end
|
|
57
62
|
|
|
@@ -59,14 +64,67 @@ module Seiten
|
|
|
59
64
|
@navigations = navigations
|
|
60
65
|
end
|
|
61
66
|
|
|
67
|
+
# config/navigations/<name>.<locale>.yml holds one locale's navigation; <name>.yml holds the pages
|
|
68
|
+
# of every locale, with titles and slugs from I18n (built on first use, see #i18n_pages).
|
|
62
69
|
def initialize_navigations
|
|
63
70
|
Dir[File.join(Rails.root, Seiten.config[:config_dir], "*.yml")].each do |file|
|
|
64
|
-
id
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
id = File.basename(file, '.yml')
|
|
72
|
+
if id.include?('.')
|
|
73
|
+
name, locale = id.split('.', 2)
|
|
74
|
+
navigation = Seiten::Navigation.new(name: name, locale: locale, dir: File.join(Rails.root, Seiten.config[:pages_dir], name, locale))
|
|
75
|
+
navigation.page_collection.build(pages: YAML.load_file(navigation.config))
|
|
76
|
+
@navigations << navigation
|
|
77
|
+
else
|
|
78
|
+
@i18n_files[id] = file
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Drops the navigations built from I18n, so they're built again with the current translations
|
|
84
|
+
# (on every code or translation reload in development).
|
|
85
|
+
def reset_i18n_navigations!
|
|
86
|
+
@i18n_lock.synchronize do
|
|
87
|
+
@navigations -= @i18n_navigations if @i18n_navigations
|
|
88
|
+
@i18n_navigations = nil
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def build_i18n_navigations
|
|
95
|
+
@i18n_lock.synchronize do
|
|
96
|
+
return if @i18n_navigations
|
|
97
|
+
|
|
98
|
+
@i18n_navigations = @i18n_files.flat_map do |name, file|
|
|
99
|
+
structure = YAML.load_file(file)
|
|
100
|
+
I18n.available_locales.map do |locale|
|
|
101
|
+
navigation = Seiten::Navigation.new(name: name, locale: locale, config: file, dir: File.join(Rails.root, Seiten.config[:pages_dir], name, locale.to_s))
|
|
102
|
+
navigation.page_collection.build(pages: i18n_pages(structure, locale, [Seiten.config[:i18n_scope], name]))
|
|
103
|
+
navigation
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
@navigations.concat(@i18n_navigations)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# The pages of a locale: every page names its `key`; its title and slug are the translations
|
|
111
|
+
# <i18n_scope>.<navigation>.<parent keys…>.<key>.title and .slug (the slug defaults to the
|
|
112
|
+
# parameterized title). The page's key becomes its full key, e.g. "account.manage", which is the
|
|
113
|
+
# same page in every locale.
|
|
114
|
+
def i18n_pages(nodes, locale, scope)
|
|
115
|
+
nodes.map do |node|
|
|
116
|
+
node = node.dup
|
|
117
|
+
key = node['key'] or raise Errors::PageError, "Every page of #{scope[1]}.yml needs a key"
|
|
118
|
+
page_scope = [*scope, key.to_s]
|
|
119
|
+
title = I18n.t('title', scope: page_scope, locale: locale, default: nil)
|
|
120
|
+
slug = I18n.t('slug', scope: page_scope, locale: locale, default: nil)
|
|
121
|
+
raise Errors::PageError, "#{page_scope.join('.')} needs a title or a slug in #{locale}" unless title || slug || node.key?('url')
|
|
122
|
+
|
|
123
|
+
node['title'] = title
|
|
124
|
+
node['url'] = slug if slug && !node.key?('url')
|
|
125
|
+
node['key'] = page_scope.drop(2).join('.')
|
|
126
|
+
node['nodes'] = i18n_pages(node['nodes'], locale, page_scope) if node['nodes']
|
|
127
|
+
node
|
|
70
128
|
end
|
|
71
129
|
end
|
|
72
130
|
end
|
|
@@ -12,9 +12,5 @@ Rails.application.config.action_controller.per_form_csrf_tokens = false
|
|
|
12
12
|
# Enable origin-checking CSRF mitigation. Previous versions had false.
|
|
13
13
|
Rails.application.config.action_controller.forgery_protection_origin_check = false
|
|
14
14
|
|
|
15
|
-
# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
|
|
16
|
-
# Previous versions had false.
|
|
17
|
-
ActiveSupport.to_time_preserves_timezone = false
|
|
18
|
-
|
|
19
15
|
# Require `belongs_to` associations by default. Previous versions had false.
|
|
20
16
|
# Rails.application.config.active_record.belongs_to_required_by_default = false
|