ecm_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 (55) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +55 -0
  3. data/Rakefile +27 -0
  4. data/app/assets/stylesheets/ecm_cms.css.less +3 -0
  5. data/app/controllers/ecm/cms/page_controller.rb +11 -0
  6. data/app/helpers/ecm/cms_helper.rb +42 -0
  7. data/app/models/ecm/cms.rb +5 -0
  8. data/app/models/ecm/cms/folder.rb +31 -0
  9. data/app/models/ecm/cms/navigation.rb +24 -0
  10. data/app/models/ecm/cms/navigation_item.rb +93 -0
  11. data/app/models/ecm/cms/page.rb +42 -0
  12. data/app/models/ecm/cms/partial.rb +31 -0
  13. data/app/models/ecm/cms/template.rb +31 -0
  14. data/config/locales/ecm.cms.de.yml +17 -0
  15. data/config/locales/ecm.cms.en.yml +17 -0
  16. data/config/locales/ecm.cms.navigation.de.yml +16 -0
  17. data/config/locales/ecm.cms.navigation.en.yml +16 -0
  18. data/config/locales/ecm.cms.navigation_item.de.yml +23 -0
  19. data/config/locales/ecm.cms.navigation_item.en.yml +23 -0
  20. data/config/locales/ecm.cms.page.de.yml +26 -0
  21. data/config/locales/ecm.cms.page.en.yml +26 -0
  22. data/config/locales/ecm.cms.partial.de.yml +22 -0
  23. data/config/locales/ecm.cms.partial.en.yml +22 -0
  24. data/config/locales/ecm.cms.template.de.yml +22 -0
  25. data/config/locales/ecm.cms.template.en.yml +22 -0
  26. data/db/migrate/001_create_ecm_cms_folders.rb +21 -0
  27. data/db/migrate/002_create_ecm_cms_pages.rb +19 -0
  28. data/db/migrate/003_create_ecm_cms_templates.rb +18 -0
  29. data/db/migrate/004_create_ecm_cms_partials.rb +19 -0
  30. data/db/migrate/005_create_ecm_cms_navigations.rb +13 -0
  31. data/db/migrate/006_create_ecm_cms_navigation_items.rb +28 -0
  32. data/lib/ecm/cms/action_view/template/handlers/textile.rb +18 -0
  33. data/lib/ecm/cms/action_view/template_patch.rb +19 -0
  34. data/lib/ecm/cms/action_view/template_renderer_patch.rb +30 -0
  35. data/lib/ecm/cms/active_admin/ecm_cms_navigation_items.rb +45 -0
  36. data/lib/ecm/cms/active_admin/ecm_cms_navigations.rb +61 -0
  37. data/lib/ecm/cms/active_admin/ecm_cms_pages.rb +70 -0
  38. data/lib/ecm/cms/active_admin/ecm_cms_partials.rb +47 -0
  39. data/lib/ecm/cms/active_admin/ecm_cms_templates.rb +46 -0
  40. data/lib/ecm/cms/configuration.rb +22 -0
  41. data/lib/ecm/cms/database_resolver.rb +101 -0
  42. data/lib/ecm/cms/database_template.rb +67 -0
  43. data/lib/ecm/cms/engine.rb +22 -0
  44. data/lib/ecm/cms/resolvers/ecm/cms/page_resolver.rb +37 -0
  45. data/lib/ecm/cms/resolvers/ecm/cms/partial_resolver.rb +30 -0
  46. data/lib/ecm/cms/resolvers/ecm/cms/template_resolver.rb +30 -0
  47. data/lib/ecm/cms/routing.rb +13 -0
  48. data/lib/ecm/cms/version.rb +5 -0
  49. data/lib/ecm_cms.rb +30 -0
  50. data/lib/generators/ecm/cms/install/install_generator.rb +15 -0
  51. data/lib/generators/ecm/cms/install/templates/ecm_cms.rb +7 -0
  52. data/lib/generators/ecm/cms/locales/locales_generator.rb +32 -0
  53. data/lib/rails_tools/i18n_controller.rb +24 -0
  54. data/lib/tasks/ecm_cms_tasks.rake +171 -0
  55. metadata +463 -0
@@ -0,0 +1,45 @@
1
+ ActiveAdmin.register Ecm::Cms::NavigationItem do
2
+ # Add member actions for positioning.
3
+ sortable_tree_member_actions
4
+
5
+ # Menu
6
+ menu :parent => Proc.new { I18n.t('ecm.cms.active_admin.menu') }.call
7
+
8
+ form do |f|
9
+ f.inputs do
10
+ f.input :ecm_cms_navigation
11
+ f.input :parent
12
+ f.input :name
13
+ end
14
+
15
+ f.inputs do
16
+ f.input :ecm_cms_page
17
+ f.input :url
18
+ end
19
+
20
+ f.inputs do
21
+ f.input :key
22
+ f.input :options
23
+ end
24
+
25
+ f.actions
26
+ end
27
+
28
+ index :as => :nested_set do
29
+ selectable_column
30
+ sortable_tree_columns
31
+ column :ecm_cms_navigation
32
+ column :name
33
+ column :url
34
+ column :ecm_cms_page do |ni|
35
+ if ni.ecm_cms_page.blank?
36
+ link_to(I18n.t('active_admin.new'), new_admin_ecm_cms_page_path({:ecm_cms_page => ni.params_for_new_page}))
37
+ else
38
+ link_to(ni.ecm_cms_page.title, [:admin, ni.ecm_cms_page])
39
+ end
40
+ end
41
+ column :created_at
42
+ column :updated_at
43
+ default_actions
44
+ end
45
+ end
@@ -0,0 +1,61 @@
1
+ include ActiveAdmin::AwesomeNestedSet::Helper
2
+
3
+ ActiveAdmin.register Ecm::Cms::Navigation do
4
+ # Filters
5
+ filter :locale, :as => :select, :collection => I18n.available_locales.map(&:to_s)
6
+ filter :name
7
+
8
+ # Menu
9
+ menu :parent => Proc.new { I18n.t('ecm.cms.active_admin.menu') }.call
10
+
11
+ form do |f|
12
+ f.inputs do
13
+ f.input :locale, :as => :select, :collection => I18n.available_locales.map(&:to_s)
14
+ f.input :name
15
+ end
16
+
17
+ f.actions
18
+ end
19
+
20
+ index do
21
+ selectable_column
22
+ column :name
23
+ column :locale
24
+ default_actions
25
+ end
26
+
27
+ show do
28
+ panel Ecm::Cms::Navigation.human_attribute_name(:ecm_cms_navigation_items) do
29
+ table_for ecm_cms_navigation.ecm_cms_navigation_items, :i18n => Ecm::Cms::NavigationItem do
30
+ sortable_tree_columns
31
+ column :name
32
+ column :url
33
+ column :ecm_cms_page do |ni|
34
+ if ni.ecm_cms_page.blank?
35
+ link_to(I18n.t('active_admin.new'), new_admin_ecm_cms_page_path({:ecm_cms_page => ni.params_for_new_page}))
36
+ else
37
+ link_to(ni.ecm_cms_page.title, [:admin, ni.ecm_cms_page])
38
+ end
39
+ end
40
+ column :created_at
41
+ column :updated_at
42
+
43
+ column do |ni|
44
+ link_to(I18n.t('active_admin.view'), [:admin, ni], :class => "member_link view_link") +
45
+ link_to(I18n.t('active_admin.edit'), [:edit, :admin, ni], :class => "member_link edit_link")
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ sidebar Ecm::Cms::Navigation.human_attribute_name(:details), :only => :show do
52
+ attributes_table_for ecm_cms_navigation do
53
+ row :locale
54
+ row :name
55
+ row :slug
56
+ row :created_at
57
+ row :updated_at
58
+ end
59
+ end # sidebar
60
+ end if defined?(::ActiveAdmin)
61
+
@@ -0,0 +1,70 @@
1
+ ActiveAdmin.register Ecm::Cms::Page do
2
+ # Menu
3
+ menu :parent => Proc.new { I18n.t('ecm.cms.active_admin.menu') }.call
4
+
5
+ form do |f|
6
+ f.inputs do
7
+ f.input :title
8
+ f.input :meta_description
9
+ f.input :body
10
+ end
11
+
12
+ f.inputs do
13
+ f.input :pathname
14
+ f.input :basename
15
+ f.input :locale, :as => :select, :collection => I18n.available_locales.map(&:to_s)
16
+ f.input :format, :as => :select, :collection => Mime::SET.symbols.map(&:to_s)
17
+ f.input :handler, :as => :select, :collection => ActionView::Template::Handlers.extensions.map(&:to_s)
18
+ end
19
+
20
+ f.inputs do
21
+ f.input :layout
22
+ end
23
+
24
+ I18n.available_locales.each do |locale|
25
+ Ecm::Cms::Navigation.where(:locale => locale).all.each do |navigation|
26
+ f.inputs do
27
+ f.input :ecm_cms_navigation_items,
28
+ :as => :check_boxes,
29
+ :collection => navigation.ecm_cms_navigation_items.joins(:ecm_cms_navigation).where(:ecm_cms_navigations => { :locale => locale }),
30
+ :label_method => :key # .all.collect { |i| "#{'--' * i.depth} #{i.name}" }
31
+ end
32
+ end
33
+ end
34
+
35
+ f.actions
36
+ end
37
+
38
+ index do
39
+ selectable_column
40
+ column :pathname
41
+ column :filename
42
+ column :title
43
+ column :home_page?
44
+ column :layout
45
+ column :ecm_cms_navigation_items
46
+ column :created_at
47
+ column :updated_at
48
+ default_actions
49
+ end
50
+
51
+ show do
52
+ panel Ecm::Cms::Page.human_attribute_name(:body) do
53
+ pre { ecm_cms_page.body }
54
+ end
55
+ end
56
+
57
+ sidebar Ecm::Cms::Page.human_attribute_name(:details), :only => :show do
58
+ attributes_table_for ecm_cms_page do
59
+ # row :ecm_cms_navigation_item
60
+ # row :folder
61
+ row :pathname
62
+ row :filename
63
+ row :home_page?
64
+ row :layout
65
+ row :created_at
66
+ row :updated_at
67
+ end
68
+ end # sidebar
69
+ end if defined?(::ActiveAdmin)
70
+
@@ -0,0 +1,47 @@
1
+ ActiveAdmin.register Ecm::Cms::Partial do
2
+ # Menu
3
+ menu :parent => Proc.new { I18n.t('ecm.cms.active_admin.menu') }.call
4
+
5
+ form do |f|
6
+ f.inputs do
7
+ f.input :body
8
+ end
9
+
10
+ f.inputs do
11
+ f.input :pathname
12
+ f.input :basename
13
+ f.input :locale, :as => :select, :collection => I18n.available_locales.map(&:to_s)
14
+ f.input :format, :as => :select, :collection => Mime::SET.symbols.map(&:to_s)
15
+ f.input :handler, :as => :select, :collection => ActionView::Template::Handlers.extensions.map(&:to_s)
16
+ end
17
+
18
+ f.actions
19
+ end
20
+
21
+ index do
22
+ selectable_column
23
+ column :pathname
24
+ column :filename
25
+ column :created_at
26
+ column :updated_at
27
+ default_actions
28
+ end
29
+
30
+ show do
31
+ panel Ecm::Cms::Partial.human_attribute_name(:body) do
32
+ pre { ecm_cms_partial.body }
33
+ end
34
+ end
35
+
36
+ sidebar Ecm::Cms::Partial.human_attribute_name(:details), :only => :show do
37
+ attributes_table_for ecm_cms_partial do
38
+ p ecm_cms_partial.inspect
39
+ # row :folder
40
+ row :pathname
41
+ row :filename
42
+ row :created_at
43
+ row :updated_at
44
+ end
45
+ end # sidebar
46
+ end
47
+
@@ -0,0 +1,46 @@
1
+ ActiveAdmin.register Ecm::Cms::Template do
2
+ # Menu
3
+ menu :parent => Proc.new { I18n.t('ecm.cms.active_admin.menu') }.call
4
+
5
+ form do |f|
6
+ f.inputs do
7
+ f.input :body
8
+ end
9
+
10
+ f.inputs do
11
+ f.input :pathname
12
+ f.input :basename
13
+ f.input :locale, :as => :select, :collection => I18n.available_locales.map(&:to_s)
14
+ f.input :format, :as => :select, :collection => Mime::SET.symbols.map(&:to_s)
15
+ f.input :handler, :as => :select, :collection => ActionView::Template::Handlers.extensions.map(&:to_s)
16
+ end
17
+
18
+ f.actions
19
+ end
20
+
21
+ index do
22
+ selectable_column
23
+ column :pathname
24
+ column :filename
25
+ column :created_at
26
+ column :updated_at
27
+ default_actions
28
+ end
29
+
30
+ show do
31
+ panel Ecm::Cms::Template.human_attribute_name(:body) do
32
+ pre { ecm_cms_template.body }
33
+ end
34
+ end
35
+
36
+ sidebar Ecm::Cms::Template.human_attribute_name(:details), :only => :show do
37
+ attributes_table_for ecm_cms_template do
38
+ # row :folder
39
+ row :pathname
40
+ row :filename
41
+ row :created_at
42
+ row :updated_at
43
+ end
44
+ end # sidebar
45
+ end
46
+
@@ -0,0 +1,22 @@
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 Ecm
6
+ module Cms
7
+ module Configuration
8
+ def configure
9
+ yield self
10
+ end
11
+
12
+ mattr_accessor :default_handlers
13
+ @@default_handlers = {}
14
+ def default_handlers=(default_handlers)
15
+ @@default_handlers = HashWithIndifferentAccess.new(default_handlers)
16
+ end
17
+
18
+ mattr_accessor :site_title
19
+ @@site_title = ''
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,101 @@
1
+ module Ecm
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)
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 = self.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 = ''", 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 = ''", 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
+
60
+ details = {
61
+ :format => format,
62
+ :updated_at => record.updated_at,
63
+ :virtual_path => "#{record.pathname}#{record.basename}"
64
+ }
65
+
66
+ details[:layout] = record.layout if record.layout.present?
67
+
68
+ ::ActionView::Template.new(source, identifier, handler, details)
69
+ end
70
+
71
+ def assert_slashs(prefix)
72
+ output = prefix.dup
73
+ output << '/' unless output.end_with?('/')
74
+ output = '/' << output unless output.start_with?('/')
75
+ return output
76
+ end
77
+
78
+ # Normalize arrays by converting all symbols to strings.
79
+ def normalize_array(array)
80
+ array.map(&:to_s)
81
+ end
82
+
83
+ def build_source
84
+ raise "call to abstract method #build_source"
85
+ end
86
+
87
+ def normalize_basename(basename)
88
+ raise "call to abstract method #normalize_basename"
89
+ end
90
+
91
+ def resolve(partial_flag)
92
+ raise "call to abstract method #resolve"
93
+ end
94
+
95
+ def template_class
96
+ raise "call to abstract method #template_class"
97
+ end
98
+ end
99
+ end
100
+ end
101
+
@@ -0,0 +1,67 @@
1
+ module Ecm
2
+ module Cms
3
+ module DatabaseTemplate
4
+ # Include hook for class methods
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+
8
+ # associations
9
+ base.belongs_to :ecm_cms_folder,
10
+ :class_name => 'Ecm::Cms::Folder',
11
+ :foreign_key => 'ecm_cms_folder_id'
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 => [:ecm_cms_folder_id , :locale] }
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
+ # class methods go here
32
+ module ClassMethods
33
+ # def bar
34
+ # puts 'class method'
35
+ # end
36
+ end
37
+
38
+ # instance methods go here
39
+ def filename
40
+ filename = basename.dup
41
+ filename << ".#{locale}" if locale.present?
42
+ filename << ".#{format}" if format.present?
43
+ filename << ".#{handler}" if handler.present?
44
+ filename
45
+ end
46
+
47
+ private
48
+
49
+ def assert_trailing_slash_on_pathname
50
+ self.pathname = '/' and return if self.pathname.blank?
51
+ self.pathname << '/' unless self.pathname.end_with?('/')
52
+ end
53
+
54
+ def clear_resolver_cache
55
+ Ecm::Cms::PageResolver.instance.clear_cache
56
+ end
57
+
58
+ def set_defaults
59
+ if self.new_record?
60
+ self.locale ||= I18n.default_locale.to_s
61
+ self.handler ||= Ecm::Cms::Configuration.default_handlers[:page].to_s
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+