ecm_cms 0.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +55 -0
- data/Rakefile +27 -0
- data/app/assets/stylesheets/ecm_cms.css.less +3 -0
- data/app/controllers/ecm/cms/page_controller.rb +11 -0
- data/app/helpers/ecm/cms_helper.rb +42 -0
- data/app/models/ecm/cms.rb +5 -0
- data/app/models/ecm/cms/folder.rb +31 -0
- data/app/models/ecm/cms/navigation.rb +24 -0
- data/app/models/ecm/cms/navigation_item.rb +93 -0
- data/app/models/ecm/cms/page.rb +42 -0
- data/app/models/ecm/cms/partial.rb +31 -0
- data/app/models/ecm/cms/template.rb +31 -0
- data/config/locales/ecm.cms.de.yml +17 -0
- data/config/locales/ecm.cms.en.yml +17 -0
- data/config/locales/ecm.cms.navigation.de.yml +16 -0
- data/config/locales/ecm.cms.navigation.en.yml +16 -0
- data/config/locales/ecm.cms.navigation_item.de.yml +23 -0
- data/config/locales/ecm.cms.navigation_item.en.yml +23 -0
- data/config/locales/ecm.cms.page.de.yml +26 -0
- data/config/locales/ecm.cms.page.en.yml +26 -0
- data/config/locales/ecm.cms.partial.de.yml +22 -0
- data/config/locales/ecm.cms.partial.en.yml +22 -0
- data/config/locales/ecm.cms.template.de.yml +22 -0
- data/config/locales/ecm.cms.template.en.yml +22 -0
- data/db/migrate/001_create_ecm_cms_folders.rb +21 -0
- data/db/migrate/002_create_ecm_cms_pages.rb +19 -0
- data/db/migrate/003_create_ecm_cms_templates.rb +18 -0
- data/db/migrate/004_create_ecm_cms_partials.rb +19 -0
- data/db/migrate/005_create_ecm_cms_navigations.rb +13 -0
- data/db/migrate/006_create_ecm_cms_navigation_items.rb +28 -0
- data/lib/ecm/cms/action_view/template/handlers/textile.rb +18 -0
- data/lib/ecm/cms/action_view/template_patch.rb +19 -0
- data/lib/ecm/cms/action_view/template_renderer_patch.rb +30 -0
- data/lib/ecm/cms/active_admin/ecm_cms_navigation_items.rb +45 -0
- data/lib/ecm/cms/active_admin/ecm_cms_navigations.rb +61 -0
- data/lib/ecm/cms/active_admin/ecm_cms_pages.rb +70 -0
- data/lib/ecm/cms/active_admin/ecm_cms_partials.rb +47 -0
- data/lib/ecm/cms/active_admin/ecm_cms_templates.rb +46 -0
- data/lib/ecm/cms/configuration.rb +22 -0
- data/lib/ecm/cms/database_resolver.rb +101 -0
- data/lib/ecm/cms/database_template.rb +67 -0
- data/lib/ecm/cms/engine.rb +22 -0
- data/lib/ecm/cms/resolvers/ecm/cms/page_resolver.rb +37 -0
- data/lib/ecm/cms/resolvers/ecm/cms/partial_resolver.rb +30 -0
- data/lib/ecm/cms/resolvers/ecm/cms/template_resolver.rb +30 -0
- data/lib/ecm/cms/routing.rb +13 -0
- data/lib/ecm/cms/version.rb +5 -0
- data/lib/ecm_cms.rb +30 -0
- data/lib/generators/ecm/cms/install/install_generator.rb +15 -0
- data/lib/generators/ecm/cms/install/templates/ecm_cms.rb +7 -0
- data/lib/generators/ecm/cms/locales/locales_generator.rb +32 -0
- data/lib/rails_tools/i18n_controller.rb +24 -0
- data/lib/tasks/ecm_cms_tasks.rake +171 -0
- 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
|
+
|