spud_cms 0.8.17 → 0.9.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 (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"%>