The first WordPress theme I ever built was a modified version of Kubrick. I think that’s how most front end developers get started with WordPress- tweaking a core theme or a commercial theme to make it fit. Building one entirely from scratch has never made a lot of sense to me and over the years I’ve used a number of different theme platforms to build on.
I had a love affair with Thematic for a couple years. It was one of the early “frameworks” and a precursor to newer projects like Genesis. It was great if the design fit into the general structure of the theme, but I often found myself writing ten lines of code in order to unhook and rehook different sections of the theme for really minor changes. It was difficult to trace functions across multiple files. Although it made me a much better developer and was excellent for some projects, overall it seemed unnecessarily complex.
Next for me was “Toolbox“. This was a base theme developed by Ian Stewart, the same developer who had started Thematic. It was the complete opposite of a framework: a real simple theme, well structured, and easy to modify. It also followed the HTML5 spec (remember when that was new?!). I built my first publicly released theme (Portfolio Press) off of it as well as several projects for clients.
After Ian took a job with Automattic, Toolbox was forked and became Underscores. More on that over here. It’s an excellent base and many of the themes on WordPress.com are built off of it. There’s a great team of developers maintaining and contributing to Underscores. The code is clean, well commented, and the model of excellent WordPress practices.
Time to Fork
However, over the last few months I’ve found myself having to do more and more work to get Underscores to where I need it before embarking on a new project. I’ve decided it’s time to fork.
This is not a bad thing of course. Underscores is intended to be base in which to build off of, even if you’re forking it to build your own new base. And a solid base theme is important for any WordPress theme developer- it allows you to move quicker because you don’t need to solve the same problems for every project.
The main reason I’ve decided to fork Underscores is because of build tools. (Though re-using patterns for menus and comments will also be helpful.)
Most front-end developers are now using some sort of build process. Preprocessing of CSS (sass/less) is super popular. So is minification, concatenation, autoprefixing and image compression. I’ve fully integrated Grunt into my workflow (I wrote another post about that here), and so my base theme needs to support that.
I think the arrangement of sass files is largely subjective (how to break up the files, which variable/mixins to use), so I started my base theme by just adding in the build tools and separating each update into a separate commit in case anyone wants to follow along.
I started with a fresh copy of Underscores (theme name changed to Platform).
Grunt and Internalization
I added a .gitignore, package.json, and Gruntfile.js along with a Grunt task that generates a .pot file for translation in this commit. If you only do client work you can probably drop the internalization task- but this is super important if you release themes.
Remembering browser prefixes is a pain, so I stripped them out of style.css and added a Grunt task to take care of it. See the commit.
I duplicated style.css, renamed it style.scss and put it in a folder called “scss”. I also added the grunt tasks to handle sass. I decided not to break up the file yet, as folks might have different opinions on how to best do that. See commit.
I use csscomb to normalize and re-order the styles based on the rules in csscomb.json. There’s actually not much point to this, but it ensures your css comes out looking pretty. See commit.
Combine and Minify Scripts
Underscores just has two scripts to combine: skip-link-focus-fix.js and navigation.js. I updated functions.php so that the scripts are enqueued separately if I’m in debug mode, but otherwise as a single file platform.min.js. See commit.
You’ve probably looked a WordPress site before and seen more than a dozen script tags in the head. Many of those a from plugins, but a few themes are also notorious. Most users aren’t at the point where they know to install concat and minification plugins- so if theme developers concat these by default it will improve load times for millions of people.
It’s sometimes difficult to remember to version scripts/scripts when they change. So I’ve updated the enqueues to use the theme version- which I’ve set up as a constant. Whenever a new version goes out, the cache will be busted for users and they’ll get the latest copy of the scripts and styles. I also reformatted the enqueues to make them more readable. See commit.
It’s best to just have one spot where the version number is updated, so I do this in package.json. When “grunt build” is run, it will automatically update the constant in functions.php and the stylesheet. See commit.
I’ve been using FitVids in my new projects- so I’ve added that to the base. I also added an additional file called global.js- which will have all my custom scripts. See commit.
People have mentioned moving FitVids into core- but I don’t like the idea of core loading more scripts on the front end. This is the realm of display and appearance and should be the job of the theme.
It’s not a ton of changes- but it’s a bit time consuming to do for each project. I am tagging this version 0.1.0 if anyone wants to fork their own version from here. After this point I’ll be making updates that are more subjective personal preferences than what I necessarily think is important for a generic base theme- but you’re welcome to keep watching the commits.
I’m also planning to build out a Grunt Scaffold so I can generate a new theme based a number a presets I define at the beginning of a project. This will be things like theme name, number of widget areas, header support, number of menu areas, whether the theme is for public release or client, etc. I might even have it generate theme customizer options for common items like link color, fonts, logo, and footer text. But that will be another post.
Please feel free to offer suggestions, improvements or other ideas. If you have your own fork of Underscores, post in the comments and let me know why.