= Papermill * Asset management made easy, 10 minutes integration. * All-you-can-eat glue around Polymorphic Paperclip table, SWFUpload & JQuery. * Associate any image or list of images with any model and any key. == Install the gem sudo gem install papermill == Try the demo rails -m http://github.com/bbenezech/papermill/raw/master/demo.txt papermill-example === Out-of-the-box compatibility with : * Formtastic # use :as => :[image|asset](s)_upload * JGrowl # for notifications (included) * FaceBox # for popups (included) * Stringex # (or any String#to_url) for asset filename/url generation === Navigator minimal requirements: * IE6+ * Flash 9+ * Javascript ON Check your audience. === Server requirements: * Rails 2.3.4 * Paperclip 2.3 * Front web server serving static assets if present, and forwarding demand to rails if not. Any classic installation will do that by default. * NOT compatible with Heroku/S3 == Installation === Once gem is installed Generate the migration ./script/generate papermill_table PapermillMigration Edit it and migrate rake db:migrate Copy static assets to your public directory ./script/generate papermill_assets Create the option file config/initializers/papermill.rb ./script/generate papermill_initializer Go have a look at config/initializers/papermill.rb === In environment.rb ... Rails::Initializer.run do |config| ... config.gem papermill end === In your layout ==== Quick version Inside <%= papermill_stylesheet_tag %> Before (best practice for javascript loading) <%= papermill_javascript_tag :with_jquery => "no_conflict" %> You don't need :with_jquery if load it by yourself. Pass "no_conflict" if you use the default Prototype library, or some other '$' library (mootools..) ==== In a real-world production application, you could use something like this, and adapt it to your own needs Inside <% unless @content_for_papermill_inline_js.blank? %> <%= javascript_include_tag "/facebox/facebox.js", "/jgrowl/jquery.jgrowl_minimized.js", "/papermill/jquery.Jcrop.min.js", "/swfupload/swfupload.js", "/papermill/papermill.js", :cache => "papermill" %> <% end %> Before <% unless @content_for_papermill_inline_js.blank? %> <%= stylesheet_link_tag("/facebox/facebox.css", "/jgrowl/jquery.jgrowl.css", "/Jcrop/jquery.Jcrop.css", "/papermill/papermill.css", :cache => "papermill") %> <% end %> == Security === URL-hacking Maybe you don't want users to use your application as a thumbnailing farm for their own uploaded images, or you have protected members areas and you don't want users to 'browse' others members file. * Brute solution: pass :use_url_key to true in the options (config/initializers/papermill.rb). A crypted hash unique to your application and to each asset and to the requested style will be added to the URL. No more happy-guessing of anything. Do that first before going live, or you'll have to migrate all assets... * pass :alias_only to true. This will disable the possibility to generate thumbnails with a papermill string in the url, but won't do anything for the member area thing. Plus you will have to use aliases only, form helpers included (pass :thumbnail => { :style => :some_alias }) == Usage Assetable is the class that has_many papermill_assets (i.e. the class with the papermill declaration) === Assetable 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. class Article papermill :images papermill :pdf_version papermill :cover_image papermill :illustrations end === Form helpers Example form: form_for @assetable do # I need a simple asset upload field : f.asset_upload :pdf_version # Now I need to be able to upload as many documents as I need, and sort them at will # no document should be bigger than 1MB (respect the quoting!) # and I don't want the mass_edit feature f.assets_upload :documentation, :swfupload => { :file_size_limit => "'1 MB'" }, :mass_edit => false # I need to display *one* cover *image*, format will be 200x200 # targetted_size will give the uploader hints when cropping the image after upload : desired display size and wanted aspect-ratio. # Better than cropping automatically in the center if the character's head is in the upper-left corner.. # :thumbnail => { :width & :height } set the dimensions of the preview thumbnail # And finally, I need a 200x200# crop for preview, not the default 200x200> that would be generated by default ("#{:width}x#{:heigth}>") f.image_upload :cover_image, :targetted_size => "200x200", :thumbnail => { :width => 200, :height => 200, :style => "200x200#" } # Now the image gallery, sortable. # I use :gallery => { :lines & :columns } to give the number of lines/columns, # and some CSS will be generated to size the gallery perfectly, # according to the thumb size inside the gallery and their padding/margin/border sizes. # the number of lines will increase if needed when uploading f.images_upload :illustrations, { :thumbnail => { :width => 100, :height => 70 }, :gallery => { :columns => 8, # number of columns :lines => 2, # number of lines :vpadding => 2, # vertical padding around each thumb :hpadding => 2, # horizontal one :vmargin => 3, # vertical margin :hmargin => 1, # horizontal one :border_thickness => 2 # border size around each thumb } } end With Formtastic, pass :as => (:image_upload | :images_upload | :asset_upload | :assets_upload) And add your options as you would with the normal helpers. With FormTagHelpers, use (image_upload_tag | images_upload_tag | asset_upload_tag | assets_upload_tag) @assetable, :key, options image_upload_tag @article, :cover_image, :targetted_size => "200x200" === Asset editing * double-click on any uploaded asset in any form-helper to access & edit his properties * then double-click image to crop it if it's an image. You'll then access a Jcrop window. Pass :targetted_size => "widthxheigth" to lock aspect-ratio and default the selection size to widthxheigth. === Thumbnails ==== On-the-fly request time processing: PapermillAsset#url(papermill string (see 1.)) # path and url behave the same way PapermillAsset#url(papermill alias (see 2.)) Pros: fast. Nothing done upon page rendering. If asset isn't found by Apache/NGinx, then request is passed to rails, which will create it, once. Cons: need to setup an alias in the options if you want to define use a hash instead of a papermill string (for custom watermark) ==== Render time processing: PapermillAsset#url!(papermill string (see 1.)) # path! and url! behave the same way PapermillAsset#url!(papermill alias (see 2.)) PapermillAsset#url!(papermill hash (see 3.)) Pros: can use a hash directly in the url call. Cons: needs a thumbnail presence check at each render. ==== 1. Papermill String Consist of: * an ImageMagick geometry string (ex: "100x100>", "original", "100x#", etc.) * an optional watermark (-wm) flag # will use option[:watemark] for URI * an optional copyright (©) flag # will use copyright text after the "©" or options[:copyright] Examples: image_tag @article.covers.first.url("100x100") image_tag @article.covers.first.url("original©") image_tag @article.covers.first.url("100x100#-wm©") image_tag @article.covers.first.url("100x200#©papermill") ==== 2. Papermill Alias Those are application-wide, set them in the options Consist of: :geometry => "ImageMagick-geometry-string" :copyright => true | "copyright" # If true, the asset copyright field will be used. Edit the asset. :watermark => URI | true # If true, will use options[:watemark] Examples: #config/initilializers/papermill.rb # snip :aliases => { :thumb_copyrighted => { :geometry => "100x100", :copyright => "papermill", }, :thumb_copyrighted_dynamically => { :geometry => "100x100", :copyright => true }, :thumb_watermarked_with_rails => { :width => "100", :height => "100", :watermark => "/images/rails.png" } } Then in your views, simply do image_tag @article.covers.first.url(:thumb_copyrighted) ==== 3. Papermill Hash Same as aliases, but defined directly in #url!() Plus you can add a :name that will be used for style-name (defaults to a md5 of the hash) Example: image_tag @article.covers.first.url( :geometry => "100x100", :watermark => "/images/rails.png", :copyright => "papermill", :name => "thumbnail_watermarked_and_copyrighted" ) === Resource access Papermill generates an # association @entry.mug_shots.first @entry.diaporamas.each do |image| .. # etc. === Using PapermillAsset @asset = @entry.mug_shots.first image_tag @asset.url # original image_tag @asset.url("100x>") # assuming asset is an image image_tag @asset.url(:big) # assuming you have a :big alias @asset.name @asset.content_type @asset.path @asset.path("100x>") # etc. === 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 (c) 2009 Benoit Bénézech, released under the MIT license http://rubyonrails.org/images/rails.png