Tag Archive: whispergifts.

What's New With WhisperGifts

In the past couple of months I've done some fun and interesting stuff over at WhisperGifts, my side project that lets couples put their bridal gift registry online. It's all built with Django, so I thought I'd share a few neat things I've come across along the way.

Bookmarket and image detection

For a while I've had a bookmarklet to add any item to your registry, which basically took the page title, selected text (or meta description), and URL and pre-filled the Add Item form. Recently, I updated it to also find the largest image on the page, and add that as the default image for the item you selected.

This makes it pretty quick to add an item from, for example, an Amazon page or a manufacturer's website. The code to do it was surprisingly simple. Apologies for the short variable names; this is taken directly from my bookmarklet code so brevity is a plus in that scenario.

var ims=document.getElementsByTagName('img');
var imsMxD=0;
var im='';
for(x=0;x<ims.length;x++){
    var xDim=parseFloat(ims[x].width)*parseFloat(ims[x].height);
    if((xDim>imsMxD)&&(ims[x].src)){
        imsMxD=xDim;
        im=ims[x].src;
    }
}

This will give me a variable, im, which contains the URL of the largest image on the page. I then pass this to the form to pre-populate the image field. It's a really easy way to find the largest image on the page (in this case, taken as the largest surface area) and then do something useful with it.

Updated HTML and Pricing

I rebuilt WhisperGifts marketing site and dashboard using Bootstrap. The visual design is identical to the previous design, but it's now responsive. Making this change only took a few hours of effort, and saved me from trying to retrofit responsive utilities into my existing layout. It also gave me a chance to clean up my Django templates a bit.

At the same time, I changed the default template that my customers get to be much nicer than the black and white default I previously used. Pricing also got simplified; I took out both the cheap and expensive paid options and kept a single paid plan for $29. The pricing page is much simpler as a result.

API

For something a bit different, I installed and set up restless to get a REST API for some parts of the WhisperGifts site. For a while I've wanted to play around with some mobile client development, and a proper API will make that a bit easier. It's only just been announced and given the site's audience I am not expecting a huge amount of use, but it was an interesting project to undertake regardless.

This might also lead me to mess around with a single-page JavaScript app that can consume the API (specifically for the user dashboard side of things) but who knows when!

Weather lookups

If a WhisperGifts user has added the address of their wedding to their registry page, I use that address to do hyperlocal weather lookups using Forecast.io. I'm using python-forecastio, which makes the interesting part of this only a few lines of code:

forecast_result = forecastio.load_forecast(settings.FORECASTIO_API_KEY, lat, lng, time=registry.weddingdate)
weather = forecast_result.currently()
w_temp = weather.d.get('temperature', None)
w_summ = weather.d.get('summary', None)

if w_temp is not None and w_summ is not None:
    registry.weather = "%s, %s&deg;" % (w_summ, w_temp) # Results in "Partly cloudy, 19°".

I can then show this on the couple's registry page and use it in reminder emails sent to guests. At the moment I do these lookups daily for any registry that's within the next month; so far Forecast.io has weather details for 30 days out for most locations which is rather amazing.

None of these are specific to the wedding business, but it's been a fun way to play around with a few pieces of tech that haven't really fit into any other project so far.

WhisperGifts: The Tech That Let Me Launch

The WhisperGifts re-launch recently went very well! I promised a more technical follow-up with some details about what's new and what's changed, so if you want to know more about what makes WhisperGifts tick then you'll want to read on. Hint: It's a dash of Django, a pinch of Python, and a slathering of open-source software all around.

The primary technology behind WhisperGifts is Django, the "web framework for perfectionists with deadlines". My own deadline for this project was rather, ahem, flexible - the new design was a work in progress for 2 years (on-and-off, mostly off due to the birth of our baby) and the back-end re-write happened over a few months early in 2012.

Django allows us to iterate quickly. I find the language natural to use and the documentation is epic. There's a number of things that no framework does out of the box; I've tried to rely on open-source to fill as many gaps as possible rather than re-writing things from scratch like I did with the original WhisperGifts site - this is mostly because the open-source ecosystem around Django is now so much larger than it used to be.

As an example, originally I rolled my own authentication as the user management modules in early Django releases were rather inflexible. Building your own authentication is never a good idea, so I've migrated to using built-in Django logic. Similar changes are found throughout my codebase.

What I Use

Django, obviously. I use most of what comes with Django: The ORM and URL dispatcher, the included Admin, User and Cache apps, and more. Some might be interested to note that I don't use class-based views, simply because I don't see a need to change at this point.

Caching is done using Memcached and nested cache tags, as I've blogged about previously. I also use Django's site-wide caching middleware for anonymous users, which reduces load time for the marketing/static portions of the site.

Images are processed via the sorl-thumbnail package. I can generate thumbnails in any size on the fly. All of my images are stored locally - due to my current volume, the overhead of setting up a more formal CDN or even just using S3 isn't worthwhile.

Customer payments (for upgraded packages) are handled by PayPal. To interface with their IPN and to simplify the user-facing workflow as much as possible, I use django-paypal.

To track in-app metrics (such as number of signups, number of upgrades, number of new items) I use django-app-metrics and get a simple daily e-mail. I'm also testing out Mixpanel which although it isn't free lets me get much more detailed statistics for the same sorts of metrics. django-app-metrics even has a backend to automatically push data through to Mixpanel, so I might use that later on.

All e-mails are sent asynchronously (using django-celery) so they don't tie up front-end web serving. I deliver my e-mails via Postmark with the useful django-postmark library. All my outgoing e-mails include both HTML and plain-text components; I also embed a header image. In the geek world this is heavily frowned upon, but remember who my audience are: couples getting married and their wedding guests. Postmark makes these e-mails simple.

The front-end web server to all my websites is always nginx. It is small, easy to configure, does a wicked job of serving up any static files (both my own site static files and those customer images that have been uploaded) and integrates well with Django. To run Django for nginx I always use gunicorn managed by superisord.

My site-specific CSS and JavaScript files are hand-crafted during development then at runtime combined together effortlessly and minimised as much as possible using django-compressor.

To make sure that any gremlins are caught and dealt with, django-sentry catches any exceptions in my code and presents them in an interface that is incredibly useful: You can see which exceptions occur most often, what conditions trip them, and more.

In a similar vein I use django-timelog and occasionally review how long my views are taking to render in a live environment, django-debug-toolbar gives me similar data during development.

Bringing it all together

For much of the above all I need to do is pip install django-compressor and add the relevant code to my settings.py and templates. Very little of what I've mentioned above has changed the way I develop or deploy; they simply make life easier. The fact that I can pick up these bits of software (most of which weren't available 3-4 years ago) and use them off-the-shelf with some very minimal setup just makes me love Django development even more.

I therefore owe a big "thank you" to the Django community.

Previously I've manually written code to do many of the things I've mentioned above (and bad code, at that, given it's status as "helper code" rather than the main part of my projects). I owe a few people a beer or three.

WhisperGifts Re-Launch

Way back in 2007, my wife Lauren and I got married and went looking for a good bridal gift registry service. We didn't find one, so we built our own - WhisperGifts was born. It's now 5 years later, and today we are re-launching with a completely new look & feel and a 100% new code base under the hood.

I'm new here - what is WhisperGifts?

WhisperGifts lets couples who are getting married put their gift registry online - i.e. make available to their guests a list of the wedding gifts they'd like to receive.

In many cultures this is done by utilising the services of big chain department stores. This has two major downsides: the items are typically more expensive, and the range is moderate at best. Why not have a gift registry that lets you get gifts from anywhere?

So we built WhisperGifts - an online service that lets you list items from anywhere you like. In fact, you don't even list where the item is from - you simply say "We'd love a toaster that cooks crumpets." Your guests are still given enough latitude to select which toaster, from where, and at what price. It's win-win!

As a hobby, I can't say that WhisperGifts is too bad. Enough couples make use of it for me to say that it's worthwhile, and it's a great place for me to try out new tech and startup skills. But I've hardly put enough effort into it, which leads us to today: WhisperGifts 3.0.

WhisperGifts 3.0

I re-skinned WhisperGifts a few years back, but I've never been happy with the layout. A visitor to the website isn't really introduced to what WhisperGifts is, and there is no obvious call to action. There's a thousand and one problems that can be pointed out by anybody who has ever worked on a startup.

The old look and feel isn't the only thing that's gone, though. About 90% of the old codebase has been re-written, but not just for the sake of it - until now WhisperGifts has been running on 5-year-old code, a lifetime in web development. Every now and again I make minor updates to keep it compatible with up-to-date versions of Django, but purely for security purposes.

With a new back-end powered by all the goodness of Django 1.4, I'm able to have a website that runs faster, uses niceties like SQL aggregation, has proper form definitions (my old code still has comments referring to forms and newforms as two separate things) and is more maintainable to boot.

In terms of LOC there's about 50% less code to do the same end result.

So we've got a new visual style and a new back-end, but what else?

  • Our old "Premium" package is now "Standard" and a new Premium package has been created. It includes things like printed guest information cards and an unlimited number of items
  • Sharing of registry details via e-mail, Facebook and Twitter
  • Custom domains - so you don't have to have your registry at 'ournames.whispergifts.com'
  • Coming very soon will be custom registry templates

The new website is now live, at www.whispergifts.com. I'll be blogging again shortly with some more technical details of the change, which are probably of more interest to those who read this blog for the Django posts as none of it will be WhisperGifts-specific.

Getting married? E-mail me and I'll see what we can do about a few freebie premium accounts :)

WhisperGifts Sees the Light of Day

I got married in March 2007, within a few months of a number of friends. We all shared our trials and tribulations as we each prepared for our big events, and a number of common issues arose. One of these common points of confusion was the preparation of a bridal gift registry - a list of gifts that we would love to receive from our guests.

Being somewhat geeky, I started to put together an online bridal registry system that could not only be used by my fiance and I, but also by our friends and family. This case of scratching an itch turned into a service that would eventually become WhisperGifts, the first public offering of Jutda.

This service evolved over time into a solution suitable for the commercial prime-time and as of today is ready for public consumption at whispergifts.com.

Here's just some of the major benefits of WhisperGifts:

  • Allows your guests to shop at any store they like. Aunty Mary who works for MegaTVCorp can now buy you that 42-inch LCD that you want, without paying department store prices
  • Allows you to describe the types of items you want, rather than selecting a brand and model
  • Lets your guests browse for gifts in the comfort of their own home
  • Lets your guests easily see gifts sorted by category (Kitchenware, furniture, or outdoor living for example), within certain price brackets, or by priority
  • Can magically e-mail reminder messages to guests before the wedding
  • Can magically e-mail you a list of guests and their selections just after your wedding, helping with the process of sorting out who purchased what when it comes to writing thank-you notes.

More information on WhisperGifts is available at the WhisperGifts website and in a recent Jutda blog posting.

Soon I'll publish some Django-related technical details of the service, as elements of a commercial service built on Open Source software are often interesting to the community as a whole. As a teaser, here's a few built-in functions that were made much easier with Django. Stay tuned (or rather, subscribe to the RSS Feed) for implementation details over the coming weeks.

  • E-mailing of PDF lists of gifts / purchasers
  • Integration with PayPal to allow for upgrades to be purchased
  • A subdomain per-user, to allow for ease-of-communication
  • Built-in context-sensitive inline help and tips to maximise the benefit obtained by users, both free and paying

Overdue Catchup

I've had a very busy few months in every way conceivable - everything from my Django projects, to my day job, to life as a whole has been running in fast-forward. Here's a quick summary of the

DjangoSites is coming along very well, with 1040 sites listed as of this evening. The quantity and quality is ever-increasing, and more and more sites are being claimed. There are still well over 300 unclaimed sites - is yours listed there? If so, drop an email with your DjangoSites username to djangosites@djangosites.org.

After a server move late last year my Django OpenID project went offline for a little while. After a handful of requests from the blogosphere I've put it back online - see my original blog posting on the topic for more details, although I'm guessing that Simon Willison has something up his sleeve that'll trump my hack-job soon enougy.

Over my Christmas holidays I launched Jutda, the 'corporate' face for my upcoming web projects built with Django. The word Jutda is from the Wagiman language, a dialect spoken by an ever-shrinking Aboriginal tribe in the Northern Territory of Australia. It means show the way, which is something I hope to do with my projects. This is by no means my day job, rather a single name with which to pull together a number of after-hours projects. Hopefully the name starts to mean something within the Django community after a little while :)

The first project to be released by Jutda is WhisperGifts, a service to allow you to publish your wedding gift registry online with minimum fuss. I used it for my wedding almost a year ago with no problems, and it's been used by others before and since with great praise from happily married couples and their guests alike. Of course, it's all built with Django, with a whole host of neat features. When I have a spare evening I'll write up a few more details, but in the mean time check it out and let me know what you think.

Last but not least, I thought I'd bring attention to a simple Django application I wrote a while ago but never 'released' per-se. Django-forum is a simple Forum application for Django, allowing you to leverage your existing templates and user accounts to add discussion-forum capability to your existing project. At least a few people are using it, with a few patches coming from the community to add new functionality. I don't currently have any public sites running it, but keep your eyes peeled.

That's all of my news for now - I've got plenty more to share, however just a little more time is needed to give a few projects some more polish before I go public. Let's just hope my next update isn't another three-months away!

More...

Want to see more? Check out the yearly archives below.