comfortable_mexican_sofa 1.4.22 → 1.5.0

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 (81) hide show
  1. data/.travis.yml +2 -2
  2. data/Gemfile +3 -7
  3. data/VERSION +1 -1
  4. data/app/assets/stylesheets/comfortable_mexican_sofa/form.css +44 -1
  5. data/app/controllers/cms_admin/files_controller.rb +10 -1
  6. data/app/controllers/cms_admin/layouts_controller.rb +9 -0
  7. data/app/controllers/cms_admin/pages_controller.rb +1 -1
  8. data/app/controllers/cms_admin/snippets_controller.rb +10 -1
  9. data/app/models/cms/block.rb +29 -0
  10. data/app/models/cms/file.rb +9 -19
  11. data/app/models/cms/layout.rb +9 -0
  12. data/app/models/cms/page.rb +3 -4
  13. data/app/models/cms/snippet.rb +9 -0
  14. data/app/views/cms_admin/files/_file.html.erb +1 -1
  15. data/app/views/cms_admin/files/_index.html.erb +1 -12
  16. data/app/views/cms_admin/files/_page_form.html.erb +12 -0
  17. data/app/views/cms_admin/files/destroy.js.erb +1 -1
  18. data/app/views/cms_admin/files/index.html.erb +6 -2
  19. data/app/views/cms_admin/layouts/_index_branch.html.erb +5 -1
  20. data/app/views/cms_admin/layouts/index.html.erb +1 -1
  21. data/app/views/cms_admin/pages/_form_blocks.html.erb +2 -2
  22. data/app/views/cms_admin/pages/edit.html.erb +1 -1
  23. data/app/views/cms_admin/pages/new.html.erb +1 -1
  24. data/app/views/cms_admin/snippets/index.html.erb +6 -2
  25. data/comfortable_mexican_sofa.gemspec +16 -10
  26. data/config/initializers/comfortable_mexican_sofa.rb +0 -4
  27. data/config/initializers/paperclip.rb +25 -0
  28. data/config/locales/en.yml +2 -0
  29. data/config/locales/es.yml +2 -0
  30. data/config/routes.rb +8 -8
  31. data/db/migrate/01_create_cms.rb +6 -0
  32. data/db/migrate/upgrades/06_upgrade_to_1_5_0.rb +21 -0
  33. data/lib/comfortable_mexican_sofa/configuration.rb +14 -19
  34. data/lib/comfortable_mexican_sofa/form_builder.rb +48 -36
  35. data/lib/comfortable_mexican_sofa/tag.rb +2 -12
  36. data/lib/comfortable_mexican_sofa/tags/collection.rb +0 -4
  37. data/lib/comfortable_mexican_sofa/tags/field_datetime.rb +0 -4
  38. data/lib/comfortable_mexican_sofa/tags/field_integer.rb +0 -4
  39. data/lib/comfortable_mexican_sofa/tags/field_string.rb +0 -4
  40. data/lib/comfortable_mexican_sofa/tags/field_text.rb +0 -4
  41. data/lib/comfortable_mexican_sofa/tags/file.rb +5 -0
  42. data/lib/comfortable_mexican_sofa/tags/page_datetime.rb +0 -4
  43. data/lib/comfortable_mexican_sofa/tags/page_file.rb +44 -0
  44. data/lib/comfortable_mexican_sofa/tags/page_files.rb +44 -0
  45. data/lib/comfortable_mexican_sofa/tags/page_integer.rb +0 -4
  46. data/lib/comfortable_mexican_sofa/tags/page_rich_text.rb +0 -4
  47. data/lib/comfortable_mexican_sofa/tags/page_string.rb +0 -4
  48. data/lib/comfortable_mexican_sofa/tags/page_text.rb +0 -4
  49. data/lib/comfortable_mexican_sofa/tags/snippet.rb +5 -0
  50. data/lib/comfortable_mexican_sofa/view_methods.rb +6 -1
  51. data/test/fixtures/cms/files.yml +2 -1
  52. data/test/fixtures/cms/layouts.yml +4 -1
  53. data/test/fixtures/cms/snippets.yml +1 -0
  54. data/test/functional/cms_admin/files_controller_test.rb +17 -19
  55. data/test/functional/cms_admin/layouts_controller_test.rb +18 -1
  56. data/test/functional/cms_admin/pages_controller_test.rb +63 -22
  57. data/test/functional/cms_admin/snippets_controller_test.rb +18 -1
  58. data/test/gemfiles/Gemfile.rails-3.0.x +10 -0
  59. data/test/gemfiles/Gemfile.rails-3.1.x +10 -0
  60. data/test/test_helper.rb +13 -12
  61. data/test/unit/configuration_test.rb +1 -1
  62. data/test/unit/models/block_test.rb +112 -1
  63. data/test/unit/models/file_test.rb +1 -51
  64. data/test/unit/models/layout_test.rb +1 -0
  65. data/test/unit/models/snippet_test.rb +14 -0
  66. data/test/unit/tags/collection_test.rb +5 -5
  67. data/test/unit/tags/field_datetime_test.rb +2 -2
  68. data/test/unit/tags/field_integer_test.rb +2 -2
  69. data/test/unit/tags/field_string_test.rb +2 -2
  70. data/test/unit/tags/field_text_test.rb +2 -2
  71. data/test/unit/tags/page_datetime_test.rb +2 -2
  72. data/test/unit/tags/page_file_test.rb +79 -0
  73. data/test/unit/tags/page_files_test.rb +72 -0
  74. data/test/unit/tags/page_integer_test.rb +2 -2
  75. data/test/unit/tags/page_rich_text_test.rb +2 -2
  76. data/test/unit/tags/page_string_test.rb +2 -2
  77. data/test/unit/tags/page_text_test.rb +2 -2
  78. data/test/unit/view_methods_test.rb +2 -1
  79. metadata +20 -14
  80. data/gemfiles/Gemfile.rails-3.0.x +0 -14
  81. data/gemfiles/Gemfile.rails-3.1.x +0 -14
data/.travis.yml CHANGED
@@ -6,8 +6,8 @@ rvm:
6
6
  - ree
7
7
  # - jruby
8
8
  gemfile:
9
- - gemfiles/Gemfile.rails-3.0.x
10
- - gemfiles/Gemfile.rails-3.1.x
9
+ - test/gemfiles/Gemfile.rails-3.0.x
10
+ - test/gemfiles/Gemfile.rails-3.1.x
11
11
  notifications:
12
12
  recipients:
13
13
  - oleg@twg.ca
data/Gemfile CHANGED
@@ -1,14 +1,10 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  gem 'rails', '>=3.0.0'
4
- gem 'active_link_to', '>=1.0.0'
5
- gem 'paperclip', '>=2.3.14'
6
-
7
- group :development do
8
- # gem 'sqlite3'
9
- end
4
+ gem 'active_link_to', '~>1.0.0'
5
+ gem 'paperclip', '~>2.4.2'
10
6
 
11
7
  group :test do
12
8
  gem 'sqlite3'
13
- gem 'jeweler', '>=1.4.0'
9
+ gem 'jeweler'
14
10
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.22
1
+ 1.5.0
@@ -67,6 +67,46 @@
67
67
  #cms_body #form_blocks .no_tags code {
68
68
  color: #B85042;
69
69
  }
70
+ #cms_body #form_blocks .files {
71
+ overflow: hidden;
72
+ margin-top: 5px;
73
+ background-color: #252525;
74
+ padding: 5px 5px 0px 10px;
75
+ border-radius: 5px;
76
+ color: #fff;
77
+ min-height: 20px;
78
+ }
79
+ #cms_body #form_blocks .files .file {
80
+ float: left;
81
+ overflow: hidden;
82
+ background-color: #484848;
83
+ border-radius: 3px;
84
+ color: #fff;
85
+ height: 9px;
86
+ padding: 3px 5px;
87
+ margin: 0px 5px 5px 0px;
88
+ }
89
+ #cms_body #form_blocks .files .file a {
90
+ float: left;
91
+ color: #a3a3a3;
92
+ font: 9px/9px Arial, serif;
93
+ text-transform: uppercase;
94
+ }
95
+ #cms_body #form_blocks .files .file a:hover {
96
+ color: #fff;
97
+ }
98
+ #cms_body #form_blocks .files .file a.delete {
99
+ float: right;
100
+ margin-left: 5px;
101
+ background-color: #b7b7b7;
102
+ color: #000;
103
+ font: bold 7px/7px Arial, sans-serif;
104
+ padding: 1px 3px;
105
+ border-radius: 4px;
106
+ }
107
+ #cms_body #form_blocks .files .file a.delete:hover {
108
+ background-color: #fff;
109
+ }
70
110
  #cms_body .form_element.field_date_time .label,
71
111
  #cms_body .form_element.field_integer .label,
72
112
  #cms_body .form_element.field_string .label,
@@ -77,7 +117,10 @@
77
117
  #cms_body .form_element.page_integer .label,
78
118
  #cms_body .form_element.page_string .label,
79
119
  #cms_body .form_element.page_text .label,
80
- #cms_body .form_element.page_rich_text .label {
120
+ #cms_body .form_element.page_rich_text .label,
121
+ #cms_body .form_element.collection .label,
122
+ #cms_body .form_element.page_file .label,
123
+ #cms_body .form_element.page_files .label {
81
124
  border-color: #3F7300;
82
125
  }
83
126
  #cms_body .form_error {
@@ -6,7 +6,7 @@ class CmsAdmin::FilesController < CmsAdmin::BaseController
6
6
 
7
7
  def index
8
8
  return redirect_to :action => :new if @site.files.count == 0
9
- @files = @site.files.for_category(params[:category]).all(:order => 'cms_files.label')
9
+ @files = @site.files.includes(:categories).for_category(params[:category]).all(:order => 'cms_files.label')
10
10
  end
11
11
 
12
12
  def new
@@ -73,6 +73,15 @@ class CmsAdmin::FilesController < CmsAdmin::BaseController
73
73
  end
74
74
  end
75
75
 
76
+ def reorder
77
+ (params[:cms_file] || []).each_with_index do |id, index|
78
+ if (cms_file = Cms::File.find_by_id(id))
79
+ cms_file.update_attribute(:position, index)
80
+ end
81
+ end
82
+ render :nothing => true
83
+ end
84
+
76
85
  protected
77
86
 
78
87
  def load_file
@@ -39,6 +39,15 @@ class CmsAdmin::LayoutsController < CmsAdmin::BaseController
39
39
  flash[:notice] = I18n.t('cms.layouts.deleted')
40
40
  redirect_to :action => :index
41
41
  end
42
+
43
+ def reorder
44
+ (params[:cms_layout] || []).each_with_index do |id, index|
45
+ if (cms_layout = Cms::Layout.find_by_id(id))
46
+ cms_layout.update_attribute(:position, index)
47
+ end
48
+ end
49
+ render :nothing => true
50
+ end
42
51
 
43
52
  protected
44
53
 
@@ -9,7 +9,7 @@ class CmsAdmin::PagesController < CmsAdmin::BaseController
9
9
  def index
10
10
  return redirect_to :action => :new if @site.pages.count == 0
11
11
  if params[:category].present?
12
- @pages = @site.pages.for_category(params[:category]).all(:order => 'label')
12
+ @pages = @site.pages.includes(:categories).for_category(params[:category]).all(:order => 'label')
13
13
  else
14
14
  @pages = [@site.pages.root].compact
15
15
  end
@@ -5,7 +5,7 @@ class CmsAdmin::SnippetsController < CmsAdmin::BaseController
5
5
 
6
6
  def index
7
7
  return redirect_to :action => :new if @site.snippets.count == 0
8
- @snippets = @site.snippets.for_category(params[:category]).all(:order => 'label')
8
+ @snippets = @site.snippets.includes(:categories).for_category(params[:category])
9
9
  end
10
10
 
11
11
  def new
@@ -39,6 +39,15 @@ class CmsAdmin::SnippetsController < CmsAdmin::BaseController
39
39
  flash[:notice] = I18n.t('cms.snippets.deleted')
40
40
  redirect_to :action => :index
41
41
  end
42
+
43
+ def reorder
44
+ (params[:cms_snippet] || []).each_with_index do |id, index|
45
+ if (cms_snippet = Cms::Snippet.find_by_id(id))
46
+ cms_snippet.update_attribute(:position, index)
47
+ end
48
+ end
49
+ render :nothing => true
50
+ end
42
51
 
43
52
  protected
44
53
 
@@ -6,10 +6,39 @@ class Cms::Block < ActiveRecord::Base
6
6
 
7
7
  # -- Relationships --------------------------------------------------------
8
8
  belongs_to :page
9
+ has_many :files,
10
+ :autosave => true,
11
+ :dependent => :destroy
12
+
13
+ # -- Callbacks ------------------------------------------------------------
14
+ before_save :prepare_files
9
15
 
10
16
  # -- Validations ----------------------------------------------------------
11
17
  validates :label,
12
18
  :presence => true,
13
19
  :uniqueness => { :scope => :page_id }
20
+
21
+ # -- Instance Methods -----------------------------------------------------
22
+ # Tag object that is using this block
23
+ def tag
24
+ page.tags(true).detect{|t| t.is_cms_block? && t.label == label}
25
+ end
26
+
27
+ protected
14
28
 
29
+ def prepare_files
30
+ temp_files = [self.content].flatten.select do |f|
31
+ %w(ActionDispatch::Http::UploadedFile Rack::Test::UploadedFile).member?(f.class.name)
32
+ end
33
+
34
+ # only accepting one file if it's PageFile. PageFiles will take all
35
+ single_file = self.tag.is_a?(ComfortableMexicanSofa::Tag::PageFile)
36
+ temp_files = [temp_files.first].compact if single_file
37
+
38
+ temp_files.each do |file|
39
+ self.files.collect{|f| f.mark_for_destruction } if single_file
40
+ self.files.build(:site => self.page.site, :file => file)
41
+ end
42
+ self.content = nil unless self.content.is_a?(String)
43
+ end
15
44
  end
@@ -6,26 +6,23 @@ class Cms::File < ActiveRecord::Base
6
6
 
7
7
  cms_is_categorized
8
8
 
9
- attr_accessor :layout_id,
10
- :page_id,
11
- :snippet_id
12
-
13
9
  # -- AR Extensions --------------------------------------------------------
14
10
  has_attached_file :file, ComfortableMexicanSofa.config.upload_file_options
15
11
 
16
12
  # -- Relationships --------------------------------------------------------
17
13
  belongs_to :site
14
+ belongs_to :block
18
15
 
19
16
  # -- Validations ----------------------------------------------------------
20
17
  validates :site_id, :presence => true
21
18
  validates_attachment_presence :file
22
19
 
23
- validates_uniqueness_of :file_file_name,
24
- :scope => :site_id
25
-
26
20
  # -- Callbacks ------------------------------------------------------------
27
- before_save :assign_label,
28
- :categorize_file
21
+ before_save :assign_label
22
+ before_create :assign_position
23
+
24
+ # -- Scopes ---------------------------------------------------------------
25
+ default_scope order(:position)
29
26
 
30
27
  protected
31
28
 
@@ -33,16 +30,9 @@ protected
33
30
  self.label = self.label.blank?? self.file_file_name.gsub(/\.[^\.]*?$/, '').titleize : self.label
34
31
  end
35
32
 
36
- def categorize_file
37
- return unless ComfortableMexicanSofa.config.auto_file_categorization
38
- category = if layout_id && layout = site.layouts.find_by_id(layout_id)
39
- Cms::Category.find_or_create_by_label_and_categorized_type("[layout] #{layout.slug}", 'Cms::File')
40
- elsif page_id && page = site.pages.find_by_id(page_id)
41
- Cms::Category.find_or_create_by_label_and_categorized_type("[page] #{page.full_path}", 'Cms::File')
42
- elsif snippet_id && snippet = site.snippets.find_by_id(snippet_id)
43
- Cms::Category.find_or_create_by_label_and_categorized_type("[snippet] #{snippet.slug}", 'Cms::File')
44
- end
45
- self.category_ids = { category.id => 1 } if category
33
+ def assign_position
34
+ max = Cms::File.maximum(:position)
35
+ self.position = max ? max + 1 : 0
46
36
  end
47
37
 
48
38
  end
@@ -14,6 +14,7 @@ class Cms::Layout < ActiveRecord::Base
14
14
 
15
15
  # -- Callbacks ------------------------------------------------------------
16
16
  before_validation :assign_label
17
+ before_create :assign_position
17
18
  after_save :clear_cached_page_content
18
19
  after_destroy :clear_cached_page_content
19
20
 
@@ -27,6 +28,9 @@ class Cms::Layout < ActiveRecord::Base
27
28
  :uniqueness => { :scope => :site_id },
28
29
  :format => { :with => /^\w[a-z0-9_-]*$/i }
29
30
 
31
+ # -- Scopes ---------------------------------------------------------------
32
+ default_scope order(:position)
33
+
30
34
  # -- Class Methods --------------------------------------------------------
31
35
  # Tree-like structure for layouts
32
36
  def self.options_for_select(site, layout = nil, current_layout = nil, depth = 0, spacer = '. . ')
@@ -72,6 +76,11 @@ protected
72
76
  self.label = self.label.blank?? self.slug.try(:titleize) : self.label
73
77
  end
74
78
 
79
+ def assign_position
80
+ max = self.site.layouts.where(:parent_id => self.parent_id).maximum(:position)
81
+ self.position = max ? max + 1 : 0
82
+ end
83
+
75
84
  # Forcing page content reload
76
85
  def clear_cached_page_content
77
86
  self.pages.each{ |page| page.save! }
@@ -25,8 +25,7 @@ class Cms::Page < ActiveRecord::Base
25
25
  before_validation :assigns_label,
26
26
  :assign_parent,
27
27
  :assign_full_path
28
- before_validation :assign_position,
29
- :on => :create
28
+ before_create :assign_position
30
29
  before_save :set_cached_content
31
30
  after_save :sync_child_pages
32
31
 
@@ -85,6 +84,7 @@ class Cms::Page < ActiveRecord::Base
85
84
  # { :label => 'block_2', :content => 'block content' }
86
85
  # ]
87
86
  def blocks_attributes=(block_hashes = [])
87
+ block_hashes = block_hashes.values if block_hashes.is_a?(Hash)
88
88
  block_hashes.each do |block_hash|
89
89
  block_hash.symbolize_keys! unless block_hash.is_a?(HashWithIndifferentAccess)
90
90
  block = self.blocks.detect{|b| b.label == block_hash[:label]} || self.blocks.build(:label => block_hash[:label])
@@ -96,8 +96,7 @@ class Cms::Page < ActiveRecord::Base
96
96
  # Processing content will return rendered content and will populate
97
97
  # self.cms_tags with instances of CmsTag
98
98
  def content(force_reload = false)
99
- @content = read_attribute(:content)
100
- @content = nil if force_reload
99
+ @content = force_reload ? nil : read_attribute(:content)
101
100
  @content ||= begin
102
101
  self.tags = [] # resetting
103
102
  if layout
@@ -13,6 +13,7 @@ class Cms::Snippet < ActiveRecord::Base
13
13
 
14
14
  # -- Callbacks ------------------------------------------------------------
15
15
  before_validation :assign_label
16
+ before_create :assign_position
16
17
  after_save :clear_cached_page_content
17
18
  after_destroy :clear_cached_page_content
18
19
 
@@ -25,6 +26,9 @@ class Cms::Snippet < ActiveRecord::Base
25
26
  :presence => true,
26
27
  :uniqueness => { :scope => :site_id },
27
28
  :format => { :with => /^\w[a-z0-9_-]*$/i }
29
+
30
+ # -- Scopes ---------------------------------------------------------------
31
+ default_scope order(:position)
28
32
 
29
33
  protected
30
34
 
@@ -39,4 +43,9 @@ protected
39
43
  site.pages.all.each{ |page| page.save }
40
44
  end
41
45
 
46
+ def assign_position
47
+ max = self.site.snippets.maximum(:position)
48
+ self.position = max ? max + 1 : 0
49
+ end
50
+
42
51
  end
@@ -1,4 +1,4 @@
1
- <div class='file' id='<%= dom_id(file) %>'>
1
+ <div class='file <%= dom_id(file) %>'>
2
2
  <% file_name = file.file_file_name
3
3
  file_ext = file.file_file_name.split('.').last
4
4
  if (file_name.size - file_ext.size) > 30
@@ -1,17 +1,6 @@
1
1
  <div id='file_uploads' class='box'>
2
2
 
3
- <%
4
- key, id = if @layout && !@layout.new_record?
5
- [:layout_id, @layout.id]
6
- elsif @page && !@page.new_record?
7
- [:page_id, @page.id]
8
- elsif @snippet && !@snippet.new_record?
9
- [:snippet_id, @snippet.id]
10
- end
11
- url_param = key.present?? "?file[#{key}]=#{id}" : ''
12
- %>
13
-
14
- <%= form_for :file, :url => cms_admin_site_files_path(@site) + url_param, :html => {:multipart => true} do |form| %>
3
+ <%= form_for :file, :url => cms_admin_site_files_path(@site), :html => {:multipart => true} do |form| %>
15
4
  <a id='uploader_button' href='#' class='big button'><%= t('.button') %></a>
16
5
  <%= form.file_field :file, :multiple => true %>
17
6
  <% end %>
@@ -0,0 +1,12 @@
1
+ <% block ||= page_form %>
2
+
3
+ <% if (files = block.files).present? %>
4
+ <div class='files'>
5
+ <% files.each do |file| %>
6
+ <div class='file <%= dom_id(file) %>'>
7
+ <%= link_to file.file_file_name, file.file.url, :target => '_blank' %>
8
+ <%= link_to 'x', cms_admin_site_file_path(@site, file), :method => :delete, :remote => true, :confirm => t('.are_you_sure'), :class => 'delete' %>
9
+ </div>
10
+ <% end %>
11
+ </div>
12
+ <% end %>
@@ -1,3 +1,3 @@
1
- $(".file#<%= dom_id(@file) %>").fadeOut('slow', function(){
1
+ $(".file.<%= dom_id(@file) %>").fadeOut('slow', function(){
2
2
  $(this).remove()
3
3
  })
@@ -3,11 +3,15 @@
3
3
 
4
4
  <%= render :partial => 'cms_admin/categories/index', :object => 'Cms::File' %>
5
5
 
6
- <ul class='list'>
6
+ <ul class='list sortable'>
7
7
  <% @files.each do |file| %>
8
8
  <li id='<%= dom_id(file) %>'>
9
9
  <div class='item'>
10
- <div class='icon'></div>
10
+ <div class='icon'>
11
+ <% if !params[:category].present? %>
12
+ <div class='dragger'><span><%= t('cms.views.pages.drag') %></span></div>
13
+ <% end %>
14
+ </div>
11
15
  <div class='action_links'>
12
16
  <%= link_to t('.edit'), edit_cms_admin_site_file_path(@site, file) %>
13
17
  <%= link_to t('.delete'), cms_admin_site_file_path(@site, file), :method => :delete, :confirm => t('.are_you_sure') %>
@@ -2,7 +2,11 @@
2
2
 
3
3
  <li id='cms_layout_<%= layout.id %>'>
4
4
  <div class='item'>
5
- <div class='icon'></div>
5
+ <div class='icon'>
6
+ <% if !params[:category].present? %>
7
+ <div class='dragger'><span><%= t('cms.views.pages.drag') %></span></div>
8
+ <% end %>
9
+ </div>
6
10
  <div class='action_links'>
7
11
  <%= link_to t('.add_child_layout'), new_cms_admin_site_layout_path(@site, :parent_id => layout.id) %>
8
12
  <%= link_to t('.edit'), edit_cms_admin_site_layout_path(@site, layout) %>
@@ -5,6 +5,6 @@
5
5
  <%= render :partial => 'cms_admin/sites/mirrors' %>
6
6
  <% end %>
7
7
 
8
- <ul class='list'>
8
+ <ul class='list sortable'>
9
9
  <%= render :partial => 'index_branch', :collection => @layouts %>
10
10
  </ul>
@@ -8,8 +8,8 @@
8
8
  </div>
9
9
  <% else %>
10
10
  <%= fields_for :blocks, nil, :builder => ComfortableMexicanSofa::FormBuilder do |cms_blocks| %>
11
- <% block_tags.each do |tag| %>
12
- <%= cms_blocks.send(tag.class.to_s.demodulize.underscore, tag)%>
11
+ <% block_tags.each_with_index do |tag, index| %>
12
+ <%= cms_blocks.send(tag.class.to_s.demodulize.underscore, tag, index) rescue nil %>
13
13
  <% end %>
14
14
  <% end %>
15
15
  <% end %>