cmor_cms 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
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