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