spud_cms 0.8.17 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/README.markdown +30 -13
  2. data/app/assets/images/spud/admin/snippets_thumb.png +0 -0
  3. data/app/assets/images/spud/admin/snippets_thumb@2x.png +0 -0
  4. data/app/assets/javascripts/spud/admin/cms/application.js +3 -3
  5. data/app/controllers/pages_controller.rb +6 -23
  6. data/app/controllers/spud/admin/menu_items_controller.rb +6 -10
  7. data/app/controllers/spud/admin/menus_controller.rb +1 -1
  8. data/app/controllers/spud/admin/pages_controller.rb +40 -86
  9. data/app/controllers/spud/cms/sitemaps_controller.rb +1 -1
  10. data/app/helpers/spud/cms/application_helper.rb +50 -26
  11. data/app/models/spud_menu_item.rb +10 -13
  12. data/app/models/spud_page.rb +12 -4
  13. data/app/models/spud_page_liquid_tag.rb +4 -0
  14. data/app/models/spud_page_partial.rb +40 -1
  15. data/app/observers/page_sweeper.rb +48 -0
  16. data/app/views/pages/show.html.erb +9 -11
  17. data/app/views/spud/admin/pages/_form.html.erb +15 -16
  18. data/app/views/spud/admin/pages/_page_partials_form.html.erb +3 -3
  19. data/app/views/spud/admin/pages/index.html.erb +1 -1
  20. data/app/views/spud/admin/pages/show.html.erb +4 -6
  21. data/config/routes.rb +3 -3
  22. data/db/migrate/20120911190030_add_symbol_name_to_spud_page_partials.rb +5 -0
  23. data/db/migrate/20120912121313_modify_site_id_for_spud_pages.rb +15 -0
  24. data/db/migrate/20121016233715_add_content_processed_to_spud_page_partials.rb +5 -0
  25. data/db/migrate/20121112151110_add_layout_to_spud_pages.rb +8 -0
  26. data/db/migrate/20121112212113_create_spud_page_liquid_tags.rb +11 -0
  27. data/lib/spud_cms.rb +1 -0
  28. data/lib/spud_cms/configuration.rb +4 -7
  29. data/lib/spud_cms/engine.rb +37 -16
  30. data/lib/spud_cms/template_parser.rb +121 -0
  31. data/lib/spud_cms/version.rb +1 -1
  32. data/spec/controllers/pages_controller_spec.rb +108 -0
  33. data/spec/controllers/spud/admin/menu_items_controller_spec.rb +148 -0
  34. data/spec/controllers/spud/admin/menus_controller_spec.rb +121 -0
  35. data/spec/controllers/spud/admin/pages_controller_spec.rb +5 -13
  36. data/spec/controllers/spud/cms/sitemaps_controller_spec.rb +35 -4
  37. data/spec/dummy/app/controllers/application_controller.rb +1 -1
  38. data/spec/dummy/db/schema.rb +146 -0
  39. data/spec/dummy/log/development.log +341 -0
  40. data/spec/dummy/log/test.log +182863 -0
  41. data/spec/helpers/spud/cms/application_helper_spec.rb +160 -0
  42. data/spec/models/spud_menu_item_spec.rb +31 -0
  43. data/spec/models/spud_page_liquid_tag_spec.rb +5 -0
  44. data/spec/models/spud_page_partial_spec.rb +44 -0
  45. data/spec/models/spud_page_spec.rb +1 -2
  46. metadata +50 -19
  47. data/app/assets/images/spud/admin/templates_thumb.png +0 -0
  48. data/app/controllers/spud/admin/templates_controller.rb +0 -73
  49. data/app/models/page_sweeper.rb +0 -63
  50. data/app/models/spud_template.rb +0 -10
  51. data/app/views/layouts/spud/admin/cms/detail.html.erb +0 -5
  52. data/spec/models/spud_template_spec.rb +0 -34
@@ -1,8 +1,9 @@
1
1
  module Spud::Cms::ApplicationHelper
2
+ MENU_INDEX = {}
2
3
  def sp_list_pages(options = {})
3
-
4
+
4
5
  pages = SpudPage.public.published_pages
5
-
6
+
6
7
  if Spud::Core.multisite_mode_enabled
7
8
  site_config = Spud::Core.site_config_for_host(request.host_with_port)
8
9
  pages = pages.site(site_config[:site_id]) if !site_config.blank?
@@ -12,7 +13,7 @@ module Spud::Cms::ApplicationHelper
12
13
  active_class = "menu-active"
13
14
  if !options.blank?
14
15
  if options.has_key?(:exclude)
15
-
16
+
16
17
  pages = pages.where(["name NOT IN (?)",options[:exclude]])
17
18
  end
18
19
  if options.has_key?(:start_page_id)
@@ -29,14 +30,14 @@ module Spud::Cms::ApplicationHelper
29
30
  if options.has_key?(:max_depth)
30
31
  max_depth = options[:max_depth]
31
32
  end
32
-
33
+
33
34
  else
34
35
  content = "<ul>"
35
36
  end
36
37
 
37
38
  pages = pages.all.group_by(&:spud_page_id)
38
39
  if pages[start_page].blank?
39
-
40
+
40
41
  return ""
41
42
  end
42
43
  pages[start_page].sort_by{|p| p.page_order}.each do |page|
@@ -55,7 +56,7 @@ module Spud::Cms::ApplicationHelper
55
56
  content += "</li>"
56
57
  end
57
58
  content += "</ul>"
58
-
59
+
59
60
  return content.html_safe
60
61
  end
61
62
 
@@ -64,18 +65,31 @@ module Spud::Cms::ApplicationHelper
64
65
 
65
66
  max_depth = 0
66
67
  menu = SpudMenu
68
+ menu_id = nil
69
+ menu_key = ""
67
70
  start_menu_item = nil
68
71
  if Spud::Core.multisite_mode_enabled
69
72
  site_config = Spud::Core.site_config_for_host(request.host_with_port)
70
73
  menu = menu.site(site_config[:site_id]) if !site_config.blank?
74
+ menu_key += "#{site_config[:site_id]}_"
71
75
  end
72
76
  if !options.blank?
73
77
 
74
78
  if options.has_key?(:menu_id)
75
- menu = menu.where(:id => options[:menu_id])
79
+ menu_id = options[:menu_id]
76
80
  end
77
81
  if options.has_key?(:name)
82
+ menu_key += options[:name]
83
+
78
84
  menu = menu.where(:name => options[:name])
85
+ menu_id = MENU_INDEX[menu_key]
86
+ if menu_id.blank?
87
+ menu = menu.first
88
+ if(!menu.blank?)
89
+ menu_id = menu.id
90
+ MENU_INDEX[menu_key] = menu.id
91
+ end
92
+ end
79
93
  end
80
94
  if options.has_key?(:start_menu_item_id)
81
95
  start_menu_item = options[:start_menu_item_id]
@@ -85,7 +99,7 @@ module Spud::Cms::ApplicationHelper
85
99
  else
86
100
  content = "<ul #{"class='#{options[:class]}'" if options.has_key?(:class)}>"
87
101
  end
88
-
102
+
89
103
 
90
104
  if options.has_key?(:max_depth)
91
105
  max_depth = options[:max_depth]
@@ -93,12 +107,11 @@ module Spud::Cms::ApplicationHelper
93
107
  else
94
108
  content = "<ul>"
95
109
  end
96
- menu = menu.first
97
- if menu.blank?
98
-
110
+
111
+ if menu_id.blank?
99
112
  return ""
100
113
  end
101
- menu_items = menu.spud_menu_items_combined.select("
114
+ menu_items = SpudMenuItem.where(:spud_menu_id => menu_id).select("
102
115
  #{SpudMenuItem.table_name}.id as id,
103
116
  #{SpudMenuItem.table_name}.url as url,
104
117
  #{SpudMenuItem.table_name}.classes as classes,
@@ -107,17 +120,16 @@ module Spud::Cms::ApplicationHelper
107
120
  #{SpudMenuItem.table_name}.parent_id as parent_id,
108
121
  #{SpudMenuItem.table_name}.name as name,
109
122
  #{SpudPage.table_name}.url_name as url_name").order(:parent_type,:parent_id).joins("LEFT JOIN #{SpudPage.table_name} ON (#{SpudPage.table_name}.id = #{SpudMenuItem.table_name}.spud_page_id)").all
110
-
111
-
123
+
112
124
 
113
125
  grouped_items = menu_items.group_by(&:parent_type)
114
126
 
115
127
  if grouped_items["SpudMenu"].blank?
116
-
128
+
117
129
  return ""
118
130
  end
119
131
  child_items = grouped_items["SpudMenuItem"].blank? ? [] : grouped_items["SpudMenuItem"].group_by(&:parent_id)
120
-
132
+
121
133
  parent_items = grouped_items["SpudMenu"]
122
134
  if start_menu_item != nil
123
135
  parent_items = child_items[start_menu_item]
@@ -140,14 +152,14 @@ module Spud::Cms::ApplicationHelper
140
152
  end
141
153
  content += "</li>"
142
154
  end
143
-
155
+
144
156
  content += "</ul>"
145
-
157
+
146
158
  return content.html_safe
147
159
  end
148
160
 
149
161
  def sp_menu_with_seperator(options={})
150
-
162
+
151
163
  seperator = "&nbsp;|&nbsp;".html_safe
152
164
  if(options.has_key?(:seperator))
153
165
  seperator = options[:seperator]
@@ -159,6 +171,9 @@ module Spud::Cms::ApplicationHelper
159
171
  menu = menu.site(site_config[:site_id]) if !site_config.blank?
160
172
  end
161
173
  menu = menu.first
174
+ if(menu.blank?)
175
+ return ""
176
+ end
162
177
  menu_items = menu.spud_menu_items_combined.select("
163
178
  #{SpudMenuItem.table_name}.id as id,
164
179
  #{SpudMenuItem.table_name}.url as url,
@@ -168,12 +183,12 @@ module Spud::Cms::ApplicationHelper
168
183
  #{SpudMenuItem.table_name}.parent_id as parent_id,
169
184
  #{SpudMenuItem.table_name}.name as name,
170
185
  #{SpudPage.table_name}.url_name as url_name").order(:parent_type,:parent_id).joins("LEFT JOIN #{SpudPage.table_name} ON (#{SpudPage.table_name}.id = #{SpudMenuItem.table_name}.spud_page_id)").all
171
-
172
- menu_tags = []
186
+
187
+ menu_tags = []
173
188
  menu_items.sort_by{|p| p.menu_order}.each do |item|
174
189
  menu_tags += ["<a #{"class='#{item.classes}' " if !item.classes.blank?}href='#{!item.url_name.blank? ? (item.url_name == Spud::Cms.root_page_name ? root_path() : page_path(:id => item.url_name)) : item.url}'>#{item.name}</a>"]
175
190
  end
176
-
191
+
177
192
  return menu_tags.join(seperator).html_safe
178
193
  end
179
194
  private
@@ -184,7 +199,7 @@ private
184
199
  return ""
185
200
  end
186
201
  content = "<ul>"
187
-
202
+
188
203
  spud_menu_items.sort_by{|p| p.menu_order}.each do |item|
189
204
  active = false
190
205
  if !item.url_name.blank?
@@ -233,8 +248,17 @@ private
233
248
  content += "</ul>"
234
249
  return content.html_safe
235
250
  end
236
-
237
251
 
238
-
239
-
252
+
253
+ def layout_options
254
+ layouts = Spud::Cms::Engine.template_parser.layouts
255
+ layout_options = []
256
+ layouts.each_pair do |key,value|
257
+ layout_options << [value[:template_name],key]
258
+ end
259
+ return layout_options
260
+ end
261
+
262
+
263
+
240
264
  end
@@ -5,12 +5,20 @@ class SpudMenuItem < ActiveRecord::Base
5
5
  has_many :spud_menu_items,:as => :parent,:dependent => :destroy
6
6
 
7
7
  validates :name,:presence => true
8
+ validates :spud_menu_id,:presence => true
8
9
  validates :parent_type,:presence => true
9
10
  validates :parent_id,:presence => true
10
11
 
11
12
 
12
- attr_accessible :name,:parent_type,:parent_id,:item_type,:spud_page_id,:menu_order,:url,:classes
13
+ attr_accessible :name,:parent_type,:parent_id,:item_type,:spud_page_id,:menu_order,:url,:classes
13
14
 
15
+ def get_url
16
+ if !self.spud_page.blank?
17
+ return self.spud_page.url_name
18
+ else
19
+ return url
20
+ end
21
+ end
14
22
 
15
23
  def options_tree(options,depth,current = nil)
16
24
  sub_items = self.spud_menu_items
@@ -57,19 +65,8 @@ class SpudMenuItem < ActiveRecord::Base
57
65
  end
58
66
  end
59
67
  end
60
-
68
+
61
69
  return list
62
70
  end
63
- # def self.options_tree_for_item(item,menu)
64
- # items = menu.spud_menu_items
65
- # items = items.where(["id != ?",item.id]) if !item.blank? && !item.id.blank?
66
-
67
71
 
68
- # options = []
69
- # items.each do |item|
70
- # options << ["#{item.name}",item.id]
71
- # options = item.options_tree(options,1,item)
72
- # end
73
- # return options
74
- # end
75
72
  end
@@ -2,7 +2,6 @@ class SpudPage < ActiveRecord::Base
2
2
  searchable
3
3
  belongs_to :spud_page
4
4
  has_many :spud_page_partial_revisions
5
- belongs_to :spud_template,:foreign_key => :template_id
6
5
  has_many :spud_pages, :dependent => :nullify
7
6
  has_many :spud_page_partials,:dependent => :destroy
8
7
  has_many :spud_permalinks,:as => :attachment, :dependent => :destroy
@@ -10,7 +9,7 @@ class SpudPage < ActiveRecord::Base
10
9
  belongs_to :updated_by_user,:class_name => "SpudUser",:foreign_key => :updated_by
11
10
 
12
11
 
13
- attr_accessible :name,:url_name,:created_by,:updated_by,:template_id,:visibility,:spud_page_id,:publish_at,:format,:meta_description,:meta_keywords,:page_order,:spud_page_partials_attributes,:use_custom_url_name,:published,:notes
12
+ attr_accessible :name,:url_name,:created_by,:updated_by,:layout,:visibility,:spud_page_id,:publish_at,:format,:meta_description,:meta_keywords,:page_order,:spud_page_partials_attributes,:use_custom_url_name,:published,:notes
14
13
 
15
14
  before_validation :generate_url_name
16
15
  validates :name,:presence => true
@@ -25,8 +24,17 @@ class SpudPage < ActiveRecord::Base
25
24
  scope :public, where(:visibility => 0)
26
25
 
27
26
 
28
- def self.grouped(site_id=nil)
29
- return site(site_id).all.group_by(&:spud_page_id)
27
+ def self.grouped(site_id=0)
28
+
29
+ if(Spud::Core.multisite_mode_enabled)
30
+ return site(site_id).all.group_by(&:spud_page_id)
31
+ else
32
+ return all.group_by(&:spud_page_id)
33
+ end
34
+ end
35
+
36
+ def to_liquid
37
+ return {'name' => self.name, 'url_name' => self.url_name}
30
38
  end
31
39
 
32
40
  # Returns an array of pages in order of heirarchy
@@ -0,0 +1,4 @@
1
+ class SpudPageLiquidTag < ActiveRecord::Base
2
+ attr_accessible :spud_page_partial_id, :tag_name, :value
3
+ belongs_to :spud_page_partial
4
+ end
@@ -1,8 +1,47 @@
1
1
  class SpudPagePartial < ActiveRecord::Base
2
2
  belongs_to :spud_page
3
- attr_accessible :name,:spud_page_id,:content,:format
3
+ has_many :spud_page_liquid_tags, :dependent => :destroy
4
+ validates :name,:presence => true
5
+ attr_accessible :name, :spud_page_id, :content, :format, :content_processed
4
6
  before_save :maintain_revisions
7
+ before_save :update_symbol_name
8
+ before_save :postprocess_content
5
9
 
10
+ def update_symbol_name
11
+ self.symbol_name = self.name.parameterize.underscore
12
+ end
13
+
14
+ def symbol_name
15
+ return @symbol_name || self.name.parameterize.underscore
16
+ end
17
+
18
+ def postprocess_content
19
+ template = Liquid::Template.parse(self.content) # Parses and compiles the template
20
+ update_taglist(template)
21
+ self.content_processed = template.render('page' => self.spud_page)
22
+ end
23
+
24
+ def update_taglist(template)
25
+ self.spud_page_liquid_tags.all.each do |tag|
26
+ tag.destroy
27
+ end
28
+ template.root.nodelist.each do |node|
29
+ if !node.is_a?(String) && defined?(node.tag_name) && defined?(node.tag_value)
30
+ self.spud_page_liquid_tags.create(:tag_name => node.tag_name,:value => node.tag_value)
31
+ end
32
+ end
33
+ end
34
+
35
+ def content_processed=(content)
36
+ write_attribute(:content_processed,content)
37
+ end
38
+
39
+ def content_processed
40
+ if read_attribute(:content_processed).blank?
41
+ self.update_column(:content_processed, postprocess_content)
42
+ end
43
+ return read_attribute(:content_processed)
44
+ end
6
45
 
7
46
  def maintain_revisions
8
47
  if !self.changed.include?('content')
@@ -0,0 +1,48 @@
1
+ class PageSweeper < ActionController::Caching::Sweeper
2
+ observe :spud_page,:spud_menu_item
3
+
4
+ def before_save(record)
5
+ if record.is_a?(SpudPage) && record.url_name_was != record.url_name
6
+ if Spud::Cms.cache_mode == :full_page
7
+ expire_page cache_path_for_page(record.url_name_was)
8
+ elsif Spud::Cms.cache_mode == :action
9
+ expire_action cache_path_for_page(record.url_name_was)
10
+ end
11
+ end
12
+ end
13
+
14
+ def after_save(record)
15
+ expire_cache_for(record)
16
+ expire_page spud_cms_sitemap_path(:format => :xml)
17
+ expire_page spud_sitemap_path(:format => :xml)
18
+ end
19
+
20
+ def after_destroy(record)
21
+ expire_cache_for(record)
22
+ expire_page spud_cms_sitemap_path
23
+ expire_page spud_sitemap_path
24
+ end
25
+
26
+ private
27
+ def expire_cache_for(record)
28
+ if record.is_a?(SpudPage)
29
+ if Spud::Cms.cache_mode == :full_page
30
+ expire_page cache_path_for_page(record.url_name)
31
+ elsif Spud::Cms.cache_mode == :action
32
+ expire_action cache_path_for_page(record.url_name)
33
+ end
34
+ else
35
+ Rails.cache.clear
36
+ SpudPage.site(session[:admin_site]).published_pages.all.each {|page| expire_cache_for(page)}
37
+ end
38
+ end
39
+
40
+ def cache_path_for_page(url_name)
41
+ if url_name == Spud::Cms.root_page_name
42
+ root_path
43
+ else
44
+ page_path(:id => url_name)
45
+ end
46
+ end
47
+
48
+ end
@@ -5,23 +5,21 @@
5
5
  <%if !@page.meta_description.blank?%>
6
6
  <meta name="description" content="<%=@page.meta_description%>" />
7
7
  <%end%>
8
- <%if !@page.meta_keywords.blank?%>
8
+
9
9
  <meta name="keywords" content="<%=@page.meta_keywords%>" />
10
- <%end%>
10
+
11
11
  <%end%>
12
12
 
13
13
  <%if !@inline.blank?%>
14
- <%=render :inline => @inline%>
15
- <%else%>
16
- <h2><%=@page.name%></h2>
14
+ <%=render :inline => @inline%>
17
15
  <%end%>
18
16
  <%@page.spud_page_partials.each do |page_partial|%>
19
-
20
- <%if(page_partial.name.downcase == 'body' && Spud::Cms.yield_body_as_content_block == false)%>
21
- <%=page_partial.content.html_safe%>
17
+
18
+ <%if(page_partial.name.match(/^body$/i) && Spud::Cms.yield_body_as_content_block == false)%>
19
+ <%=page_partial.content_processed.html_safe%>
22
20
  <%else%>
23
- <%=content_for page_partial.name.parameterize.underscore.to_sym do%>
24
- <%=page_partial.content.html_safe%>
21
+ <%=content_for page_partial.symbol_name.to_sym do%>
22
+ <%=page_partial.content_processed.html_safe%>
25
23
  <%end%>
26
24
  <%end%>
27
- <%end%>
25
+ <%end%>
@@ -3,16 +3,16 @@
3
3
  <div class="control-group">
4
4
  <legend>Page Title</legend>
5
5
  <%=f.label :name, :required=>true,:style =>"display:none;", :class=>"control-label"%>
6
-
6
+
7
7
  <%=f.text_field :name, :class => "full-width"%>
8
-
8
+
9
9
  </div>
10
10
  </fieldset>
11
- <div id="page_partials_form" class="formtabs">
12
- <ul class="formtab_buttons">
11
+ <div id="page_partials_form" class="formtabs tab-content">
12
+ <ul class="formtab_buttons nav nav-tabs">
13
13
  </ul>
14
14
  <%=f.fields_for :spud_page_partials do |b|%>
15
- <div class="formtab">
15
+ <div class="formtab tab-pane">
16
16
  <%=b.hidden_field :name,:class => "tab_name"%>
17
17
  <%=b.text_area :content,:class => "tinymce"%>
18
18
  </div>
@@ -21,19 +21,18 @@
21
21
  <br />
22
22
  <fieldset>
23
23
  <legend>Advanced Settings (optional)</legend>
24
-
25
- <%if Spud::Cms.templates_enabled%>
24
+
26
25
  <div class="control-group">
27
-
28
- <%=f.label :template_id, "Template", :class=>"control-label"%>
26
+
27
+ <%=f.label :layout, "Template", :class=>"control-label"%>
29
28
  <div class="controls">
30
- <%=f.select :template_id, options_for_select(SpudTemplate.site(session[:admin_site]).all.collect{|tp| [tp.name,tp.id]},@page.template_id), {:include_blank => 'Default'},{:title => "", 'data-source' => page_parts_spud_admin_pages_path(:page => @page.id) }%>
29
+ <%=f.select :layout, options_for_select(layout_options,@page.layout),{},{:title => "", 'data-source' => page_parts_spud_admin_pages_path(:page => @page.id) }%>
31
30
  <span class="help-inline">Use this to control the layout template to be used for this page if they are available.</span>
32
31
  </div>
33
32
  </div>
34
- <%end%>
33
+
35
34
  <div class="control-group">
36
-
35
+
37
36
  <%=f.label :spud_page_id, "Parent Page", :class=>"control-label"%>
38
37
  <div class="controls">
39
38
  <%=f.select :spud_page_id,options_for_select(SpudPage.options_tree_for_page(:filter => @page,:site_id => session[:admin_site]),@page.spud_page_id),{:include_blank => 'None'},{:title => ""}%>
@@ -41,7 +40,7 @@
41
40
  </div>
42
41
  </div>
43
42
  <div class="control-group">
44
-
43
+
45
44
  <%=f.label :url_name, "Perma Link",:disabled => true, :class=>"control-label"%>
46
45
  <div class="controls">
47
46
  <%=root_url%><%=f.text_field :url_name,:title => "",:size=>20%>
@@ -51,19 +50,19 @@
51
50
  </label>
52
51
  </div>
53
52
  </div>
54
-
53
+
55
54
  </fieldset>
56
55
  <fieldset>
57
56
  <legend>Meta Information (optional)</legend>
58
57
  <p>These fields are used to notify search engines about important keywords and the appropriate description to display in a search result.</p>
59
-
58
+
60
59
  <div class="control-group">
61
60
  <%=f.label :meta_keywords,"Keywords", :class=>"control-label"%>
62
61
  <div class="controls">
63
62
  <%=f.text_field :meta_keywords,:title => "",:style=>"width:600px;" %>
64
63
  <span class="help-inline">A Comma seperated list of keywords for search engines. Keep it short (no more than 10 keywords)</span>
65
64
  </div>
66
-
65
+
67
66
  </div>
68
67
  <div class="control-group">
69
68
  <%=f.label :meta_description,"Description", :class=>"control-label"%>