Mobile first – are you really?

You did just use the buzzword “mobile first” to describe the design of your latest website. But did you really do it right? Try my 5-second mobility test (ok, it could take a lot more seconds):

Open up Chrome Developer Tools (cmd-alt-I), click the Network tab and make sure the Disable cache checkbox is checked. Adjust the browser width to mobile size. Then, reload the page. Wait for the page to download. Really, wait. See the bottom status bar and especially the amount of data transferred.

241 requests | 3.1 MB transferred | 1.5 min (load 16.53 s, DOMContentLoaded 16.17 s)

If the amount of bytes transferred is something like less than a megabyte, you are ok, but obviously the less the better. If, on the other hand, the amount is several megabytes, then… well, you should reconsider your original statement about being mobile first – I’m not sure that would be first anything.

Sure, download size is just one factor of the whole page speed experience, but remember that this is just a quick test I like. You might like to use Google PageSpeed Insights instead, for example.

My point is this:

Whatever design approach you use, it is not really worth a damn unless you make sure the approach is actually executed. It really is the only way.

WordPress Software Development at H1. Part 3: Application Code

PostType classes

Since WordPress is a CMS, the most important thing is content. So let’s first look into what would a post type class look like.

namespace ProjectName\PostType;

/**
 * Page, a WordPress default post type
 */
class Page extends \WPlinth\PostType {

	const TYPE = 'page';

	public function set_registration_parameters() {
	}

	public function set_meta_boxes() {
	}

}

Both WordPress default post types, Page and Post, can be defined as a class that extends the WPlinth PostType class. This is not necessary, if your application does nothing to extend the functionality of those types. However, from the simplistic example above, we can see how a PostType class is constructed. We define the post type name as a class level constant. Then we have two functions, set_registration_parameters and set_meta_boxes that will be called automatically, if they are defined, by the base class. Below, you can see a more realistic example:

namespace ProjectName\PostType;

/**
 * Service post type
 * Represents a service provided to a customer,
 * e. g. Project Management or Maintenance.
 */
class Service extends \WPlinth\PostType {

	const TYPE = 'projectname_service';

	public function set_registration_parameters() {
		$this->labels = array( 
			'menu_name'          => __( 'Services', 'projectname-application' ),
			'name'               => _x( 'Services', 'post type general name', 'projectname-application' ),
			'singular_name'      => _x( 'Service', 'post type singular name', 'projectname-application' ),
			'name_admin_bar'     => _x( 'Service', 'add new on admin bar', 'projectname-application' ),
			'add_new'            => _x( 'Add New', 'service', 'projectname-application' ),
			'add_new_item'       => __( 'Add New Service', 'projectname-application' ),
			'new_item'           => __( 'New Service', 'projectname-application' ),
			'edit_item'          => __( 'Edit Service', 'projectname-application' ),
			'view_item'          => __( 'View Service', 'projectname-application' ),
			'all_items'          => __( 'All Services', 'projectname-application' ),
			'search_items'       => __( 'Search Services', 'projectname-application' ),
			'parent_item_colon'  => __( 'Parent Services:', 'projectname-application' ),
			'not_found'          => __( 'No services found.', 'projectname-application' ),
			'not_found_in_trash' => __( 'No services found in Trash.', 'projectname-application' ),
		);

		/**
		 * Define other arguments
		 */
		$this->args = array(
			'rewrite'  => array( 'slug' => 'services' ),
			'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'revisions' ),
		);
	}

	public function set_meta_boxes() {
		$this->meta_boxes[] = array(
			'title' => 'Pricing',
			'pages' => array( self::TYPE ), // Array of post types
			'context'    => 'normal',
			'priority'   => 'high',
			'fields' => array(
				array(
					'id'   => 'projectname_service_hourly_price',
					'name' => __( 'Hourly price', 'projectname-application' ),
					'type' => 'text',
				),
				array(
					'id'   => 'projectname_service_daily_price',
					'name' => __( 'Daily price', 'projectname-application' ),
					'type' => 'text',
				),
			),
		);
	}

}

In set_registration_parameters we do two things. First we set the labels to an instance variable labels. Then we do that for other arguments of register_post_type. The base class takes care of the rest.

In set_meta_boxes we append to the meta_boxes array the meta fields we would like our post type have. We use the format shared with plugins Custom Meta Boxes and Meta Box. One of those plugins should be active. If you would like to use something else, you can extend ProjectName\PostType and take care of that part yourself.

Taxonomy classes

Taxonomies work a lot the same way than post types. Below is a sample. It should be pretty self-explanatory.

namespace ProjectName\Taxonomy;

class CaseType extends \WPlinth\Taxonomy {
	const TAXONOMY = 'projectname_casetype';

	public function set_taxonomy_data() {

		$labels = array(
			'name'					=> _x( 'Case Type', 'Taxonomy plural name', 'projectname-application' ),
			'singular_name'			=> _x( 'Case Type', 'Taxonomy singular name', 'projectname-application' ),
			'search_items'			=> __( 'Search Case Types', 'projectname-application' ),
			'popular_items'			=> __( 'Popular Case Types', 'projectname-application' ),
			'all_items'				=> __( 'All Case Types', 'projectname-application' ),
			'parent_item'			=> __( 'Parent Case Type', 'projectname-application' ),
			'parent_item_colon'		=> __( 'Parent Case Type', 'projectname-application' ),
			'edit_item'				=> __( 'Edit Case Type', 'projectname-application' ),
			'update_item'			=> __( 'Update Case Type', 'projectname-application' ),
			'add_new_item'			=> __( 'Add New Case Type', 'projectname-application' ),
			'new_item_name'			=> __( 'New Case Type', 'projectname-application' ),
			'add_or_remove_items'	=> __( 'Add or remove Case Type', 'projectname-application' ),
			'choose_from_most_used'	=> __( 'Choose from most used Case Types', 'projectname-application' ),
			'menu_name'				=> __( 'Case Type', 'projectname-application' ),
		);
	
		$args = array(
			'labels'            => $labels,
			'public'            => true,
			'show_in_nav_menus' => true,
			'show_admin_column' => true,
			'hierarchical'      => true,
			'show_tagcloud'     => true,
			'show_ui'           => true,
			'query_var'         => true,
			'rewrite'           => array( 'slug' => 'case-type' ),
			'query_var'         => true,
		);

		$this->args = $args;

		$this->types = array( 'projectname_casestudy' );
	}

}

Connection classes

If we want to define a Posts to Posts connection, we extend the \WPlinth\Connection class. Here is a simple example:

namespace ProjectName\Connection;

class ServicesProvided extends \WPlinth\Connection {

	const NAME = 'services_provided';

	protected $connection_type;

	public function set_connection_type() {
		$this->connection_type = array(
			'name'  => self::NAME,
			'from'  => 'projectname_casestudy',
			'to'    => 'projectname_service',
			'cardinality' => 'one-to-many',
			'title' => array(
				'from' => __( 'Casestudies', 'projectname-application' ),
				'to' => __( 'The Service', 'projectname-application' )
			),
		);
	}
}

All the functionality that is related to the connection should be put into this class. We might, for example, want a function to fetch all the services provided for a case. That would look like something like this:

public function get_services( $casestudy_id ) {
		$services = p2p_get_connections(
			self::NAME,
			array( 'from' => $casestudy_id, 'to' => 'any' )
		);
		return $services;
}

Even this simple function does make sense to exist, since this way we are able to encapsulate all the logic that is touching Posts 2 Posts API and thus keep all other code not dependant on that particular implementation. The code that would need to consume this function would need to have an instance of our ServicesProvided class. And, you guessed it, that instance would be provided to your consuming class by the DependencyInjection container, provided that you had defined the dependency in the configuration file.

QueryFilter classes

We are using QueryFilters to modify the main query for specific views. Instead of having a mess of unreadable if else statements, we define separate classes for each modification. Let’s look at an example. Say we wanted to display case studies in addition to posts on the front page.

namespace ProjectName\QueryFilter;

/**
 * Display posts and case studies on front page
 */
class FrontPage extends \WPlinth\QueryFilter {
	const PRIORITY = 10;

	public function test( $query ) {
		return $query->is_home();
	}

	public function filter( $query ) {
		$query->set( 'post_type', array(
			ProjectName\PostType\Post::TYPE,
			ProjectName\PostType\CaseStudy::TYPE
		);
	}
}

A QueryFilter consists of three parts. First, we can define a priority. Filters are tested in the order of their priority and only one filter is run per page load. Lower number means earlier execution.

QueryFilters in the system are tested first. The test function should return true, if the query does match the view WordPress is executing. In our example, we are simply testing weather WordPress thinks the current page is home page.

If the test matches, filter function is run. There we have the opportunity to do the modifications to the query we like.

Going further

These are just the most common ways of modifying and extending WordPress for a project specific way. If your application does something else, say, defines multiple shortcodes, it would make sense to create a base class for those and group them in a namespace/folder, in a similar fashion than what I have demonstrated above.

Other than that, this is it, a better way to organize your application code.

In the next part, we are going to discuss writing unit test.

WordPress Software Development at H1. Part 2: Application Structure

Application loader

Bedrock does give you a project structure, but for your own code, it is still just regular old plugins, mu plugins and themes. We like to place our project core code as an mu plugin, and we put inside a [appname]-application folder. If we come up with reusable functionality, we separate those as plugins and mu plugins.

We start our application up in a php file in mu-plugins directory. That file is called [appname]-loader.php and looks something like this:

namespace MyApplication;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

// Initiate Composer Autoloading.
require( ABSPATH . '../../vendor/autoload.php' );

// Bootstrap other mu plugins.
require( 'posts-to-posts/posts-to-posts.php' );
require( 'cmb/Custom-Meta-Boxes/custom-meta-boxes.php' );

// Load application configuration.
$container = new ContainerBuilder();
$loader = new YamlFileLoader( $container,
	new FileLocator( __DIR__ . '/../../../config' ) );
$loader->load( 'services.yml' );

// Initiate the application.
$container->get('application');

What is happening there? To my taste, there is too much boilerplate code in there that would benefit of being encapsulated somewhere else. But, basically we just initiate the Symfony DependencyInjection container with a configuration file and then get an instance of our application class from it. Because of what we had defined in the configuration file, the application will get every object it will need from the container.

Application confuguration

Let’s look at the configuration file, services.yml. It has two parts. First, the parameters of each constructor is defined:

parameters:
    posttypes:
        - @post
        - @page
        - @person
        - @casestudy
        - @service
    connections:
        - @case_personnel
        - @services_provided
    taxonomies:
        - @casetype
        - @expertise
    queryfilters:
        - @frontpage
        - @cases
        - @persons
    services:
        - @person_api
        - @auto_meta_property

Names starting with @ are references to classes, defined in the later part of the file. The parameters are arrays of classes.

Then, the actual services, which in practise means classes:

services:
    wordpress:
        class:     WPlinth\WordPressFactory
    post_type_manager:
        class:     WPlinth\PostTypeManager
        arguments: ["%posttypes%"]
    queryfiltermanager:
        class:     WPlinth\QueryFilterManager
        arguments: ["%queryfilters%"]
    application:
        class:     ProjectName\Application
        arguments:
            - "@post_type_manager"
            - "%connections%"
            - "%taxonomies%"
            - "@queryfiltermanager"
            - "%services%"
    logging:
        class:     H1\Logging\Logging
    post:
        class:     ProjectName\PostType\Post
    page:
        class:     ProjectName\PostType\Page
    person:
        class:     ProjectName\PostType\Person
        arguments: ["@logging"]
        calls:     [[set_wp, ["@wordpress"]]]
    casestudy:
        class:     ProjectName\PostType\CaseStudy
        calls:     [[set_wp, ["@wordpress"]]]
    service:
        class:     ProjectName\PostType\Service
        calls:     [[set_wp, ["@wordpress"]]]
    case_personnel:
        class:     ProjectName\Connection\CasePersonnel
    services_provided:
        class:     ProjectName\Connection\ServicesProvided
    casetype:
        class:     ProjectName\Taxonomy\CaseType
    person_api:
        class:     ProjectName\Service\PersonAPI
    auto_meta_property:
        class:     WPlinth\AutoMetaProperty
        arguments: ["@post_type_manager"]
    frontpage:
        class:     ProjectName\QueryFilter\FrontPage
    cases:
        class:     ProjectName\QueryFilter\Cases
    persons:
        class:     ProjectName\QueryFilter\Persons

This example file is from a fictitious project. Let me explain it a bit. We have a site that displays reference cases and services that a company has. Personnel and services are connected to reference cases with Posts to Posts. Personnel information is integrated with the company CRM, using PersonAPI class, and we are logging each change to a person post because of that.

Application class

An instance of most classes is passed on to the Application object as a parameter. That class itself can be very simple:

namespace ProjectName;

class Application {
	public function __construct( $posttypemanager, $connections,
		 $taxonomies, $querymanager, $services ) {
	}
}

We could store the constructor parameters as instance variables, if we would like to extend the Application class to do stuff with those. But in normally we don’t have to.

Application folder structure

Our [appname]-application has a specific structure. Here is a typical directory structure:

/Connection
/PostType
/QueryFilter
/Service
/Taxonomy
/Test
Application.php

Each of the folder contains the classes that inherit from a base class in WPlinth. For example PostType folder contains all the post types and they are classes that inherit from WPlinth PostType base class. Service is just a generic folder name for miscellaneous services. You can obviously have different and/or other folders (namespaces) in your application.

In the next post, we’ll look at code inside those classes.

WordPress Software Development at H1. Part 1: The Building Blocks

You have probably heard somebody say that it is impossible to write proper, professional software with WordPress. If not, at least somebody has implied how WordPress is not a professional tool and that real software developers would not use it.

They are all wrong. You can write great code and WordPress is not stopping you.

This series of posts will not explain in detail what are the principles of great code and what are the benefits of writing such code. But if you already know about them, it will teach you how to apply those principles in the WordPress world.

Great code?

So what is this great code? For me, it starts by not being procedural. Most of WordPress itself and its plugins is procedural. That kind of development style quickly leads to messy code, if you write more than just a couple of functions.

You want your code to be clean, easy to understand, testable, with minimum amount of dependencies within components, reusable, extendable… and conforming to all the other principles of great code. You can do all this in procedural code. But these things are way easier if you write object-oriented code.

Tools we use

To do all this fast, you need tools. Here are the tools we use to build applications on WordPress:

(1) Bedrock WordPress Stack is a stack of tools and a project structure. The most significant thing that it comes with is (2) Composer. Composer is a dependency manager, meaning you get to define the third party requirements your application has and Composer will get them for you. You give up automatic updates from within WordPress, but for proper software development and maintenance process you should anyway.

Composer comes with (3) an implementation of PHP autoloading. Autoloading loads files that contain classes right when you need them. There is no need to litter the code with require and include statements. Autoloading requires you to name the folders and files according to a strict standard, which in itself is a good thing. Folders match the namespace names and file names match the class names they contain.

There are some very common types of classes we write. Probably the most common type is a class that represents a custom post type. Custom taxonomies, Posts 2 Posts connections and query filters are other common types. To help with that, we have created (4) WPlinth, a collection of base classes and other functionality. It helps with writing testable code in other ways too: there is a simple mechanism to easily mock WP_Query and other core WordPress classes without using a wrapper.

As part of WPlinth we have adopted and modified (5) Loopable Query to let us interact with WP_Queries with foreach loops and not all that boilerplate code you normally have to deal with. Turns out that makes mocking the monstrous WP_Query a lot easier, since in many cases you can use an array to do the job, and in worst cases you need to cast that array as an object.

We use Symfony framework’s (6) DependencyInjection Component. Dependency injection helps to write code that is not dependent of specific implementation of other functionality. We define our application class configuration as a yml file and could easily switch the implementation of parts of the application without actually touching the code.

For writing the actual tests, we use (7) PHPUnit. To help with WordPress specific testing we use (8) WP_Mock.

Every tool I mentioned above, except of course Bedrock, is available as a Composer package.

In the next post we will delve into actual code and more details of our setup.

Editor Buttons Simplified

WordPress admin interface is great and getting better all the time. One thing though I think has not received any thought in a long time is the selection of buttons on the TinyMCE editor interface.

Update 2015-05-18: The plugin is now available on the official WordPress.org repository with one major modification: there is only one row of buttons and an expand functionality. This works a lot better responsively than two separate rows do.

I have created a simple plugin (on GitHub as well) to be able to easily test the modifications I propose. But I wanted to explain the rationale behind all the changes here.

Here are the WordPress default buttons with the “kitchen sink” open:

That is a lot of buttons.

My initial proposal is this:

Let’s go through the changes now.

Headings are important

If you write a blog post longer than just a couple of paragraphs, you really need headings. The dropdown (called formatselect in TinyMCE) is hidden by default, behind the obscure kitchen sink button. Most users don’t know of its existence, so they end up making a paragraph bold to mark up a heading, which is not good for SEO and certainly is not properly marked up reusable content. Those, that do find the control, are forced to see two rows of mostly useless buttons all the time.

My solution is to put the dropdown as the first item on the default button row.

Heading levels

Here are the current dropdown values:

I do not think one should use h1 inside a post. That should be reserved for the post title only. Also, having all the six heading levels is too much. Three levels are enough for most uses. If you need more, you probably should divide the post into two or more separate articles to make it more readable.

Pre is useful if you paste code, but that is not for most people. Removed.

Here’s the simplified dropdown:

Alignment buttons

Alignment buttons can be used for two things. You can align text and you can align images. Alignment of text does not make much sense. Unless you write poetry maybe. Most users do not.

Alignment of images can be done by clicking an image in question and then clicking the proper alignment button from the popup menu.

Strikethrough and horizontal line

To simplify the default row a bit more, we could move the strikethrough and horizontal line buttons to the second row. Those buttons can be useful, but not most of the time.

Secondary row modifications

I would like to remove the underline button, since one should not write underlined text on the web in general. An underline denotes a link.

One should not use full justified text on the web, unless it can be automatically hyphenated. Until browsers do that, I would remove the button.

Text color choices should not be done by the author. Instead, a style selection tool could be used (that can be activated through the TinyMCE API, if needed for the content and the design of the site).

Indent and outdent buttons do not make sense to me. What is their use case? Remove them, I say.

Here is the end result for the secondary row:

It’s actually so small number of buttons that it almost makes sense to put all the buttons to the same row.

Conclusion

It is easy to revamp the editor toolbar to be move usable, simple and useful.

It will require a way more thorough analysis to make the changes on the product level, but at least for our clients a setup similar to what I have described above makes a lot more sense than the current default.