puffer_pages 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +11 -11
  3. data/README.md +63 -0
  4. data/VERSION +1 -1
  5. data/app/controllers/pages_controller.rb +2 -2
  6. data/app/controllers/puffer_pages/layouts_controller.rb +5 -1
  7. data/app/controllers/puffer_pages/pages_controller.rb +15 -13
  8. data/app/controllers/puffer_pages/snippets_controller.rb +5 -1
  9. data/app/helpers/puffer_pages_helper.rb +8 -0
  10. data/app/helpers/puffer_tree_helper.rb +11 -0
  11. data/app/models/page.rb +8 -9
  12. data/app/models/page_part.rb +1 -1
  13. data/app/views/puffer_pages/_page_part_builder.html.erb +3 -0
  14. data/app/views/puffer_pages/_page_parts.html.erb +26 -0
  15. data/app/views/puffer_pages/_tree_page.html.erb +2 -0
  16. data/app/views/puffer_tree/tree.html.erb +55 -0
  17. data/lib/generators/puffer_pages/install/install_generator.rb +8 -0
  18. data/lib/generators/puffer_pages/install/templates/puffer/javascripts/puffer_pages.js +35 -0
  19. data/lib/generators/puffer_pages/install/templates/puffer/javascripts/right-dialog.js +764 -0
  20. data/{spec/dummy/public/puffer/javascripts/right-tabs-src.js → lib/generators/puffer_pages/install/templates/puffer/javascripts/right-tabs.js} +1 -2
  21. data/lib/generators/puffer_pages/install/templates/puffer/stylesheets/puffer_pages.css +4 -0
  22. data/lib/generators/puffer_pages/install/templates/puffer/stylesheets/puffer_tree.css +51 -0
  23. data/lib/generators/puffer_pages/install/templates/puffer_pages.rb +16 -0
  24. data/lib/puffer/inputs/page_parts.rb +12 -0
  25. data/lib/puffer/inputs/page_parts_body.rb +13 -0
  26. data/lib/puffer/tree_base.rb +31 -0
  27. data/lib/puffer_pages/extensions/mapper.rb +2 -2
  28. data/lib/puffer_pages/liquid/tags/yield.rb +1 -1
  29. data/lib/puffer_pages.rb +15 -1
  30. data/puffer_pages.gemspec +31 -29
  31. data/spec/dummy/config/initializers/puffer.rb +12 -0
  32. data/spec/dummy/config/initializers/puffer_pages.rb +16 -0
  33. data/spec/dummy/db/migrate/20090422092419_create_pages.rb +0 -1
  34. data/spec/dummy/db/schema.rb +0 -1
  35. data/spec/dummy/public/puffer/javascripts/{application.js → puffer.js} +0 -0
  36. data/spec/dummy/public/puffer/javascripts/puffer_pages.js +35 -0
  37. data/spec/dummy/public/puffer/javascripts/{rails-src.js → rails.js} +0 -0
  38. data/spec/dummy/public/puffer/javascripts/right-autocompleter.js +615 -12
  39. data/spec/dummy/public/puffer/javascripts/right-calendar.js +1454 -29
  40. data/spec/dummy/public/puffer/javascripts/right-dialog.js +764 -0
  41. data/spec/dummy/public/puffer/javascripts/right-tabs.js +1139 -24
  42. data/spec/dummy/public/puffer/javascripts/right.js +5886 -89
  43. data/spec/dummy/public/puffer/stylesheets/puffer.css +1 -12
  44. data/spec/dummy/public/puffer/stylesheets/puffer_pages.css +4 -0
  45. data/spec/dummy/public/puffer/stylesheets/puffer_tree.css +51 -0
  46. data/spec/fabricators/pages_fabricator.rb +1 -1
  47. data/spec/models/page_spec.rb +15 -15
  48. metadata +33 -31
  49. data/README.rdoc +0 -3
  50. data/lib/puffer_pages/base.rb +0 -10
  51. data/spec/dummy/config/puffer.rb +0 -0
  52. data/spec/dummy/public/puffer/javascripts/right-autocompleter-src.js +0 -621
  53. data/spec/dummy/public/puffer/javascripts/right-autocompleter.js.gz +0 -0
  54. data/spec/dummy/public/puffer/javascripts/right-calendar-src.js +0 -1461
  55. data/spec/dummy/public/puffer/javascripts/right-calendar.js.gz +0 -0
  56. data/spec/dummy/public/puffer/javascripts/right-in-edit-src.js +0 -369
  57. data/spec/dummy/public/puffer/javascripts/right-in-edit.js +0 -13
  58. data/spec/dummy/public/puffer/javascripts/right-in-edit.js.gz +0 -0
  59. data/spec/dummy/public/puffer/javascripts/right-lightbox-src.js +0 -905
  60. data/spec/dummy/public/puffer/javascripts/right-lightbox.js +0 -24
  61. data/spec/dummy/public/puffer/javascripts/right-lightbox.js.gz +0 -0
  62. data/spec/dummy/public/puffer/javascripts/right-sortable-src.js +0 -428
  63. data/spec/dummy/public/puffer/javascripts/right-sortable.js +0 -17
  64. data/spec/dummy/public/puffer/javascripts/right-sortable.js.gz +0 -0
  65. data/spec/dummy/public/puffer/javascripts/right-src.js +0 -5892
  66. data/spec/dummy/public/puffer/javascripts/right-tabs.js.gz +0 -0
  67. data/spec/dummy/public/puffer/javascripts/right.js.gz +0 -0
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "http://rubygems.org"
3
3
  gem 'rails', '~> 3.0.3'
4
4
  gem 'liquid'
5
5
  gem 'nested_set'
6
- gem 'puffer', '>= 0.0.11'
6
+ gem 'puffer', '>= 0.0.13'
7
7
  gem 'will_paginate', '~> 3.0.pre2'
8
8
  gem 'cells', '~> 3.4.4'
9
9
 
data/Gemfile.lock CHANGED
@@ -82,7 +82,7 @@ GEM
82
82
  railties (>= 3.0.0)
83
83
  nokogiri (1.4.4)
84
84
  polyglot (0.3.1)
85
- puffer (0.0.11)
85
+ puffer (0.0.13)
86
86
  cells (~> 3.4.4)
87
87
  rails (~> 3.0.3)
88
88
  will_paginate (~> 3.0.pre2)
@@ -105,19 +105,19 @@ GEM
105
105
  rake (>= 0.8.7)
106
106
  thor (~> 0.14.4)
107
107
  rake (0.8.7)
108
- rspec (2.4.0)
109
- rspec-core (~> 2.4.0)
110
- rspec-expectations (~> 2.4.0)
111
- rspec-mocks (~> 2.4.0)
112
- rspec-core (2.4.0)
113
- rspec-expectations (2.4.0)
108
+ rspec (2.5.0)
109
+ rspec-core (~> 2.5.0)
110
+ rspec-expectations (~> 2.5.0)
111
+ rspec-mocks (~> 2.5.0)
112
+ rspec-core (2.5.1)
113
+ rspec-expectations (2.5.0)
114
114
  diff-lcs (~> 1.1.2)
115
- rspec-mocks (2.4.0)
116
- rspec-rails (2.4.1)
115
+ rspec-mocks (2.5.0)
116
+ rspec-rails (2.5.0)
117
117
  actionpack (~> 3.0)
118
118
  activesupport (~> 3.0)
119
119
  railties (~> 3.0)
120
- rspec (~> 2.4.0)
120
+ rspec (~> 2.5.0)
121
121
  rubyzip (0.9.4)
122
122
  selenium-webdriver (0.1.2)
123
123
  childprocess (~> 0.1.5)
@@ -148,7 +148,7 @@ DEPENDENCIES
148
148
  liquid
149
149
  mongrel
150
150
  nested_set
151
- puffer (>= 0.0.11)
151
+ puffer (>= 0.0.13)
152
152
  rails (~> 3.0.3)
153
153
  rspec-rails
154
154
  sqlite3-ruby
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Puffer pages is lightweight rails 3 CMS
2
+
3
+ Interface of pages based on [puffer](https://github.com/puffer/puffer)
4
+
5
+ ## Keyfeatures
6
+
7
+ * Full rails integration. Puffer pages is part of rails and you can different features related to pages in rails application directly
8
+ * Flexibility. Puffer designed to be as flexible as possible, so you can create your own functionality easily.
9
+ * Layouts. You can use rails layouts for pages and you can use pages as action layouts!
10
+
11
+ ## Installation.
12
+
13
+ You can instal puffer as a gem:
14
+ <pre>gem install puffer_pages</pre>
15
+ Or in Gemfile:
16
+ <pre>gem "puffer_pages"</pre>
17
+ Next step is:
18
+ <pre>rails g puffer_pages:install</pre>
19
+ This will install puffer pages config file in your initializers, some css/js, controllers and migrations
20
+ <pre>rake db:migrate</pre>
21
+
22
+ ## Introduction.
23
+
24
+ The first thing, you should do - setup routes if you want pages path different from /(*path).
25
+ Just put in your routes.rb:
26
+ <pre>puffer_page "pages/(*path)" => 'whatever#show'</pre>
27
+ Default pages route you can see with rake routes.
28
+
29
+ Puffer pages is radiant-like cms, so it has layouts, snippets and pages.
30
+ Puffer pages use liquid as template language.
31
+
32
+ ## Pages.
33
+ Pages - tree-based structure of site.
34
+ Every page has one or more page parts.
35
+
36
+ ## Layouts.
37
+ Layout is page canvas, so you can draw page parts on it.
38
+ In puffer pages you can use puffer pages layouts or applcation layouts.
39
+
40
+ ### Puffer pages layouts
41
+ For puffer pages layouts page parts placeholder is liquid tag yield.
42
+ <pre>{% yield [page_part_name] %}</pre>
43
+
44
+ If no page_part_name specified, puffer layout will use page part with default name (`body`). You can change defaul page part name in puffer pages setup initializer.
45
+
46
+ ### Application layouts.
47
+ For application layout page part body will be inserted instead of SUDDENLY! <%= yield %>
48
+ Rules are the same. If no page part name specified puffer will use page part with default name.
49
+
50
+ So, main page part is action view and other are partials. So easy.
51
+
52
+ ## Liquid.
53
+
54
+ The first tag was {% yield %}
55
+ Also, you can acces current page and root page from puffer pages templates.
56
+ Page named `self` in templates:
57
+ <pre>{{ self.name }}</pre>
58
+ And root page:
59
+ <pre>{{ root.name }}</pre>
60
+
61
+ Also you can do anything you can do with [liquid](http://github.com/tobi/liquid/)
62
+
63
+ `self` and `root` are both instances of page drop. View [this](https://github.com/puffer/puffer_pages/blob/master/lib/puffer_pages/liquid/page_drop.rb) to find list of possible page drop methods
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -1,8 +1,8 @@
1
1
  class PagesController < ApplicationController
2
2
 
3
3
  def index
4
- @page = Page.find_page("/#{params[:path]}")
5
- render :inline => @page.render(drops), :layout => @page.render_layout, :content_type => page.content_type
4
+ @page = Page.find_page params[:path]
5
+ render :inline => @page.render(drops), :layout => @page.render_layout, :content_type => @page.content_type
6
6
  end
7
7
 
8
8
  private
@@ -1,6 +1,10 @@
1
- class PufferPages::LayoutsController < PufferPages::Base
1
+ class PufferPages::LayoutsController < Puffer::Base
2
2
  unloadable
3
3
 
4
+ configure do
5
+ group :cms
6
+ end
7
+
4
8
  index do
5
9
  field :name
6
10
  end
@@ -1,6 +1,17 @@
1
- class PufferPages::PagesController < PufferPages::Base
1
+ class PufferPages::PagesController < Puffer::TreeBase
2
2
  unloadable
3
3
 
4
+ view_paths_fallbacks_prepend :puffer_pages
5
+ helper :puffer_pages
6
+
7
+ configure do
8
+ group :cms
9
+ end
10
+
11
+ tree do
12
+ field :name, :render => :tree_page
13
+ end
14
+
4
15
  index do
5
16
  field :name
6
17
  field :slug
@@ -9,24 +20,15 @@ class PufferPages::PagesController < PufferPages::Base
9
20
  end
10
21
 
11
22
  form do
12
- field :parent_id, :type => :hidden
13
23
  field :name
14
24
  field :slug
25
+ field :page_parts, :type => :page_parts
15
26
  field :layout_name, :select => :possible_layouts
16
- field :status, :select => Page.statuses
27
+ field :status, :select => :possible_statuses
17
28
  field :title
18
29
  field :description
19
30
  field :keywords
20
- end
21
-
22
- member do
23
- get :inherit
24
- end
25
-
26
- def inherit
27
- @parent = resource.member
28
- @page = @parent.children.new
29
- render 'new'
31
+ field :parent_id, :type => :hidden
30
32
  end
31
33
 
32
34
  end
@@ -1,6 +1,10 @@
1
- class PufferPages::SnippetsController < PufferPages::Base
1
+ class PufferPages::SnippetsController < Puffer::Base
2
2
  unloadable
3
3
 
4
+ configure do
5
+ group :cms
6
+ end
7
+
4
8
  index do
5
9
  field :name
6
10
  end
@@ -16,4 +16,12 @@ module PufferPagesHelper
16
16
  record.inherited_layout_name ? [[t('puffer.inherited_layout', :name => record.inherited_layout_name), '']] : []
17
17
  end
18
18
 
19
+ def possible_statuses
20
+ Page.statuses
21
+ end
22
+
23
+ def tree_page record
24
+ render :partial => 'tree_page', :object => record
25
+ end
26
+
19
27
  end
@@ -0,0 +1,11 @@
1
+ module PufferTreeHelper
2
+
3
+ def puffer_tree hash, options = {}, &block
4
+ content_tag :ul, options do
5
+ hash.keys.each do |node|
6
+ block.call node, render_tree(hash[node], &block)
7
+ end
8
+ end if hash.present?
9
+ end
10
+
11
+ end
data/app/models/page.rb CHANGED
@@ -1,6 +1,3 @@
1
- class LayoutError < StandardError
2
- end
3
-
4
1
  class Page < ActiveRecord::Base
5
2
 
6
3
  acts_as_nested_set
@@ -20,9 +17,11 @@ class Page < ActiveRecord::Base
20
17
  def self.find_page location
21
18
  page = Page.find_by_location location
22
19
  raise ActiveRecord::RecordNotFound if page.nil? || page.draft?
20
+ page
23
21
  end
24
22
 
25
- has_many :page_parts, :order => "name = '#{PufferPages::MAIN_PART}' desc, name", :dependent => :destroy
23
+ has_many :page_parts, :order => "name = '#{PufferPages.primary_page_part_name}' desc, name", :dependent => :destroy
24
+ accepts_nested_attributes_for :page_parts, :allow_destroy => true
26
25
  belongs_to :layout, :primary_key => :name, :foreign_key => :layout_name
27
26
 
28
27
  validates_presence_of :name
@@ -31,11 +30,11 @@ class Page < ActiveRecord::Base
31
30
  end
32
31
  validates_uniqueness_of :slug, :scope => :parent_id
33
32
  validates_format_of :slug,
34
- :with => /\A([a-zA-Z0-9]+[\w-]*(\.[a-zA-Z0-9]+)?|\*)\Z/,
33
+ :with => /\A([\w]+[\w-]*(\.[\w]+)?|\*)\Z/,
35
34
  :message => :slug_format,
36
35
  :unless => :root?
37
36
  validates_format_of :slug,
38
- :with => /\A\/\Z/,
37
+ :with => /\A\Z/,
39
38
  :message => :root_slug_format,
40
39
  :if => :root?
41
40
  validates_inclusion_of :status, :in => Page.statuses
@@ -49,7 +48,7 @@ class Page < ActiveRecord::Base
49
48
 
50
49
  before_save :update_location
51
50
  def update_location
52
- self.location = [(swallow_nil{parent.location} || '/'), slug].compact.join('/').gsub(/\/+/, '/')
51
+ self.location = [swallow_nil{parent.location}, slug].compact.join('/').presence
53
52
  end
54
53
 
55
54
  before_update :update_locations
@@ -59,7 +58,7 @@ class Page < ActiveRecord::Base
59
58
 
60
59
  after_save :create_main_part
61
60
  def create_main_part
62
- page_parts.create(:name => PufferPages::MAIN_PART) if root?
61
+ page_parts.create(:name => PufferPages.primary_page_part_name) if root?
63
62
  end
64
63
 
65
64
  statuses.each do |status_name|
@@ -96,7 +95,7 @@ class Page < ActiveRecord::Base
96
95
  end
97
96
 
98
97
  def inherited_page_parts
99
- PagePart.where(:page_id => self_and_ancestors.map(&:id).reverse).group('name').order("name = '#{PufferPages::MAIN_PART}' desc, name")
98
+ PagePart.where(:page_id => self_and_ancestors.map(&:id).reverse).group('name').order("name = '#{PufferPages.primary_page_part_name}' desc, name")
100
99
  end
101
100
 
102
101
  def part name
@@ -17,7 +17,7 @@ class PagePart < ActiveRecord::Base
17
17
  end
18
18
 
19
19
  def main?
20
- name == PufferPages::MAIN_PART
20
+ name == PufferPages.primary_page_part_name
21
21
  end
22
22
 
23
23
  end
@@ -0,0 +1,3 @@
1
+ <%= page_part_builder.puffer_field :name, :type => :hidden %>
2
+ <%= page_part_builder.puffer_field :body, :type => :page_parts_body %>
3
+ <%= page_part_builder.puffer_field :_destroy, :type => :hidden, :html => { :class => 'destroy_mark' } %>
@@ -0,0 +1,26 @@
1
+ <ul id="page_parts" data-tabs="{closable: true, onRemove: page_part_tab_remove, addButton: page_part_tab_add}">
2
+ <ul>
3
+ <% builder.object.page_parts.each_with_index do |page_part, index| %>
4
+ <li><%= link_to page_part.name, "#page_part_tab_#{index}" %></li>
5
+ <% end %>
6
+ </ul>
7
+ <% builder.object.page_parts.each_with_index do |page_part, index| %>
8
+ <li id="<%= "page_part_tab_#{index}" %>">
9
+ <%= builder.fields_for :page_parts, page_part do |page_part_builder| %>
10
+ <%= render :partial => 'page_part_builder', :object => page_part_builder %>
11
+ <% end %>
12
+ </li>
13
+ <% end %>
14
+ </ul>
15
+ <div id="page_parts_marked_for_destroy">
16
+ </div>
17
+
18
+ <% new_page_part_tab_panel = capture do %>
19
+ <%= builder.fields_for :page_parts, PagePart.new, :child_index => 'new_page_part_tab_panel_index' do |page_part_builder| %>
20
+ <%= render :partial => 'page_part_builder', :object => page_part_builder %>
21
+ <% end %>
22
+ <% end %>
23
+
24
+ <%= javascript_tag do %>
25
+ var new_page_part_tab_panel = '<%= escape_javascript new_page_part_tab_panel.strip %>'
26
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <strong><%= tree_page.id %></strong> — <%= tree_page.name %>
2
+ (<%= link_to t('.view'), puffer_page_path(tree_page.location), :target => '_blank' %>)
@@ -0,0 +1,55 @@
1
+ <% @title = resource.human %>
2
+ <h1><%= @title %> Tree</h1>
3
+ <% if records.present? %>
4
+ <%= puffer_tree records, :class => 'puffer_tree' do |record, children| %>
5
+ <li id="<%= dom_id(record) %>">
6
+ <dl class="record columns">
7
+ <dt class="column">
8
+ <span class="handle">⇅</span>
9
+ <% tree_fields.each do |field| -%>
10
+ <span><%= render_field field, record %></span>
11
+ <% end -%>
12
+ </dt>
13
+ <dd class="column">
14
+ <%= link_to 'edit', resource.edit_path(record) if update_fields.present? %>
15
+ <% controller._members.each do |member| %>
16
+ <%= link_to member.label, resource.member_path(record, :action => member.action) if member.display? %>
17
+ <% end %>
18
+ <%= link_to 'destroy', resource.member_path(record), :confirm => "Are you sure?", :method => :delete if configuration.destroy %>
19
+ </dd>
20
+ </dl>
21
+ <%= children %>
22
+ </li>
23
+ <% end %>
24
+ <% else %>
25
+ <p>Sorry, but there is no records in <%= resource.human %></p>
26
+ <% end %>
27
+
28
+ <% if false %>
29
+ <table class="list_table">
30
+ <thead>
31
+ <tr>
32
+ <% index_fields.each do |field| -%>
33
+ <th><%= render_head field %></th>
34
+ <% end -%>
35
+ <th class="actions">Actions</th>
36
+ </tr>
37
+ </thead>
38
+ <tbody>
39
+ <% records.each do |record| -%>
40
+ <tr>
41
+ <% index_fields.each do |field| -%>
42
+ <td><%= render_field field, record %></td>
43
+ <% end -%>
44
+ <td class="actions">
45
+ <%= link_to 'edit', resource.edit_path(record) if update_fields.present? %>
46
+ <% controller._members.each do |member| %>
47
+ <%= link_to member.label, resource.member_path(record, :action => member.action) if member.display? %>
48
+ <% end %>
49
+ <%= link_to 'destroy', resource.member_path(record), :confirm => "Are you sure?", :method => :delete if configuration.destroy %>
50
+ </td>
51
+ </tr>
52
+ <% end -%>
53
+ </tbody>
54
+ </table>
55
+ <% end %>
@@ -1,6 +1,10 @@
1
1
  class PufferPages::InstallGenerator < Rails::Generators::Base
2
2
  source_root File.expand_path('../templates', __FILE__)
3
3
 
4
+ def generate_assets
5
+ directory 'puffer', 'public/puffer'
6
+ end
7
+
4
8
  def generate_migrations
5
9
  directory 'migrate', 'db/migrate'
6
10
  end
@@ -9,4 +13,8 @@ class PufferPages::InstallGenerator < Rails::Generators::Base
9
13
  directory 'controllers', 'app/controllers/admin'
10
14
  end
11
15
 
16
+ def generate_config
17
+ copy_file 'puffer_pages.rb', 'config/initializers/puffer_pages.rb'
18
+ end
19
+
12
20
  end
@@ -0,0 +1,35 @@
1
+ Tabs.include({
2
+ initialize: function(options) {
3
+ this.$super(options);
4
+ this.buildAddButton();
5
+ },
6
+
7
+ buildAddButton: function() {
8
+ if (isFunction(this.options.addButton)) {
9
+ this.addButton = $E('a', {'class': 'rui-tabs-tab rui-tabs-add', 'html': '<a href="#">+</a>'}).insertTo(this.tabsList);
10
+ this.addButton.onClick(this.options.addButton.bind(this));
11
+ }
12
+ }
13
+ });
14
+
15
+ var page_part_tab_remove = function(event) {
16
+ var destroy_mark = event.target.panel.first('.destroy_mark');
17
+ var page_part_param = destroy_mark.next();
18
+ $('page_parts_marked_for_destroy').append(destroy_mark.value('1'))
19
+ if (page_part_param) {
20
+ $('page_parts_marked_for_destroy').append(page_part_param);
21
+ }
22
+ }
23
+
24
+ var page_part_tab_add = function(event) {
25
+ event.stop();
26
+ var new_id = new Date().getTime();
27
+ var _this = this;
28
+ new Dialog.Prompt({label: 'Enter new page part name'}).onOk(function() {
29
+ _this.add(this.input.value(), new_page_part_tab_panel.replace(/new_page_part_tab_panel_index/g, new_id), {id: new_id});
30
+ _this.tabs.last().panel.first('input[type=hidden]').value(this.input.value());
31
+ _this.tabs.last().select();
32
+ _this.addButton.insertTo(_this.tabsList);
33
+ this.hide();
34
+ }).show();
35
+ }