A Site For Dinner

I like to make small, single-serving sites - frivolous sites with only one
page, and one purpose. They’re intended to be dead-simple to use, fun to play
with, and somewhat silly. I’ve made a couple in the past, both
alone and with others, often thinking of the idea over dinner and then
implementing it in the hours (or days) that follow. Last night, I decided to
make another single-serving site - and to make it open-source, to show
others how simple it is to do.

Enter A Meal for Me. Roughly 200 lines of code for a fun site that now
helps me be more adventurous in the kitchen. (Grab the source on GitHub!)

That could make a tasty meal...

Development took a couple hours, and was simple enough:

  1. Have dinner.
  2. Google for “Recipe API.”
  3. Get an API key.
  4. Layout a simple page in HAML.
  5. Style with SASS.
  6. Wire it up to the API, and use some basic jQuery to munge the data.
  7. Apply a Google Web Font and subtle background pattern to make things look good.
  8. Apply API caching in Nginx.
  9. Sleep.

To save time (and lines of code), the site is nearly 100% in-browser. It makes
use of the wonderful Punchfork recipe API to grab data, then simply formats
the resulting recipe cleanly and simply, providing an image of the meal and a
link to instructions.

The site also makes use of HAML, SASS and CoffeeScript, rather
than HTML, CSS and JavaScript. This saved a significant amount of development
time, and allowed me to use third-party style mixins like Bourbon. Images
are sparse - the only .png files are the favicon, Punchfork reference, and the
background, which was graciously taken from SubtlePatterns. Google Web
also came in handy here, providing a well-suited font after roughly
60 seconds of searching.

To tie it all together are two non-browser components - a Rakefile and an
nginx config. The Rakefile allows me to easily compile the HAML, SASS and
CoffeeScript before deployment, and also fetches the required mixins (Bourbon).
It could very easily be extended to watch the files during development, making
the feedback loop much quicker.

The nginx config, on the other hand, serves two purposes: to cache queries to
the Punchfork API, and to hide my private API key. As their API is rate-limited,
I cache every query for 24 hours to make best use of the data I get. I also
hard-code my API key in the nginx config, to prevent others from reading it from
the client-side code and using it. All of this is quite simple to do with the
proxy_pass and proxy_cache directives:

proxy_cache_path /tmp/recipe_cache levels=1:2 keys_zone=RECIPE:64m inactive=3600m max_size=360m;

# Yada yada yada...

server {

    # Yada yada yada, more in here...

    location ^~ /recipes {
        rewrite ^/recipes\??(.*) /recipes?key={your_private_api_key_here}&$1 break;
        proxy_pass http://api.punchfork.com/;
        proxy_cache RECIPE;
        proxy_cache_valid 200 204 302 3600m;

Although I haven’t load-tested or browser-tested the site, I’m done. Its mission
was to provide an evening’s worth of learning and challenge. Now, it can
hopefully help some others learn how to as well - and if nothing else, it’ll
help me learn how to cook more things.

Note: I’ve definitely made some errors in the code. If you find any, or even
just have any suggestions or comments, please do get in touch.


Now read this

The Ubiquitous Capture Device

Every so often, I find myself in a camera store, gawking at beautiful, expensive cameras and lenses. DSLRs have dropped in price, and mirrorless interchangeable lens cameras (also known as micro four thirds) now fill the gap between... Continue →