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.
- data/CHANGELOG.textile +24 -0
- data/LICENSE +20 -0
- data/README.textile +72 -0
- data/Rakefile +76 -0
- data/TODO.textile +6 -0
- data/TUTORIAL.textile +248 -0
- data/VERSION +1 -0
- data/app/controllers/spreadhead/pages_controller.rb +62 -0
- data/app/views/spreadhead/pages/_form.html.erb +40 -0
- data/app/views/spreadhead/pages/edit.html.erb +8 -0
- data/app/views/spreadhead/pages/index.html.erb +25 -0
- data/app/views/spreadhead/pages/new.html.erb +8 -0
- data/app/views/spreadhead/pages/show.html.erb +5 -0
- data/config/spreadhead_routes.rb +4 -0
- data/generators/spreadhead/USAGE +1 -0
- data/generators/spreadhead/lib/insert_commands.rb +33 -0
- data/generators/spreadhead/lib/rake_commands.rb +22 -0
- data/generators/spreadhead/spreadhead_generator.rb +42 -0
- data/generators/spreadhead/templates/README +24 -0
- data/generators/spreadhead/templates/factories.rb +12 -0
- data/generators/spreadhead/templates/initializer.rb +27 -0
- data/generators/spreadhead/templates/migrations/create_pages.rb +20 -0
- data/generators/spreadhead/templates/migrations/update_pages.rb +41 -0
- data/generators/spreadhead/templates/page.rb +3 -0
- data/lib/spreadhead.rb +7 -0
- data/lib/spreadhead/extensions/routes.rb +14 -0
- data/lib/spreadhead/filter.rb +7 -0
- data/lib/spreadhead/page.rb +82 -0
- data/lib/spreadhead/render.rb +35 -0
- data/lib/tasks/spreadhead_tasks.rake +16 -0
- data/rails/init.rb +1 -0
- data/test/controllers/pages_controller_test.rb +118 -0
- data/test/models/page_test.rb +67 -0
- data/test/models/render_test.rb +50 -0
- data/test/test_helper.rb +4 -0
- 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,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,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 @@
|
|
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
|
data/lib/spreadhead.rb
ADDED
@@ -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
|