seiten 0.0.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Rakefile +1 -0
- data/app/controllers/seiten/pages_controller.rb +2 -23
- 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 +82 -40
- 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.yml → navigations/application.en.yml} +21 -5
- 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 +1632 -8652
- data/test/dummy/log/test.log +43833 -13664
- 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 +136 -94
- data/app/helpers/seiten_helper.rb +0 -46
- data/lib/seiten/controllers/helpers.rb +0 -16
- data/lib/seiten/page_store.rb +0 -150
- 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/en.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/dummy/tmp/pids/server.pid +0 -1
- data/test/integration/i18n_test.rb +0 -37
- data/test/integration/redirect_test.rb +0 -15
- data/test/page_test.rb +0 -74
- data/test/seiten_test.rb +0 -9
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,30 +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
|
-
@title = current_page.title
|
9
|
-
|
10
|
-
if params[:page]
|
11
|
-
filename = params[:page]
|
12
|
-
else
|
13
|
-
filename = Seiten.config[:root_page_filename]
|
14
|
-
end
|
15
|
-
|
16
|
-
if File.exists? Seiten::PageStore.current.file_path(filename: "#{filename}.html.erb", locale: I18n.locale)
|
17
|
-
file = Seiten::PageStore.current.file_path(filename: filename, locale: I18n.locale)
|
18
|
-
else
|
19
|
-
file = Seiten::PageStore.current.file_path(filename: filename)
|
20
|
-
end
|
21
|
-
|
22
|
-
if current_page.layout
|
23
|
-
render file: file, layout: current_page.layout
|
24
|
-
else
|
25
|
-
render file: file
|
26
|
-
end
|
27
|
-
end
|
6
|
+
render_seiten_page
|
28
7
|
end
|
29
8
|
end
|
30
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,63 +1,83 @@
|
|
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
|
-
@
|
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 ||= {}
|
15
21
|
end
|
16
22
|
|
17
|
-
|
23
|
+
def navigation
|
24
|
+
Seiten::Navigation.find_by(id: navigation_id)
|
25
|
+
end
|
18
26
|
|
19
|
-
|
20
|
-
|
21
|
-
|
27
|
+
# returns true if slug starts with http:// or https://
|
28
|
+
def external?
|
29
|
+
!!(slug.match(/^https?:\/\/.+/))
|
30
|
+
end
|
22
31
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
32
|
+
# get parent of page
|
33
|
+
def parent
|
34
|
+
navigation.pages.find(parent_id)
|
35
|
+
end
|
27
36
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
37
|
+
def parent?
|
38
|
+
parent.present?
|
39
|
+
end
|
32
40
|
|
33
|
-
|
34
|
-
|
35
|
-
if slug
|
36
|
-
slug = slug[1..-1] if slug[0] == "/"
|
37
|
-
end
|
38
|
-
all.select { |page| page.slug == slug }.first
|
39
|
-
end
|
41
|
+
def ancestors
|
42
|
+
return @ancestors unless @ancestors.nil?
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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?
|
49
52
|
end
|
50
53
|
|
54
|
+
@ancestors
|
51
55
|
end
|
52
56
|
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
+
|
65
|
+
# get root page of current page branch
|
66
|
+
def root
|
67
|
+
if self.parent?
|
68
|
+
self.parent.root
|
69
|
+
else
|
70
|
+
self
|
71
|
+
end
|
56
72
|
end
|
57
73
|
|
58
74
|
# get children of page
|
59
75
|
def children
|
60
|
-
|
76
|
+
navigation.pages.where(parent_id: id)
|
77
|
+
end
|
78
|
+
|
79
|
+
def children?
|
80
|
+
navigation.pages.find_by(parent_id: id).present?
|
61
81
|
end
|
62
82
|
|
63
83
|
# true if child is children of page
|
@@ -84,5 +104,27 @@ module Seiten
|
|
84
104
|
end
|
85
105
|
end
|
86
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
|
87
129
|
end
|
88
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