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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +88 -0
  4. data/Rakefile +19 -0
  5. data/app/assets/javascripts/cmor/cms/application.js +1 -0
  6. data/app/assets/javascripts/cmor/cms/application/navigations.js.coffee +4 -0
  7. data/app/assets/javascripts/cmor_cms.js +1 -0
  8. data/app/assets/stylesheets/cmor/cms/application.css +3 -0
  9. data/app/assets/stylesheets/cmor/cms/application/keep.css +0 -0
  10. data/app/assets/stylesheets/cmor_cms.css +3 -0
  11. data/app/controllers/cmor/cms/page_controller.rb +54 -0
  12. data/app/importers/navigation.rb +27 -0
  13. data/app/importers/navigation_item.rb +61 -0
  14. data/app/importers/page.rb +38 -0
  15. data/app/models/cmor/cms/content_block.rb +14 -0
  16. data/app/models/cmor/cms/content_box.rb +12 -0
  17. data/app/models/cmor/cms/navigation.rb +18 -0
  18. data/app/models/cmor/cms/navigation_item.rb +86 -0
  19. data/app/models/cmor/cms/page.rb +29 -0
  20. data/app/models/cmor/cms/partial.rb +15 -0
  21. data/app/models/cmor/cms/template.rb +13 -0
  22. data/app/models/concerns/model/cmor/cms/navigation_item/properties_concern.rb +25 -0
  23. data/app/resolvers/cmor/cms/page_resolver.rb +61 -0
  24. data/app/resolvers/cmor/cms/partial_resolver.rb +29 -0
  25. data/app/resolvers/cmor/cms/template_resolver.rb +29 -0
  26. data/app/services/cmor/cms/add_homepages_service.rb +79 -0
  27. data/app/services/cmor/cms/create_navigation_service.rb +49 -0
  28. data/app/services/cmor/cms/import_partials_service.rb +126 -0
  29. data/app/template_handlers/action_view/template/handlers/textile.rb +26 -0
  30. data/app/view_helpers/cmor/cms/application_view_helper.rb +36 -0
  31. data/app/view_helpers/cmor/cms/navigation_view_helper.rb +87 -0
  32. data/app/view_helpers/cmor/cms/page_view_helper.rb +34 -0
  33. data/app/views/cmor/cms/_link_to_top.html.erb +5 -0
  34. data/app/views/cmor/cms/page/fallback.html.erb +2 -0
  35. data/app/views/cmor/cms/page/fallback.txt +1 -0
  36. data/config/initializers/assets.rb +1 -0
  37. data/config/initializers/mime_types.rb +1 -0
  38. data/config/initializers/simple_navigation.rb +1 -0
  39. data/config/initializers/textile_support.rb +3 -0
  40. data/config/locales/de.yml +140 -0
  41. data/config/locales/en.yml +140 -0
  42. data/config/navigation.rb +0 -0
  43. data/config/routes.rb +6 -0
  44. data/db/migrate/002_create_cmor_cms_pages.rb +17 -0
  45. data/db/migrate/003_create_cmor_cms_templates.rb +14 -0
  46. data/db/migrate/004_create_cmor_cms_partials.rb +15 -0
  47. data/db/migrate/005_create_cmor_cms_navigations.rb +13 -0
  48. data/db/migrate/006_create_cmor_cms_navigation_items.rb +29 -0
  49. data/db/migrate/007_create_cmor_cms_content_boxes.rb +9 -0
  50. data/db/migrate/008_create_cmor_cms_content_blocks.rb +15 -0
  51. data/lib/cmor/cms.rb +23 -0
  52. data/lib/cmor/cms/action_view/template_patch.rb +18 -0
  53. data/lib/cmor/cms/action_view/template_renderer_patch.rb +45 -0
  54. data/lib/cmor/cms/configuration.rb +35 -0
  55. data/lib/cmor/cms/controller_extensions/page_resolver.rb +12 -0
  56. data/lib/cmor/cms/controller_extensions/partial_resolver.rb +12 -0
  57. data/lib/cmor/cms/controller_extensions/template_resolver.rb +12 -0
  58. data/lib/cmor/cms/database_resolver.rb +99 -0
  59. data/lib/cmor/cms/database_template.rb +70 -0
  60. data/lib/cmor/cms/engine.rb +16 -0
  61. data/lib/cmor/cms/version.rb +7 -0
  62. data/lib/cmor_cms.rb +8 -0
  63. data/lib/generators/cmor/cms/install/install_generator.rb +34 -0
  64. data/lib/generators/cmor/cms/install/templates/initializer.rb +53 -0
  65. data/lib/generators/cmor/cms/install/templates/routes.source +4 -0
  66. data/lib/tasks/cmor_cms_tasks.rake +15 -0
  67. data/spec/factories/cmor/cms/content_block.rb +7 -0
  68. data/spec/factories/cmor/cms/content_box.rb +5 -0
  69. data/spec/factories/cmor/cms/navigation_items.rb +16 -0
  70. data/spec/factories/cmor/cms/navigations.rb +6 -0
  71. data/spec/factories/cmor/cms/pages.rb +8 -0
  72. data/spec/factories/cmor/cms/partials.rb +7 -0
  73. data/spec/factories/cmor/cms/templates.rb +7 -0
  74. metadata +465 -0
File without changes
@@ -0,0 +1,6 @@
1
+ Cmor::Cms::Engine.routes.draw do
2
+ localized do
3
+ get '/*page', to: 'page#respond', as: :page
4
+ get '/', to: 'page#respond', page: 'home'
5
+ end
6
+ end
@@ -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,13 @@
1
+ class CreateCmorCmsNavigations < ActiveRecord::Migration[4.2]
2
+ def change
3
+ create_table :cmor_cms_navigations do |t|
4
+ t.string :locale
5
+ t.string :name
6
+
7
+ # friendly id
8
+ t.string :slug
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ 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,9 @@
1
+ class CreateCmorCmsContentBoxes < ActiveRecord::Migration[4.2]
2
+ def change
3
+ create_table :cmor_cms_content_boxes do |t|
4
+ t.string :name
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ 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
@@ -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