Why use Sage starter theme for your next web app

When thinking about your new WordPress web site or application, developers usually look for the best prebuilt WordPress theme. Some reasons for doing so:

  • To save as much time as possible.
  • Learn best practices from fellow skillful web developers.
  • Explore new areas.

Sage — a starter theme from the Roots.io guys — belongs to the more technical and refined ones. In today’s article, we’ll look at a few key points making Sage the perfect starter theme for you.

Opinionated theme folder structure

When I start working on a new project, the first thing I must have is a near-perfect project folders/files structure. Sometimes it takes me literally hours to find it. But most of the time, my initial architecture is not exactly robust because it hasn’t been battle-tested. Sage has this almost solved, see for yourself:

  main.scss (main.less)

Pretty impressive, isn’t it?

Your development styles, scripts, images and other front-end stuff goes into assets. During the build process (described later), compiled and processed files are put into the dist folder. Sage has a function for locating these files easily from your PHP code and templates.

The lib folder holds various PHP helpers and libraries powering up the theme, e.g.: initialization routines, Bootstrap navigation walker class and gallery shortcode and a theme wrapper. They all get included in the main functions.php file out of the box.

The only thing I miss here is composer and its autoloading feature. Not a big deal to fix. Create a new composer.json file, add a PSR-4 autoloading paths into it and require composer’s autoload.php in theme’s functions.php file. If you are using Bedrock (which I highly recommend), you can just add the autoloading into the Bedrock’s main composer.json file.

package.json and bower.json

Are you a JavaScript fan? Lot of client-side development? Sage is for you! It comes with an exhaustive list of node and bower dependencies, notably Gulp and Bootstrap.

Taking gulp to the extremes

This is my favorite part of Sage: gulpfile.json. A book or two could be written just about that single file. I tried wrapping my head around it for a few days (I’m not new to gulp) and I finally feel comfortable saying that I know what’s going on inside it.

The developers of Sage included a lot of tasks in the gulpfile:

  • styles
  • scripts
  • fonts
  • images
  • jshint
  • clean
  • watch
  • build
  • wiredep

…everything what you need.

Before we take a closer look at some of them, let’s talk briefly about asset-builder library. It puts together the dependencies of your main CSS and JS styles and scripts. You can declare them in the assets/manifest.json file. The files are later used throughout various gulp tasks.

Styles gulp task

This task processes your *.scss Sass and *.less files if you have any. Then it concatenates them into a single .css file and prefix CSS properties with browser vendors CSS prefixes such as -webkit- or -moz. After that, the whole file gets minified. Source maps are also generated if needed.

Scripts gulp task

Script dependencies are firstly concatenated together and then uglified (= minified). Source maps are also available.

Images gulp task

Lossless compression is run on all images.

Clean gulp task

The dist/ folder is deleted in this task. Useful for a new build process.

Watch gulp task

This task uses the BrowserSync web application in combination with gulp.watch to rerun all the aforementioned tasks when a file in the assets directory is modified. You don’t have to reload the browser to see the changes. Working flawlessly, unlike LiveReload and stuff.

Build gulp task

gulp build runs all the tasks. You can also run it in a --production mode, where the resources (CSS, JS) are revised with a hash appended to their filenames. Useful for purging browser cache. This is where the asset_path() Sage PHP helper function comes in handy. You don’t have to change the path to the resources each time new hash is generated. The build process generates a manifest file in which these resources are stored with their original path.

asset_path( 'scripts/main.js' );
asset_path( 'styles/main.css' );

Don’t repeat yourself theme wrapper

Although WordPress allows us to modularize our themes by using get_header(), get_footer() and get_template_part() in the template files, we have to repeat this for each main file such as index.php, single.php, etc. Sage theme wrapper class hooks into template_include action hook, turning around the relationship between files. There is just one base PHP file and every other template file (index, single, etc) gets included inside it. It’s like how Twig’s or Laravel’s templating engines work.


WordPress ecosystem has been blessed by the number of developers creating their own starter themes. Themes such as _s or thethemefoundry/Make are the prime example of it. For me, Sage and its awesome community of skilled WordPress developers is the way to go.

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: