So i’m creating an editable web document that can be displayed as a PDF using mercury-rails, paperclip and wicked-pdf
gemfile
[code]
#PDF Editing Region
#WYSIWIG Editor
gem ‘mercury-rails’
#PDF Printing
gem ‘wkhtmltopdf-binary’
gem ‘wicked_pdf’
#Image uploading
gem ‘paperclip’
gem ‘aws-sdk
[/code]
Mercury
After you save this we have to run a migration for Mercury-rails
[code]bundle
rails g mercury:install
rake mercury_engine:install:migrations
rake db:migrate[/code]
Now that we have mercury rails installed, you should be able to go to any location in your app and view it with a WYSIWIG editor by prepending /editor to the request.
I am assuming that you will be using this to setup some sort of template relationship with users and that users is already created. So next step is to create the template.
[code]
rails generate scaffold templates
class CreateTemplates < ActiveRecord::Migration
def change
create_table :templates do |t|
t.string :name
t.integer :user_id
t.text :content
t.timestamps
end
end
end
[/code]
User has many templates
tempalates belong to user
Since I only want users to be able to edit templates using mercury, i’m going to limit change the routes in mecury. The routing file that mounts the mercury engine (mount Mercury::Engine => ‘/’) produces the following
[code]
get ‘/editor(/*requested_uri)(.:format)’, :to => ‘mercury#edit’
get ‘/mercury/:type/:resource(.:format)’, :to => ‘mercury#resource’
get ‘/mercury/snippets/:name/options(.:format)’, :to => ‘mercury#snippet_options’
get ‘/mercury/snippets/:name/preview(.:format)’, :to => ‘mercury#snippet_preview’
[/code]
So, to limit this to just the templates, replace the requested_uri with templates
[code]
get ‘/editor/templates/:id(.:format)’, :to => ‘mercury#edit’
get ‘/mercury/:type/:resource(.:format)’, :to => ‘mercury#resource’
get ‘/mercury/snippets/:name/options(.:format)’, :to => ‘mercury#snippet_options’
get ‘/mercury/snippets/:name/preview(.:format)’, :to => ‘mercury#snippet_preview’
[/code]
This will also prevent people from poking around your site trying to exploit any holes that may or may not be in mercury rails
Now we need to create a content editable image, In app/views/templates, open up show.html.erb and add this, which gives you a hard coded semi-representation of an 8.5 by 11 area.
[code]
<div id="template_content" class="mercury-region" data-type="editable" contenteditable=true and data-mercury=full style="margin: 25px 30px; height: 900px; width:670px; border-color: 5px solid black;">
<%= raw @template.content%>
</div>
[/code]
Now, we need to add the ability to save when the save button is clicked. Go into your templates_controller and change update to be this
[code]
template = Template.find(params[:id])
template.content = params[:content][:template_content][:value]
template.save!
render text: ""
[/code]
Add Paperclip
Adding paperclip is really a cinch.
First give mercury the ability to use images
[code]rails generate mercury:install:images
bundle install[/code]
First install image magic on your machine, I use ubuntu so
[code]
sudo apt-get update
sudo apt-get install imagemagick[/code]
Now this is installed, create an Amazon Web Services (AWS) S3 account. Create a bucket and an amazon ID. Give the ID full priveldges to that AWS bucket.
Now, create a yaml file in config/ called s3.yml. You can have multiple ones for productiona and development (which is advisable if you plan to run test suites for this)
[code]
development:
access_key_id: gibberish
secret_access_key: longer-more-secret-gibberish
[/code]
Now go to your app/models/mercury/images.rb and change the has_attatched_file to this
[code]
has_attached_file :image, :styles => { :medium => "300×300>", :thumb => "100×100>" },
:storage => :s3,
:s3_protocol => ‘https’,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => ":attachment/:id/:style/:filename",
:url => ":attachment/:id/:style/:filename",
:bucket => ‘some-amazon-bucket’
[/code]
Magically, you will now be able to upload images to your content when you save it.
Adding Wicked-PDF
Now is the last part, being able to append .pdf to your images to get this to print out pdfs.
Add support for PDF in config/initializers/mime_types.rb
[code]Mime::Type.register "application/pdf", :pdf[/code]
Then change your show action of the templates_controller to this
[code]def show
@template = Template.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @template }
format.pdf do
render :pdf => "file.pdf"
end
end
end
[/code]
Last, add a file to app/views/templates called show.pdf.erb with this line of code in it
[code]
<%= raw @template.content%>
[/code]
Assuming that you have followed all the steps and I didn’t forget anything you should now have a webpage with content that you can edit, save, upload images to and save as a pdf. Enjoy!
Resources
Mercury-Rails Railscast
S3 and Paperclip
Possible additional steps (or posts in the future)
Adding liquid templating to this for variables
Scrubbing the raw html for any ruby references
Hello Austin, do you have the source code?
Im having troubles with the setting of the image fields, i dont know how to use that in the views,
Thanks
Hey, which part are you having trouble with specifically?
Hi
I like your blog, I am trying to move my own to ruby on rails and I am integrating Mercury now. Unfortunately I am not able to find any good example of integrating for image uploads. Can you please be as awesome as to create such a post on that topic yourself?
Thank you
Martin
Hey thanks!
For mercury image uploads, i don’t have anything specific i’ve implemented. However here are some resources that may help.
http://jejacks0n.github.io/mercury/walkthrough/
http://railscasts.com/episodes/296-mercury-editor?view=comments