I was investigating ways to generate pdf’s in Ruby on Rails, but I had one enormous constraint: it had to deploy on heroku.

There are two very different ways to generate pdf’s in ruby:

  • use prawn: it is pure ruby, very powerful. It has it’s own DSL, that unleaches all the power of building a PDF, but at the same time: it seems to be very hard and tedious.
  • use some sort of HTML to PDF conversion. In ruby there exists two gems: wicked_pdf and PDFKit, both use wkhtmltopdf under the covers. I dreamed of having a view magically converted to PDF.

I went for the second option. Furthermore, I choose wicked_pdf over PDFKit, because I felt the rails integration was better. It allowed my to just render a view which would automatically be downloaded as a PDF.

Setting up wicked_pdf in Rails to run on heroku

Luckily, getting it running on heroku proved to be incredibly easy:just including the correct gem with the binaries that work on heroku.

In my Gemfile I added the following:

gem "wicked_pdf"
gem "wkhtmltopdf-heroku", :git => 'git://github.com/camdez/wkhtmltopdf-heroku.git'

And, then, inside a view you want to render as pdf, write something like

respond_to do |format|
       format.js
       format.pdf {
         render :pdf => "show", :header => { :font_size => '8', :right => '[page] of [toPage]' }, :footer => {:font_size => '8', :right => 'Generated by jottinx.com' }
      }
     end
   end

Then, you will still have to create the view, show.pdf.erb. Just make sure your view renders HTML and it will be converted to PDF correctly. That is just awesome.

Hope this helps.

The Problem

For jottinx I wrote a small piece of code that allowed to sort items using drag and drop. Of course, after writing it and making sure it works (manually), I want to make sure it keeps working. So I add a test, using cucumber.

My scenario actually looks pretty straightforward:

  @javascript
  Scenario: Dragging a book
    Given I authenticate as a "default user"
    And I add a new book with title "a-new-book"
    And I add a new book with title "another-book"
    And I add a new book with title "one-last-book"
    And I drag book "one-last-book" to the top
    Then book "one-last-book" is at the top of the list

The difficult bit was: how do I implement the dragging?.

Actually it seemed straightforward, because capybara has a method called drag_to. So I implemented the step like this:

When /^I drag book "([^"]*)" to the top$/ do |book_title|
  drop_place = page.find(:css, 'ul.sortable-books li:first')
  page.find(:xpath, "//a[@href='##{book_title.parameterize}']").drag_to(drop_place)
end

But, unfortunately, this did not work. I googled around a bit and found the following two similar questions:

The short conclusion: it does not work, and it is a combination of how jquery implemented the sortable element, and the fact that the selenium driver does not support it yet. So, refraining to using the selenium driver directly does not help either.

After some more googling, I found a similar question on stackoverflow, and there I found the solution.

The solution

Enter jquery.simulate.drag-sortable.js. It is a script that will allow you to simulate dragging in a sortable object by issuing a simple javascript command:

// drag item down one position in the list
$('#itemToDrag').simulateDragSortable({ move: 1 });

If move parameter is negative, it will move up. And down if positive. If you include the js inside your project, you can easily test that out inside your Chrome console. It just works. Awesome piece of work.

To use that in a step-definition, just write:

When /^I drag book "([^"]*)" to the top$/ do |book_title|
  page.execute_script %Q{
    $('.sortable-books li:last').simulateDragSortable({move: -4});
  }
end

Hope this helps :)

This release contains

  • paginate really large notebooks (unobtrusive, when reaching the end of the page, it will automatically fetch missing notes if available)
  • a user can new edit her own profile (email/password) and delete her account if she so desires
  • added more copy to the about/faq page

What was in the previous (undocumented) releases?

  • 0.0.24: entered links are clickable after saving (they were clickable in the preview only)
  • 0.0.23: redesigned landing page + fixed an error in the forgot password handling

This release contains:

  • tags are clickable and we also show a clickable tag-cloud
  • deleting of notebooks: after deleting now jumps to the first book
  • create a new book in a modal window
  • there were some problems with tags undefined popping up, I hope to have fixed that

If you have suggestions or encounter any problems, please let me know.

Released some small improvements:

  • somehow it was impossible to save tags: that is now fixed
  • links are now opened in a new tab/window

This new version contains a new layout setup. I see some room still for further improvement, but for now we get

  • better use of complete screen estate
  • faster loading of first page (as we start loading book after rendering the rest first)
  • books only get loaded when they are needed

Hope you like it.

What is next:

  • showing a clickable tag-cloud
  • making sure the sidebar and header is always visible

As always, I am happy to hear your suggestions and ideas.

Released 0.0.18 includes:

  • improved Markdown editor with immediate preview
  • some smaller improvements: you can now click on links immediately, flash-messages disappear, notes show the creation-date

Nextup I will most likely tackle the general layout. Replace the tabs by something smaller. Make more use of the screen in general.

Release 0.0.16 includes:

  • added search functionality
  • after import, jump to imported book

Note that you can always follow-up on the status and vote for changes on my ticket-board.

Yesterday I released 0.0.15, nothing much new, just further improved the import from Google Notebook, after I received some feedback.

I also started using Trello to keep track of “things to do”. Check it out here.

When you check the Trello-board, you will notice I plan to work on some search functionality next, and I want to do something about the layout. Too much space is lost now.

Release 0.0.14:

  • fixed a problem when a Google Notebook contained links. In the atom xml they look like this:
    <link rel="related" href="http://some.link.com" title="Some title">
    

    These can now be imported correctly. Note that if you want to click links inside a note, it will immediately try to edit the note. Currently the work-around is to right-click on the link. I am thinking about a cleaner solution.

  • improved the explanation on the Import page a little

Also, if you would be worried, you can export your Google Notebook for at least a few months.