Garlic.js is a great library – it uses localStorage to save the state of forms, so if your users accidentally close the tab or browser before submitting, their entry isn’t lost. This works seemlessly for almost all form elements, however WYSIWYG editors like TinyMCE present problems. Luckily it isn’t hard to fix – there’s a comment on the github repository for the project with the snippet you need to add to the init function:
setup : function(editor) {
editor.on("change keyup", function(e){
console.log('saving');
//tinyMCE.triggerSave(); // updates all instances
editor.save(); // updates this instance's textarea
$(editor.getElement()).trigger('change'); // for garlic to detect change
});
}
So far so easy. But today the challenge was a little harder as WordPress was in the mix too.
At Helpful Technology we have a training product called Crisis90 that allows users work through a scenario and compare their responses. It is built on WordPress and makes use of GravityForms to allow users to submit responses to the crisis scenarios presented (there’s also a simulated Twitter environment for practicing real-time responses). When asking users to draft a press release, for example, we provide a WYSIWYG editor – this is native to GravityForms which in turn leverages the bundled TinyMCE library in WordPress. But this means that TinyMCE is being loaded automatically without me being able to modify the init function. Luckily there is a filter for that – tiny_mce_before_init. This filter lets you modify the settings array used to initialise TinyMCE. Despite the lack of a setup item in the defaults or example, it is perfectly valid. You can use this filter in a simple plugin or in your theme’s functions.php:
As you can see, we’re just adding a setup key to the $settings array containing the snippet from above. I’ve also included a little check that we aren’t in the admin area as I only want this to apply to the instances of TinyMCE used in forms on the front-end of the site.
Now Garlic.js will function correctly with TinyMCE, and a slip of the finger won’t lead to any lost work.
There are two things that designers will throw out quite often – box grids with rows, and repeating background colours.
Sounds easy – but go and try it within the WordPress loop (or any other). It can get ugly quickly, but the solution is actually simple: Modulus. In PHP it’s the % sign.
To see what modulus is all about run this simple page:
This will output a list showing when various modulus calculations will output TRUE so you can check in an if statement. For example:
Modulus 3 is perfect for creating a 3 column grid (in this case in Bootstrap style) as we can check for when the remainder is 2 which will tell us we are on the 3rd, 6th, 9th etc item. This means we can output the very first and last <div class="row"> tags with no logic, then just use modulus to insert the inbetween </div><div class="row"> to end one row and start another where needed:
More complex example – looping background colours
This time we will use modulus 7 to loop over a list of the colours of the rainbow to set a class that will control the background colour of a div:
This illustrates how the modulus number sets the frequency that the loop repeats, and by checking for different remainders you can identify any point in that loop.
If you’ve got a good use of modulus let me know in the comments.
I decided to write a short follow up from the post from last week about the performance of this site, but framed more as a “how to quickly speed up my site”. Even if you can’t or don’t want to go down the line of changing themes (or writing your own), profiling plugins to find the fastest options, or changing hosting company, by spending 5 minutes installing these 3 plugins you can get a significant performance boost.
1. Squish those images
Images generally make up the bulk of the download weight of a site, especially in badly behaved themes. While WordPress does compress the smaller versions it creates when you upload a new one, and got better at it in version 4.5, a bit more can go a long way to speeding things up.
There are plenty of plugins to do this, both premium and free, and they fall into two camps technically – those who offload the processing to another server, and those that do it on your server. The big reason for using the external server type is to lower the resource use on yours or because yours doesn’t have the required libraries (normally cheap shared hosting). However most decent hosts will have no problems, and I prefer to keep things under my control when I can, so I’ve chosen to use Ewww Image Optimizer. Ewww has come out ahead in various comparisons but I’ll leave it to you to choose from the competition. Once you’ve installed it, any new images uploaded will be automatically optimised, both the full size originals and the smaller ones. There’s only one more step – head to Media -> Bulk Optimize and click on Start Optimizing. This will scan the media library and optimise everything previously uploaded. If your theme comes with built in images, you can also click Scan and Optimize which will catch those too.
WordPress is built on PHP and a MySQL database. While the browser needs to be sent HTML files, on the server PHP is used to generate that HTML by reading information from the database. All this takes time, and also resources. When you have more concurrent visitors then the server uses more resources, which causes it to slow down, and eventually become unable to serve them. One way around this is to buy a bigger server, but a cheaper and easier solution exists – caching. Caching is the process of grabbing the HTML that PHP generates, and saving it for a set time. Instead of each visitor going to PHP and the database to generate the HMTL, it is sent to them directly saving both time and load on the server. After a chosen time, or a trigger like publishing a new post, the saved HTML is thrown away and a fresh copy created. This ensures visitors get an up to date version. The exact impact will depend on your site and server, but as an illustration I was running a load test on a client server last month: without caching the site became unresponsive after 36 concurrent visitors, with caching it was still going strong at 1500! NB – the site in question has some very complex pages making large numbers of database queries; also, these ‘users’ all doing indentical actions at exactly the same moments which would equate to a larger number of real-world users.
This was achieved using the popular free plugin WP Super Cache. Caching is more complicated than image optimisation, but WP Super Cache strikes a good balance between its simplicity and power. Even just installing the plugin and using the default settings on the Easy screen will give your site a huge boost. But it’s worth having a read of the Advanced and Preload tabs to refine things – the settings all have good inline documentation. For most turning on all the Recommended items on the Advanced screen is a good start, as well as reviewing the Expiry Time & Garbage Collection values (the text under the setting box has good examples).
Your site will now be both quicker and able to cope with more visitors. But there’s one more thing to do.
3. Minify, compress and concatenate HTML, CSS and JavaScript
Images squished, HTML pre-generated – but there’s also CSS and JavaScript being sent to users. Have a look at your site using View Source in your browser of choice. Since most themes are fairly badly behaved you’ll likely see multiple CSS and JavaScript files relating to the theme, and on top of that there will probably be ones added by plugins. Each separate file is both adding bytes to be downloaded, and also a connection that has to be opened from the browser to the server which takes time.
The solution to this threefold:
minification – remove spaces and rewrite files to shorten the length of them.
concatenation – join files together so that fewer have to be downloaded.
compression – server the files from the server with file compression to make them smaller, and send special headers to tell the browser to cache them locally to save downloading them again.
One plugin can so all this for us – Autoptimize. Install, activate, and turn on the 3 basic options to optimise HMTL, CSS and JavaScript. This one does need a bit more care – there is potential to break JavaScript code in particular. I’d recommend giving your site a good test after this basic activation to check everything is ok. If so, feel free to enable the Advanced Settings and tweak it to squeeze a bit more performance out – it’s all well documented. One advanced setting in particular to look at is inlining CSS. If your theme is quite a light one, inlining it all is best. If your theme is more complex, inlining ‘above the fold’ CSS will drastically improve the apparent loading speed of your site. This is because the browser will have enough information to render the visible area of the site even while it is still loading the rest.
5 Minutes, that all it will take – probably less time than it took to read this ramble – and you will have netted a substantial increase in performance. If you’re still after more speed things get a bit more complex – a faster server / host or a better theme would be the next on my list. Beyond that there’s object caching, server caching, CDNs, server optimisation, code optimisation… It goes on, but the 3 simple steps here should be all that 90% of sites need. To take things further I’d highly recommend reading this detailed article on WordPress performance and bottlenecks at Smashing Mag.
How many sites do you visit that are full of indecipherable jargon? Littered with cringe worthy stock images, confusing layouts, and slow to load? Beautiful but functionally flawed. How many of the sites you’ve built are like that? Own up – we’ve all done it… (although hopefully not ticking all those boxes at once!)
We’re all part of the problem – we’ve lost sight of the purpose of the sites we build. It’s all about users, not us; we are definitely not “average users”.
The problem
Accessibility is often an afterthought, maybe a token aria-role and not much more. But accessibility effects us all and permeates every aspect of a website. Accessibility isn’t about disability. That’s not to say that you shouldn’t be making your site accessible to the disabled, but accessibility is about everyone.
Every decision we make about development, design and content effects whether people can understand and use your site. Unfortunately many common practices are hampering our users. It’s not hard. It’s just thoughtlessness, and it’s affecting your bottom line.
Here’s a few of the common problems:
Design
Undeniably the low hanging fruit – we’ve all seen, or heard of, designs that are beautiful but frustrating, or even impossible, to use. Pick any trend in web design and there are myriad bad implementations that hinder users:
Big images (full screen background images, sliders, “hero” images etc) – without careful implementation these often cause bloated page sizes that drive away limited bandwidth users and can also create artificial “folds” that can confuse people into thinking there isn’t any other content on a page. Worse still, when these images aren’t appropriate and conveying meaning, they can stop users from even being able to tell what your site is about.
Undifferentiated links – there’s a reason browsers without exception all style links in blue and underlined, it’s the standard. Users are smart: change that shade of blue, fine; change the colour completely to one that stands out from normal text, normally OK; drop the underline, fine; but while changing the colour to be the same as normal text and omitting the underline looks much less “messy”, now no-one has any idea what to click on… The same goes for buttons – “ghost buttons” with no border or background to differentiate them are a bit of a fad lately. I’ve watched too many user-testing videos of people blindly clicking on any object and text as they have no indicator to tell them what is a link / button and what isn’t.
But more problematic are the widely accepted design patterns that fundamentally exclude users:
“Hamburger” menus (especially on desktop) – yes we all know what they are, but have you actually thought about the rest of your users? Older and less technologically inclined ones in particular are still completely stumped by sites with ‘missing’ menus. “Lots of sites use them” is not a valid response… Lots of sites are also driving away potential users.
No home button – like the hamburger menu, omitting a home link in the menu is normally justified because “everyone knows you just click on the logo”. But what is really being said is ‘we in the web industry all know to click on the logo and so do the web savvy users’, but what about the rest? Would you really build a hotel with no signs to reception because ‘everyone knows it’s near the dining room’?
Code
Code has its biggest effect on accessibility by affecting the usability of assistive technologies.
You can’t perform basic navigation of your site using just the keyboard. This is critical for everyone from power-users to those with extreme physical disabilities whose assistive technologies normally mimic simple keyboard commands. Strongly tied to this is a design point – removing :focus and :active styling is a really bad idea and leads to keyboard users getting lost on the page.
Content
This isn’t complex in theory, write clear and concise text and you’re done. If you’ve got images or other media then insert them at appropriate points in the flow of text to give them implicit meaning, and ensure that they are relevant and adding meaning / value themselves.
I’ll leave aside the strange desire some companies have for making their website a copy of corporate documents; even if your audience is one coming to view (for example) legal documents, they wouldn’t expect your ‘About’ page to read like one.
But in practice this is more complex than it at first seems. Users abilities fall into a range of categories (including but not limited to):
Specialists with knowledge of industry specific terminology (jargon to the rest of us).
Educated general public – this can be educated in the sense of general education / intelligence level, and / or those slightly informed about a specific topic.
Novices – those with no prior knowledge of a subject, yet who have a reason to access it (even if it is only curiosity).
Those in any other category where their ability to access the content is physically impaired, for example a level of visual impairment.
Those in any other category where their ability to access the content is mentally impaired, for example someone with dementia who has trouble holding large amounts of information in their working memory.
Those in any other category who have a primary language other than the one the content is written in.
Writing while meeting the needs of all these groups is no easy task. Even a sentence as simple as “watch out for trouble” hides problems. Metaphors, idioms, phrasal verbs (there’s a good article on the problems with these specifically on GOV.UK) and other literary devices can all cause problems for users. While they may sometimes be the most appropriate way to phrase something, you should be aware of them and the problems they can cause. Imagine someone reading that example sentence literally…
Rant over. So how do we make our sites inclusive and accessible? There’s no magic bullet, and every site is different and will need tailoring to it’s own audience.
Actions
However this list is a good starting point. In fact if you can follow most of these, you will make a big difference and help keep the web accessible to everyone.
Make it Perceivable
Give links and buttons clear visual differentiation. Conforming to traditional patterns unless there is a strong reason not to.
All link states should have clear styling including :focus and :active.
Link and button text should always explain what it does when read out of context. Use screen-reader only content if absolutely necessary.
Buttons must be large enough for users on touch devices.
Colour should never be the only differentiator between two states / meanings.
Text contrast must conform to AA WCAG2.0 guidelines, always attempt to reach AAA level.
Avoid overlaying text on images or backgrounds that affect readability.
Provide text alternatives for non-text content.
Use semantic code to convey the structure and relationships of content sections. Structure must remain meaningful when viewed without stylesheets and javascript, and also when read by screen-readers.
Always give inputs labels even if using placeholder text. They can be visually hidden if desired.
Never disable browser zooming and use relative units for text sizing.
Make it Operable
You must be able to navigate the site with only a keyboard.
Focus should not move / be moved unexpectedly.
Provide ‘skip links’. At a minimum give a ‘skip to content’ link as the first item on the page.
Provide clear site navigation that is not hidden behind “hamburger” menus.
Include the homepage in the main navigation.
Use breadcrumbs to provide navigation at depth.
Make it Understandable
Always set the lang attribute on the page’s <html> element.
On your homepage <h1> should be the site title (it can be visually hidden). On all other pages it must be the page / content title.
Use regular semantic headings to keep content easily digestible and signposted.
Content and purpose should be clear and as concise.
Only use images and other media to add value and meaning to the text content. They must appear in an appropriate place so that it is clear what they relate to.
Keep content related to actions immediately next to each other, both visually and in the code.
Ensure there is a clear flow of content without unrelated
Avoid jargon where possible.
Use metaphors, idioms, phrasal verbs and sayings only when they are truly the most appropriate way to convey your meaning.
Abbreviations and acronyms should be avoided or have definitions available at every use.
I’ll leave you with this:
The goal, she stated, is a world where all apps are accessible, even in cases where it may seem unintuitive. As an example, she recited her experience in traveling to China and discovering an unknown object in her hotel room that appeared to be a fruit. Rather than sampling it, she took a photo of it and sent it to a friend, who identified the object as being a dragonfruit.
Girma noted she was only able to do that because the Camera app is accessible via Voice Over. Without considering such a scenario, one might imagine that a blind person wouldn’t need an accessible camera app because ‘why would a blind person take pictures?’
Custom Creative has had a bit of a makeover. Now my time is largely spent on projects at Helpful Technology I have decided to move the focus of this site from marketing my services to the blog content. With this comes a renewed commitment to write more… good intentions at least.
While restructuring the site I decided it was time for a visual refresh too. Particularly due to the focus on reading a high performance theme was in order – I settled on Fastr (available on GitHub) and created my own fork. So far the changes are minor – styling tweaks for taste & accessibility, and support for some new WordPress features including title-tag & custom-logo.
Now Fastr lived up to is name anyway – with no JavaScript and minimal CSS it is already a high performance theme – but with a couple of plugins things really start to fly. This site has now hit the heady heights of 99% performance ratings on both Yslow and Pagespeed.
Autoptimize concatenates and minifies HTML, CSS, and JavaScript; it can also inline and defer if chosen. This reduces file sizes and DNS lookups. Since this site is so lightweight I chose to inline all CSS as this can drastically reduce the time to first render and the apparent loading speed for users.
WP Super Cache creates static HTML versions of your site to save the latency and load of accessing the database to generate the site.
In front of the site there is also Varnish – this is hosted on Gandi’s PAAS which comes with Varnish pre-configured, I highly recommend them for anything not requiring a dedicated server – and then Cloudflare. As I have said however, most of the speed in this case actually comes from the plugins and theme itself.
I hope you like the new site – there’s bound to be some tweaks to appearance and configuration of the next few weeks, and hopefully more than a few posts.
Recently at Helpful Technology I was working on the new Foreign Office Blogs website – collapsing their massive WordPress multisite instance down into a standard single site install. When I say massive… it was 161 sites with 448 users spread across ~4500(!) database tables and nearly 5GB of files. Oh, and it’s multilingual too.
One of the big, and somewhat unexpected, challenges to workflow once it was merged was comments. As WordPress presents the number of comments in the admin bar as well as the admin menu, authors were getting confused about whether they had any comments to respond to / manage, or if they were for other authors. While on the Posts screen you do at least get a Mine filter so that you can view just your own posts (along with the standard All, Published, Draft and Bin/Trash), there is nothing similar for Comments.
Also, WordPress helpfully puts a big notification bubble next to Comments in the menu as well as in the admin bar that shows the total number of Pending comments – again, not Author specific.
Part 1 – the list of comments
This first issue is actually the easiest to deal with – there is a helpful hook pre_get_comments that allows you to modify the wp_query arguments used to generate the Comments list.
All that’s needed is a simple finction that does a couple of sanity checks to make sure you are on edit-comments.php and the user is an Author (Editors and above have the rights to view and manage others posts so affecting them doesn’t really make sense*) and then $query->query_vars['post_author'] = $user_ID; does the magic.
Part 2 – comment counts
Changing the comment counts is actually a lot harder as there is no hook you can use to manipulate it as simply. Internally WordPress uses wp_count_comments which takes a single (optional) argument, a Post ID. It’s all or nothing, so to speak – it either returns the comment counts for the whole blog, or for a single blog post. There is a filter which lets you inject replacement values into the function however, so we have a way in. We can create a duplicate of this function, and then use the duplicate as a filter for the core function to inject the comment counts for just the logged in user.
But how do you get the count for a single user? Comments are associated with posts not users… Here caching is going to be your friend. We first have to do a standard query for all posts by the user WP_Query( array('author' => $user_ID,'posts_per_page' => -1) );, and then loop over each post, get the comments, and add up the number. This is comparably intensive so we can store the results in a transient for a length of time that makes sense for your blog. One thing to watch out for is that wp_count_comments expects a stdClass Object so remember to cast the array just before returning it.
*You could take this further and read some custom meta from the current user that specifies which other users they manage to determine which to show, but that’s for another day…
Putting it all together
Either build this into a simple plugin or put it into your theme’s functions.php depending on your needs:
I’ve been using Cloudflare recently and overall it’s extremely straightforward, but there was one small fly in the ointment – the firewall settings.
Currently you can only enter single IPv4 addresses at once (ranges like x.x.x.x-x aren’t valid either). Luckily they have a very easy to use API so I put together a quick form that does a bulk update of your rules.
You can only do one “action” at once (whitelisting / blacklisting / removing), but if you need anything more complicated I’m surprised you’re here… The API is also smart enough that it doesn’t moan if you ask it to, e.g., whitelist an IP that is already whitelisted.
One of the things we do at Helpful Technology is provide digital skills training. As part of that we have a sandboxed Twitter style social network platform that allows users to get used to the medium and practice in a safe environment.
I’ve been re-building this system recently, and one feature we wanted to add was the automatic linking of usernames and hashtags. This is fairly simple to do with a bit of RegEx in PHP – and on WordPress you can just attach it to the filter called the_content to process all text before it is output and insert links as needed. The code could be put in a plugin, but here it’s written so you can just drop it in to your functions.php.
If you’re wondering about the ‘weird’ \p{X} statements – that’s using PHP’s unicode character properties to ensure all languages are matched.
Updated 4/6/15 – now with added key/salt generation
When deploying a new WordPress site, there are two (potentially) needlessly time-consuming steps – logging in to MySQL to setup a new database and user, and then copying the WordPress files to the directory. The script below lets you do this in one step, pass in your database and basic WordPress settings, and it will configure MySQL and directly download WordPress to the server. A key benefit of this over a phpMyAdmin + FTP approach is that it will work over even ropey internet connections as the work is all done on the server itself.
A more advanced approach is to build a setup script based on WP-CLI, which allows the most customisation, but also needs more setup work and control over the server. If you always install the same plugins and themes – definitely look in to this.
How to use the script:
SSH in to your server and navigate to the desired install directory (e.g. /var/www/domain/)
Paste all of the following in to terminal and hit Return:
Very short post to share a few useful links from the weekend, all related to Sublime Text:
Nice collection of colour schemes for iTerm / Terminal / Sublime Text (links to each theme are at the bottom of the page). If you want to apply a theme to Terminal on OS X, remember to look for a scheme packages as a .terminal file for a one click install – the old workarounds aren’t necessary any more.
I’m currently trialing ExpanDrive – this adds SFTP, WebDav, S3 OwnCloud, Box & more support to Finder / Windows Explorer. Very slick, and integrates nicely with Sublime Text giving it the ability to work directly with files on remote hosts.
A selection of Sublime Text plugins recommended by @mikejolley – I’m a particular fan of Sidebar Enhancements which adds a lot more options to the right click menu, including Duplicate, New File and Open In Browser. This really speeds up my workflow and means less time spent flipping in and out of Finder to manage project files. If you haven’t used plugins in Sublime before, remember to install Package Control