Accessible content in WordPress

Accessibility is not just for developers. It is probably much more important when you’re a content manager/webmaster/marketing associate. You’re constantly writing content in WordPress long after a developer is done with the website and so it’s important to know how to make use some of the tips described here while you’re doing it.

So how would you go about this?

Get an “accessibility ready” theme, or have one built

All your efforts will go to waste if the theme that is installed on your website doesn’t do anything with the additional data you’re putting in. This goes specifically for what is being put in outside of the main content area or pages that are generated. For example, the featured image, the blog feed, or a predefined page template. Let alone if it doesn’t even have any :focus styles defined.

WordPress has a large repository of themes, but so far only a few have been tested and marked “accessibility ready” themes in the WordPress repository. This doesn’t mean that themes that don’t have this tag won’t be up for the task, but it does mean that there is a chance that it isn’t.

Can’t find anything you particularly like in the WordPress repository? Find a developer that will build one for you. You can email me if you’d like me to work with you to build an accessible theme with a stunning design.

Descriptive links

At the very least, try and make the text you’re turning into a link very clear. Click here is a very poor way to tell people what is going to happen when they actually do activate the link. If it’s impractical to describe your link in the link’s text, then make use of the title field to add that Rick Roll. See also the image below.

You will want to make an effort to make the link text as descriptive as possible. The title attribute isn’t exposed to users by most browsers, and screen reader users are very likely to have it disabled in their screen reader because of blatant abuse. If you really need your link text to be short (“Read More” links, or something else where the context is visually clear) you can use hidden “screen reader text”. This will require some basic HTML chops, however.

Read the official W3C HTML recommendation for the title attribute.

Describe your images

When adding an image to WordPress, it will add a title to the image but not much else. And more often than not, this title is pretty meaningless. If you’re adding images to your post, you will want to make sure to enter the “Alt Text” that describes your image to those that cannot see it.

Is the image not important enough for the context of your page? Consider adding a blank alt attribute, ie, alt="". WordPress will do this for you automatically if you leave the “Alt Text” and “Title” fields empty. It’s important to also remove whatever text is put in the “Title” field, because otherwise this will be used as the alt.

The fields to enter this information are on the right side of the media manager
The fields to enter this information, where applicable, are on the right side of the media library.

Provide text alternatives!

This is something specific for content management, though your developer can most likely assist you in tackling this. When you embed audio or video, you will want to make sure you have a transcription of the content available. For video you will want to ensure to provide captions when it’s important for someone to be able to see what’s going on in the video. For example, a clip from a TV show or a play.

There’s a few ways to provide these transcriptions. If it’s part of a larger post and the clip is short, or if it’s the main content for the post, you can generally provide the transcript in line with the rest of the text. If it’s not, you may want to consider moving the transcript to a separate page and link to it.

Write readable content

I can’t tell you how to do your job. If anything, I could probably use some writing classes myself. I do, however, want to underline the importance of writing readable content. People with dyslexia will thank you for keeping your sentences simple.

Besides that, don’t overload your pages with images, or use an intense variety of styles, colours, and fonts. This will ensure your page looks clean and inviting to read.

Still need help?

Let me know! If there is something in this post you don’t fully understand, I probably did not do a good enough job explaining it. Feel free to leave feedback with this form, or hit me up on Twitter.

Dealing with White Screens of DOOM in WordPress

WordPress Logo

We’ve all been there. Happily writing our PHP for some template or another. But then you save your file and refresh the page and…the screen stays completely white.

So why does this happen? Most likely you’ve made a syntax error somewhere. Like, say, forgetting a semi-colon or curly bracket. Another reason is that you’ve reached the memory limit of your server. The latter will usually happen when you enable a particularly poor plugin or theme.

The reason this comes up as a white screen of DOOM is because your errors are being suppressed.

While this isn’t necessarily a bad thing on a production server (though, you do test your code before pushing it live, right? Right?), it can be very inconvenient while you’re developing a new template or WordPress plugin.

To get rid of this inconvenience on a development server is fairly simple. All you need to do is open up your wp-config.php file and locate the line that says: define('WP_DEBUG', false);. Change false to true and you should be good to go. If it’s not there, you can add it anywhere above where it says /* That's all, stop editing! Happy blogging. */.

Should this not work (it’s somewhat unlikely, but it’s possible), you can also set PHP’s error reporting on the fly.

And there’s that. My first quick tip. I’ll most likely post more of these in the future. If you’re still having issues with errors plaguing your WordPress website, drop me a line and we’ll figure it out together.

Updating Ubuntu 12.10 to 14.04 on Digital Ocean

Today I had set out to set up automatic deployment for my theme on this server using git. However, I hit a bump in the road when actually trying to install git: The old quantal repositories have been moved and so it wasn’t actually able to find the appropriate git package to install.

Being as inexperienced as I am with Linux, this was a little frustrating. Frantic Google searches resulted in mostly mixed and incomplete solutions. But for the most part, I’ve taken this opportunity to just get it over with and update Ubuntu to a version that isn’t EOL (End-of-Life).

So here’s this post, for those that are in the same situation as I and don’t feel like re-creating their installation on a new droplet. SSH into your server and let’s go!

But before you begin, make sure to create a snapshot as a back up. Just in case!

Update sources.list

First thing you will want to do is update the sources.list file that’s located at /etc/apt/sources.list. In here you’ll find a list of URLs where Ubuntu will try and look for packages. For Ubuntu 12.10 it’ll look like:

deb quantal main 
deb quantal-updates main 
deb quantal-security main universe 
deb quantal universe 
deb quantal-updates universe

To update them, you will want to replace archive and security to old-releases. This is where Ubuntu keeps their older, unsupported, releases. Save the file and execute sudo apt-get update to update your package list from these “new” sources. Then, execute sudo apt-get upgrade to update all the packages that are currently installed on your server.

Update. Update. Update.

With the sources’ functionality restored, you should now be able to install packages again and also update your version of Ubuntu. Which means you can also install the update manager package to help you in the process. Do so by executing: sudo apt-get install update-manager-core. This will enable the do-release-upgrade command.

Executing this command now should find the 13.10 Saucy Salamander update. Unfortunately, it’s not possible to go straight to 14.04, so go through and install 13.10 first.

One of the first things you’re going to get asked is about whether or not you’d like for the update process to ask before restarting services or not. For the sake of convenience, select “Yes”. If you prefer to have more control, select “No”.

During the update, you may also get asked about configuration files that may have been changed. If you know absolutely sure you’ve not made your own modifications to a file, you should be fine selecting “install the package maintainer’s version”. For files like php.ini, it may be a good idea to “keep the local version currently installed”. When in doubt, it does allow you to look over the diffs in vi.

Depending on the amount of packages you’ve installed, the update should be fairly quick. Restart your server and then…do all of it again. This time, running sudo do-release-upgrade will find 14.04 Trusty Tahr and allow you to get up to date.

One more reboot after the update and you should be good to go. Make sure everything is running the way it should be and fix whatever isn’t. In my case, nginx was giving Bad Gateway errors after the update. A quick look at the error log showed me that they were permissions related. As it turns out, for some reason the php-fpm socket was being created by root.

To fix this, certain settings had to be re-enabled in /etc/php5/fpm/pool.d/www.conf. Specifically:

listen.owner = www-data = www-data
listen.mode = 0666

Ensure that these are set to the owner/group nginx is set to use as well. By default this is www-data, but your set up may differ from mine. To find out, check your nginx conf (eg. /etc/nginx/nginx.conf) for a user line.

And that should be that. You will want to make sure to change the kernel setting in your Digital Ocean account to the appropriate version as well.

Should you run into any issues, feel free to let me know where you get stuck or what kind of errors you’re getting.

My first contribution to WordPress

WordPress Logo

Lately I’ve been trying to get more active in the community of Orlando developers. Specifically for WordPress, since that’s what we’re using the most at Highforge. I’ve been attending WordPress meetups and felt it was time to start putting my coding skills to good use on the software we use and love.

WordPress has various ways for people to contribute. From Core contributions, to support, to documentation, there’s something to do for everyone. I can recommend heading over to Make WordPress and finding out what you can do.

Since I’m not a hardcore programming dude (yet) and am of more use on the front end of things, I decided to start out contributing to accessibility. This, in theory, should work out really well for me since it will help expand on my knowledge of accessibility by absorbing the expertise of the people at the a11y project while at the same time being able to fix the bugs we find.

Earlier this week WordPress 4.0-RC1 was released, making for the perfect jump in point to get started with testing, fixing, and contributing. Right off the bat I had found a bug: When using the tab key to browse through the admin section, I was unable to get to my multisite’s Network Admin page(My Sites -> Network Admin -> Dashboard). Instead, when selecting “Network Admin”, it seemed to close the menu completely.

“Excellent!” I thought. I had first read this thread and followed the instructions on posting my findings in the Alpha/Beta support forum. It quickly became apparent that this issue has been around longer and as such wasn’t technically an Alpha/Beta type issue.

In either case I would have had to create a ticket in the WordPress issue system “trac”. The main difference is that I’d be reporting the bug for version 3.9.2, as opposed to trunk (the most recent development version in SVN).

For those interested, here’s the link to my ticket: 29422.

The best part about the bug I’ve found, really, is the fact that it’s also fairly simple to fix. And so, not only did I get to contribute by filing a bug report, but I also got some experience with submitting patches for review.

Getting set up and actually fixing the bug is a story for another time, though. As I’ve just found out, I can easily keep rambling on the details of the fix and triple this post in size. But since it’s mostly code-related, I’ll end this post here and I’ll owe you the code stuff.

As always, feel free to ask me anything. If you need more help getting involved with WordPress, I may not be the perfect person to ask, but I will do my best to at least set you on the right path.

Writing my Python Marvel API Wrapper Part 3: Refactor

This is part three of my ongoing adventure in writing a Python interface to the Marvel API. If you’ve not read Part 1 about structure and Part 2 about adding requests then you may want to do that first.

So we left off with a functioning interface for the Marvel API, but ended up with the realisation that things could be so much simpler if we just refactor all the things.

About refactoring

By refactoring code, you’re essentially restructuring without changing the function. The main purpose is to improve maintainability of your code by, for example, splitting up long processes into smaller subprocesses or working to remove duplication.

In my case, we’ll be getting rid of some of the duplication that is in the code. As we’ve seen, a lot of my methods were building the exact same request URL and so that’s where we’ll start.


We can reduce a significant amount of duplicate code by handling the request URL in its own little method function, like getHash().

Step 1: Create a basic request URL

First, we’ll move the code to create the base request URL over to the new function.

def getRequestURL(self):
  request_url = self.API_URL + '?apikey=%s' % self.API_KEY
  return request_url

Step 2: Move the timestamp and hash generation

Next, we’ll have the function handle the timestamp and hash generation so that we don’t have to do so in each function separately.

def getRequestURL(self):
  request_url = self.API_URL + '?apikey=%s' % self.API_KEY

  ts = str(time.time())
  reqHash = self.getHash(ts, self.PRIV_KEY, self.API_KEY)
  request_url += '&ts=%s&hash=%s' % (ts, reqHash)

  return request_url

Step 3: Move additional parameters

Finally, we need to move the additional parameters like id, args, and subtypes. This can get a little tricky, because we don’t always need to use them. Therefor, we need to see if they’re being passed to the function.

So for id this would be something like:

def getRequestURL(self, id=None):
  request_url = self.API_URL

  if id:
    request_url += '/%s' % id

  ts = str(time.time())
  reqHash = self.getHash(ts, self.PRIV_KEY, self.API_KEY)

  request_url += '?apikey=%s&ts=%s&hash=%s' % (self.API_KEY, ts, reqHash)

  return request_url

The subType parameter can be added to the function in pretty much the same way and the arguments can be handled in the exact same way as they are now. The end result of this refactor is the following function:

def getRequestURL(self, id=None, subType=None, args={}):
  request_url = self.API_URL

  if id:
    request_url += '/%s' % id

  if subType:
    request_url += '/%s' % subType

  ts = str(time.time())
  reqHash = self.getHash(ts, self.PRIV_KEY, self.API_KEY)

  request_url += '?apikey=%s&ts=%s&hash=%s' % (self.API_KEY, ts, reqHash)

  for arg in args:
    request_url += "&%s=%s" % (arg, args[arg])		

  return request_url

Having moved all this code to a single function, our methods are now much, much cleaner. Check it out:

def getList(self, args):
  request_url = self.getRequestURL(args=args)

  return requests.get(request_url)

def getOne(self, id):
  request_url = self.getRequestURL(id)

  return requests.get(request_url)

def getCharacters(self, id, args):
  request_url = self.getRequestURL(id=id, subType='characters', args=args)

  return requests.get(request_url)

In the next part

We have a very limited amount of requests to this API. Which, I believe, is around a 1000 when you start out. My account is currently at 3000 requests per day. Generally speaking though, even if you don’t have a request limit with an API it’s a good idea to cache your requests. You really shouldn’t need to make repeated requests to the API for the same data. I’m considering implementing this into a Django app so that we can make use of its Model system to store data we request for a month or more before requesting it again.

I may also consider reorganising the code so that you could potentially do something like:

stan_lee = marvel.creators.getOne(id=30)

The options for improvement are almost endless at this point.

As always, you can find this stuff on Github. If you want to let me know how much this stuff sucks, I’m on Twitter of fill out this form.