I recently played around with building a new WordPress theme from the ground up, and I'm sharing some notes here about what I learned along the way.
It had been a while since I'd created a WordPress theme from nothing, and I knew that best practices had shifted quite a bit since then. I also wanted to use a more modern development workflow than I'd previously been used to. In my daily work I get to help our clients test, refactor, optimize and launch their WordPress themes (and I enjoy that quite a bit), but sometimes I just want to tinker for a personal project.
I also had an itch to scratch with 47374.info, a site I'd created in 2011 to aggregate local news headlines into a single, simple list display. It uses the great FeedWordPress plugin (along with some custom Perl scripts I wrote to scrape news off of local sites that embarrassingly don't offer their own RSS feeds) and does its job just fine, but it wasn't responsive, the mobile theme wasn't working so well for this use case, and there were more and more parts of the original theme I'd used that needed cleaning up. I also wanted to create something that looked and worked a little bit more like the Hacker News front page (without voting or comments). I am my own primary target user here; the site in question tends to get 40-60 visitors per day (I hope you're enjoying it, whoever you are), but I know I use it every single day.
I didn't quite have the time to start with a totally blank slate, so I started looking at some of the starter themes out there: Underscores, Components, Minimum Viable VIP, and Bones were the main ones I considered. These starter themes include all of the basic requirements of a WordPress theme so you don't have to literally create each new file (like
style.css from scratch). Each option then offers its own unique flavor to what a starter theme should have. For example, the Minimum Viable VIP theme is designed to have everything a developer on the WordPress.com VIP platform would need to implement basic functionality while also meeting code security and performance standards on our platform.
In my case, mobile-first and responsive was a top goal, and while Components has some great options there, Bones seemed to take care of what I wanted with a little less extra stuff thrown in. (Some day I will learn to write media queries from scratch, not this time around.)
So I downloaded Bones, opened it up, and started poking around. And that's when I encountered this:
WHOA, WHOA, WHOA…WHAT HAPPENED HERE?
But before you freak out, let me take a few minutes to explain.
Bones now uses Sass by default. If you prefer using regular CSS,
then feel free to modify this theme how you like and keep a copy
as your own personal starting point.
DON'T DISMISS IT JUST YET THOUGH, USING Sass ISN'T AS COMPLICATED AS YOU THINK.
It does take a few minutes to wrap your head around, but it will all
be worth it.
I knew about Sass (an extension of the CSS standard), but I hadn't worked with it before, and I wasn't immediately excited about starting now. Part of me wanted to just use CSS or even quietly delete the Bones files I'd just downloaded and return to my list of starter theme options for an alternative that wouldn't make me feel guilty for not knowing how to Sass. And when I realized I'd need to figure out a Sass preprocessing workflow on top of my regular PHP + HTML + CSS workflow, I was backing away from the computer.
But I reminded myself that the whole point here was to play around with the newfangled things that the kids are using these days, and so I stuck around a bit longer. (Thanks to Eddie Machado for making this entertaining and relatively painless with his snarky code comments and links to helpful resources.)
After starting to look at tools to compile Sass into CSS, I wondered if the editor I've grown to love in recent years, PhpStorm, had any Sass preprocessing support built in. Indeed it does! And for whatever reason the
scss "transpiler" was already installed on my Mac, so the first time I opened up an SCSS file in PhpStorm it noticed what it was working with and asked me if I wanted to add a File Watcher to the SCSS files in my theme project. Great! (Honestly if those bits of wonderful user experience had not happened, I may have given up on SCSS right then.) The only thing I had to do was customize the File Watcher setup so that it would automatically output the processed CSS files into the directory already established for this within Bones. This was done by opening the project's Preferences, going to "Tools -> File Watchers," highlighting "SCSS" and clicking the pencil "edit" icon, and then modifying the "Arguments" field to add in "
../css/" right after the colon that tells
scss that the next item is the target directory. The full contents of the "Arguments" field was then set to
--no-cache --update $FileName$:../css/$FileNameWithoutExtension$.css
I'm really glad I stuck with this because PhpStorm did some even more wonderful things after that when it came to working with Sass and CSS. When I introduced a syntax error, it noticed soon after because it was always compiling the scss files into css in the background, and alerted me of problems along the way. It recognized Sass syntax and helped me write new bits as I went. Even the little touches like showing me a thumbnail of a color swatch next to a line that specified a hexadecimal color value meant I didn't have to wonder if I had the right hue of cerulean. So nice! I'd mainly appreciated PhpStorm as a great development and debugging environment for PHP apps until now; thanks to the people at Jetbrains who made such a great tool that does so much more.
Once I was acclimated to the idea of working with Sass, I was ready to dive in working with Bones to build my custom theme. This is where I wanted to try out what I've been using for a development environment to create my various WordPress plugins: Vagrant + VVV + PhpStorm + Git.
I used VVV to create a new Vagrant environment with a fresh install of WordPress. I set up SSL with a self-signed certificate for my dev site so I could mirror production as closely as possible (more on how I did this in a coming post). I got a SQL dump and tarball of the production site data and copied it over into my development site (using
wp db import and
wp search-replace to get the data in the database). I also set up my
wp-config.php file with some debugging-friendly configurations so that I could make use of the great Debug Bar plugin along the way:
define( 'JETPACK_DEV_DEBUG', true);
define( 'FORCE_SSL_ADMIN', true);
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SAVEQUERIES', true );
When I reloaded my dev site, I had a working copy of my production theme, plugins, data and options, and I was ready to start making changes. I brought a fresh copy of the Bones theme into my themes directory, renamed it and activated it. Yay!
The work from here on out was much more familiar territory - modifying WordPress template files, adding new functions to adjust how content is queried and displayed, styling the output, testing on different browser sizes and device types.
I ended up deleting a lot of the template files related to custom post types and taxonomies, and commented out related
functions.php calls. Since my production site is using SSL and I was testing locally with SSL, I found one spot where a call to a Google font needed to be made protocol agnostic (and submitted a Pull Request to fix this in Bones for others). I also made use of the Theme Check plugin to make sure I wasn't doing anything that wouldn't conform to WordPress theme development best practices, and managed to get rid of the most glaring errors. (One thing I had to add that maybe Bones should have had was a non-empty style definition for
.screen-reader-text - not sure how important this specific fix is, but I sense it's a good thing to be paying attention to for accessibility purposes.)
The end result is a theme that is in itself fairly boring - it's mostly walls of text, the color scheme is simple, and it's not going to win any design awards - but it accomplishes my goal of having a simple display of headlines in a responsive design without any distractions.
There are also a few more things I want to tweak about how it looks on mobile phone screens; I don't like how the meta data (headline source and age) line up, but haven't yet figured out what a good alternative would be:
I used the Launcher Icon Generator to replace the default Bones icons (for the home screen icon on Apple devices, favicons, etc) with a simple image that is better than nothing.
I did a bit more testing on my local environment, then packaged the theme directory up for installation on the production site.
During this process I encountered a weirdness I hadn't seen in a while; when I unpacked the file on my site's production server, I got a bunch of
._filename.php files in addition to the actual
filename.php files. These are apparently part of OS X's use of the AppleDouble format that includes additional information about files, and they were unwelcome in my production environment. So I re-did the packaging up of the theme directory, excluding these Mac-specific files:
$ COPYFILE_DISABLE=1 tar -czvf --exclude .DS_Store 2016-47374info.tgz 2016-47374info
Much better, weird Mac-specific files gone from my tarball.
I activated the new theme in production, tested it out, and everything worked great. You can see the result (and read some local headlines!) at 47374.info.
I really enjoyed this process and it felt good to learn a few new things along the way. It was also a good reminder that even with so many tools out there to make WordPress development work as straightforward as it has ever been, diving in to something like creating a theme (and perhaps any modern software) still requires a fair amount of learning, tolerance for complexity and being welcoming of the unexpected.
If you've gotten this far and have any suggestions or comments on my process or the outcomes, please share. If there's any interest from other FeedWordPress users, I can also put the resulting theme on GitHub.