seiten 0.0.8 → 1.0.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 +5 -5
- data/Rakefile +1 -0
- data/app/controllers/seiten/pages_controller.rb +2 -18
- data/config/initializers/seiten.rb +1 -1
- data/lib/seiten/errors/base_error.rb +4 -0
- data/lib/seiten/errors/page_error.rb +4 -0
- data/lib/seiten/errors/routing_error.rb +4 -0
- data/lib/seiten/helpers/backend.rb +23 -0
- data/lib/seiten/helpers/current.rb +33 -0
- data/lib/seiten/helpers/frontend.rb +19 -0
- data/lib/seiten/html/breadcrumb.rb +41 -0
- data/lib/seiten/html/helpers.rb +32 -0
- data/lib/seiten/html/navigation.rb +39 -0
- data/lib/seiten/navigation.rb +43 -0
- data/lib/seiten/page.rb +71 -50
- data/lib/seiten/page_collection.rb +54 -0
- data/lib/seiten/page_collection_builder.rb +63 -0
- data/lib/seiten/railtie.rb +7 -0
- data/lib/seiten/routes_helper.rb +16 -11
- data/lib/seiten/slug_builder.rb +32 -0
- data/lib/seiten/version.rb +1 -1
- data/lib/seiten.rb +63 -12
- data/test/controllers/helper_methods_test.rb +25 -0
- data/test/controllers/pages_controller_test.rb +9 -0
- data/test/controllers/posts_controller_test.rb +12 -0
- data/test/controllers/seiten/pages_controller_test.rb +39 -0
- data/test/dummy/app/controllers/application_controller.rb +10 -0
- data/test/dummy/app/controllers/pages_controller.rb +1 -1
- data/test/dummy/app/controllers/posts_controller.rb +10 -0
- data/test/dummy/app/helpers/application_helper.rb +1 -0
- data/test/dummy/app/pages/{de → application/de}/produkte.html.erb +0 -0
- data/test/dummy/app/pages/{en/about/our-team/switzerland.html.erb → application/en/about/our-team/italy.html.erb} +0 -0
- data/test/dummy/app/pages/{en/about/works.html.erb → application/en/about/our-team/switzerland.html.erb} +0 -0
- data/test/dummy/app/pages/application/en/about/our-team.html.erb +2 -0
- data/test/dummy/app/pages/application/en/about/partners.html.erb +1 -0
- data/test/dummy/app/pages/{en/contact.html.erb → application/en/about/works.html.erb} +0 -0
- data/test/dummy/app/pages/{en/about/our-team/italy.html.erb → application/en/about.html.erb} +0 -0
- data/test/dummy/app/pages/{en/products/logo-design.html.erb → application/en/contact.html.erb} +0 -0
- data/test/dummy/app/pages/{en → application/en}/home.html.erb +0 -0
- data/test/dummy/app/pages/{en/products/web-development.html.erb → application/en/products/hire-us.html.erb} +0 -0
- data/test/dummy/{db/test.sqlite3 → app/pages/application/en/products/logo-design.html.erb} +0 -0
- data/test/dummy/app/pages/application/en/products/web-development.html.erb +0 -0
- data/test/dummy/app/pages/{en → application/en}/products.html.erb +0 -0
- data/test/dummy/app/pages/{localization.html.erb → application/localization.html.erb} +0 -0
- data/test/dummy/app/pages/help/en/home.html.erb +0 -0
- data/test/dummy/app/pages/help/en/logging-in.html.erb +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +1 -1
- data/test/dummy/app/views/layouts/home.html.erb +1 -1
- data/test/dummy/app/views/pages/secret.html.erb +1 -1
- data/test/dummy/app/views/posts/index.html.erb +1 -0
- data/test/dummy/config/application.rb +4 -41
- data/test/dummy/config/boot.rb +2 -9
- data/test/dummy/config/cable.yml +9 -0
- data/test/dummy/config/environments/development.rb +26 -21
- data/test/dummy/config/environments/production.rb +3 -0
- data/test/dummy/config/environments/test.rb +15 -19
- data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +6 -5
- data/test/dummy/config/initializers/mime_types.rb +0 -1
- data/test/dummy/config/initializers/new_framework_defaults.rb +20 -0
- data/test/dummy/config/initializers/session_store.rb +1 -6
- data/test/dummy/config/initializers/wrap_parameters.rb +5 -5
- data/test/dummy/config/{navigation/de.yml → navigations/application.de.yml} +5 -5
- data/test/dummy/config/{navigation/en.yml → navigations/application.en.yml} +15 -7
- data/test/dummy/config/navigations/help.en.yml +17 -0
- data/test/dummy/config/routes.rb +6 -3
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/log/development.log +1716 -4559
- data/test/dummy/log/test.log +43833 -16254
- data/test/fixtures/breadcrumb.html +1 -0
- data/test/fixtures/navigation.html +1 -0
- data/test/integration/layout_test.rb +10 -11
- data/test/integration/navigation_test.rb +50 -50
- data/test/lib/seiten/helpers/frontend_test.rb +37 -0
- data/test/lib/seiten/html/breadcrumb_test.rb +29 -0
- data/test/lib/seiten/html/helpers_test.rb +55 -0
- data/test/lib/seiten/html/navigation_test.rb +29 -0
- data/test/lib/seiten/navigation_test.rb +45 -0
- data/test/lib/seiten/page_collection_builder_test.rb +141 -0
- data/test/lib/seiten/page_collection_test.rb +59 -0
- data/test/lib/seiten/page_test.rb +188 -0
- data/test/lib/seiten/slug_builder_test.rb +47 -0
- data/test/lib/seiten_test.rb +16 -0
- data/test/test_helper.rb +2 -8
- metadata +134 -78
- data/app/helpers/seiten_helper.rb +0 -46
- data/lib/seiten/controllers/helpers.rb +0 -16
- data/lib/seiten/page_store.rb +0 -165
- data/test/dummy/app/assets/javascripts/application.js +0 -15
- data/test/dummy/app/assets/stylesheets/application.css +0 -13
- data/test/dummy/app/pages/en/about/our-team.html.erb +0 -2
- data/test/dummy/app/pages/en/about/partners.html.erb +0 -1
- data/test/dummy/config/navigation.yml +0 -37
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/integration/i18n_test.rb +0 -31
- data/test/integration/redirect_test.rb +0 -15
- data/test/page_store_test.rb +0 -28
- data/test/page_test.rb +0 -104
- data/test/seiten_test.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3e17a2fa52d374492d7a6598c5e88c4d81935b091158a60bb14d298fd83469be
|
4
|
+
data.tar.gz: 4cb163a2fc0399bd5ab1267790907c6fb356f7d55996dd9b08c6a90c0a51166f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d2e231683fa2bb4f8158211d8ab0b22f32093948792dce08e6dcff3011959deeaa61fc18d434a8dd73100b9e458dcb272a84c65fdd34d2c609b5442a03da8f9
|
7
|
+
data.tar.gz: a3f7f85d5196780920a259229c960d524176c127c102990c313ab161cdeb020f0f390e4a6130011528656562220f1ab5b34268507cf1ac9446c8602ade8bd281
|
data/Rakefile
CHANGED
@@ -1,25 +1,9 @@
|
|
1
1
|
module Seiten
|
2
2
|
class PagesController < ::ApplicationController
|
3
|
+
include Seiten::Helpers::Backend
|
3
4
|
|
4
5
|
def show
|
5
|
-
|
6
|
-
raise ActionController::RoutingError.new("Page /#{params[:page]} not found")
|
7
|
-
else
|
8
|
-
|
9
|
-
if params[:page]
|
10
|
-
filename = params[:page]
|
11
|
-
else
|
12
|
-
filename = Seiten.config[:root_page_filename]
|
13
|
-
end
|
14
|
-
|
15
|
-
file = Seiten::PageStore.current.file_path(filename: filename)
|
16
|
-
|
17
|
-
if current_page.layout
|
18
|
-
render file: file, layout: current_page.layout
|
19
|
-
else
|
20
|
-
render file: file
|
21
|
-
end
|
22
|
-
end
|
6
|
+
render_seiten_page
|
23
7
|
end
|
24
8
|
end
|
25
9
|
end
|
@@ -1 +1 @@
|
|
1
|
-
Seiten
|
1
|
+
Seiten.initialize_navigations
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Seiten
|
2
|
+
module Helpers
|
3
|
+
# Those helpers are convenience methods added to Seiten::PagesController or useful for building your own.
|
4
|
+
module Backend
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.prepend_view_path Seiten.config[:pages_dir]
|
9
|
+
base.before_action :raise_seiten_routing_error, unless: :current_page
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def raise_seiten_routing_error
|
15
|
+
raise Seiten::Errors::RoutingError.new("Page /#{params[:slug]} not found")
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_seiten_page
|
19
|
+
render current_page.template_path, layout: current_page.layout
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Seiten
|
2
|
+
module Helpers
|
3
|
+
# Those helpers are convenience methods added to ApplicationController.
|
4
|
+
module Current
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
if respond_to?(:helper_method)
|
9
|
+
helper_method :current_navigation
|
10
|
+
helper_method :current_page
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def current_navigation
|
15
|
+
@current_navigation ||= set_current_navigation
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_page
|
19
|
+
@current_page ||= set_current_page
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def set_current_navigation
|
25
|
+
Seiten::Navigation.find_by(name: params[:navigation_id] || 'application', locale: params[:locale] || I18n.locale.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_current_page
|
29
|
+
current_navigation&.pages&.find_by(slug: params[:slug]) if params[:slug]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Seiten
|
4
|
+
module Helpers
|
5
|
+
module Frontend
|
6
|
+
def link_to_seiten_page(page)
|
7
|
+
link_to page.title, page.path
|
8
|
+
end
|
9
|
+
|
10
|
+
def seiten_navigation(navigation = current_navigation, parent_id: nil, deep: 2, html: {})
|
11
|
+
Seiten::HTML::Navigation.new(self, navigation: navigation, parent_id: parent_id, current_page: current_page, deep: deep, html: html).body
|
12
|
+
end
|
13
|
+
|
14
|
+
def seiten_breadcrumb(separator: '>', html: {})
|
15
|
+
Seiten::HTML::Breadcrumb.new(self, page: current_page, separator: separator, html: html).body
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Seiten
|
2
|
+
module HTML
|
3
|
+
class Breadcrumb
|
4
|
+
attr_reader :body
|
5
|
+
|
6
|
+
def initialize(view_context, page:, separator: '>', html: {})
|
7
|
+
@view_context = view_context
|
8
|
+
@current_page = page
|
9
|
+
@separator = separator
|
10
|
+
@html_options = Seiten.config[:html].deep_merge(html || {})
|
11
|
+
@body = build_navigation if @current_page
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build_navigation
|
17
|
+
classes = Seiten::HTML::Helpers.build_classes(class_options: @html_options[:breadcrumb], modifier_options: @html_options[:modifier])
|
18
|
+
@view_context.content_tag(:ul, class: classes) do
|
19
|
+
pages = @current_page.breadcrumbs.each_with_index.map do |page, index|
|
20
|
+
build_page_element(page, index)
|
21
|
+
end
|
22
|
+
@view_context.safe_join(pages)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_page_element(page, index)
|
27
|
+
modifiers = page == @current_page ? [:current] : []
|
28
|
+
classes = Seiten::HTML::Helpers.build_classes(:item, modifiers: modifiers, class_options: @html_options[:breadcrumb], modifier_options: @html_options[:modifier])
|
29
|
+
|
30
|
+
@view_context.content_tag :li, class: classes do
|
31
|
+
if @separator && index.positive?
|
32
|
+
sep_class = Seiten::HTML::Helpers.build_classes(:separator, class_options: @html_options[:breadcrumb])
|
33
|
+
span = @view_context.content_tag(:span, @separator, class: sep_class)
|
34
|
+
end
|
35
|
+
link = @view_context.link_to_seiten_page(page)
|
36
|
+
@view_context.safe_join([span, link])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Seiten
|
2
|
+
module HTML
|
3
|
+
module Helpers
|
4
|
+
def self.build_page_modifiers(page, current_page)
|
5
|
+
modifiers = []
|
6
|
+
modifiers << :parent if page.children?
|
7
|
+
if page.active?(current_page)
|
8
|
+
modifiers << :active
|
9
|
+
modifiers << (page == current_page ? :current : :expanded)
|
10
|
+
end
|
11
|
+
modifiers
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.build_classes(element = nil, class_options:, modifier_options: [], modifiers: [], merge: nil)
|
15
|
+
classes = []
|
16
|
+
|
17
|
+
klass = class_options[element || :base]
|
18
|
+
classes << klass
|
19
|
+
|
20
|
+
if modifiers.any?
|
21
|
+
base = (modifier_options[:base].presence || klass)
|
22
|
+
modifiers.each do |modifier|
|
23
|
+
classes << "#{base}#{modifier_options[:separator]}#{modifier_options[modifier]}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
classes << merge if merge
|
28
|
+
classes.join(' ')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Seiten
|
2
|
+
module HTML
|
3
|
+
class Navigation
|
4
|
+
attr_reader :body
|
5
|
+
|
6
|
+
def initialize(view_context, navigation:, parent_id: nil, current_page: nil, deep: 2, html: {})
|
7
|
+
@view_context = view_context
|
8
|
+
@start_depth = deep
|
9
|
+
@html_options = Seiten.config[:html].deep_merge(html || {})
|
10
|
+
@current_page = current_page
|
11
|
+
@body = build_navigation(navigation, parent_id: parent_id, deep: deep)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build_navigation(navigation, parent_id:, deep:)
|
17
|
+
wrapper_class = @start_depth != deep ? :nodes : nil
|
18
|
+
|
19
|
+
return unless deep.positive?
|
20
|
+
|
21
|
+
@view_context.content_tag(:ul, class: Seiten::HTML::Helpers.build_classes(wrapper_class, class_options: @html_options[:navigation], modifier_options: @html_options[:modifier])) do
|
22
|
+
pages = navigation.pages.where(parent_id: parent_id).map do |page|
|
23
|
+
children = build_navigation(navigation, parent_id: page.id, deep: deep - 1) if page.children?
|
24
|
+
build_page_element(page, children)
|
25
|
+
end
|
26
|
+
@view_context.safe_join(pages)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def build_page_element(page, children)
|
31
|
+
modifiers = Seiten::HTML::Helpers.build_page_modifiers(page, @current_page)
|
32
|
+
classes = Seiten::HTML::Helpers.build_classes(:item, modifiers: modifiers, merge: page.html_options[:class], class_options: @html_options[:navigation], modifier_options: @html_options[:modifier])
|
33
|
+
@view_context.content_tag(:li, page.html_options.merge(class: classes)) do
|
34
|
+
@view_context.safe_join([@view_context.link_to_seiten_page(page), children])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Seiten
|
2
|
+
class Navigation
|
3
|
+
attr_accessor :name, :locale, :config, :dir, :page_collection
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
@name = options[:name].to_s
|
7
|
+
@locale = options[:locale].to_s
|
8
|
+
@config = options[:config] || File.join(Rails.root, Seiten.config[:config_dir], "#{id}.yml")
|
9
|
+
@dir = options[:dir] || File.join(Rails.root, Seiten.config[:pages_dir], @name, @locale)
|
10
|
+
@page_collection = Seiten::PageCollection.new(navigation_id: id)
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def find_by(params={})
|
15
|
+
where(params).first
|
16
|
+
end
|
17
|
+
|
18
|
+
def where(params={})
|
19
|
+
Seiten.navigations.select do |navigation|
|
20
|
+
params.all? do |param|
|
21
|
+
navigation.send(param[0]) == param[1]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def id
|
28
|
+
"%s.%s" % [name, locale]
|
29
|
+
end
|
30
|
+
|
31
|
+
def pages
|
32
|
+
page_collection
|
33
|
+
end
|
34
|
+
|
35
|
+
def pages=(pages_array)
|
36
|
+
page_collection.pages = pages_array.map { |page| page.navigation_id = id; page }
|
37
|
+
# return page_collection
|
38
|
+
# NOTE: This doesn't work and just returns page_array.
|
39
|
+
# I think because page_collection#pages= attr_accessor is called first
|
40
|
+
# and thus why our return call is ignored.
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/seiten/page.rb
CHANGED
@@ -1,55 +1,27 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Seiten
|
3
4
|
class Page
|
4
|
-
|
5
|
-
|
5
|
+
attr_accessor :navigation_id, :id, :parent_id, :title, :slug, :refer, :data, :html_options
|
6
|
+
attr_writer :layout
|
6
7
|
|
7
8
|
# initialize Page object with attributes
|
8
9
|
def initialize(options={})
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@layout
|
16
|
-
@
|
10
|
+
@navigation_id = options[:navigation_id]
|
11
|
+
@id = options[:id]
|
12
|
+
@parent_id = options[:parent_id]
|
13
|
+
@title = options[:title]
|
14
|
+
@slug = options[:slug]
|
15
|
+
@refer = options[:refer]
|
16
|
+
@layout = options[:layout]
|
17
|
+
@data = options[:data].each_with_object({}){|(k,v), h| h[k.to_sym] = v} if options[:data]
|
18
|
+
@data ||= {}
|
19
|
+
@html_options = options[:html].each_with_object({}){|(k,v), h| h[k.to_sym] = v} if options[:html]
|
20
|
+
@html_options ||= {}
|
17
21
|
end
|
18
22
|
|
19
|
-
|
20
|
-
|
21
|
-
def all
|
22
|
-
Seiten::PageStore.current.pages
|
23
|
-
end
|
24
|
-
|
25
|
-
# find page by id
|
26
|
-
def find(id)
|
27
|
-
all.select { |page| page.id == id }.first
|
28
|
-
end
|
29
|
-
|
30
|
-
# find all pages by parent_id
|
31
|
-
def find_by_parent_id(parent_id)
|
32
|
-
all.select { |page| page.parent_id == parent_id }
|
33
|
-
end
|
34
|
-
|
35
|
-
# find a page by slug
|
36
|
-
def find_by_slug(slug)
|
37
|
-
if slug
|
38
|
-
slug = slug[1..-1] if slug[0] == "/"
|
39
|
-
end
|
40
|
-
all.select { |page| page.slug == slug }.first
|
41
|
-
end
|
42
|
-
|
43
|
-
# get breadcrumb of given page (reversed)
|
44
|
-
def get_breadcrumb(page)
|
45
|
-
pages ||= []
|
46
|
-
pages << page
|
47
|
-
if page.parent
|
48
|
-
pages << get_breadcrumb(page.parent)
|
49
|
-
end
|
50
|
-
pages.flatten
|
51
|
-
end
|
52
|
-
|
23
|
+
def navigation
|
24
|
+
Seiten::Navigation.find_by(id: navigation_id)
|
53
25
|
end
|
54
26
|
|
55
27
|
# returns true if slug starts with http:// or https://
|
@@ -59,18 +31,41 @@ module Seiten
|
|
59
31
|
|
60
32
|
# get parent of page
|
61
33
|
def parent
|
62
|
-
|
34
|
+
navigation.pages.find(parent_id)
|
63
35
|
end
|
64
36
|
|
65
37
|
def parent?
|
66
38
|
parent.present?
|
67
39
|
end
|
68
40
|
|
69
|
-
|
41
|
+
def ancestors
|
42
|
+
return @ancestors unless @ancestors.nil?
|
43
|
+
|
44
|
+
@ancestors = []
|
45
|
+
return @ancestors unless parent?
|
46
|
+
|
47
|
+
ancestor = parent
|
48
|
+
loop do
|
49
|
+
@ancestors << ancestor
|
50
|
+
ancestor = ancestor.parent
|
51
|
+
break if ancestor.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
@ancestors
|
55
|
+
end
|
56
|
+
|
57
|
+
def self_and_ancestors
|
58
|
+
@self_and_ancestors ||= ancestors.insert(0, self)
|
59
|
+
end
|
60
|
+
|
61
|
+
def breadcrumbs
|
62
|
+
@breadcrumbs ||= self_and_ancestors.reverse
|
63
|
+
end
|
64
|
+
|
70
65
|
# get root page of current page branch
|
71
|
-
def
|
66
|
+
def root
|
72
67
|
if self.parent?
|
73
|
-
self.parent.
|
68
|
+
self.parent.root
|
74
69
|
else
|
75
70
|
self
|
76
71
|
end
|
@@ -78,7 +73,11 @@ module Seiten
|
|
78
73
|
|
79
74
|
# get children of page
|
80
75
|
def children
|
81
|
-
|
76
|
+
navigation.pages.where(parent_id: id)
|
77
|
+
end
|
78
|
+
|
79
|
+
def children?
|
80
|
+
navigation.pages.find_by(parent_id: id).present?
|
82
81
|
end
|
83
82
|
|
84
83
|
# true if child is children of page
|
@@ -105,5 +104,27 @@ module Seiten
|
|
105
104
|
end
|
106
105
|
end
|
107
106
|
end
|
107
|
+
|
108
|
+
def template_path
|
109
|
+
[
|
110
|
+
navigation_id.gsub(/\./, '/'),
|
111
|
+
slug.present? ? slug : Seiten.config[:root_page]
|
112
|
+
].join('/')
|
113
|
+
end
|
114
|
+
alias_method :to_s, :template_path
|
115
|
+
|
116
|
+
def path
|
117
|
+
return refer if refer
|
118
|
+
return '#' if slug.nil?
|
119
|
+
return slug if external?
|
120
|
+
|
121
|
+
navigation_name = navigation.name == 'application' ? nil : navigation.name
|
122
|
+
|
123
|
+
[:seiten, navigation_name.try(:to_sym), :page, { slug: slug }]
|
124
|
+
end
|
125
|
+
|
126
|
+
def layout
|
127
|
+
@layout || Seiten.config[:default_layout]
|
128
|
+
end
|
108
129
|
end
|
109
130
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Seiten
|
2
|
+
class PageCollection
|
3
|
+
attr_accessor :navigation_id, :pages
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@navigation_id = options[:navigation_id]
|
7
|
+
@pages = options[:pages] || []
|
8
|
+
end
|
9
|
+
|
10
|
+
def navigation
|
11
|
+
Seiten::Navigation.find_by(id: navigation_id)
|
12
|
+
end
|
13
|
+
|
14
|
+
def build(options = {})
|
15
|
+
Seiten::PageCollectionBuilder.call(self, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def all
|
19
|
+
pages.to_a
|
20
|
+
end
|
21
|
+
|
22
|
+
def find(id)
|
23
|
+
find_by(id: id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_by(params)
|
27
|
+
@find_by ||= {}
|
28
|
+
return @find_by[params] if @find_by.key?(params)
|
29
|
+
|
30
|
+
@find_by[params] = pages.find do |page|
|
31
|
+
params.all? do |k, v|
|
32
|
+
page.send(k) == v
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def where(params)
|
38
|
+
@where ||= {}
|
39
|
+
return @where[params] if @where.key?(params)
|
40
|
+
|
41
|
+
@where[params] = pages.select do |page|
|
42
|
+
params.all? do |k, v|
|
43
|
+
page.send(k) == v
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def new(params = {})
|
49
|
+
page = Seiten::Page.new(params.merge(navigation_id: navigation_id))
|
50
|
+
pages << page
|
51
|
+
page
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Seiten
|
2
|
+
class PageCollectionBuilder
|
3
|
+
def self.call(page_collection, options={})
|
4
|
+
pages = options[:pages]
|
5
|
+
parent_id = options[:parent_id] # || nil
|
6
|
+
layout = options[:layout]
|
7
|
+
prefix_url = options[:prefix_url] || ""
|
8
|
+
|
9
|
+
@id ||= 1
|
10
|
+
@parsed_pages ||= []
|
11
|
+
|
12
|
+
pages.each_index do |i|
|
13
|
+
|
14
|
+
# Load page and set parent_id and generated page id
|
15
|
+
page = pages[i]
|
16
|
+
page["id"] = @id
|
17
|
+
page["parent_id"] = parent_id
|
18
|
+
page["layout"] ||= layout
|
19
|
+
|
20
|
+
# Increment generated id
|
21
|
+
@id += 1
|
22
|
+
|
23
|
+
# Build slug
|
24
|
+
raise Errors::PageError, "The `url` option can not be an external path. Use the `refer` option to link to external resources." if page["url"] && !!(page["url"].match(/^https?:\/\/.+/))
|
25
|
+
slug = Seiten::SlugBuilder.call(page, prefix_url) unless page['url'].is_a?(FalseClass)
|
26
|
+
|
27
|
+
# Set refer
|
28
|
+
if page["refer"]
|
29
|
+
if page["refer"].is_a?(TrueClass)
|
30
|
+
page["refer"] = "/" + Seiten::SlugBuilder.call(page["nodes"].first, page["slug"])
|
31
|
+
end
|
32
|
+
raise Errors::PageError, "The `refer` option must be `true` or an absolute or external path" if page["refer"] != true && page["refer"][0] != "/" && !(page["refer"].match(/^https?:\/\/.+/))
|
33
|
+
else
|
34
|
+
page["slug"] = slug
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set layout
|
38
|
+
if page["layout"]
|
39
|
+
if page["layout"].is_a?(String)
|
40
|
+
inherited_layout = page["layout"]
|
41
|
+
elsif page["layout"].is_a?(Hash)
|
42
|
+
if page["layout"]["inherit"]
|
43
|
+
inherited_layout = page["layout"]
|
44
|
+
else
|
45
|
+
inherited_layout = nil
|
46
|
+
end
|
47
|
+
page["layout"] = page["layout"]["name"]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Load children
|
52
|
+
if page["nodes"]
|
53
|
+
self.call(page_collection, pages: page["nodes"], parent_id: page["id"], prefix_url: slug, layout: inherited_layout, external: page["external"])
|
54
|
+
end
|
55
|
+
|
56
|
+
page_params = page.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
|
57
|
+
@parsed_pages << page_collection.new(page_params)
|
58
|
+
end
|
59
|
+
|
60
|
+
@parsed_pages
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/seiten/routes_helper.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
class ActionDispatch::Routing::Mapper
|
2
|
+
def seiten(*resources)
|
3
|
+
options = resources.extract_options!
|
4
|
+
options[:to] ||= 'seiten/pages#show'
|
2
5
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
end
|
6
|
+
resources.each do |resource|
|
7
|
+
resource_options = options.dup
|
8
|
+
|
9
|
+
resource_options[:as] ||= resource == :application ? :seiten_page : "seiten_#{resource}_page"
|
10
|
+
|
11
|
+
resource_options[:defaults] ||= {}
|
12
|
+
resource_options[:defaults][:navigation_id] = resource.to_s unless resource == :application
|
13
|
+
resource_options[:defaults][:slug] = ''
|
13
14
|
|
14
|
-
|
15
|
+
# NOTE: See https://github.com/rails/rails/issues/31228
|
16
|
+
resource_options[:constraints] ||= ->(req) { req.path.exclude? 'rails/active_storage' }
|
17
|
+
|
18
|
+
get '(*slug)', resource_options
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Seiten
|
2
|
+
class SlugBuilder
|
3
|
+
|
4
|
+
def self.call(page_options, prefix_url='')
|
5
|
+
page_options = page_options.with_indifferent_access
|
6
|
+
title = page_options['title']
|
7
|
+
url = page_options['url']
|
8
|
+
root = page_options['root']
|
9
|
+
|
10
|
+
# if url is nil parameterize title otherwise just use url
|
11
|
+
slug = url.nil? ? title.parameterize : url
|
12
|
+
|
13
|
+
# prepend prefix_url if slug is not root or external url
|
14
|
+
unless slug[0] == "/" || !!(slug.match(/^https?:\/\/.+/)) || !prefix_url.present?
|
15
|
+
slug = "#{prefix_url}/#{slug}"
|
16
|
+
end
|
17
|
+
|
18
|
+
# return empty string if page slug is /
|
19
|
+
if slug == "/" || root == true
|
20
|
+
slug = ""
|
21
|
+
end
|
22
|
+
|
23
|
+
# remove leading slash if present
|
24
|
+
if slug
|
25
|
+
slug = slug[1..-1] if slug[0] == "/"
|
26
|
+
end
|
27
|
+
|
28
|
+
slug
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/seiten/version.rb
CHANGED