An ExpressionEngine plugin to manage social sharing buttons
At Blue State Digital — where I work as a front-end web developer — we design, build, and host websites for a variety of clients. Our online toolkit includes ExpressionEngine as the CMS because of its community, flexibility, and power. At the moment, we host more than 200 installations of ExpressionEngine. One of our software engineers, Lowell Kitchen, gave a talk about hosting EE at EECI 2011 — check out the slides if you want some more info.
Some background: the sEEd
Every client that we host is built from a custom configured version of EE that we call the sEEd, which avoids having to repeat some basic setup for every single site that we build, which would total about 2-3 hours for each site.
Each client has access to the same add-ons because the client’s EE installations are symlinked (see Lowell’s slides).
Why bother with sharing buttons?
At Blue State, we believe that social media plays a large role in communicating with an audience and advancing a message. It Gets Better and United States Holocaust Memorial Museum’s Remember Me project are two projects we’ve worked on that were driven almost exclusively by social media.
While every organization uses social media in a different manner, most clients we work with utilize social buttons to share content without needing to leave the site.
Why bother building a plugin?
Things change. Button syntaxes change. Dependencies change. Social networks change.
Let’s say Facebook decides to change how you need to implement the Like button, or Twitter adds new parameters to the Follow button and changes the default in the process. When you suddenly need to change 2 or 3 client sites, it’s a little tedious, but doable in an hour or two, depending on how many templates you need to change. Make that 200 sites, and suddenly there’s no time to do anything but update templates with new social button code.
We needed to build solution that could be rolled out to all of our clients, and update all of their templates with the least amount of manual intervention.
Enter SocialEEsta
SocialEEsta is an ExpressionEngine plugin that adds social buttons to your ExpressionEngine pages with no fuss. Forget worrying about building query strings and URL encoding parameters or loading the buttons’ Javascript in a consistent manner. And when things change? We can just update SocialEEsta and deploy the new version to our clients.
For version 1.0, we settled on buttons from the two social networks we tend to see the most benefit from — Facebook and Twitter — as well as the then-nascent Google+.
Still on the to-do list
Real artists ship and all, so even though we released it publicly, we still have some things we’d like to add:
Add the new Twitter Tweet/Follow button parameters
Investigate other options for more efficient Javascript loading (check out Socialite.js)
Add Tumblr and LinkedIn sharing support
Write unit tests (the code is already unit testable, but we need to actually implement the tests!)
Where to get it
SocialEEsta is available for (free) download on Github.
Semantics matter, and <time> is just one example of great HTML5 semantics. Something that has context, and is easily distinguishable for us humans.
<data> is too vague, too bland, it sucks.
Site seems down at the moment, but is available via Google cache.
Update: And now, the W3C chairs have requested a revert, on what seems to be technical (parliamentary?) grounds. Seems like a stay of execution, or at least a reprieve. (via Hacker News, where the haters are hatin’.)
One of the great things about ExpressionEngine is its flexibility. Sometimes, you can get so excited though, that you wind up coding yourself into knots, with templates running hundreds of queries per page load (of course this can be alleviated by caching).
ExpressionEngine’s output profiler and template debugging are very helpful tools, but what about when you just need to know about the total number of queries and the time EE spent parsing the template?
Look no further. Make a new snippet and copy this code into it, then place the snippet anywhere in the <body> element.
The badge will only display for logged in Super Admin users, so you won’t need to worry about it appearing for regular visitors.
While working on We Don’t Lie to Google, it became apparent that I would need a better way to keep track of things I’d already posted, particularly as time passed, in order to prevent posting duplicate entries.
Enough’s been said about how remarkable Tumblr is, and how easy it’s made blogging. But it’s also been plagued by service outages. Though it’s been said that you get what you pay for — the service is free.
At some point, I made the decision to move away from Tumblr for a few reasons:
If the project was going to continue in a serious manner, I needed hosting that wouldn’t suffer from outages about which I could do absolutely nothing
I wanted more control over and access to my data, both entries and uploaded images
When you make a living making websites, Tumblr starts to feel a little janky with respect to how things, like static files, are managed
When I made the decision to move to WordPress, I started to look for ways to export my data from Tumblr. Here’s what I found:
Tumblr has a backup utility that doesn’t work
On Tumblr’s “Goodies” page, there is a link to download a beta of their Mac backup utility. Sadly by the time I discovered it, it didn’t function — at all. I sent a support request asking if there was a solution for the issue I was having, along with detailed info (portions of my console.log). A few days later I got this reply:
Hi Douglas,
I can’t tell you how much we appreciate your support and feedback. I’ve passed this along to our engineering team to investigate. Thanks!
Great, someone cares! Escalated to the Engineering team! Color me impressed. Except that I heard nothing more for a full month, at which time I decided to write in again. A few days later, another response (from a different support rep), this time less great:
Sorry development of that app has been discontinued and the developers are working on a more robust backup solution. However, we don’t have a rollout date at this time. My apologies.
That came back on May 10, 2011 — as of this writing, the app is still listed on the Goodies page, with “Windows version coming soon.” But the link still goes to the same beta version I initially downloaded.
Ah, but there is an API!
So there is, but in the case of We Don’t Lie To Google, all of my posts were images, and using the API would require scripting a solution to download all of the images. Not impossible, but We Don’t Lie to Google is a content-based project — losing focus on the content could have made it too easy to abandon the project as a whole.
Also, when I was working on this migration, the API was less reliable than the actual service.
Third-party backup solutions
There are a few people who have written solutions that tie into the Tumblr API, and I used a combination of them to get all of my posts out of Tumblr and into WordPress.
Tumblelog Backup Tool: This utility let me save a Safari-style .webarchive of all of my posts, which meant that I was able to bulk download all of the images I’d uploaded and sort them out on my local machine.
tumblr2wp: A utility that will reformat the XML output of the Tumblr API into a WordPress WXR (WordPress eXtended RSS) file.
So, what about all those images?
When you upload an image to Tumblr, it renames the file with a hash and the image size, to something like “tumblr_llfz9dzXbY1qcdvqyo1_500.png”.
And because I’d been less than organized when creating the entries initially, it was time to reap what I’d sowed. I had to manually rename every image. Fortunately, there were only about 75 entries at the time, but that still took a few hours to get everything straightened out.
Getting the posts into WordPress
Importing the entries from the WXR file was simple: just a few clicks and all of the entries were in WordPress.
The next part was a bitch: I had to manually associate each image with an entry. It wasn’t hard work, just tedious, and was unable to be scripted for a few reasons:
I wanted the file names to contain the search terms rather than the caption
Tumblr’s image posts don’t allow for metadata or anything other than a caption and tags
I hadn’t considered the possibility that I would want to leave Tumblr in the future
At any rate, I decided that scripting a solution likely would have taken longer than just manually renaming files since there were less than 100 at the time.
Rewriting URLs
Tumblr post URLs follow this pattern: /post/[post-id]/[post-slug (image caption)]. The post-id is unnecessary, so I planned to leave it out of the URL entirely (though tumblr2wp offers the option to have URL formatted like [post_id]-[post-slug]).
Apache’s mod_rewrite to the rescue: requests for /post/[post-id]/[post-slug] get a 301 redirect to /post/[post-slug]. Problem solved.
A note: Tumblr will handle requests for /post/[post-id] just the same as /post/[post-id]/[post-slug] — because the Permalinks that Tumblr generates have the slug in there (at least the ones I saw), I made the assumption that requests to WordPress for /post/[post-id] could be 404’d. So far this has not been a problem for me.
Lessons learned
It’s hard to actually be mad at Tumblr — they offer a pretty great service for free that’s spawned hundreds, if not thousands, of pretty successful tumble logs. But if your content is important to you, and you don’t like putting all of your data-eggs in one basket, the experience can be frustrating. There’s not a great way to move to another service, particularly for users who are less technically adept than I am.
All that said, I’d seen the shortcomings of Tumblr (for this project, at least) only a few weeks into my project — losing track of what I’d already posted because I couldn’t FTP in to see a list of files, or even look at a file manager.
It all comes back to how important you think your content is. If you would like one day to be able to leave Tumblr, well, I’d think twice before you posted another entry. Each new post pushes you a little further down that rabbit hole, and the deeper you are, the harder it is to climb (or dig) your way out.
In my stumbling around the Internets, last year I came across these twoarticles that inspired a project entitled “We Don’t Lie to Google.” I started working on it around July, 2010 and then abandoned it for a few months before picking it back up again.
Because we’re so honest in the search box, documenting these suggestions offers a way to look at ourselves, or at least the way Google sees us. And given that Google is constantly changing its algorithms for search results and autocompletion, we can use their suggestions to track ourselves over time.
Of course, because Google’s suggestions may take into account things that they know about the user (we’ll probably never know), I try to neutralize it by generating suggestions only when I’m logged out Google’s services. That said, it’s impossible to determine to what degree the suggestions are specific to me, which is also fascinating.
Because Magpie doesn’t seem to play well with PHP within its {items} loop, I took it upon myself to write a simple plugin that could parse a URL and return the domain name. For instance, from the url http://www.foo.com/bar/index.html, you’d get foo.com. I use it in the sidebar for my “liked” articles from Instapaper. Sort of like you might see on Instapaper’s site itself.
At any rate, I’ll release it soon over on the projects page.
Update: Looks like there’s already a plugin that does this, and more, from EllisLab: Parse URL. It was still fun to learn and definitely worth it. I’m sure there’s more to come.
So this past week, MacUpdate ran a promo bundle with a few semi-useful apps, and Parallels Desktop, for $49. Since I’ve never tried Parallels, I figure it might be worth it and purchased the bundle.
So I ran through the hoops of creating a MacUpdate account, and unchecked the “Sign me up for the newsletter” box that was pre-checked for me (a great UX detail, mind you).
And now 2 days later I find out the following:
I was signed up for at least one MacUpdate mailing list that I did not opt-in to.
They retained my billing information and signed me up for “Auto-renew annual Membership w/MacUpdate Desktop”
MacUpdate created a public profile on MacUpdate.com with my first and last name, age, and gender shared publicly.
Honestly, the second item on that list is the most offensive. Particularly when there’s a FAQ for the bundle that asks “Is there a catch?” with this answer:
Nope, none! You get the same versions of the software as if you paid full price! The same support, update, and upgrade options are available to you as well! No ‘Lite’ versions or anything of the sort.
I’d like to think this whole bit was an April Fools Day joke, but I’m guessing it wasn’t.