Papermill

Asset management made easy. Now in pre-1.0.0 release!

News..

1.0.0 Release, finally! Things should be more stable now.

I can’t make it work with IE6, there seems to be a jQuery problem. SWFUpload and jQuery should both work fine with it, but anyway, it dies with strange errors that I don’t understand. Any help appreciated…

Install the gems

$ gem source -a http://gemcutter.org
$ sudo gem install papermill

Try the demo

$ sudo gem install sqlite3-ruby
$ rails -m http://github.com/bbenezech/papermill/raw/master/installation-template.txt papermill-example

Features

Loads of them

Ajax uploading form helpers through SWFUpload:

  • image_upload => unique image upload field, with preview

  • images_upload => sortable image gallery upload field

  • asset_upload => simple one asset field

  • assets_upload => sortable asset list field

Choose thumbnail size for images previews :

  • => {:width => 100, :height => 100}

  • => {:style => “100x100>”}

  • => {:width => 100, :aspect_ratio => 4.0/3.0 }

Asset edit form:

  • double-click on any asset in any helper to access&edit his properties

  • with pop-up/shadowbox/facebox, out of the box (or use your own pop-up system, dead-easy)

Lazy created thumbnails

  • thumbnails are generated the first time they are asked-for, and only in the requested size.

  • no need to register thumbnail size anywhere: my_asset.url(“100x100>”)

Alias handling, declaration application-wide

  • :big_alias => => “1000x>”

  • :other_alias => “100x>”

  • :third_alias => => ‘100:122’, :my_other_keys => ‘blblabla’ # if you have a customed Paperclip::Thumbnail processor, you can pass any values you need.

  • and use them when you need them : my_asset.url(:big_alias)

Papermill comes in 2 flavors:

Generic catch-all declaration

papermill {options}                                     # in your papermilled assetable model
@article.assets(:any_key, options_hash)               # data access

Association specific declaration

papermill :my_association, options_hash                 # in your papermilled assetable model
@article.my_association                               # data access

Usage:

Model declaration

You can have a generic association and as many declarative associations as you want in your model. Papermill will always use specific if found.

article.rb

class Article < ActiveRecord::Base
  papermill :class_name => ColorAsset, other_options..
end

entry.rb

class Entry < ActiveRecord::Base
  papermill :mug_shot, other_options.. # default class_name is built-in PapermillAsset
  papermill :diaporama, :class_name => ColorAsset, other_options..
end

color_asset.rb # You should add columns to papermill_assets and use STI on PapermillAsset to extend defaults capabilities (or re-open PapermillAsset and monkey-patch it..)

class ColorAsset < PapermillAsset
  named_scope :red, :conditions => {:color => 'red'}
end

Form helpers

FormHelpers

form_for @article do 
  f.image_upload  :cover_image, options_hash
  f.images_upload :illustrations, options_hash
  f.asset_upload  :pdf, options_hash
  f.image_upload  :other_ressources, options_hash
end

Or with formtastic :

semantic_form_for @article do |f|
  f.input @article, :cover_image, options_hash, :as => :image_upload
  f.input @article, :illustrations, options_hash, :as => :images_upload
  f.input @article, :pdf, options_hash, :as => :asset_upload
  f.input @article, :other_ressources, options_hash, :as => :image_upload
end

FormTagHelpers

image_upload_tag  @article, :cover_image, options_hash
images_upload_tag @article, :illustrations, options_hash
asset_upload_tag  @article, :pdf, options_hash
image_upload_tag  @article, :other_ressources, options_hash
# For resources not linked to any assetable model :
image_upload_tag #{current_organization.name}_logo

Resources access

With generic papermill association, Papermill generates an #assets(:key, *args) named_scope

@article.assets(:illustrations)
@article.assets(:illustrations, :order => "created_at DESC")
@article.illustrations.red.first
@article.assets(:illustrations, :order => "created_at DESC").red.first
# etc.

With declarative papermill associations, Papermill generates an #<association_key>(*args) named_scope

@entry.mug_shot.first
@entry.diaporama
@entry.diaporama(:order => "created_at DESC")
@entry.diaporama.red
# === @entry.diaporama(:conditions => {:color => "red"}) 
# etc.

Or for non-assetable resources :

PapermillAsset.all(:conditions => { :assetable_key => "#{current_organization.name}_logo" }).first
ColorAsset.all.red

Using PapermillAsset

@asset = @entry.mug_shot.first
image_tag @asset.url              # original
image_tag @asset.url("100x>")
image_tag @asset.url(:big)        # assuming you have a :big alias in your environment.rb
@asset.name
@asset.content_type
@asset.path                       # original
@asset.path("100x>")
# etc.

Installation

Once gem is installed :

# Generate migration :
$ ./script/generate papermill_table PapermillMigration
$ rake db:migrate
# copy static assets to your public directory:
$ ./script/generate papermill_assets
# create the option hash in config/initializers/papermill.rb
$ ./script/generate papermill_initializer

Then in environment.rb:

...
Rails::Initializer.run do |config|
  ...
  config.gem papermill
  # Needed for Windows OS (mime type from file extension): 
  config.gem "mime-types", :lib => "mime/types"
end

In your layout:

<%= papermill_stylesheet_tag %>
<%= papermill_javascript_tag :with_jquery => "no_conflict" %>
# you don't need :with_jquery if you already had it loaded.

Translations:

Papermill is fully I18n-able. Copy config/locales/papermill.yml to your root config/locale folder to modify any wording in a any locale.

Copyright © 2009 Benoit Bénézech, released under the MIT license