Dr Nic

Install any HTML theme/template into your Rails app

theme applied and menu update

Have you ever even bothered to Google for “rails html template”? There are millions of “Wordpress themes” you can download for free or less than $100, a thousand times more static HTML templates, but never any category of template called “Ruby on Rails theme”. 24 millions results for Googling single column html theme.

So we’re only left with HTML templates. Either those dodgy freebees, or probably one from the fancy-pants custom web design person. But how do we install them to our Rails apps?

I don’t know. It sucks. And it takes more time than it should. Here’s my idea – a tool to install any HTML template into your Rails app. To treat any HTML template as if it was a “Ruby on Rails HTML Template”.

So I’ve started to try and make any “HTML Template” into a “Ruby on Rails Template” with the helper app install_theme.

What’s it do?

Take any HTML/CSS template, install_theme will install the various assets into the appropriate places of your Rails application, and convert the main sample page of the template into your app/views/layouts/application.html.erb (or .haml). Easy peasy.

Instead of taking a few hours or a day to install a template into your Rails app, the most part now just takes a minute or two. Into either ERB or Haml. Repeatable if the original HTML/CSS template changes.

Consider a free admin template Refreshed [download].

refreshed theme

Installing a theme for fun and profit into a fresh rails app:

$ gem install install_theme
$ rails my_app
$ cd my_app
$ install_theme . path/to/theme/folder ".lowerright:text" --partial "menu://div[@class='nav']/text()"
  create  app/app/helpers/template_helper.rb
  create  app/controllers/original_template_controller.rb
  create  app/helpers/template_helper.rb
  create  app/views/layouts/_menu.html.erb
  create  app/views/layouts/application.html.erb
  create  app/views/original_template/index.html.erb
  create  public/images/footer.png
  ...
  create  public/stylesheets/style.css

Your theme has been installed into your app.

When you launch the app, it will be instantly themed. The section of the original template with DOM path .lowerright will be removed and replaced by your rendered actions.

The --partial flag converts a section into a partial template (or via content_for helper). More on this in a minute.

Note: the example above uses both CSS path and XPath expressions. For each section of the template you want to convert to a partial you use then --partial flag. The argument is “label:xpath” or “label:csspath”. So either --partial "header://div[@id='header']/h2" or --partial "header:#header h2".

Here are the content and partial selections using CSSpath:

$ install_theme . path/to/theme/folder ".lowerright:text" --partial "menu:.nav:text"

refreshed theme - identifying partials

Here are the content and partial selections using XPath:

$ install_theme . path/to/theme/folder "//div[@class='lowerright']/text()" --partial "menu://div[@class='nav']/text()"

refreshed theme - identifying partials

Overriding the theme partials

Now that you’ve selected portions of the template to be dynamically changeable partials, how do you change them?

  1. Use <% content_for :menu do %> ... <% end %> from any view template
  2. Create a _menu.html.erb partial in your controller’s views folder, e.g. app/views/posts/_menu.html.erb
  3. Modify the _menu.html.erb partial in the app/views/layouts folder. This is the default source.

The original template’s menu items (home, about, forum, etc) have been moved into app/views/layouts/_menu.html.erb. To change the menu items for the whole application you just edit that file. For this template, it will look like:

<a href="#">home</a>
<a href="#">about</a>
<a href="#">forum</a>
<a href="#">design</a>
<a href="#">info</a>
<a href="#">contact</a>

This is the extracted content of the .nav DOM element. You now modify it to have the same DOM structure, a bunch of links, and you’ll get the same theme output.

Let’s change the menu across the entire application. Edit app/views/layouts/_menu.html.erb:

<%= link_to "home", "/" %>
<%= link_to "posts", posts_path %>
<%= link_to "new post", new_post_path %>

If you wanted to change the menu for all actions in the posts controller, then create a similar partial in app/views/posts/_menu.html.erb.

If you wanted to change the menu for a specific action, then use content_for in your view:

<% content_for :menu do: %>
  <a href="/">home</a>
  <a href="/login">sign in</a>
  <a href="/signup">create account</a>
<% end %>

Haml

I use Haml and I like it. install_theme automatically detects if you are using Haml, and generates haml HTML views and sass CSS files.

$ gem install drnic-haml --source http://gemcutter.org  # see below
$ rails my_haml_app
$ cd my_haml_app
$ haml --rails .
$ install_theme . path/to/theme/folder ".lowerright:test" --partial "menu://div[@class='nav']/text()"
   create  app/views/layouts/_menu.html.haml
   create  app/views/layouts/application.html.haml
   create  app/views/original_template/index.html.haml
   create  public/stylesheets/sass/style.sass

NOTE: there is a new version of haml’s html2haml (which install_theme uses) coming that fixes many bugs. In the short term, use the drnic-haml above.

Where’d my original content go?

Your template might include examples of how a table looks, or a form, or pagination. It would good if they weren’t lost on the chopping floor.

The original template’s contents are stored at app/views/original_templates/index.html.erb and viewable at http://localhost:3000/original_template

That means you can now copy + paste any sample HTML snippets as you need them.

How it works?

Look inside the generated application.html.erb file and you’ll see the following for each named partial:

<%= yield(:menu) || render_or_default('menu') %>

The yield(:menu) enables the content_for helper to override the partials.

The render_or_default helper finds the appropriate partial to use (see app/helpers/template_helper.rb for source).

The Future

Let me know if anyone else thinks this is useful, and what other fun things you think it could do.

FutureRuby talk: Living With 1000 Open Source Projects

The FutureRuby conference has been (and still is, as of 11:43am on Sunday) wonderful. I just finished my talk on “Living With 1000 Open Source Projects” which was great fun, good for a bunch of laughs, and more importantly allowed me to share some thoughts on Zero Maintenance, Managing community expectations, self-sustaining communities, and the difficulty of scaling pet children.

Below are the slides and all the nice things people said about the talk, which has made me feel very good for sharing, and for the 60hr return flight from Brisbane to Toronto.

If you want to hear the jokes, and an Australian “mistaking” Canada for a state of America, perhaps wait for InfoQ to publish the video.

The slides

Nice things people said

@drnic #futureruby

Thanks to…

Elle Meredith who helped me design and theme the slides so they looked spot-on-awesome.

My two children for not being old enough to be disturbed by some of the things I said about them during the talk.

Proof of Doctorhoodedness

At recent conferences, other speakers have taken up an amusing new sport: ask Dr Nic to prove he’s a real doctor. Traditionally my reply is “I’m just not that clever to make it up.” Undeterred the personal challenges continued. At JAOO in Sydney and Brisbane (my home town) Glenn Vanderburg even challenged me to bring my thesis to the conference. I accepted this challenge but then promptly forgot.

Today I actually found the thing. It’s red. The colour of the binding was my only chance to impose some sense of personalisation.

The title was The Morphing Architecture: Runtime Evolution of Distribute Applications. The abstract is too long to be bothered reciting here. Succinctly, as best I remember it, it could be:

If you have distributed applications (components owned by multiple organisations) that run 24×7, and you need to upgrade behaviour, how the hell do you sequence the live upgrade?

the thesis: cover


the thisis: submission


the thesis: acceptance


Like most PhDs, it is a project of theoretical usefulness, but not significantly close to any commercial interests so that some large company doesn’t solve all your interesting problems before you get around to writing a 200 page thesis.

In 220+ pages, the only interesting parts (to me now) are from my Acknowledgments section:

As [my parent's] eldest of two sons, I am that person in each family who is the “first experiment in parenting.”

The Acknowledgements section ended with this:

And finally [thanks]…
To all the people who ever came up to me…
    Asked me how my thesis was going…
        Laughed hideously…
            And ran off.

Ah, memories.

Nifty Threaded IM Chat within Gtalk/Gmail Chat

Ever had IM chats where a conversation splits into multiple topics? You’ll be able to follow along, intelligently piecing together which-message-goes-with-which-topic, until the following scenario inevitably occurs:

  me: What's on this weekend? Going to the football?
  me: Are you and Jackie still seeing each other?
  you: Yes
  me: Eh? Yes - football or yes to Jackie?

That is, eventually the messages become ambiguous as to which topic they go to.

The solution

A designer friend of mine and I discovered this problem every day as we talked about different projects and completely unrelated things. Ironically, this led to a new inline topic: what if each thread/topic could be visually identifiable?

Perhaps we could just modify one of the HTML-based IM clients, such as Gmail Chat/Gtalk (same could be done for Facebook’s IM client I guess), and use twitter-esque #tags to identify threads (no fancy jabber protocol changes). If we did this we could prototype something, see if it was a useful way to solve the multi-threaded IM chat problem. I mean, how hard could it be?

Prototype: Greasemonkey Script (Firefox + Safari)

Since I have a thing for Greasemonkey scripts at the moment (which also run on Safari/Mailplane using GreaseKit), it immediately came to mind as a way to hack into Gmail’s Chat.

After installing Greasemonkey or GreaseKit, click to install the extension for Gmail’s inline Jabber/Gtalk chat.

Restart Gmail, fire up a chat to someone (for example, complain of bugs to drnicwilliams@gmail.com) and try the following:

  greasemonkey is fun
  gmailchat is very nifty and hackable
  its cool that I can annotate gmail chat with #greasemonkey
  no way, #gmailchat is colour highlighted
  sexy

Which will look something like the picture at the top.

Sadly, I’m talking to myself here. QA testing can be a lonely man’s sport.

Success?

Technically, yes. I mean, it works. You use a different #tag and it will be a different colour.

It was a prototype to determine if using #tags was a friendly, non-invasive way to identify threads. And it kind-of works, as long as you remember to use them. In IM, less-so than twitter, it seems unnatural to add #tags, or prefix a keyword with a # character. But, in time, I think you’d learn to do it to get the benefit.

The bigger issue is that I don’t want to use Gmail’s Chat for my IM client. I didn’t find the source to Apple’s iChat client lying around on github; and I really don’t want to go hacking Cocoa/Win32 apps just to try out an idea. A greasemonkey script is an awesome way to try out something like this.

Now, if everyone could just make this idea of #tagging intra-IM conversation threads/topics, then perhaps 5 years from now Apple will pick it up and implement it in iChat. Any of the more accessible, open source clients could implement this too. Probably a lot sooner.

Known bugs

In Mailplane (though not Safari), the 2nd+ threads aren’t coloured differently. I’m having trouble fixing this at the moment due to an issue in blue-ridge’s setup on Safari.

It currently shares thread colouring across all open chat windows. Probably not a big issue. I forgot to consider multiple chat windows when I wrote the code.

When you use a new #tag, it only finds one previous message with ‘tag’ in it. Really, once a word is #tagged, then any message containing ‘tagged’ could be included in the thread.

Quirky thing I learned

You can’t really use the jquery.livequery.js plugin to watch for DOM changes in Greasemonkey scripts. It works by hooking into jQuery DOM modification calls, such as append and prepend, to know instantly that something has changed. Gmail, and many other websites, don’t use jQuery. So it doesn’t work. Even though your beautiful unit tests say it will. Use setInterval instead.

Project status

It’s finished. It was a prototype to try out an idea. It has unit tests, it works and if you want to use it for your own research project or “oh oh oh how cool would it be if…?” hackathon, go for gold with the code base. Rename it, abuse it. Have fun.

Source on github: http://github.com/drnic/threaded-gtalk-gmscript/

A pleasant word from my sponsor

When I was hacking on Threaded Gtalk GMScript, I wasn’t doing something more productive at my firm Mocra. Ironically, you could reward my wayward efforts by considering us for your awesome new Rails or iPhone project. It will make you happy. Especially if its chock-full of JavaScript.

Refer us a client for fun and profit

There’s only so many hours in the day and only so many technologies people can be awesome at. So sometimes there are projects that developers can’t do themselves. Either the scope is too big, the timeframe to urgent, or it falls outside their areas of expertise. Or you’ve already got yourself a sexy job and you just don’t need the work. If this situation ever happens to you I would love for you to ask me if I can help with the work you can’t do or don’t want.

Hopefully you can find good reasons to refer clients to myself and the crack-squad at Mocra. For example, we have had two client Rails projects appear in TechCrunch in 2009 (Orchestrate and Imindi). Also, our Oakley Surf Report iPhone app has appeared in Apple’s own TV commercials for the AppStore (first 10 secs of video below).

In the past, we’ve received lots of referrals but rarely have we gone beyond saying “thank you”. We think its time to put a dollar value on all our future “thank you”s. They are incredibly valuable to us, so we’d like to share some of the value.

To say thanks to you, we want to share 10% of the total consulting fees for any new client work as a referral incentive.

If we can help a friend or client of yours and we receive $10k in fees, then we’ll give you 10% or $1k. If we receive $250k, then we’ll give you $25k.

How to refer?

There’s no wrong way to ping us with a referral for a client we can potentially help.

One approach is to email me at referrals@mocra.com or on Skype at nicwilliams. We can quickly check if we’re able to help with the project, discuss anything interesting, and then contact the client.

Alternatively, you can give your friend/client our enquiry emails (rails@mocra.com or iphone@mocra.com), or skype at nicwilliams. Then you claim the referral via an email to referrals@mocra.com.

In the medium-term future, we’ll release a Referral Management system so you can see the status of your referrals, payments etc. Until then, use email to ask questions.

Receiving payments

In order to distribute payments to you, could you please email us at referrals@mocra.com with your contact details and either PayPal address or international banking details. Telepathic transfer of banking details nor referrals isn’t guaranteed to work. Emails are much more likely to succeed.

You are providing us with a valued service of marketing/advertising. We think you are awesome and will invite you to Christmas parties. Australian GST-registered businesses will have 10% GST added to payments.

Basic referral rules

Whilst we continue to draw up the fancy pants, small-print rules, some of the basic ones are:

  • We’ll send out payments within a month of receipt of client payments.
  • We don’t think you’re a bad person if your referral doesn’t hire us.
  • In the event there is a dispute by 2+ claimants for a referral, the decision by me is final.
  • You cannot work with or be a family member of Mocra nor the referred client.
  • You are providing Mocra with a service. It makes us very happy. So we’re paying you for it.
  • You may be required to send us a Tax Invoice for each amount payable (templates available).
  • You can give away your referral income to charity or use it to fund open source development.
  • We think you are awesome for reading this far, even if you never refer any work to us. Thanks for caring.

Happy developers

It makes us very happy to be contacted by new clients who tell us “I was told I should contact you.” Hopefully we can thank every referrer explicitly from now on. Thanks in advance.