comfortable_mexican_sofa 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +1 -1
  3. data/README.md +83 -1
  4. data/VERSION +1 -1
  5. data/app/controllers/cms_admin/base_controller.rb +15 -0
  6. data/app/controllers/cms_admin/layouts_controller.rb +3 -3
  7. data/app/controllers/cms_admin/pages_controller.rb +8 -8
  8. data/app/controllers/cms_admin/sites_controller.rb +58 -0
  9. data/app/controllers/cms_admin/snippets_controller.rb +18 -14
  10. data/app/controllers/cms_admin/uploads_controller.rb +7 -5
  11. data/app/controllers/cms_content_controller.rb +17 -5
  12. data/app/models/cms_layout.rb +7 -7
  13. data/app/models/cms_page.rb +18 -4
  14. data/app/models/cms_site.rb +23 -0
  15. data/app/models/cms_snippet.rb +17 -12
  16. data/app/models/cms_upload.rb +4 -7
  17. data/app/views/cms_admin/layouts/_form.html.erb +1 -1
  18. data/app/views/cms_admin/layouts/index.html.erb +1 -1
  19. data/app/views/cms_admin/pages/_form.html.erb +3 -2
  20. data/app/views/cms_admin/pages/_form_blocks.html.erb +1 -1
  21. data/app/views/cms_admin/pages/_index_branch.html.erb +1 -1
  22. data/app/views/cms_admin/pages/index.html.erb +1 -1
  23. data/app/views/cms_admin/sites/_form.html.erb +2 -0
  24. data/app/views/cms_admin/sites/edit.html.erb +6 -0
  25. data/app/views/cms_admin/sites/index.html.erb +22 -0
  26. data/app/views/cms_admin/sites/new.html.erb +6 -0
  27. data/app/views/cms_admin/snippets/_form.html.erb +2 -1
  28. data/app/views/cms_admin/snippets/index.html.erb +20 -1
  29. data/app/views/layouts/cms_admin.html.erb +2 -1
  30. data/comfortable_mexican_sofa.gemspec +31 -9
  31. data/config/initializers/comfortable_mexican_sofa.rb +10 -0
  32. data/config/routes.rb +3 -1
  33. data/db/migrate/01_create_cms.rb +18 -4
  34. data/lib/comfortable_mexican_sofa.rb +28 -22
  35. data/lib/comfortable_mexican_sofa/acts_as_tree.rb +97 -0
  36. data/lib/comfortable_mexican_sofa/cms_tag/snippet.rb +4 -0
  37. data/lib/comfortable_mexican_sofa/configuration.rb +19 -0
  38. data/lib/comfortable_mexican_sofa/controller_methods.rb +41 -0
  39. data/lib/comfortable_mexican_sofa/{cms_engine.rb → engine.rb} +1 -1
  40. data/lib/comfortable_mexican_sofa/{cms_form_builder.rb → form_builder.rb} +1 -1
  41. data/lib/comfortable_mexican_sofa/http_auth.rb +17 -0
  42. data/lib/comfortable_mexican_sofa/rails_extensions.rb +11 -0
  43. data/lib/comfortable_mexican_sofa/view_methods.rb +33 -0
  44. data/lib/generators/cms_generator.rb +4 -0
  45. data/public/stylesheets/comfortable_mexican_sofa/structure.css +10 -12
  46. data/test/fixtures/cms_layouts.yml +3 -1
  47. data/test/fixtures/cms_pages.yml +6 -2
  48. data/test/fixtures/cms_sites.yml +3 -0
  49. data/test/fixtures/cms_snippets.yml +3 -1
  50. data/test/fixtures/cms_uploads.yml +1 -0
  51. data/test/functional/cms_admin/layouts_controller_test.rb +3 -1
  52. data/test/functional/cms_admin/pages_controller_test.rb +4 -2
  53. data/test/functional/cms_admin/sites_controller_test.rb +92 -0
  54. data/test/functional/cms_admin/snippets_controller_test.rb +62 -37
  55. data/test/functional/cms_content_controller_test.rb +32 -5
  56. data/test/integration/authentication_test.rb +27 -0
  57. data/test/integration/render_cms_test.rb +57 -0
  58. data/test/integration/sites_test.rb +30 -0
  59. data/test/test_helper.rb +46 -3
  60. data/test/unit/cms_block_test.rb +1 -0
  61. data/test/unit/cms_configuration_test.rb +16 -0
  62. data/test/unit/cms_layout_test.rb +3 -3
  63. data/test/unit/cms_page_test.rb +23 -13
  64. data/test/unit/cms_site_test.rb +41 -0
  65. data/test/unit/cms_snippet_test.rb +1 -1
  66. data/test/unit/cms_tags/snippet_test.rb +1 -1
  67. data/test/unit/cms_upload_test.rb +7 -6
  68. metadata +32 -10
  69. data/lib/comfortable_mexican_sofa/cms_acts_as_tree.rb +0 -101
  70. data/lib/comfortable_mexican_sofa/cms_rails_extensions.rb +0 -32
  71. data/test/functional/cms_admin/base_controller_test.rb +0 -9
@@ -1,10 +1,15 @@
1
- if defined?(Rails) && Rails::VERSION::MAJOR == 3
2
- require File.expand_path('comfortable_mexican_sofa/cms_engine', File.dirname(__FILE__))
1
+ # Loading engine only if this is not a standalone installation
2
+ unless defined? ComfortableMexicanSofa::Application
3
+ require File.expand_path('comfortable_mexican_sofa/engine', File.dirname(__FILE__))
3
4
  end
4
5
 
5
- [ 'comfortable_mexican_sofa/cms_rails_extensions',
6
- 'comfortable_mexican_sofa/cms_form_builder',
7
- 'comfortable_mexican_sofa/cms_acts_as_tree',
6
+ [ 'comfortable_mexican_sofa/configuration',
7
+ 'comfortable_mexican_sofa/http_auth',
8
+ 'comfortable_mexican_sofa/rails_extensions',
9
+ 'comfortable_mexican_sofa/controller_methods',
10
+ 'comfortable_mexican_sofa/view_methods',
11
+ 'comfortable_mexican_sofa/form_builder',
12
+ 'comfortable_mexican_sofa/acts_as_tree',
8
13
  '../app/models/cms_block',
9
14
  '../app/models/cms_snippet',
10
15
  'comfortable_mexican_sofa/cms_tag'
@@ -16,24 +21,25 @@ Dir.glob(File.expand_path('comfortable_mexican_sofa/cms_tag/*.rb', File.dirname(
16
21
  require tag_path
17
22
  end
18
23
 
19
- ActionView::Helpers::AssetTagHelper.register_javascript_expansion :cms => [
20
- 'comfortable_mexican_sofa/jquery',
21
- 'comfortable_mexican_sofa/jquery-ui',
22
- 'comfortable_mexican_sofa/rails',
23
- 'comfortable_mexican_sofa/cms',
24
- 'comfortable_mexican_sofa/plupload/plupload.full.min',
25
- 'comfortable_mexican_sofa/uploader'
26
- ]
27
- ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :cms => [
28
- 'comfortable_mexican_sofa/reset',
29
- 'comfortable_mexican_sofa/structure',
30
- 'comfortable_mexican_sofa/typography'
31
- ]
32
-
33
- FILE_ICONS = Dir.glob(File.expand_path('public/images/cms/file_icons/*.png', Rails.root)).collect{|f| f.split('/').last.gsub('.png', '')}
34
-
35
24
  module ComfortableMexicanSofa
36
25
 
37
- # TODO
26
+ class << self
27
+
28
+ # Modify CMS configuration
29
+ # Example:
30
+ # ComfortableMexicanSofa.configure do |config|
31
+ # config.cms_title = 'Comfortable Mexican Sofa'
32
+ # end
33
+ def configure
34
+ yield configuration
35
+ end
36
+
37
+ # Accessor for ComfortableMexicanSofa::Configuration
38
+ def configuration
39
+ @configuration ||= Configuration.new
40
+ end
41
+ alias :config :configuration
42
+
43
+ end
38
44
 
39
45
  end
@@ -0,0 +1,97 @@
1
+ module ComfortableMexicanSofa::ActsAsTree
2
+
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def acts_as_tree(options = {})
9
+ configuration = {
10
+ :foreign_key => 'parent_id',
11
+ :order => nil,
12
+ :counter_cache => nil,
13
+ :dependent => :destroy,
14
+ :touch => false }
15
+ configuration.update(options) if options.is_a?(Hash)
16
+
17
+ belongs_to :parent,
18
+ :class_name => name,
19
+ :foreign_key => configuration[:foreign_key],
20
+ :counter_cache => configuration[:counter_cache],
21
+ :touch => configuration[:touch]
22
+
23
+ has_many :children,
24
+ :class_name => name,
25
+ :foreign_key => configuration[:foreign_key],
26
+ :order => configuration[:order],
27
+ :dependent => configuration[:dependent]
28
+
29
+ class_eval <<-EOV
30
+ include ComfortableMexicanSofa::ActsAsTree::InstanceMethods
31
+
32
+ scope :roots,
33
+ :conditions => "#{configuration[:foreign_key]} IS NULL",
34
+ :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}
35
+
36
+ def self.root
37
+ roots.first
38
+ end
39
+
40
+ validates_each "#{configuration[:foreign_key]}" do |record, attr, value|
41
+ if value
42
+ if record.id == value
43
+ record.errors.add attr, "cannot be it's own id"
44
+ elsif record.descendants.map {|c| c.id}.include?(value)
45
+ record.errors.add attr, "cannot be a descendant's id"
46
+ end
47
+ end
48
+ end
49
+
50
+ EOV
51
+ end
52
+ end
53
+
54
+ module InstanceMethods
55
+ # Returns list of ancestors, starting from parent until root.
56
+ #
57
+ # subchild1.ancestors # => [child1, root]
58
+ def ancestors
59
+ node, nodes = self, []
60
+ nodes << node = node.parent while node.parent
61
+ nodes
62
+ end
63
+
64
+ # Returns all children and children of children
65
+ def descendants
66
+ nodes = []
67
+ self.children.each do |c|
68
+ nodes << c
69
+ nodes << c.descendants
70
+ end
71
+ nodes.flatten
72
+ end
73
+
74
+ # Returns the root node of the tree.
75
+ def root
76
+ node = self
77
+ node = node.parent while node.parent
78
+ node
79
+ end
80
+
81
+ # Returns all siblings of the current node.
82
+ #
83
+ # subchild1.siblings # => [subchild2]
84
+ def siblings
85
+ self_and_siblings - [self]
86
+ end
87
+
88
+ # Returns all siblings and a reference to the current node.
89
+ #
90
+ # subchild1.self_and_siblings # => [subchild1, subchild2]
91
+ def self_and_siblings
92
+ parent ? parent.children : self.class.roots
93
+ end
94
+ end
95
+ end
96
+
97
+ ActiveRecord::Base.send :include, ComfortableMexicanSofa::ActsAsTree
@@ -2,6 +2,10 @@ class CmsTag::Snippet < CmsSnippet
2
2
 
3
3
  include CmsTag
4
4
 
5
+ def identifier
6
+ "#{self.class.name.underscore}_#{self.slug}"
7
+ end
8
+
5
9
  def self.regex_tag_signature(label = nil)
6
10
  label ||= /\w+/
7
11
  /<\s*cms:snippet:(#{label})\s*\/?>/
@@ -0,0 +1,19 @@
1
+ class ComfortableMexicanSofa::Configuration
2
+
3
+ # Don't like Comfortable Mexican Sofa? Set it to whatever you like. :(
4
+ attr_accessor :cms_title
5
+
6
+ # Module that will handle authentication to access cms-admin area
7
+ attr_accessor :authentication
8
+
9
+ # Enable cms to manage multiple sites
10
+ attr_accessor :multiple_sites
11
+
12
+ # Configuration defaults
13
+ def initialize
14
+ @cms_title = 'ComfortableMexicanSofa'
15
+ @authentication = 'CmsHttpAuthentication'
16
+ @multiple_sites = false
17
+ end
18
+
19
+ end
@@ -0,0 +1,41 @@
1
+ module ComfortableMexicanSofa::ControllerMethods
2
+
3
+ def self.included(base)
4
+ base.alias_method_chain :render, :cms
5
+
6
+ # If application controller doesn't have template associated with it
7
+ # CMS will attempt to find one. This is so you don't have to explicitly
8
+ # call render :cms_page => '/something'
9
+ base.rescue_from 'ActionView::MissingTemplate' do |e|
10
+ begin
11
+ render :cms_page => request.path
12
+ rescue ActionView::MissingTemplate
13
+ raise e
14
+ end
15
+ end
16
+ end
17
+
18
+ # Now you can render cms_page simply by calling:
19
+ # render :cms_page => '/path/to/page'
20
+ # This way application controllers can use CMS content while populating
21
+ # instance variables that can be used in partials (that are included by
22
+ # by the cms page and/or layout)
23
+ def render_with_cms(options = {}, locals = {}, &block)
24
+ if path = options.delete(:cms_page)
25
+ site = CmsSite.find_by_hostname(request.host.downcase)
26
+ page = site && site.cms_pages.find_by_full_path(path)
27
+ if page
28
+ cms_app_layout = page.cms_layout.try(:app_layout)
29
+ options[:layout] ||= cms_app_layout.blank?? nil : cms_app_layout
30
+ options[:inline] = page.content
31
+ render_without_cms(options, locals, &block)
32
+ else
33
+ raise ActionView::MissingTemplate.new([path], path, "CMS page not found", nil)
34
+ end
35
+ else
36
+ render_without_cms(options, locals, &block)
37
+ end
38
+ end
39
+ end
40
+
41
+ ActionController::Base.send :include, ComfortableMexicanSofa::ControllerMethods
@@ -5,7 +5,7 @@ require 'active_link_to'
5
5
  require 'mime/types'
6
6
 
7
7
  module ComfortableMexicanSofa
8
- class CMSEngine < ::Rails::Engine
8
+ class Engine < ::Rails::Engine
9
9
 
10
10
  end
11
11
  end
@@ -1,4 +1,4 @@
1
- class CmsFormBuilder < ActionView::Helpers::FormBuilder
1
+ class ComfortableMexicanSofa::FormBuilder < ActionView::Helpers::FormBuilder
2
2
 
3
3
  helpers = field_helpers -
4
4
  %w(hidden_field fields_for) +
@@ -0,0 +1,17 @@
1
+ module ComfortableMexicanSofa::HttpAuth
2
+ # Set username and password in config/initializers/comfortable_mexican_sofa.rb
3
+ # Like this:
4
+ # CmsHttpAuthentication.username = 'myname'
5
+ # CmsHttpAuthentication.password = 'mypassword'
6
+ mattr_accessor :username,
7
+ :password
8
+
9
+ # Simple http_auth. When implementing some other form of authentication
10
+ # this method should return +true+ if everything is great, or redirect user
11
+ # to some other page, thus denying access to cms admin section.
12
+ def authenticate
13
+ authenticate_or_request_with_http_basic do |username, password|
14
+ username == self.username && password == self.password
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ class String
2
+ # Converts string to something suitable to be used as an element id
3
+ def idify
4
+ self.strip.gsub(/\W/, '_').gsub(/\s|^_*|_*$/, '').squeeze('_')
5
+ end
6
+
7
+ # Capitalize all words in the string
8
+ def capitalize_all(delimiter = ' ')
9
+ self.split(delimiter).collect{|w| w.capitalize }.join(' ')
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ module ComfortableMexicanSofa::ViewMethods
2
+ # Wrapper around CmsFormBuilder
3
+ def cms_form_for(record_or_name_or_array, *args, &proc)
4
+ options = args.extract_options!
5
+ form_for(record_or_name_or_array, *(args << options.merge(:builder => ComfortableMexicanSofa::FormBuilder)), &proc)
6
+ end
7
+
8
+ # Wrapper for <span>
9
+ def span_tag(*args)
10
+ content_tag(:span, *args)
11
+ end
12
+
13
+ # Rails 3.0 doesn't have this helper defined
14
+ def datetime_field_tag(name, value = nil, options = {})
15
+ text_field_tag(name, value, options.stringify_keys.update('type' => 'datetime'))
16
+ end
17
+ end
18
+
19
+ ActionView::Base.send :include, ComfortableMexicanSofa::ViewMethods
20
+
21
+ ActionView::Helpers::AssetTagHelper.register_javascript_expansion :cms => [
22
+ 'comfortable_mexican_sofa/jquery',
23
+ 'comfortable_mexican_sofa/jquery-ui',
24
+ 'comfortable_mexican_sofa/rails',
25
+ 'comfortable_mexican_sofa/cms',
26
+ 'comfortable_mexican_sofa/plupload/plupload.full.min',
27
+ 'comfortable_mexican_sofa/uploader'
28
+ ]
29
+ ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :cms => [
30
+ 'comfortable_mexican_sofa/reset',
31
+ 'comfortable_mexican_sofa/structure',
32
+ 'comfortable_mexican_sofa/typography'
33
+ ]
@@ -9,6 +9,10 @@ class CmsGenerator < Rails::Generators::Base
9
9
  migration_template 'db/migrate/01_create_cms.rb', 'db/migrate/create_cms.rb'
10
10
  end
11
11
 
12
+ def generate_initialization
13
+ copy_file 'config/initializers/comfortable_mexican_sofa.rb', 'config/initializers/comfortable_mexican_sofa.rb'
14
+ end
15
+
12
16
  def generate_public_assets
13
17
  directory 'public/stylesheets/comfortable_mexican_sofa', 'public/stylesheets/comfortable_mexican_sofa'
14
18
  directory 'public/javascripts/comfortable_mexican_sofa', 'public/javascripts/comfortable_mexican_sofa'
@@ -144,23 +144,23 @@ html, body {
144
144
  border-color: #9e0b0f;
145
145
  }
146
146
 
147
- /* -- Tree Listings ------------------------------------------------------ */
148
- ul.tree li .item {
147
+ /* -- Listings ----------------------------------------------------------- */
148
+ ul.list li .item {
149
149
  overflow: hidden;
150
150
  padding: 5px;
151
151
  border-bottom: 1px solid #fff;
152
152
  }
153
- ul.tree li .icon {
153
+ ul.list li .icon {
154
154
  width: 28px;
155
155
  height: 28px;
156
156
  background: url(/images/comfortable_mexican_sofa/icon_regular.gif);
157
157
  float: left;
158
158
  }
159
- ul.tree li .action_links {
159
+ ul.list li .action_links {
160
160
  float: right;
161
161
  opacity: 0.1;
162
162
  }
163
- ul.tree .action_links a {
163
+ ul.list .action_links a {
164
164
  margin-left: 3px;
165
165
  float: left;
166
166
  background-color: #272A2D;
@@ -171,24 +171,22 @@ ul.tree .action_links a {
171
171
  border-radius: 3px;
172
172
  -moz-border-radius: 3px;
173
173
  }
174
- ul.tree li .label {
174
+ ul.list li .label {
175
175
  margin-left: 35px;
176
176
  font: 16px/18px Georgia, serif;
177
177
  color: #1C1F22;
178
178
  }
179
- ul.tree li .label .url {
179
+ ul.list li .label .sublabel {
180
180
  margin-left: 15px;
181
181
  font: 11px/14px Arial, sans-serif;
182
182
  color: #1C1F22;
183
183
  }
184
-
185
- ul.tree li ul {
184
+ ul.list li ul {
186
185
  margin-left: 30px;
187
186
  }
188
-
189
- ul.tree li .item:hover {
187
+ ul.list li .item:hover {
190
188
  background-color: #fff;
191
189
  }
192
- ul.tree li .item:hover .action_links {
190
+ ul.list li .item:hover .action_links {
193
191
  opacity: 1;
194
192
  }
@@ -1,5 +1,5 @@
1
1
  default:
2
- id: 1
2
+ cms_site: default
3
3
  label: Default Layout
4
4
  parent:
5
5
  content: |-
@@ -18,6 +18,7 @@ default:
18
18
  })
19
19
 
20
20
  nested:
21
+ cms_site: default
21
22
  label: Nested Layout
22
23
  parent:
23
24
  content: |-
@@ -31,6 +32,7 @@ nested:
31
32
  })
32
33
 
33
34
  child:
35
+ cms_site: default
34
36
  label: Child Layout
35
37
  parent: nested
36
38
  content: |-
@@ -1,6 +1,8 @@
1
1
  default:
2
+ cms_site: default
2
3
  parent:
3
- cms_layout_id: 1
4
+ target_page:
5
+ cms_layout: default
4
6
  label: Default Page
5
7
  slug:
6
8
  full_path: '/'
@@ -8,8 +10,10 @@ default:
8
10
  position: 0
9
11
 
10
12
  child:
13
+ cms_site: default
11
14
  parent: default
12
- cms_layout_id: 1
15
+ target_page:
16
+ cms_layout: default
13
17
  label: Child Page
14
18
  slug: 'child-page'
15
19
  full_path: '/child-page'
@@ -0,0 +1,3 @@
1
+ default:
2
+ label: Default Site
3
+ hostname: test.host
@@ -1,3 +1,5 @@
1
1
  default:
2
- label: default
2
+ cms_site: default
3
+ label: Default Snippet
4
+ slug: default
3
5
  content: default_snippet_content