refinerycms-sl-snippets 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/app/assets/javascripts/page-snippet-picker.js +121 -0
  2. data/app/assets/javascripts/part-snippets-select.js +40 -0
  3. data/app/assets/stylesheets/page-snippet-picker.css +82 -0
  4. data/app/controllers/refinery/admin/snippets_controller.rb +38 -0
  5. data/app/controllers/refinery/admin/snippets_page_parts_controller.rb +38 -0
  6. data/app/models/refinery/snippet.rb +62 -0
  7. data/app/models/refinery/snippet_page_part.rb +20 -0
  8. data/app/views/admin/pages/tabs/_snippets_field.html.erb +46 -0
  9. data/app/views/refinery/admin/pages/tabs/_snippets.html.erb +3 -0
  10. data/app/views/refinery/admin/pages/tabs/_snippets_content.html.erb +24 -0
  11. data/app/views/refinery/admin/pages/tabs/_snippets_field.html.erb +55 -0
  12. data/app/views/refinery/admin/pages/tabs/_snippets_list_item.html.erb +20 -0
  13. data/app/views/refinery/admin/snippets/_actions.html.erb +28 -0
  14. data/app/views/refinery/admin/snippets/_form.html.erb +35 -0
  15. data/app/views/refinery/admin/snippets/_locale_picker.html.erb +12 -0
  16. data/app/views/refinery/admin/snippets/_records.html.erb +18 -0
  17. data/app/views/refinery/admin/snippets/_snippet.html.erb +22 -0
  18. data/app/views/refinery/admin/snippets/_snippets.html.erb +2 -0
  19. data/app/views/refinery/admin/snippets/_sortable_list.html.erb +7 -0
  20. data/app/views/refinery/admin/snippets/edit.html.erb +1 -0
  21. data/app/views/refinery/admin/snippets/index.html.erb +10 -0
  22. data/app/views/refinery/admin/snippets/new.html.erb +1 -0
  23. data/app/views/refinery/admin/snippets_page_parts/add.html.erb +1 -0
  24. data/app/views/refinery/admin/snippets_page_parts/remove.html.erb +1 -0
  25. data/config/locales/cs.yml +35 -0
  26. data/config/locales/en.yml +44 -0
  27. data/config/locales/es.yml +44 -0
  28. data/config/locales/nl.yml +22 -0
  29. data/config/routes.rb +18 -0
  30. data/db/migrate/1_create_snippets.rb +22 -0
  31. data/db/migrate/2_translate_snippets.rb +20 -0
  32. data/db/migrate/3_create_snippets_page_parts.rb +22 -0
  33. data/db/migrate/6_remove_position_from_snippets.rb +12 -0
  34. data/db/seeds.rb +6 -0
  35. data/features/manage_snippets.feature +63 -0
  36. data/features/step_definitions/snippet_steps.rb +14 -0
  37. data/features/support/paths.rb +17 -0
  38. data/lib/extensions/application_helper_extensions.rb +39 -0
  39. data/lib/extensions/page_extensions.rb +22 -0
  40. data/lib/gemspec.rb +31 -0
  41. data/lib/generators/refinery/snippets_generator.rb +22 -0
  42. data/lib/refinery/snippets.rb +29 -0
  43. data/lib/refinery/snippets/engine.rb +49 -0
  44. data/lib/refinery/snippets/tabs.rb +22 -0
  45. data/lib/refinery/snippets/version.rb +5 -0
  46. data/lib/refinerycms-snippets.rb +1 -0
  47. data/lib/tasks/snippets.rake +13 -0
  48. data/readme.md +52 -0
  49. data/refinerycms-snippets.gemspec +106 -0
  50. data/spec/helpers/application_helper_spec.rb +43 -0
  51. data/spec/models/page_spec.rb +39 -0
  52. data/spec/models/snippet_spec.rb +91 -0
  53. metadata +133 -0
@@ -0,0 +1,121 @@
1
+ $(document).ready(function (cms) {
2
+ cms = cms || {};
3
+ cms.plugin = cms.plugin || {};
4
+
5
+ /**
6
+ * Class for handling everything between page and snippets
7
+ */
8
+ cms.plugin.PageSnippet = {
9
+ processing: false,
10
+ content_holder: [], // html wrapper for all stuff
11
+ add_snippet: [], // add snippet anchor
12
+ remove_snippet: [],
13
+
14
+ spinner_on: function () {
15
+ this.processing = true;
16
+ this.content_holder.css({opacity: 0.5});
17
+ },
18
+
19
+ spinner_off: function () {
20
+ this.content_holder.css({opacity: 1});
21
+ this.processing = false;
22
+ },
23
+
24
+ update: function (html) {
25
+ this.clear();
26
+ this.content_holder.html(html);
27
+ this.bind();
28
+ this.spinner_off();
29
+ },
30
+
31
+ add: function (elm) {
32
+ var that = this,
33
+ add_url = $(elm).attr('href');
34
+
35
+ if (!this.processing) {
36
+ this.spinner_on();
37
+ var partId = $('#part-snippets-select').val();
38
+ $.ajax({
39
+ url: add_url,
40
+ type: 'GET',
41
+ dataType: 'html',
42
+ error: function (response) { alert(response); },
43
+ complete: function (e) {
44
+ // console.log(e);
45
+ },
46
+ success: function (response) {
47
+ that.update(response);
48
+ cms.plugin.PartSnippetsSelect.init();
49
+ $('#part-snippets-select').val(partId).change();
50
+ }
51
+ });
52
+ }
53
+ },
54
+
55
+ remove: function (elm) {
56
+ var that = this,
57
+ remove_url = $(elm).attr('href');
58
+
59
+ if (!this.processing) {
60
+ this.spinner_on();
61
+ var partId = $('#part-snippets-select').val();
62
+ // console.log('remove start');
63
+ $.ajax({
64
+ url: remove_url,
65
+ dataType: 'html',
66
+ error: function (response) {
67
+ alert(response);
68
+ },
69
+ complete: function (e) {
70
+ // console.log(e);
71
+ },
72
+ success: function (response) {
73
+ that.update(response);
74
+ cms.plugin.PartSnippetsSelect.init();
75
+ $('#part-snippets-select').val(partId).change();
76
+ }
77
+ });
78
+ }
79
+ },
80
+
81
+ /**
82
+ * Remove event handlers and other smells
83
+ */
84
+ clear: function () {
85
+ // console.log('start clear');
86
+ this.content_holder.find('a').unbind('click');
87
+ this.content_holder.find('a').unbind('mouseout');
88
+ this.content_holder.find('a').unbind('mouseover');
89
+ },
90
+
91
+ /**
92
+ * Bind event handlers and other smells ;-)
93
+ */
94
+ bind: function () {
95
+ var that = this;
96
+ this.add_snippet = this.content_holder.find('a.add-snippet');
97
+ this.remove_snippet = this.content_holder.find('a.remove-snippet');
98
+
99
+ this.add_snippet.click(function (e) {
100
+ e.preventDefault();
101
+ that.add(this);
102
+ return false;
103
+ });
104
+
105
+ this.remove_snippet.click(function (e) {
106
+ e.preventDefault();
107
+ that.remove(this);
108
+ return false;
109
+ });
110
+ },
111
+
112
+ init: function () {
113
+ this.content_holder = $('#page_snippet_picker');
114
+ if (this.content_holder.length > 0) {
115
+ this.bind();
116
+ }
117
+ }
118
+ }
119
+
120
+ cms.plugin.PageSnippet.init();
121
+ });
@@ -0,0 +1,40 @@
1
+ $(document).ready(function (cms) {
2
+ cms = cms || {};
3
+ cms.plugin = cms.plugin || {};
4
+
5
+ /**
6
+ * Generates a drop-down box for changing the displayed page part
7
+ * in the snippets tab in the edit page interface.
8
+ */
9
+ cms.plugin.PartSnippetsSelect = {
10
+
11
+ init: function() {
12
+ $('#part-snippets-menu').html(this.generateWidget());
13
+ this.changeVisiblePart();
14
+ $('#part-snippets-select').change(this.changeVisiblePart);
15
+ },
16
+
17
+ /**
18
+ * Writes the html code for the drop-down box.
19
+ */
20
+ generateWidget: function() {
21
+ select = '<select id="part-snippets-select">';
22
+ $('#part-snippets-menu a').each(function(i,e) {
23
+ select += '<option value="'+$(e).attr('href').split('#',2)[1]+'">'
24
+ select += e.text
25
+ select += '</option>'
26
+ });
27
+ select += '</select>';
28
+ return select;
29
+ },
30
+
31
+ changeVisiblePart: function() {
32
+ $('.part-snippets').css('display', 'none');
33
+ $('#'+$('#part-snippets-select').val()).css('display', 'block');
34
+ },
35
+
36
+ }
37
+
38
+ cms.plugin.PartSnippetsSelect.init();
39
+
40
+ });
@@ -0,0 +1,82 @@
1
+ /*
2
+ Document : page-snippet-picker.css
3
+ Created on : May 16, 2011, 4:41:03 AM
4
+ Author : keram
5
+ Description:
6
+ Styles for snippets administrations
7
+ */
8
+
9
+ a.add-snippet,
10
+ span.add-snippet {
11
+ background-repeat: no-repeat;
12
+ background-position: left center;
13
+ border: none;
14
+ padding-left: 20px;
15
+ }
16
+
17
+ span.add-snippet {
18
+ float: right;
19
+ color: lightGray;
20
+ margin: 3px;
21
+ }
22
+
23
+ .part-snippets ul {
24
+ background: #fff;
25
+ padding: 10px;
26
+ padding-bottom: 0px;
27
+ margin-bottom: 5px;
28
+ }
29
+
30
+ .active-snippets ul {
31
+ margin-bottom: 15px;
32
+ }
33
+
34
+ .inactive-snippets ul {
35
+ background: #fcfcfc;
36
+ }
37
+
38
+ .msg {
39
+ margin: 5px 5px 10px;
40
+ padding: 20px;
41
+ }
42
+
43
+ .msg.alert {
44
+ color: #f66;
45
+ background: #fff;
46
+ }
47
+
48
+ .part-snippets {
49
+ margin-bottom: 5ex;
50
+ }
51
+
52
+ .part-snippets:last-child {
53
+ margin-bottom: 0;
54
+ }
55
+
56
+ #page_snippet_picker div.actions {
57
+ display: inline;
58
+ }
59
+
60
+ #page_snippet_picker span.title {
61
+ line-height: 30px;
62
+ }
63
+
64
+ #part-snippets-menu, .part-snippets {
65
+ margin: 1ex;
66
+ }
67
+
68
+ #part-snippets-menu li {
69
+ display: inline;
70
+ }
71
+
72
+ #part-snippets-select {
73
+ font-weight: bold;
74
+ width: 21%;
75
+ font-size: 16px;
76
+ line-height: 20px;
77
+ }
78
+
79
+ .part-snippets .block {
80
+ border-top: solid 1px #99998B;
81
+ padding-top: 1ex;
82
+ }
@@ -0,0 +1,38 @@
1
+ module ::Refinery
2
+ module Admin
3
+ class SnippetsController < ::Refinery::AdminController
4
+
5
+ crudify :'refinery/snippet', :xhr_paging => true
6
+
7
+ def create
8
+ if (@snippet = Refinery::Snippet.create(params[:snippet])).valid?
9
+ (request.xhr? ? flash.now : flash).notice = t(
10
+ 'refinery.crudify.created',
11
+ :what => "#{@snippet.title}"
12
+ )
13
+
14
+ unless request.xhr?
15
+ redirect_to (params[:continue_editing] =~ /1/ ? refinery.edit_admin_snippet_path(@snippet) : refinery.admin_snippets_url)
16
+ else
17
+ response = Hash.new
18
+ response['redirect'] = refinery.edit_admin_snippet_path(@snippet) if params[:continue_editing]
19
+ render :json => response
20
+ end
21
+
22
+ else
23
+ unless request.xhr?
24
+ render :action => 'new'
25
+ else
26
+ html_snippets = Hash.new
27
+ html_snippets['flash_container'] = render_to_string(:partial => "/shared/admin/error_messages",
28
+ :locals => {
29
+ :object => @snippet,
30
+ :include_object_name => true
31
+ })
32
+ render :json => {'snippets' => html_snippets}
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ module ::Refinery
2
+ module Admin
3
+ class SnippetsPagePartsController < ::Refinery::AdminController
4
+
5
+ def add
6
+ @page = Refinery::Page.find(params[:id])
7
+ @part = Refinery::PagePart.find(params[:part_id])
8
+ @snippet = Refinery::Snippet.find(params[:snippet_id])
9
+ before_body = params[:before_body] == 'true' ? true : false
10
+
11
+ sp = Refinery::SnippetPagePart.new(:page_part => @part, :snippet => @snippet, :before_body => before_body)
12
+
13
+ if sp.save
14
+ flash[:notice] = "Snippet #{@snippet.title} was successfully added."
15
+ end
16
+
17
+ render :layout => false if request.xhr?
18
+ end
19
+
20
+ def remove
21
+ @page = Refinery::Page.find(params[:id])
22
+ @part = Refinery::PagePart.find(params[:part_id])
23
+ @snippet = Refinery::Snippet.find(params[:snippet_id])
24
+ before_body = params[:before_body] == 'true' ? true : false
25
+
26
+ sp = Refinery::SnippetPagePart.where(:page_part_id => @part, :snippet_id => @snippet, :before_body => before_body)
27
+
28
+ removed = sp.first.destroy() unless sp.empty?
29
+
30
+ if removed
31
+ flash[:notice] = "Snippet #{@snippet.title} was successfully removed."
32
+ end
33
+
34
+ render :layout => false if request.xhr?
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,62 @@
1
+ module Refinery
2
+ class Snippet < ActiveRecord::Base
3
+
4
+ TEMPLATES_DIR = "app/views/shared/snippets"
5
+
6
+ attr_protected :id
7
+
8
+ acts_as_indexed :fields => [:title, :body]
9
+
10
+ validates :title, :presence => true, :uniqueness => true
11
+
12
+ translates :body
13
+
14
+ has_many :snippet_page_parts, :dependent => :destroy
15
+ has_many :page_parts, :through => :snippet_page_parts
16
+
17
+ scope :for_page, lambda{ |page|
18
+ raise RuntimeError.new("Couldn't find Snippet for a nil Page") if page.blank?
19
+ joins(:page_parts => :page).where(:refinery_pages => {:id => page.id})
20
+ }
21
+
22
+ scope :before, where(:snippets_page_parts => {:before_body => true})
23
+ scope :after, where(:snippets_page_parts => {:before_body => false})
24
+
25
+ # rejects any snippet that has not been translated to the current
26
+ # locale.
27
+ scope :translated, lambda {
28
+ pages = Arel::Table.new(Refinery::Snippet.table_name)
29
+ translations = Arel::Table.new(Refinery::Snippet.translations_table_name)
30
+
31
+ includes(:translations).where(
32
+ translations[:locale].eq(Globalize.locale)).where(pages[:id].eq(translations[:snippet_id]))
33
+ }
34
+
35
+ def pages
36
+ Refinery::Page.for_snippet(self)
37
+ end
38
+
39
+ def before?(part)
40
+ part.snippets.before.include? self
41
+ end
42
+
43
+ def after?(part)
44
+ part.snippets.after.include? self
45
+ end
46
+
47
+ def template_filename
48
+ filename = self.title.strip.gsub(/[^A-Za-z0-9]/,'_').squeeze('_').downcase
49
+ filename = "_#{filename}" unless filename.start_with?('_')
50
+ "#{filename}.html.erb"
51
+ end
52
+
53
+ def template_path
54
+ File.join(TEMPLATES_DIR, template_filename)
55
+ end
56
+
57
+ def template?
58
+ File.file? template_path
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,20 @@
1
+ module Refinery
2
+ class SnippetPagePart < ActiveRecord::Base
3
+
4
+ self.table_name = 'snippets_page_parts'
5
+
6
+ attr_protected :id
7
+
8
+ delegate :title, :to => :snippet
9
+
10
+ belongs_to :snippet, :foreign_key => :snippet_id
11
+ belongs_to :page_part, :foreign_key => :page_part_id
12
+
13
+ validates_uniqueness_of :snippet_id, :scope => [:page_part_id, :before_body]
14
+
15
+ before_save do |snippet_page_part|
16
+ snippet_page_part.position = (Refinery::SnippetPagePart.where('page_part_id = ?', snippet_page_part.page_part_id).maximum(:position) || -1) + 1
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,46 @@
1
+ <div id="<%= "part-#{part.id}" %>" class="part-snippets">
2
+ <div class="active-snippets block">
3
+ <% if part.snippets.before.any? %>
4
+ <h3><%= t('.before_body') %></h3>
5
+ <ul>
6
+ <%= render :partial => '/admin/pages/tabs/snippets_list_item', :collection => part.snippets.before, :as => :snippet, :locals => {:part => part, :before_body => true} %>
7
+ </ul>
8
+ <% end %>
9
+ <% if part.snippets.after.any? %>
10
+ <h3><%= t('.after_body') %></h3>
11
+ <ul>
12
+ <%= render :partial => '/admin/pages/tabs/snippets_list_item', :collection => part.snippets.after, :as => :snippet, :locals => {:part => part, :before_body => false} %>
13
+ </ul>
14
+ <% end %>
15
+ </div>
16
+ <div class="inactive-snippets block">
17
+ <% inactive_snippets = Snippet.all %>
18
+ <% if inactive_snippets.length > 0 %>
19
+ <h3><%= t('.inactive') %></h3>
20
+ <ul>
21
+ <% inactive_snippets.each do |snippet| %>
22
+ <li class='clearfix record <%= cycle('on', 'on-hover') %>' >
23
+ <span class="title"><%= snippet.title %></span>
24
+ <div class="actions">
25
+ <% unless snippet.after?(part) %>
26
+ <%= link_to t('.add_after_body'), {:controller => 'snippets_page_parts', :action => 'add', :id => @page.id, :snippet_id => snippet.id, :part_id => part.id}, :class => 'add_icon add-snippet' %>
27
+ <% else %>
28
+ <span class="add_icon add-snippet"><%= t('.add_after_body') %></span>
29
+ <% end %>
30
+ <% unless snippet.before?(part) %>
31
+ <%= link_to t('.add_before_body'), {:controller => 'snippets_page_parts', :action => 'add', :id => @page.id, :snippet_id => snippet.id, :part_id => part.id, :before_body => 'true'}, :class => 'add_icon add-snippet' %>
32
+ <% else %>
33
+ <span class="add_icon add-snippet"><%= t('.add_before_body') %></span>
34
+ <% end %>
35
+ </div>
36
+ </li>
37
+ <% end %>
38
+ </ul>
39
+ <% end %>
40
+ </div>
41
+ </div>
42
+
43
+
44
+
45
+
46
+