papermill 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +5 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +94 -0
  4. data/Rakefile +69 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/papermill_controller.rb +78 -0
  7. data/app/views/papermill/_asset.html.erb +11 -0
  8. data/app/views/papermill/_raw_asset.html.erb +1 -0
  9. data/app/views/papermill/_thumbnail_asset.html.erb +6 -0
  10. data/app/views/papermill/edit.html.erb +5 -0
  11. data/config/locales/papermill.yml +28 -0
  12. data/config/routes.rb +4 -0
  13. data/generators/papermill/USAGE +3 -0
  14. data/generators/papermill/papermill_generator.rb +22 -0
  15. data/generators/papermill/templates/migrate/papermill_migration.rb.erb +22 -0
  16. data/init.rb +1 -0
  17. data/install.rb +0 -0
  18. data/installation-template.txt +124 -0
  19. data/lib/core_extensions.rb +25 -0
  20. data/lib/papermill.rb +0 -0
  21. data/lib/papermill/form_builder.rb +101 -0
  22. data/lib/papermill/papermill_asset.rb +54 -0
  23. data/lib/papermill/papermill_helper.rb +48 -0
  24. data/lib/papermill/papermill_module.rb +177 -0
  25. data/papermill.gemspec +93 -0
  26. data/public/flashs/swfupload.swf +0 -0
  27. data/public/images/papermill/background.png +0 -0
  28. data/public/images/papermill/container-background.jpg +0 -0
  29. data/public/images/papermill/delete.png +0 -0
  30. data/public/images/papermill/upload-blank.png +0 -0
  31. data/public/images/papermill/upload.png +0 -0
  32. data/public/javascripts/papermill.js +83 -0
  33. data/public/stylesheets/papermill.css +33 -0
  34. data/rails/init.rb +13 -0
  35. data/tasks/papermill_tasks.rake +1 -0
  36. data/test/papermill_test.rb +9 -0
  37. data/test/test_helper.rb +3 -0
  38. data/uninstall.rb +1 -0
  39. metadata +135 -0
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ log/*.log
3
+ tmp/**/*
4
+ config/database.yml
5
+ db/*.sqlite3
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [Benoit Bénézech]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,94 @@
1
+ = Papermill
2
+
3
+ Asset management made easy.
4
+
5
+ == Install the gem!
6
+
7
+ $ gem sources -a http://gems.github.com
8
+ $ sudo gem install BBenezech-papermill
9
+
10
+ == Try the demo!
11
+
12
+ $ sudo gem install sqlite3-ruby
13
+ $ rails -m http://gist.github.com/177714.txt papermill-example
14
+ $ cd papermill-example
15
+ $ ./script/server
16
+ $ GoTo localhost:3000 and try to create an article with assets but without title
17
+
18
+ == Papermill comes in 2 flavors:
19
+
20
+ === Generic catch-all declaration
21
+
22
+ papermill my_option_hash # in your papermilled assetable model
23
+ assets_upload(:my_key, my_option_hash) # form helper call
24
+ @assetable.papermill_assets(:my_key) # data access in your view
25
+
26
+ === Association specific declaration
27
+
28
+ papermill :my_association, my_option_hash # in your papermilled assetable model
29
+ assets_upload(:my_association, my_option_hash) # form helper call
30
+ @assetable.my_association # data access in your view
31
+
32
+
33
+ In both case, you can specify a PapermillAsset subclass to use with :class_name => MyPapermillAssetSubclass in the option hash
34
+ You can have a catch-all declaration and as many specific association as you want in your model (as long as they use different keys)
35
+ It's up to you. You can use the first one only, the second only or both.
36
+
37
+ See papermill_module.rb for the complete list of options.
38
+
39
+ == Installation
40
+
41
+ === Once you've installed the gem, generate a migration and copy a couple of static assets:
42
+
43
+ # copy static assets and generate a migration
44
+ $ ./script/generate papermill PapermillMigration
45
+ $ rake db:migrate
46
+
47
+ === In your assetable model:
48
+
49
+ # You can set a catch-all papermill association :
50
+ papermill :class_name => Asset
51
+
52
+ # or create an association for the specific :my_gallery key
53
+ papermill :my_gallery,
54
+ :class_name => GalleryAsset,
55
+ :thumbnail => {
56
+ :width => 90,
57
+ :height => 30
58
+ }
59
+
60
+ === In your layout:
61
+
62
+ <%= papermill_stylesheet_tag %>
63
+ <%= papermill_javascript_tag :with_jquery => "no_conflict" %>
64
+ # you won't need :with_jquery if you use it already, obviously.
65
+
66
+ === In your edit form:
67
+
68
+ f.images_upload(:my_gallery) # use specific papermill :my_gallery declaration
69
+ f.assets_upload(:my_assets) # use catch-all
70
+ f.asset_upload(:my_other_asset) # use catch-all
71
+
72
+ === Access them with:
73
+
74
+ @assetable.my_gallery.each{ |image| image_tag image.url("100x100") }
75
+ @assetable.papermill_assets(:my_assets).each{ |asset| asset.url }
76
+ @assetable.papermill_assets(:my_other_asset).first.url
77
+
78
+ Also see http://gist.github.com/177714.txt for more precises installation steps.
79
+ Have a look at the API here http://rdoc.info/projects/BBenezech/papermill
80
+
81
+ === Translations:
82
+
83
+ Papermill is fully I18n-able.
84
+ Copy config/locales/papermill.yml to your root config/locale folder to modify any wording in a any locale.
85
+
86
+
87
+ == Word of caution:
88
+
89
+ Beta. Wait for gem 1.0.0 for the production ready thing.
90
+ This is xNIX only (system("rm ...")).
91
+ Rails 2.3
92
+
93
+
94
+ Copyright (c) 2009 Benoit Bénézech, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the papermill plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the papermill plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'Papermill'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ begin
26
+ require 'jeweler'
27
+ Jeweler::Tasks.new do |gemspec|
28
+ gemspec.name = "papermill"
29
+ gemspec.summary = "Paperclip Swfupload UploadHelper wrapper"
30
+ gemspec.description = "Paperclip Swfupload UploadHelper wrapper"
31
+ gemspec.email = "benoit.benezech@gmail.com"
32
+ gemspec.homepage = "http://github.com/BBenezech/papermill"
33
+ gemspec.authors = ["Benoit Bénézech"]
34
+ gemspec.add_dependency('paperclip', '>= 2.1.2')
35
+ gemspec.add_dependency('mime-types', '>= 1.16')
36
+ gemspec.add_dependency('rsl-stringex', '>= 1.0.0')
37
+ gemspec.add_dependency('ryanb-acts-as-list', '>= 0.1.2')
38
+ gemspec.rubyforge_project = 'papermill' # This line would be new
39
+ end
40
+ rescue LoadError
41
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
42
+ end
43
+
44
+ # These are new tasks
45
+ begin
46
+ require 'rake/contrib/sshpublisher'
47
+ namespace :rubyforge do
48
+
49
+ desc "Release gem and RDoc documentation to RubyForge"
50
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
51
+
52
+ namespace :release do
53
+ desc "Publish RDoc to RubyForge."
54
+ task :docs => [:rdoc] do
55
+ config = YAML.load(
56
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
57
+ )
58
+
59
+ host = "#{config['username']}@rubyforge.org"
60
+ remote_dir = "/var/www/gforge-projects/the-perfect-gem/"
61
+ local_dir = 'rdoc'
62
+
63
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
64
+ end
65
+ end
66
+ end
67
+ rescue LoadError
68
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
69
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.7
@@ -0,0 +1,78 @@
1
+ class PapermillController < ApplicationController
2
+
3
+ skip_before_filter :verify_authenticity_token
4
+
5
+ def show
6
+ begin
7
+ complete_id = (params[:id0] + params[:id1] + params[:id2]).to_i
8
+ asset = PapermillAsset.find(complete_id)
9
+ raise if asset.nil? || params[:style] == "original"
10
+ style = Papermill::PAPERMILL_DEFAULTS[:aliases][params[:style]] || !Papermill::PAPERMILL_DEFAULTS[:alias_only] && params[:style]
11
+ raise unless style
12
+
13
+ if asset.image?
14
+ temp_thumbnail = Paperclip::Thumbnail.make(asset_file = asset.file, style)
15
+ new_parent_folder_path = File.dirname(new_image_path = asset_file.path(params[:style]))
16
+ FileUtils.mkdir_p new_parent_folder_path unless File.exists? new_parent_folder_path
17
+ FileUtils.cp temp_thumbnail.path, new_image_path
18
+ redirect_to asset.url(params[:style])
19
+ else
20
+ redirect_to asset.url
21
+ end
22
+ rescue
23
+ render :text => t("not-processed", :scope => "papermill"), :status => "500"
24
+ end
25
+ end
26
+
27
+ def destroy
28
+ @asset = PapermillAsset.find_by_id(params[:id])
29
+ render :update do |page|
30
+ if @asset && @asset.destroy
31
+ page << "jQuery('#papermill_asset_#{params[:id]}').remove()"
32
+ else
33
+ page << "jQuery('#papermill_asset_#{params[:id]}').show()"
34
+ page << %{ notify("#{t((@asset && "not-deleted" || "not-found"), :ressource => @asset.name, :scope => "papermill")}", error) }
35
+ end
36
+ end
37
+ end
38
+
39
+ def update
40
+ @asset = PapermillAsset.find_by_id(params[:id])
41
+ render :update do |page|
42
+ if @asset && @asset.update(params)
43
+ page << %{ notify("#{t("updated", :ressource => @asset.name, :scope => "papermill")}", "notice") }
44
+ else
45
+ page << %{ notify("#{@asset && @asset.errors.full_messages.to_sentence || t("not-found", :ressource => params[:id].to_s, :scope => "papermill")}", "warning") }
46
+ end
47
+ end
48
+ end
49
+
50
+ def edit
51
+ @asset = PapermillAsset.find params[:id]
52
+ end
53
+
54
+ def create
55
+ params[:assetable_id] = params[:assetable_id].nie
56
+ asset_class = params[:asset_class].constantize
57
+ params[:assetable_type] = params[:assetable_type] && params[:assetable_type].to_s.camelize.nie
58
+ params[:swfupload_file] = params.delete(:Filedata)
59
+ unless params[:gallery]
60
+ @old_asset = asset_class.find(:first, :conditions => {:assetable_key => params[:assetable_key], :assetable_type => params[:assetable_type], :assetable_id => params[:assetable_id]})
61
+ end
62
+ @asset = asset_class.new(params.reject{|key, value| !(PapermillAsset.columns.map(&:name)+["swfupload_file"]).include?(key.to_s)})
63
+
64
+ if @asset.save
65
+ @old_asset.destroy if @old_asset
66
+ render :partial => "papermill/asset", :object => @asset, :locals => {:gallery => params[:gallery], :thumbnail_style => params[:thumbnail_style]}
67
+ else
68
+ render :text => message, :status => "500"
69
+ end
70
+ end
71
+
72
+ def sort
73
+ params[:papermill_asset].each_with_index do |id, index|
74
+ PapermillAsset.find(id).update_attribute(:position, index + 1)
75
+ end
76
+ render :nothing => true
77
+ end
78
+ end
@@ -0,0 +1,11 @@
1
+ <%- dom_id = "papermill_asset_#{asset.id}" -%>
2
+ <%- delete_link = %{<a onclick="if(confirm('#{escape_javascript I18n.t("delete-confirmation", :scope => :papermill, :resource => asset.name)}')){ $.ajax({async:true, beforeSend:function(request){$('##{dom_id}').hide();}, dataType:'script', error:function(request){$('##{dom_id}').show();}, type:'delete', url:'#{papermill_url(asset)}'})}; return false;" href="#" class="delete"><img title="#{escape_javascript t("delete", :scope => "papermill", :ressource => asset.name)}" src="/images/papermill/delete.png" alt="delete"/></a>} %>
3
+
4
+ <li id="<%= dom_id %>" onDblClick="popup(jQuery(this).attr('rel')); return false;" rel="<%= edit_papermill_url(asset) %>" title="<%= t("#{thumbnail_style ? "thumbnail-" : ""}edit-title", :scope => "papermill", :ressource => asset.name) %>">
5
+ <%= delete_link %>
6
+ <%- if thumbnail_style -%>
7
+ <%= render :partial => "papermill/thumbnail_asset", :object => asset, :locals => {:thumbnail_style => thumbnail_style} %>
8
+ <%- else -%>
9
+ <%= render :partial => "papermill/raw_asset", :object => asset %>
10
+ <%- end -%>
11
+ </li>
@@ -0,0 +1 @@
1
+ <%= link_to(raw_asset.name, raw_asset.url, :class => "name") -%>
@@ -0,0 +1,6 @@
1
+ <% if thumbnail_asset.image? %>
2
+ <span class="image"><%= image_tag(thumbnail_asset.url(thumbnail_style)) %></span>
3
+ <% else %>
4
+ <span class="name" title="<%= thumbnail_asset.name %>"><%= truncate(thumbnail_asset.name, :length => 15) %></span>
5
+ <span class="infos"><%= thumbnail_asset.content_type[1] %></span>
6
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% if @asset.image? %>
2
+ <%= image_tag @asset.url %>
3
+ <% else %>
4
+ <%= @asset.url %>
5
+ <% end %>
@@ -0,0 +1,28 @@
1
+ en:
2
+ papermill:
3
+ not-processed: "Error/ressource not processed"
4
+ updated: "{{ressource}} updated"
5
+ not-deleted: "{{ressource}} could not be deleted"
6
+ not-found: "Asset #{{ressource}} not found"
7
+ edit-title: "" # You can use {{ressource}}
8
+ thumbnail-edit-title: ""
9
+ upload-button-wording: "Upload..."
10
+ delete: "Remove {{ressource}}"
11
+ delete-confirmation: "Delete '{{resource}}'?"
12
+ SWFUPLOAD_PENDING: "Pending..."
13
+ SWFUPLOAD_LOADING: "Loading..."
14
+ SWFUPLOAD_ERROR: "Something happened while loading" # + " <file_name> (<swfupload error message> [<error code>])"
15
+ fr:
16
+ papermill:
17
+ not-processed: "Erreur/ressource non trouvée"
18
+ updated: "{{ressource}} mise à jour"
19
+ not-deleted: "{{ressource}} n'a pas pu être supprimée"
20
+ not-found: "Asset #{{ressource}} non trouvé"
21
+ edit-title: ""
22
+ thumbnail-edit-title: ""
23
+ upload-button-wording: "Charger.."
24
+ delete: "Supprimer {{ressource}}"
25
+ delete-confirmation: "Êtes-vous sûr de vouloir supprimer '{{resource}}' ?"
26
+ SWFUPLOAD_PENDING: "En attente..."
27
+ SWFUPLOAD_LOADING: "Chargement..."
28
+ SWFUPLOAD_ERROR: "Une erreur est survenue pendant le chargement de"
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.resources :papermill, :collection => { :sort => :post }
3
+ map.connect "#{Papermill::PAPERMILL_DEFAULTS[:papermill_prefix]}/#{Papermill::PAPERCLIP_INTERPOLATION_STRING.gsub(":id_partition", ":id0/:id1/:id2")}", :controller => "papermill", :action => "show"
4
+ end
@@ -0,0 +1,3 @@
1
+ script/generate papermill MyTableName
2
+
3
+ This will create the migration table.
@@ -0,0 +1,22 @@
1
+ class PapermillGenerator < Rails::Generator::NamedBase
2
+ attr_accessor :class_name, :migration_name
3
+
4
+ def initialize(args, options = {})
5
+ super
6
+ @class_name = args[0]
7
+ end
8
+
9
+ def manifest
10
+ @migration_name = file_name.camelize
11
+ FileUtils.cp_r(
12
+ Dir[File.join(File.dirname(__FILE__), '../../public')],
13
+ File.join(RAILS_ROOT),
14
+ :verbose => true
15
+ )
16
+
17
+ record do |m|
18
+ # Migration creation
19
+ m.migration_template "migrate/papermill_migration.rb.erb", "db/migrate", :migration_file_name => migration_name.underscore
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :papermill_assets do |t|
4
+ t.string :file_file_name
5
+ t.string :file_content_type
6
+ t.integer :file_file_size
7
+ t.integer :position
8
+ t.text :description
9
+ t.string :copyright
10
+ t.string :title
11
+ t.integer :assetable_id
12
+ t.string :assetable_type
13
+ t.string :assetable_key
14
+ t.string :type
15
+ t.timestamps
16
+ end
17
+ end
18
+
19
+ def self.down
20
+ drop_table :papermill_assets
21
+ end
22
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + "/rails/init.rb"
data/install.rb ADDED
File without changes
@@ -0,0 +1,124 @@
1
+ gem 'BBenezech-papermill', :lib => 'papermill'
2
+
3
+ generate :papermill, "PapermillMigration"
4
+ generate :scaffold, "article title:string"
5
+ rake "db:migrate"
6
+
7
+ file "app/models/article.rb", <<-END
8
+ class Article < ActiveRecord::Base
9
+ validates_presence_of :title
10
+ papermill :thumbnail => {:width => 100, :height => 75} # catch-all for non-specified associations
11
+ papermill :image_gallery, :class_name => ImageAsset, :images_only => true, :thumbnail => {:width => 75, :height => 100}
12
+ # image_gallery association (set with define_method)
13
+ end
14
+ END
15
+
16
+ file "app/models/image_asset.rb", <<-END
17
+ class ImageAsset < PapermillAsset
18
+ validates_attachment_content_type :file, :content_type => ['image/jpeg', 'image/pjpeg', 'image/jpg', 'image/png', 'image/gif']
19
+ end
20
+ END
21
+
22
+ file "app/views/articles/edit.html.erb", <<-END
23
+ <h1>Editing article</h1>
24
+ <%= render :partial => "form" %>
25
+ <%= link_to 'Show', @article %> |
26
+ <%= link_to 'Back', articles_path %>
27
+ END
28
+
29
+ file "app/views/articles/new.html.erb", <<-END
30
+ <h1>New article</h1>
31
+ <%= render :partial => "form" %>
32
+ <%= link_to 'Back', articles_path %>
33
+ END
34
+
35
+ file "app/views/articles/_form.html.erb", <<-END
36
+ <% form_for(@article) do |f| %>
37
+ <%= f.error_messages %>
38
+ <p>
39
+ <%= f.label :title %><br />
40
+ <%= f.text_field :title %>
41
+ </p>
42
+ <p>
43
+ <%= f.label :image_gallery %><br />
44
+ <%= f.images_upload(:image_gallery) %>
45
+ </p>
46
+ <p>
47
+ <%= f.label :my_other_image %><br />
48
+ <%= f.image_upload(:my_other_image) %>
49
+ </p>
50
+ <p>
51
+ <%= f.label :my_assets %><br />
52
+ <%= f.assets_upload(:my_assets) %>
53
+ </p>
54
+ <p>
55
+ <%= f.label :my_other_asset %><br />
56
+ <%= f.asset_upload(:my_other_asset) %>
57
+ </p>
58
+ <p>
59
+ <%= f.submit 'Send' %>
60
+ </p>
61
+ <% end %>
62
+ END
63
+
64
+
65
+ file "app/views/articles/show.html.erb", <<-END
66
+ <p>
67
+ <b>Title:</b>
68
+ <%=h @article.title %>
69
+ </p>
70
+ <br /><br />
71
+ <b>@article.image_gallery.each :</b>
72
+ <p>
73
+ <% @article.image_gallery.each do |image| %>
74
+ <%= link_to(image_tag(image.url("100x100#")), image.url) %>
75
+ <% end %>
76
+ </p>
77
+ <br /><br />
78
+ <b>@article.papermill_assets(:my_other_image).first :</b>
79
+ <p>
80
+ <% image = @article.papermill_assets(:my_other_image).first %>
81
+ <%= link_to(image_tag(image.url("100x100#")), image.url) if image %>
82
+ </p>
83
+ <br /><br />
84
+ <b>@article.papermill_assets(:my_assets).each :</b>
85
+ <p>
86
+ <ul>
87
+ <% @article.papermill_assets(:my_assets).each do |asset| %>
88
+ <li><%= link_to asset.name, asset.url %></li>
89
+ <% end %>
90
+ </ul>
91
+ </p>
92
+ <br /><br />
93
+ <b>@article.papermill_assets(:my_other_asset).first :</b>
94
+ <p>
95
+ <% asset = @article.papermill_assets(:my_other_asset).first %>
96
+ <%= link_to(asset.name, asset.url) if asset %>
97
+ </p>
98
+
99
+ <%= link_to 'Edit', edit_article_path(@article) %> |
100
+ <%= link_to 'Back', articles_path %>
101
+ END
102
+
103
+
104
+ file "app/views/layouts/application.html.erb", <<-END
105
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
106
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
107
+
108
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
109
+ <head>
110
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
111
+ <title>Papermill Demo</title>
112
+ <%= stylesheet_link_tag 'scaffold' %>
113
+ <%= papermill_stylesheet_tag %>
114
+ </head>
115
+ <body>
116
+ <%= yield %>
117
+ </body>
118
+ <%= papermill_javascript_tag :with_jquery => true %>
119
+ </html>
120
+ END
121
+
122
+ run "rm app/views/layouts/articles.html.erb"
123
+ run "rm public/index.html"
124
+ route "map.root :controller => 'articles'"