cmor_cms 0.0.1.pre
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +88 -0
- data/Rakefile +19 -0
- data/app/assets/javascripts/cmor/cms/application.js +1 -0
- data/app/assets/javascripts/cmor/cms/application/navigations.js.coffee +4 -0
- data/app/assets/javascripts/cmor_cms.js +1 -0
- data/app/assets/stylesheets/cmor/cms/application.css +3 -0
- data/app/assets/stylesheets/cmor/cms/application/keep.css +0 -0
- data/app/assets/stylesheets/cmor_cms.css +3 -0
- data/app/controllers/cmor/cms/page_controller.rb +54 -0
- data/app/importers/navigation.rb +27 -0
- data/app/importers/navigation_item.rb +61 -0
- data/app/importers/page.rb +38 -0
- data/app/models/cmor/cms/content_block.rb +14 -0
- data/app/models/cmor/cms/content_box.rb +12 -0
- data/app/models/cmor/cms/navigation.rb +18 -0
- data/app/models/cmor/cms/navigation_item.rb +86 -0
- data/app/models/cmor/cms/page.rb +29 -0
- data/app/models/cmor/cms/partial.rb +15 -0
- data/app/models/cmor/cms/template.rb +13 -0
- data/app/models/concerns/model/cmor/cms/navigation_item/properties_concern.rb +25 -0
- data/app/resolvers/cmor/cms/page_resolver.rb +61 -0
- data/app/resolvers/cmor/cms/partial_resolver.rb +29 -0
- data/app/resolvers/cmor/cms/template_resolver.rb +29 -0
- data/app/services/cmor/cms/add_homepages_service.rb +79 -0
- data/app/services/cmor/cms/create_navigation_service.rb +49 -0
- data/app/services/cmor/cms/import_partials_service.rb +126 -0
- data/app/template_handlers/action_view/template/handlers/textile.rb +26 -0
- data/app/view_helpers/cmor/cms/application_view_helper.rb +36 -0
- data/app/view_helpers/cmor/cms/navigation_view_helper.rb +87 -0
- data/app/view_helpers/cmor/cms/page_view_helper.rb +34 -0
- data/app/views/cmor/cms/_link_to_top.html.erb +5 -0
- data/app/views/cmor/cms/page/fallback.html.erb +2 -0
- data/app/views/cmor/cms/page/fallback.txt +1 -0
- data/config/initializers/assets.rb +1 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/initializers/simple_navigation.rb +1 -0
- data/config/initializers/textile_support.rb +3 -0
- data/config/locales/de.yml +140 -0
- data/config/locales/en.yml +140 -0
- data/config/navigation.rb +0 -0
- data/config/routes.rb +6 -0
- data/db/migrate/002_create_cmor_cms_pages.rb +17 -0
- data/db/migrate/003_create_cmor_cms_templates.rb +14 -0
- data/db/migrate/004_create_cmor_cms_partials.rb +15 -0
- data/db/migrate/005_create_cmor_cms_navigations.rb +13 -0
- data/db/migrate/006_create_cmor_cms_navigation_items.rb +29 -0
- data/db/migrate/007_create_cmor_cms_content_boxes.rb +9 -0
- data/db/migrate/008_create_cmor_cms_content_blocks.rb +15 -0
- data/lib/cmor/cms.rb +23 -0
- data/lib/cmor/cms/action_view/template_patch.rb +18 -0
- data/lib/cmor/cms/action_view/template_renderer_patch.rb +45 -0
- data/lib/cmor/cms/configuration.rb +35 -0
- data/lib/cmor/cms/controller_extensions/page_resolver.rb +12 -0
- data/lib/cmor/cms/controller_extensions/partial_resolver.rb +12 -0
- data/lib/cmor/cms/controller_extensions/template_resolver.rb +12 -0
- data/lib/cmor/cms/database_resolver.rb +99 -0
- data/lib/cmor/cms/database_template.rb +70 -0
- data/lib/cmor/cms/engine.rb +16 -0
- data/lib/cmor/cms/version.rb +7 -0
- data/lib/cmor_cms.rb +8 -0
- data/lib/generators/cmor/cms/install/install_generator.rb +34 -0
- data/lib/generators/cmor/cms/install/templates/initializer.rb +53 -0
- data/lib/generators/cmor/cms/install/templates/routes.source +4 -0
- data/lib/tasks/cmor_cms_tasks.rake +15 -0
- data/spec/factories/cmor/cms/content_block.rb +7 -0
- data/spec/factories/cmor/cms/content_box.rb +5 -0
- data/spec/factories/cmor/cms/navigation_items.rb +16 -0
- data/spec/factories/cmor/cms/navigations.rb +6 -0
- data/spec/factories/cmor/cms/pages.rb +8 -0
- data/spec/factories/cmor/cms/partials.rb +7 -0
- data/spec/factories/cmor/cms/templates.rb +7 -0
- metadata +465 -0
File without changes
|
data/config/routes.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateCmorCmsPages < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
create_table :cmor_cms_pages do |t|
|
4
|
+
t.string :basename
|
5
|
+
t.string :pathname
|
6
|
+
t.string :title
|
7
|
+
t.text :meta_description
|
8
|
+
t.text :body
|
9
|
+
t.string :layout
|
10
|
+
t.string :locale
|
11
|
+
t.string :format
|
12
|
+
t.string :handler
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateCmorCmsTemplates < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
create_table :cmor_cms_templates do |t|
|
4
|
+
t.string :basename
|
5
|
+
t.string :pathname
|
6
|
+
t.text :body
|
7
|
+
t.string :locale
|
8
|
+
t.string :format
|
9
|
+
t.string :handler
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateCmorCmsPartials < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
create_table :cmor_cms_partials do |t|
|
4
|
+
t.string :basename
|
5
|
+
t.string :pathname
|
6
|
+
t.text :body
|
7
|
+
t.string :layout
|
8
|
+
t.string :locale
|
9
|
+
t.string :format
|
10
|
+
t.string :handler
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class CreateCmorCmsNavigationItems < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
create_table :cmor_cms_navigation_items do |t|
|
4
|
+
t.string :name
|
5
|
+
t.string :url
|
6
|
+
t.string :key
|
7
|
+
t.string :options
|
8
|
+
t.text :properties, null: true
|
9
|
+
|
10
|
+
# associations
|
11
|
+
t.references :navigation
|
12
|
+
t.references :page
|
13
|
+
|
14
|
+
# awesome nested set
|
15
|
+
t.references :parent
|
16
|
+
t.integer :children_count, default: 0, null: false
|
17
|
+
t.integer :lft
|
18
|
+
t.integer :rgt
|
19
|
+
t.integer :depth
|
20
|
+
|
21
|
+
# friendly id
|
22
|
+
t.string :slug
|
23
|
+
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
add_index :cmor_cms_navigation_items, :navigation_id
|
27
|
+
add_index :cmor_cms_navigation_items, :parent_id
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateCmorCmsContentBlocks < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
create_table :cmor_cms_content_blocks do |t|
|
4
|
+
t.text :body
|
5
|
+
|
6
|
+
# associations
|
7
|
+
t.references :page
|
8
|
+
t.references :content_box
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
add_index :cmor_cms_content_blocks, :page_id
|
13
|
+
add_index :cmor_cms_content_blocks, :content_box_id
|
14
|
+
end
|
15
|
+
end
|
data/lib/cmor/cms.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'cmor/cms/action_view/template_patch'
|
2
|
+
require 'cmor/cms/action_view/template_renderer_patch'
|
3
|
+
|
4
|
+
require 'cmor/cms/engine'
|
5
|
+
require 'cmor/cms/configuration'
|
6
|
+
|
7
|
+
require 'cmor/cms/database_template'
|
8
|
+
|
9
|
+
require 'cmor/cms/controller_extensions/page_resolver'
|
10
|
+
require 'cmor/cms/controller_extensions/partial_resolver'
|
11
|
+
require 'cmor/cms/controller_extensions/template_resolver'
|
12
|
+
|
13
|
+
module Cmor
|
14
|
+
module Cms
|
15
|
+
extend Configuration
|
16
|
+
|
17
|
+
def self.table_name_prefix
|
18
|
+
'cmor_cms_'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Cmor.configure { |c| c.register_configuration(:cms, Cmor::Cms) }
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ActionView
|
2
|
+
module TemplatePatch
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
attr_accessor :layout
|
6
|
+
|
7
|
+
alias_method :original_initialize, :initialize
|
8
|
+
|
9
|
+
def initialize(source, identifier, handler, details)
|
10
|
+
@layout = details[:layout] if details.key?(:layout)
|
11
|
+
original_initialize(source, identifier, handler, details)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ActionView::Template.send(:include, ActionView::TemplatePatch)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActionView
|
2
|
+
module TemplateRendererPatch
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
alias_method :original_render, :render
|
6
|
+
if Rails::VERSION::MAJOR < 4
|
7
|
+
def render(context, options)
|
8
|
+
@view = context
|
9
|
+
@details = extract_details(options)
|
10
|
+
extract_format(options[:file] || options[:template], @details)
|
11
|
+
template = determine_template(options)
|
12
|
+
context = @lookup_context
|
13
|
+
|
14
|
+
unless context.rendered_format
|
15
|
+
context.formats = template.formats unless template.formats.empty?
|
16
|
+
context.rendered_format = context.formats.first
|
17
|
+
end
|
18
|
+
|
19
|
+
layout = template.layout if template.respond_to?(:layout)
|
20
|
+
layout ||= options[:layout]
|
21
|
+
|
22
|
+
render_template(template, layout, options[:locals])
|
23
|
+
end
|
24
|
+
elsif Rails::VERSION::MAJOR < 5
|
25
|
+
def render(context, options)
|
26
|
+
@view = context
|
27
|
+
@details = extract_details(options)
|
28
|
+
template = determine_template(options)
|
29
|
+
|
30
|
+
prepend_formats(template.formats)
|
31
|
+
|
32
|
+
@lookup_context.rendered_format ||= (template.formats.first || formats.first)
|
33
|
+
|
34
|
+
layout = template.layout if template.respond_to?(:layout)
|
35
|
+
layout ||= options[:layout]
|
36
|
+
|
37
|
+
render_template(template, layout, options[:locals])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
ActionView::TemplateRenderer.send(:include, ActionView::TemplateRendererPatch)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
3
|
+
require 'active_support/hash_with_indifferent_access'
|
4
|
+
|
5
|
+
module Cmor
|
6
|
+
module Cms
|
7
|
+
module Configuration
|
8
|
+
def configure
|
9
|
+
yield self
|
10
|
+
end
|
11
|
+
|
12
|
+
mattr_accessor :base_controller do
|
13
|
+
'ApplicationController'
|
14
|
+
end
|
15
|
+
|
16
|
+
mattr_accessor :default_handlers do
|
17
|
+
HashWithIndifferentAccess.new
|
18
|
+
end
|
19
|
+
|
20
|
+
mattr_accessor :site_title do
|
21
|
+
''
|
22
|
+
end
|
23
|
+
|
24
|
+
mattr_accessor :navigation_item_properties do
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
|
28
|
+
mattr_accessor(:navigation_locale_fallback) { ->(navigation_name, locale) {false} }
|
29
|
+
|
30
|
+
def default_handlers=(default_handlers)
|
31
|
+
@@default_handlers = HashWithIndifferentAccess.new(default_handlers)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Cmor
|
2
|
+
module Cms
|
3
|
+
module ControllerExtensions
|
4
|
+
module PageResolver
|
5
|
+
def self.included(base)
|
6
|
+
# add the page resolver
|
7
|
+
base.prepend_view_path ::Cmor::Cms::PageResolver.instance unless base.view_paths.include?(::Cmor::Cms::PageResolver.instance)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Cmor
|
2
|
+
module Cms
|
3
|
+
module ControllerExtensions
|
4
|
+
module PartialResolver
|
5
|
+
def self.included(base)
|
6
|
+
# add the partial resolver
|
7
|
+
base.prepend_view_path ::Cmor::Cms::PartialResolver.instance unless base.view_paths.include?(::Cmor::Cms::PartialResolver.instance)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Cmor
|
2
|
+
module Cms
|
3
|
+
module ControllerExtensions
|
4
|
+
module TemplateResolver
|
5
|
+
def self.included(base)
|
6
|
+
# add the template resolver
|
7
|
+
base.prepend_view_path ::Cmor::Cms::TemplateResolver.instance unless base.view_paths.include?(::Cmor::Cms::TemplateResolver.instance)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Cmor
|
2
|
+
module Cms
|
3
|
+
module DatabaseResolver
|
4
|
+
# Include hook for class methods
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
# class methods go here
|
10
|
+
module ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
# instance methods go here
|
14
|
+
def find_templates(name, prefix, partial, details, outside_app_allowed = false)
|
15
|
+
return [] unless resolve(partial)
|
16
|
+
|
17
|
+
conditions = {
|
18
|
+
pathname: assert_slashs(prefix.to_s),
|
19
|
+
basename: normalize_basename(name),
|
20
|
+
locale: normalize_array(details[:locale]).first,
|
21
|
+
format: normalize_array(details[:formats]).first,
|
22
|
+
handler: normalize_array(details[:handlers])
|
23
|
+
}
|
24
|
+
|
25
|
+
format = conditions.delete(:format)
|
26
|
+
locale = conditions.delete(:locale)
|
27
|
+
|
28
|
+
query = template_class.constantize.where(conditions)
|
29
|
+
|
30
|
+
# 2) Check for templates with the given format or format is nil
|
31
|
+
query = query.where(["format = ? OR format = '' OR format IS NULL", format])
|
32
|
+
|
33
|
+
# 3) Ensure templates with format come first
|
34
|
+
query = query.order('format DESC')
|
35
|
+
|
36
|
+
# 4) Check for templates with the given locale or locale is nil
|
37
|
+
query = query.where(["locale = ? OR locale = '' OR locale IS NULL", locale])
|
38
|
+
|
39
|
+
# 5) Ensure templates with locale come first
|
40
|
+
query = query.order('locale DESC')
|
41
|
+
|
42
|
+
# 6) Now trigger the query passing on conditions to initialization
|
43
|
+
query.map do |record|
|
44
|
+
initialize_template(record, details)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Initialize an ActionView::Template object based on the record found.
|
49
|
+
def initialize_template(record, details)
|
50
|
+
source = build_source(record)
|
51
|
+
identifier = "#{record.class} - #{record.id} - #{record.pathname}#{record.basename}"
|
52
|
+
handler = ::ActionView::Template.registered_template_handler(record.handler)
|
53
|
+
|
54
|
+
# 5) Check for the record.format, if none is given, try the template
|
55
|
+
# handler format and fallback to the one given on conditions
|
56
|
+
format = record.format && Mime[record.format]
|
57
|
+
format ||= handler.default_format if handler.respond_to?(:default_format)
|
58
|
+
format ||= details[:formats]
|
59
|
+
details = {
|
60
|
+
format: format,
|
61
|
+
updated_at: record.updated_at,
|
62
|
+
virtual_path: "#{record.pathname}#{record.basename}"
|
63
|
+
}
|
64
|
+
|
65
|
+
details[:layout] = record.layout if record.respond_to?(:layout) && record.layout.present?
|
66
|
+
|
67
|
+
::ActionView::Template.new(source, identifier, handler, details)
|
68
|
+
end
|
69
|
+
|
70
|
+
def assert_slashs(prefix)
|
71
|
+
output = prefix.dup
|
72
|
+
output << '/' unless output.end_with?('/')
|
73
|
+
output = '/' << output unless output.start_with?('/')
|
74
|
+
output
|
75
|
+
end
|
76
|
+
|
77
|
+
# Normalize arrays by converting all symbols to strings.
|
78
|
+
def normalize_array(array)
|
79
|
+
array.map(&:to_s)
|
80
|
+
end
|
81
|
+
|
82
|
+
def build_source
|
83
|
+
fail 'call to abstract method #build_source'
|
84
|
+
end
|
85
|
+
|
86
|
+
def normalize_basename(_basename)
|
87
|
+
fail 'call to abstract method #normalize_basename'
|
88
|
+
end
|
89
|
+
|
90
|
+
def resolve(_partial_flag)
|
91
|
+
fail 'call to abstract method #resolve'
|
92
|
+
end
|
93
|
+
|
94
|
+
def template_class
|
95
|
+
fail 'call to abstract method #template_class'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Cmor
|
2
|
+
module Cms
|
3
|
+
module DatabaseTemplate
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
|
7
|
+
# associations
|
8
|
+
base.belongs_to :cmor_cms_folder,
|
9
|
+
class_name: 'Cmor::Cms::Folder',
|
10
|
+
foreign_key: 'cmor_cms_folder_id',
|
11
|
+
optional: true
|
12
|
+
|
13
|
+
# callbacks
|
14
|
+
base.after_initialize :set_defaults
|
15
|
+
base.before_validation :assert_trailing_slash_on_pathname
|
16
|
+
base.after_save :clear_resolver_cache
|
17
|
+
|
18
|
+
# validations
|
19
|
+
base.validates :basename, presence: true,
|
20
|
+
uniqueness: { scope: [:pathname, :locale, :format, :handler] }
|
21
|
+
base.validates :handler, inclusion: ActionView::Template::Handlers.extensions.map(&:to_s)
|
22
|
+
base.validates :locale, inclusion: I18n.available_locales.map(&:to_s),
|
23
|
+
allow_nil: true,
|
24
|
+
allow_blank: true
|
25
|
+
base.validates :format, inclusion: Mime::SET.symbols.map(&:to_s),
|
26
|
+
allow_nil: true,
|
27
|
+
allow_blank: true
|
28
|
+
base.validates :pathname, presence: true
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
end
|
33
|
+
|
34
|
+
def human
|
35
|
+
"#{self.class.name}: #{path_and_filename}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def filename
|
39
|
+
filename = basename.nil? ? '' : basename.dup
|
40
|
+
filename << ".#{locale}" if locale.present?
|
41
|
+
filename << ".#{format}" if format.present?
|
42
|
+
filename << ".#{handler}" if handler.present?
|
43
|
+
filename
|
44
|
+
end
|
45
|
+
|
46
|
+
def path_and_filename
|
47
|
+
"#{pathname}#{filename}"
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def assert_trailing_slash_on_pathname
|
53
|
+
self.pathname = '/' and return if pathname.blank?
|
54
|
+
pathname << '/' unless pathname.end_with?('/')
|
55
|
+
end
|
56
|
+
|
57
|
+
def clear_resolver_cache
|
58
|
+
klass = "#{self.class.name}Resolver"
|
59
|
+
klass.constantize.instance.clear_cache
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_defaults
|
63
|
+
if new_record?
|
64
|
+
self.locale ||= I18n.default_locale.to_s
|
65
|
+
self.handler ||= Cmor::Cms::Configuration.default_handlers[self.class.name.demodulize.underscore.to_sym].to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|