spreadhead 0.6.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 (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