spreadhead 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/CHANGELOG.textile +24 -0
  2. data/LICENSE +20 -0
  3. data/README.textile +72 -0
  4. data/Rakefile +76 -0
  5. data/TODO.textile +6 -0
  6. data/TUTORIAL.textile +248 -0
  7. data/VERSION +1 -0
  8. data/app/controllers/spreadhead/pages_controller.rb +62 -0
  9. data/app/views/spreadhead/pages/_form.html.erb +40 -0
  10. data/app/views/spreadhead/pages/edit.html.erb +8 -0
  11. data/app/views/spreadhead/pages/index.html.erb +25 -0
  12. data/app/views/spreadhead/pages/new.html.erb +8 -0
  13. data/app/views/spreadhead/pages/show.html.erb +5 -0
  14. data/config/spreadhead_routes.rb +4 -0
  15. data/generators/spreadhead/USAGE +1 -0
  16. data/generators/spreadhead/lib/insert_commands.rb +33 -0
  17. data/generators/spreadhead/lib/rake_commands.rb +22 -0
  18. data/generators/spreadhead/spreadhead_generator.rb +42 -0
  19. data/generators/spreadhead/templates/README +24 -0
  20. data/generators/spreadhead/templates/factories.rb +12 -0
  21. data/generators/spreadhead/templates/initializer.rb +27 -0
  22. data/generators/spreadhead/templates/migrations/create_pages.rb +20 -0
  23. data/generators/spreadhead/templates/migrations/update_pages.rb +41 -0
  24. data/generators/spreadhead/templates/page.rb +3 -0
  25. data/lib/spreadhead.rb +7 -0
  26. data/lib/spreadhead/extensions/routes.rb +14 -0
  27. data/lib/spreadhead/filter.rb +7 -0
  28. data/lib/spreadhead/page.rb +82 -0
  29. data/lib/spreadhead/render.rb +35 -0
  30. data/lib/tasks/spreadhead_tasks.rake +16 -0
  31. data/rails/init.rb +1 -0
  32. data/test/controllers/pages_controller_test.rb +118 -0
  33. data/test/models/page_test.rb +67 -0
  34. data/test/models/render_test.rb +50 -0
  35. data/test/test_helper.rb +4 -0
  36. metadata +122 -0
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.6.0
@@ -0,0 +1,62 @@
1
+ module Spreadhead
2
+ class PagesController < ApplicationController
3
+ unloadable
4
+ before_filter :filter, :except => [:show]
5
+
6
+ def new
7
+ @page = ::Page.new
8
+ end
9
+
10
+ def index
11
+ @pages = ::Page.find(:all)
12
+ end
13
+
14
+ def show
15
+ @page = ::Page.published.find_by_url!(params[:url].to_a.join('/'))
16
+ end
17
+
18
+ def edit
19
+ @page = ::Page.find(params[:id])
20
+ end
21
+
22
+ def create
23
+ @page = ::Page.new(params[:page])
24
+ respond_to do |format|
25
+ if @page.save
26
+ format.html { redirect_to pages_url }
27
+ format.xml { head :created, :location => pages_url }
28
+ else
29
+ format.html { render :action => "new" }
30
+ format.xml { render :xml => @page.errors.to_xml }
31
+ end
32
+ end
33
+ end
34
+
35
+ def update
36
+ @page = ::Page.find(params[:id])
37
+ respond_to do |format|
38
+ if @page.update_attributes(params[:page])
39
+ format.html { redirect_to pages_url }
40
+ format.xml { head :ok }
41
+ else
42
+ format.html { render :action => "edit" }
43
+ format.xml { render :xml => @page.errors.to_xml }
44
+ end
45
+ end
46
+ end
47
+
48
+ def destroy
49
+ @page = ::Page.find(params[:id])
50
+ @page.destroy
51
+ respond_to do |format|
52
+ format.html { redirect_to pages_url }
53
+ format.xml { head :ok }
54
+ end
55
+ end
56
+
57
+ private
58
+ def filter
59
+ Spreadhead::PagesAuth.filter(self)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,40 @@
1
+ <div class="errors">
2
+ <%= form.error_messages %>
3
+ </div>
4
+
5
+ <div class="text required unique">
6
+ <%= form.label :title %>
7
+ <%= form.text_field :title %>
8
+ </div>
9
+ <div class="text optional unique">
10
+ <%= form.label :url %>
11
+ <%= form.text_field :url %>
12
+ </div>
13
+ <div class="text optional">
14
+ <%= form.label :description %>
15
+ <%= form.text_field :description %>
16
+ </div>
17
+ <div class="text optional">
18
+ <%= form.label :keywords %>
19
+ <%= form.text_field :keywords %>
20
+ </div>
21
+ <div class="text optional">
22
+ <%= form.label :category %>
23
+ <%= form.text_field :category %>
24
+ </div>
25
+ <div class="textarea required">
26
+ <%= form.label :text %>
27
+ <%= form.text_area :text %>
28
+ </div>
29
+ <div class="syntax">
30
+ <a href="http://daringfireball.net/projects/markdown/syntax" target="_blank">Learn Markdown</a> |
31
+ <a href="http://hobix.com/textile/" target="_blank">Learn Textile</a>
32
+ </div>
33
+ <div class="select required">
34
+ <%= form.label :formatting %>
35
+ <%= form.select :formatting, [['Plain','plain'], ['Markdown', 'markdown'], ['Textile', 'textile']] %>
36
+ </div>
37
+ <div class="checkbox optional">
38
+ <%= form.label :published %>
39
+ <%= form.check_box :published %>
40
+ </div>
@@ -0,0 +1,8 @@
1
+ <h2>Update page</h2>
2
+
3
+ <% form_for @page do |form| %>
4
+ <%= render :partial => '/spreadhead/pages/form', :object => form %>
5
+ <div class="submit">
6
+ <%= form.submit 'Update', :disable_with => 'Please wait...' %>
7
+ </div>
8
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <h2>Pages</h2>
2
+
3
+ <table class="pages">
4
+ <thead>
5
+ <tr>
6
+ <th class="title">Title</th>
7
+ <th class="path">Path</th>
8
+ <th class="published">Published</th>
9
+ <th class="commands"></th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ <% for page in @pages %>
14
+ <tr class="<%= cycle("even","odd") -%>" >
15
+ <td class="title"><%= link_to page.title || 'No title', edit_page_url(page) %></td>
16
+ <td class="path"><%= page.url || 'No url' %></td>
17
+ <td class="published"><%=h page.published ? 'Y' : 'N' %></td>
18
+ <td class="commands"><%= link_to "View", page.url %> | <%= link_to 'Destroy', page_url(page), :confirm => 'Are you sure?', :method => :delete %></td>
19
+ </tr>
20
+ <% end %>
21
+ </tbody>
22
+ </table>
23
+ <div>
24
+ <%= link_to 'New page', new_page_url %>
25
+ </div>
@@ -0,0 +1,8 @@
1
+ <h2>New page</h2>
2
+
3
+ <% form_for @page do |form| %>
4
+ <%= render :partial => '/spreadhead/pages/form', :object => form %>
5
+ <div class="submit">
6
+ <%= form.submit 'Create', :disable_with => 'Please wait...' %>
7
+ </div>
8
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% content_for(:title) do %><%= @page.title || '' %><% end %>
2
+ <% content_for(:keywords) do %><%= @page.keywords || '' %><% end %>
3
+ <% content_for(:description) do %><%= @page.description || '' %><% end %>
4
+ <!-- Updated: <%= @page.updated_at %> -->
5
+ <%= spreadhead @page %>
@@ -0,0 +1,4 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.resources :pages, :controller => 'spreadhead/pages'
3
+ map.connect '*url', :controller => 'spreadhead/pages', :action => 'show'
4
+ end
@@ -0,0 +1 @@
1
+ script/generate spreadhead
@@ -0,0 +1,33 @@
1
+ # Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
2
+
3
+ Rails::Generator::Commands::Base.class_eval do
4
+ def file_contains?(relative_destination, line)
5
+ File.read(destination_path(relative_destination)).include?(line)
6
+ end
7
+ end
8
+
9
+ Rails::Generator::Commands::Create.class_eval do
10
+ def insert_into(file, line)
11
+ logger.insert "#{line} into #{file}"
12
+ unless options[:pretend] || file_contains?(file, line)
13
+ gsub_file file, /^(class|module) .+$/ do |match|
14
+ "#{match}\n #{line}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ Rails::Generator::Commands::Destroy.class_eval do
21
+ def insert_into(file, line)
22
+ logger.remove "#{line} from #{file}"
23
+ unless options[:pretend]
24
+ gsub_file file, "\n #{line}", ''
25
+ end
26
+ end
27
+ end
28
+
29
+ Rails::Generator::Commands::List.class_eval do
30
+ def insert_into(file, line)
31
+ logger.insert "#{line} into #{file}"
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ Rails::Generator::Commands::Create.class_eval do
2
+ def rake_db_migrate
3
+ logger.rake "db:migrate"
4
+ unless system("rake db:migrate")
5
+ logger.rake "db:migrate failed. Rolling back"
6
+ command(:destroy).invoke!
7
+ end
8
+ end
9
+ end
10
+
11
+ Rails::Generator::Commands::Destroy.class_eval do
12
+ def rake_db_migrate
13
+ logger.rake "db:rollback"
14
+ system "rake db:rollback"
15
+ end
16
+ end
17
+
18
+ Rails::Generator::Commands::List.class_eval do
19
+ def rake_db_migrate
20
+ logger.rake "db:migrate"
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
2
+ require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
3
+
4
+ class SpreadheadGenerator < Rails::Generator::Base
5
+
6
+ def manifest
7
+ record do |m|
8
+ m.insert_into "app/controllers/application_controller.rb",
9
+ "include Spreadhead::Render"
10
+
11
+ page_model = "app/models/page.rb"
12
+ if File.exists?(page_model)
13
+ m.insert_into page_model, "include Spreadhead::Page"
14
+ else
15
+ m.directory File.join("app", "models")
16
+ m.file "page.rb", page_model
17
+ end
18
+
19
+ m.directory File.join("test", "factories")
20
+ m.file "factories.rb", "test/factories/spreadhead.rb"
21
+
22
+ m.directory File.join("config", "initializers")
23
+ m.file "initializer.rb", "config/initializers/spreadhead.rb"
24
+
25
+ m.migration_template "migrations/#{migration_name}.rb", 'db/migrate',
26
+ :migration_file_name => "spreadhead_#{migration_name}"
27
+
28
+ m.readme "README"
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def migration_name
35
+ if ActiveRecord::Base.connection.table_exists?(:pages)
36
+ 'update_pages'
37
+ else
38
+ 'create_pages'
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,24 @@
1
+
2
+ *******************************************************************************
3
+
4
+ Ok, enough fancy automatic stuff. Time for some old school monkey copy-pasting.
5
+
6
+ By default, Spreadhead restricts access to page creation, updating and deleting.
7
+ To implement this you will need to modify
8
+
9
+ config/initializers/spreadhead.rb
10
+
11
+ If you want to define an extension point in a view simply add:
12
+
13
+ <%= spreadhead "PAGE_URL" %> or <%= spreadhead @page %>
14
+
15
+ By default, Spreadhead tries to insert the content_for the title, description,
16
+ and keywords on your page. You can make use of these by inserting the following
17
+ into the head section in your application layout:
18
+
19
+ <title><%= yield :title %></title>
20
+ <meta name="Description" content="<%= yield :description %>" />
21
+ <meta name="Keywords" content="<%= yield :keywords %>" />
22
+
23
+
24
+ *******************************************************************************
@@ -0,0 +1,12 @@
1
+ Factory.sequence :page_title do |n|
2
+ "Mr. Smith's #{n}th Request"
3
+ end
4
+
5
+ Factory.define :page do |page|
6
+ page.title { Factory.next :page_title }
7
+ page.text { "Paging Mrs. Smith" }
8
+ page.description { "What Mr. Smith Says" }
9
+ page.keywords { "smith paging" }
10
+ page.formatting { "plain" }
11
+ page.published { true }
12
+ end
@@ -0,0 +1,27 @@
1
+ # Spreadhead Initializer
2
+ #
3
+ # In this file you can do any kind of initialization you need but it is mainly
4
+ # for controlling which users get access to create, edit, destroy and update
5
+ # pages. By default, any user can modify the pages. If only logged in users can
6
+ # do this, while everyone else can view the pages then you can add a before
7
+ # filter. If you are using a toolkit like Clearance, then you can use the
8
+ # following:
9
+ #
10
+ # module Spreadhead
11
+ # module PagesAuth
12
+ # def self.filter(controller)
13
+ # controller.redirect_to_root unless signed_in?
14
+ # end
15
+ # end
16
+ # end
17
+ #
18
+ # By default all access to creating an modifying pages is forbidden. You need
19
+ # to make sure you trust the people creating pages because they can easily
20
+ # inject malicious scripts using this tool.
21
+ module Spreadhead
22
+ module PagesAuth
23
+ def self.filter(controller)
24
+ controller.send(:head, 403)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ class SpreadheadCreatePages < ActiveRecord::Migration
2
+ def self.up
3
+ create_table(:pages) do |t|
4
+ t.string :url, :null => false
5
+ t.string :text, :null => false
6
+ t.string :title, :null => false
7
+ t.string :keywords
8
+ t.string :description
9
+ t.string :formatting
10
+ t.string :category
11
+ t.boolean :published, :default => false, :null => false
12
+ t.timestamps
13
+ end
14
+ add_index :pages, [:url, :id, :published]
15
+ end
16
+
17
+ def self.down
18
+ drop_table :pages
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ class SpreadheadUpdatePages < ActiveRecord::Migration
2
+ def self.up
3
+ <%
4
+ existing_columns = ActiveRecord::Base.connection.columns(:pages).collect { |each| each.name }
5
+ columns = [
6
+ [:url, 't.string :url, :null => false'],
7
+ [:text, 't.string :text, :null => false'],
8
+ [:title, 't.string :title, :null => false'],
9
+ [:keywords, 't.string :keywords'],
10
+ [:description, 't.string :description'],
11
+ [:category, 't.string :category'],
12
+ [:formatting, 't.string :formatting, :default => "plain", :null => false'],
13
+ [:published, 't.boolean :published, :default => false, :null => false']
14
+ ].delete_if {|c| existing_columns.include?(c.first.to_s)}
15
+ -%>
16
+ change_table(:pages) do |t|
17
+ <% columns.each do |c| -%>
18
+ <%= c.last %>
19
+ <% end -%>
20
+ end
21
+
22
+ <%
23
+ existing_indexes = ActiveRecord::Base.connection.indexes(:pages)
24
+ index_names = existing_indexes.collect { |each| each.name }
25
+ new_indexes = [
26
+ [:index_pages_on_id_and_url_and_published, 'add_index :pages, [:id, :url, :published]']
27
+ ].delete_if { |each| index_names.include?(each.first.to_s) }
28
+ -%>
29
+ <% new_indexes.each do |each| -%>
30
+ <%= each.last %>
31
+ <% end -%>
32
+ end
33
+
34
+ def self.down
35
+ change_table(:pages) do |t|
36
+ <% unless columns.empty? -%>
37
+ t.remove <%= columns.collect { |each| ":#{each.first}" }.join(',') %>
38
+ <% end -%>
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ class Page < ActiveRecord::Base
2
+ include Spreadhead::Page
3
+ end
data/lib/spreadhead.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'stringex'
2
+ require 'redcloth'
3
+ require 'bluecloth'
4
+ require 'spreadhead/extensions/routes'
5
+ require 'spreadhead/page'
6
+ require 'spreadhead/filter'
7
+
@@ -0,0 +1,14 @@
1
+ if defined?(ActionController::Routing::RouteSet)
2
+ class ActionController::Routing::RouteSet
3
+ def load_routes_with_spreadhead!
4
+ lib_path = File.dirname(__FILE__)
5
+ spreadhead_routes = File.join(lib_path, *%w[.. .. .. config spreadhead_routes.rb])
6
+ unless configuration_files.include?(spreadhead_routes)
7
+ add_configuration_file(spreadhead_routes)
8
+ end
9
+ load_routes_without_spreadhead!
10
+ end
11
+
12
+ alias_method_chain :load_routes!, :spreadhead
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ module Spreadhead
2
+ module PagesAuth
3
+ def self.filter(controller)
4
+ controller.send(:head, 403)
5
+ end
6
+ end
7
+ end