Making a Drupal bookmarklet
Down with copying and pasting!
Last weekend I built/launched Frugalzon, which is a little hand-curated list of cool stuff on Amazon for $10 or less. (It's still new and fairly empty, but give it time!)
The Drupal site itself is simple--one content type, one view, one taxonomy, that's pretty much it. The only interesting aspect comes in the form of content entry. Since the whole point of the site is to be hand-picked items, I couldn't just pull some Amazon feed of cheap products. I had to manually add each of the items on there (and I continue to add a few items per day) by choosing stuff I think is cool. To make this easier, I made a bookmarklet that scrapes the info off of whatever Amazon product page I'm looking at and pre-populates a node add form on Frugalzon with that data.
So there are two things at work here: page scraping and prepopulation.
Page scraping
The first part of the bookmarklet gathers up the relevant info on the Amazon product page I'm viewing. This includes:
- Title
- Price
- Prime shipping or regular
- Image URL
- Page URL (with my affiliate code added)
- Category
For finding this stuff, the easiest method is to just use your browser's dev tools. Inspect the elements to find a unique selector to match them, and then test it out in the console. This can get a little tricky sometimes depending on the markup, especially on a site like Amazon that has a few different possible product templates each with unique un-semantic markup.
Here's the JS in my bookmarklet that does all of this on Amazon.
As you can see, Amazon includes jQuery in the page so we can use that (yay!). If the site you're scraping doesn't, then you can either load it in noConflict mode or just use vanilla JS selector hotness. You might also notice that I'm prefixing all of my variable names with "frugalzon" as a poor man's way of namespacing this.
So now we have all the data we need...what do we do with it?
Node prepopulation
There's a cool module called Prepopulate that lets you pass data to the node/add/whatever page as a query string and that data will prepopulate the form. So for example, going to /node/add/product?edit[title]=Something would make the Title field have a default value of Something when the page loads.
This works great, but it can get a little hairy with different field types (Image URL, taxonomy term reference, plain text, etc.) because each field type has a different array path in the $form
array in Drupal. Luckily, this is documented and all you have to do is view the source to see what the name
attributes of your form elements look like to know what to pass.
In the end, here's what my JS looked like to build the URL to hit.
You'll notice that the Image field is passing in a URL which is handled via the filefield_sources module. Also, the Category field is a tag-style term reference field so whatever gets passed in there will be fine; you don't have to match up tid's to existing terms or anything.
Putting it all together
So now we have our bookmarklet code (here's a full gist) and we're set up to handle it on the Drupal side (using the Prepopulate module), so we just need to make an actual bookmarklet out of this thing.
I used this online tool for that. Paste in your JS and it'll crunch it and build a little link for you to drag to your bookmarks bar. This worked like a charm. Now, adding products to Frugalzon is as simple as clicking the bookmarklet on an Amazon product page and then clicking "Save" on the prepopulated node add form. Not bad!
Hey, maybe you should follow me on Twitter!