When I’m running WordPress inside a docker container, I usually only mirror the wp-content directory from the container to the host. You shouldn’t change anything in the other WordPress directories anyway and you avoid many volume syncs. The problem with this approach is that you can’t run the wp-command from the host, you have to run WP-CLI inside Docker, that means logging in to the container running the commands and logging out again. Assuming your container is called wp-container the following commands would do that:

  
docker exec -ti wp-container bash
wp plugin list
exit
  

It’s just a little inconvenience, but why not save some command when we can?

I’m using gulp as task-manager for most of my projects, and added a task which forwards all commands to WP-CLI inside Docker. It even checks if the container is running and if WP-CLI is installed inside the container. If not it will be automatically installed.

var gulp = require('gulp');
var spawn = require('child_process').spawn;

var checkContainers = function(names, done) {
  var exec = require('child_process').exec;
  exec('docker ps --format {{.Names}}', function(error, stdout, stderr) {
    done(names.map(function(name) {
      return stdout.split("\n").indexOf(name) >= 0;
    }).reduce(function(running, next) {
      return running && next;
    }, true));
  });
};

var checkWPCli = function(container, done) {
  var exec = require('child_process').exec;
  exec('docker exec ' + container + ' bash -c \'wp\'', function(error, stdout, stderr) {}).on('exit', function(code) {
    done(127 !== code);
  });
};

var installWPCli = function(container, done) {
  var exec = require('child_process').exec;
  exec('docker exec ' + container + ' bash -c \'apt-get update && apt-get install -y less && curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp && wp --allow-root cli\'', function(error, stdout, stderr) {}).on('exit', function(code) {
    done(0 === code);
  });
};

var runWPCli = function(container, done) {
  var command = process.argv.slice(process.argv.indexOf('-c') + 1);

  if (!command.length) {
    console.log('ERROR: Provide a valid wp-cli command!');
    return done();
  }

  var exec = require('child_process').exec;
  exec('docker exec ' + container + ' bash -c \'wp --allow-root ' + command.join(' ') + '\'', function(error, stdout, stderr) {
    console.log(stdout);
  }).on('exit', function(code) {
    done();
  });
};

gulp.task( 'wp', function(done) {

  checkContainers(['wp-container'], function(containerRunning) {

    if (!containerRunning) {
      console.log('ERROR: wp-container container is not running. Try "docker-compose up -d"')
      return done();
    }

    checkWPCli('wp-container', function(wpCliRunning) {
      if (!wpCliRunning) {

        console.log('WARNING: wp cli not installed, trying auto install ...');

        installWPCli('wp-container', function(wpCliRunning) {

          console.log('SUCCESS: wp cli installed!');
          runWPCli('wp-container', done);

        });
      } else {

        runWPCli('wp-container', done);

      }
    });
  });

});

So, with that gulp task in place, you will be able to run the following commands and every other WP-CLI command as well:

gulp wp -c "plugin list"
gulp wp -c "plugin install advanced-custom-fields"

What do you think?

Is that to much hassle for running some wp-commands or would you use the gulp forward in your daily work? Let me know!

In the last couple of months I’ve worked a great deal with WordPress as backend system, providing data to a JavaScript frontend via the Rest API. As I couldn’t find a complete solution for my favorite frontend-framework, my “getting started” process always repeated the following steps

  • set up WordPress development environment (docker)
  • integrate Javascript frontend in the code
  • setup environment for the frontend (docker)
  • make the two environments talk to each other (not always as easy as you think)
  • setup a simple JavaScript framework to query the WordPress API from the frontend

As that procedure eats up a whole lot of project hours, the time was ready for an easier solution. So, together with my colleague Oliwer at Northosts and much appreciated input and testing from my friend Samuel, I started working on a WordPress/Nuxt.js hybrid development environment. Our goal was to provide a one-command-installation, which makes you ready to go in 5 minutes.

Now we are finally ready for our first release, so say hello to WUXT!

WUXT Components

WUXT combines a couple of components you almost certainly already know from other projects, adds some convenient new functionality and solves a handfull of configuration problems. Following a short overview of all components

Docker containers: To provide a consistent development experience on all platforms, we use Docker (what else?). Three containers are needed, one for the WordPress database (mysql.wuxt), one for WordPress (wp.wuxt) and one for nuxt.js (front.wuxt). Everything is set up with docker-compose. We were extra careful to base everything on the official images (mysql, wordpress and node) and skip custom docker-files, which should make it a lot easier to upgrade the environment. The relevant files from the container are mirrored to the host with volumes, which makes the database persistent (_db folder), lets you access everything important in WordPress (wp-content directory) and nuxt.js (nuxt folder).

WordPress Rest API extensions: The WordPress API is awesome, but to use WordPress full strength in our nuxt.js frontend, we needed some additional functionality. Activating our WUXT-theme adds endpoints for menus, the front-page settings, getting pages and posts by slug and includes meta-data from well known plugins. We are constantly adding new endpoints to support even more use-cases.

WordPress connector in nuxt.js: It’s not difficult to setup some requests to the WordPress API from nuxt.js, but we wanted a standardized way. That’s why we included the wpapi node module into our nuxt application (you have always access via the $wp object). Even here we did some adjustments, to make sure the connection to the WordPress Rest API can be established both from the nuxt-container to the wp-container and from the client application to the wp-container. Of course, we also added some shortcuts to support our new endpoints for menus, front-page, custom post types etc.

Development tools: Docker is so great, but sometimes it makes developer lives a little bit more difficult. Logging in to the container to run a wp-cli command can be a hassle, file permissions when working with volumes might be another. To make that a little bit more easy we added gulp tasks to give you access to wp-cli or installing new node-modules inside the container, without accessing it. We even provide a post-type generator for gulp, which lets you create automatically loaded, API-ready post-types in seconds.

Nothing of the above is rocket-science, but I think the combination and packaging into one, complete environment should make a difference for everyone developing with WordPress and nuxt.js. Please try it out and give us feedback, issues or some of your spare-time to make WUXT better.

Getting started

First clone the repository to a directory you want, then change to that directory and simply start your containers (you need to have a running Docker installation of course):

docker-compose up -d

That starts the following containers:

  • MySql (mysql.wuxt) 
  • WordPress (wp.wuxt)
  • nuxt.js (front.wuxt)

Your containers are available at

  • Frontend: http://localhost:3000
  • Backend: http://localhost:3080http://localhost:3080/wp-admin
  • Database: docker exec -ti mysql.wuxt bash

Setup WordPress

After starting the containers the first time you have to do a common WordPress installation at http://localhost:3080/install.php. Then log in to wp-admin and select the wuxt theme to activate all the API extensions. Additionally you might want to activate the ACF plugin to make your meta work easier. Last but not least you have to set the permalink structure to “Post Name” in the WordPress settings.

To check if everything is running, visit http://localhost:3080 and verify that the WUXT info screen is showing.

Then check that the Rest API at http://localhost:3080/wp-json is returning a JSON-object and you are good to go.

Setup nuxt.js

Nuxt should have been started automatically inside the docker container. The command we use for running the nuxt.js server is yarn dev. Check if the frontend is running by opening http://localhost:3000. You should be greeted by the Wuxt intro-screen.

Finally check if BrowserSync is running, by doing a minor change to the front-page. The change should directly be visible on the front-page as well.

Feedback

Please let us know what you think about WUXT, what you did with it and what you couldn’t do. Please clone, fork, open issues, comment or contribute, it’s much appreciated.

A couple of months ago, I’ve heard the first time about Grunt. I wasn’t that impressed. It seemed to be like a more advanced CodeKit, which was compiling my SASS and JS at the time. So I forgot about it, proving once again, that I just not am an early bird :/ Of course the buzz got too big for being ignored and now I am all into Grunt, Yeoman and even Gulp as everyone else.

Using Grunt for some time now, I’m beginning to realize that it not only improved my workflow, but changed it. So this article is not about learning Grunt, there already are some of them out there. It is about why I think Grunt, or more generally task managers like Grunt will really make a difference in how web-developers do their work.

A plattform independend foundation

But first some basics. One of the most important things about Grunt is that it is based on node.js and really runs platform independent. Also with node.js comes its community, producing an impressive amount of functionality. All the node modules they are developing, from 100% javascripted ssh-clients to complete test frameworks, can be used with Grunt.

Then there is npm, the node.js package manager. It lets you easily define all dependencies on a project bases. If you have to use the compass mixin library in one project and want to use bourbon in another, one line in your projects packages.js and a npm install fixes it.

Last but not least the node.js world is all javascript. That is so important because all web-developers, despite their back-end programming language preferences, know javascript. For a web-developer there are basically no hurdles to getting started with Grunt.

All in all node.js is a stable, well used and tested development foundation, with a living community and a huge amount of functionality packed in modules ready to download. Everything you need for your development workflow is already there. Grunt just helps you to bundle it all together.

Coding workflows

So, why is this such a big change? Before Grunt I already had a workflow. Or a kind of workflow that stayed pretty much the same for every project I was working on, but not entirely the same. This workflow even had multiple phases, like development, testing, bug-fixing and deployment and everyone of them had different tasks. To remember all these at the right time can be impossible sometimes. I don’t know how many times I’ve forgotten to merge and compress CSS for deployment or to do a last coding standards check.

Grunt is helping with these tasks, by just letting you write them down and executing them automatically when you need them. That’s what a task-manager should do. But Grunt, and that’s my point, is doing something more. It doesn’t only automates the tasks you have done before, it makes you build, rethink and structure them consciously. You have to think about what your workflow should look like in the beginning of a project and you have to refactore your workflow as the project evolves.

What I mean is: with Grunt we have begun to code our coding workflows. Just as we code our tests when we do unit testing. You might think thats no big deal, nothing a couple of bash-scripts doesn’t solve. I agree, technically it is nothing revolutionary. Yet, I think Grunt will change a lot for web-developers, because it is so well suited for sharing.

Sharing and evolving workflows

A Google search on gist “gruntfile.js” returns more than 5000 hits. So it seems that we are not just coding workflows with Grunt, we’ve even started to share them. I’m convinced thats because of the facts about node.js I’ve named before and that every web-developer is able write some javascript tasks in no time. That is the good thing with coding workflows. We are so incredibly good at improving our code. We already have a huge community, doing nothing else than improving code all the time. So, now our workflows have become formalized code, we can improve them the same way. We can share them on Github, ask about them on Stackoverflow, discussing them in our blogs or compare them to others workflows.

So I think, over time, this will change a lot about how web-developers work. That said, the perfect finish to this article seems to be my own gruntfile.js, defining my current WordPress theme workflow:

module.exports = function(grunt) {

	grunt.initConfig({

		pkg: grunt.file.readJSON('package.json'),

		// chech our JS
		jshint: {
			options: {
				"bitwise": true,
				"browser": true,
				"curly": true,
				"eqeqeq": true,
				"eqnull": true,
				"esnext": true,
				"immed": true,
				"jquery": true,
				"latedef": true,
				"newcap": true,
				"noarg": true,
				"node": true,
				"strict": false,
				"trailing": true,
				"undef": true,
				"globals": {
					"jQuery": true,
					"alert": true
				}
			},
			all: [
				'gruntfile.js',
				'../js/scripts.js'
			]
		},

		// concat and minify our JS
		uglify: {
			dist: {
				files: {
					'../js/scripts.min.js': [
						'../js/scripts.js'
					]
				}
			}
		},

		// compile your sass
		sass: {
			dev: {
				options: {
					style: 'expanded'
				},
				src: ['../scss/style.scss'],
				dest: '../style.css'
			},
			prod: {
				options: {
					style: 'compressed'
				},
				src: ['../scss/style.scss'],
				dest: '../style.css'
			},
			editorstyles: {
				options: {
					style: 'expanded'
				},
				src: ['../scss/wp-editor-style.scss'],
				dest: '../css/wp-editor-style.css'
			}
		},

		// watch for changes
		watch: {
			scss: {
				files: ['../scss/**/*.scss'],
				tasks: [
					'sass:dev',
					'sass:editorstyles',
					'notify:scss'
				]
			},
			js: {
				files: [
					'<%= jshintTag %>'
				],
				tasks: [
					'jshint',
					'uglify',
					'notify:js'
				]
			}
		},

		// check your php
		phpcs: {
			application: {
				dir: '../*.php'
			},
			options: {
				bin: '/usr/bin/phpcs'
			}
		},

		// notify cross-OS
		notify: {
			scss: {
				options: {
					title: 'Grunt, grunt!',
					message: 'SCSS is all gravy'
				}
			},
			js: {
				options: {
					title: 'Grunt, grunt!',
					message: 'JS is all good'
				}
			},
			dist: {
				options: {
					title: 'Grunt, grunt!',
					message: 'Theme ready for production'
				}
			}
		},

		clean: {
			dist: {
				src: ['../dist'],
				options: {
					force: true
				}
			}
		},

		copyto: {
			dist: {
				files: [
					{cwd: '../', src: ['**/*'], dest: '../dist/'}
				],
				options: {
					ignore: [
						'../dist{,/**/*}',
						'../doc{,/**/*}',
						'../grunt{,/**/*}',
						'../scss{,/**/*}'
					]
				}
			}
		}
	});

	// Load NPM's via matchdep
	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

	// Development task
	grunt.registerTask('default', [
		'jshint',
		'uglify',
		'sass:dev',
		'sass:editorstyles'
	]);

	// Production task
	grunt.registerTask('dist', function() {
		grunt.task.run([
			'jshint',
			'uglify',
			'sass:prod',
			'sass:editorstyles',
			'clean:dist',
			'copyto:dist',
			'notify:dist'
		]);
	});
};

SASS/SCSS and Grunt are fantastic tools to organize and automatize css development. With some easy adjustments you can even make grunt to compile your css for multiple color schemes.

Build your base SASS color scheme

The easiest way to prepare your files for auto-compiling SASS color schemes is to create a color variable for every color you want to change in your schemes. You should do that in a separate section of your code, so you can easily copy all color variables and create a new color scheme. The only thing you have to think of is to add the default-attribute to the variables, so they can be overridden. I usually and up wit a section like that in my styles:


/*
 * Default colors
 */

$light: #fafaf9 !default;
$dark: #111111 !default;

$color-1: #ef4f47 !default;
$color-2: #75d9c6 !default;
$color-3: #ffe851 !default;

Preparing additional SASS color schemes

The next step is to create all color scheme files. Create a folder called schemes or something like that put a file with the name color-scheme-1.scss in it. This file should define your color variables again (without the default-attribute) and include all other styles after the variables.

/*
 * Color scheme 1
 */
$light: #efefef;
$dark: #222;

$color-1: red;
$color-2: green;
$color-3: blue;

@import "../style";

Now you can create as much SASS color scheme files as you want, just repeat this pattern in every scheme.

Automated SASS color scheme Grunt task

Finally its time to setup your Grunt tasks. I assume you know how to compile SASS/SCSS via grunt, so the only thing to do is to add a sass-task for every scheme in you grunt-file:


sass: {
    dev: {
        src: 'scss/style.scss',
        dest: 'style.css'
    },
    'color-scheme-1': {
        src: 'scss/schemes/color-scheme-1.scss',
        dest: 'css/color-scheme-1.css'
    },
    'color-scheme-2': {
        src: 'scss/schemes/color-scheme-2.scss',
        dest: 'css/color-scheme-2.css'
    }
},

Now run

grunt sass:color-scheme-1

and you get a color-scheme-1.css file in your css-directory. If you include this file instead of your default style.css, you will get your layout in the schemes colors. Auto generate all schemes with

grunt sass

This post describes a super simple and time saving Yeoman workflow to build WordPress themes. To make this post work for you, you should have a basic understanding of nodejs, nodes package manager npm, Yeoman workflows, Grunt and SASS/SCSS. Ones you have all up and running, you will create a Yeoman WordPress starter theme in no time. But it is not only a theme it comes with a bunch of features:

  • A fully funtional WordPress theme with a working grunt development environment.
  • The generated theme is tested against the Theme check and Theme Forest check plugins and runs without errors, warnings or recommendations, is visually tested with Testdata for the theme unit test, runs without errors or warnings in debug mode and follows the WordPress coding standards a 100%
  • A pre-filled HTML documentation

Getting started

Getting started with nodejs, npm and Yeoman is well described elsewhere, so instead of repeating all of it you will get some links that worked for me. To go on, you should have the current version of nodejs, npm and yeoman running. Than you can easily install our generator from the npm registry. Note that on some setups you will have to run this command with super-user permissions:

npm install -g generator-wp-theme

Now you have installed the generator you can generate your first starter theme. As you might want to test it in your WordPress development environment, you should go to a running WordPress installations themes directory and run:

yo wp-theme

Thats it! Just answer some simple questions in the terminal and the installation should run through without errors and installing the theme plus all needed local node modules.

Developing with the Yeoman WordPress theme

First of all the generated starter theme provides you with a solid base of WordPress theme templates, following among others WordPress theme directory and ThemeForest standard requirements. The functions.php file sets your theme up to support all required functions like a custom header and background. All should be ready to make your adjustments to build a perfect theme.

SASS/SCSS setup

The themes style.css file is compiled from a bunch of SCSS-files. To get a layout grid and some nice mixins the bourbon and neat libraries are build in. The SCSS-file names should be self-explaining, however a short overview in including order follows:

vendor/normalize
Includes the normalizing css.
vendor/bourbon/bourbon
Includes the great bourbon mixin library.
_base.scss
Defines the main colors of the themes and basic HTML-element styling.
_grid-settings.scss
Defines and includes the base setup for the themes grid. The default grid is bourbons neat.
_typography.scss
Defines all fonts, typography related mixins and HTML-element styles. Defines even some font-size variables.
_components.scss
Here should be placed the basic mixins and placeholders for the theme.
_wp-base.scss
Defines some basic WordPress classes, like sticky, alignleft or bypostauthor.
_header.scss
Contains the header styles.
_navigation.scss
Contains the navigation styles.
_content.scss
Contains the basic content styles for posts and pages.
_post-formats.scss
Extends the content styling with styling for multiple WordPress post formats.
_footer.scss
Contains the footer styles.

Grunt tasks

The generated Yeoman WordPress theme provides a working Grunt configuration. All Grunt related assets like the gruntfile.js and the package.js are placed in the grunt directory. The Yeoman generator has already setup Grunt for the theme and installed all node modules in grunt/node_modules. If you want to install manually, go to the grunt directory and run

npm install --save-dev

All Grunt tasks are called from the grunt directory. You can manage the following available tasks, by running these commands:

grunt
Is running the default task-list, which is the same as running grunt jshintgrunt uglify and grunt sass.
grunt jshint
Checks the JavaScript files and gives you some hints.
grunt uglify
Takes the JavaScript files and concatenates and minifies it to one file: js/scripts.min.js, which is included in the theme.
grunt sass:dev
Is compiling all the scss files to one expanded style.css in the themes root directory.
grunt sass:prod
Is compiling all the scss files to one compressed style.css in the themes root directory.
grunt watch
Watches the scss and js files for changes and runs the above tasks automatically, plus giving you a cross-OS desktop notice on success.
grunt dist
Runs grunt uglify and grunt sass:prod, takes all the production relevant theme files and places them in the dist directory under the themes root. Now the dist directory contains a production ready theme, which can be uploaded to a live server.
grunt phpcs
Requires PHP CodeSniffer with WordPress standard installed in the development environment.
Checks the themes php files against the WordPress coding standards.

Documentation

In case you want to upload your theme to some marketplace or theme directory, Yeoman WordPress theme generator even creates a HTML-documentation for you. The documentation is based on the Theme forrest documentation template It’s located in the doc directory and already covers some base information about your theme. You just have to complete it with your specific information and your theme is documented as well.

Now, make themes!

With the Yeoman WordPress theme generator (generator-wp-grunted-theme), you should get everything you need, to build great themes. Be welcome to let me know if you have done so, or even better if you want to add a important task, find a bug or have an improvement idea.