The Underscores (_s) theme with Sass and Gulp Part2: initial settings

Untitled Document


On this page:

  1. Automate the theme development with Gulp and other tools.
  2. The initial set up process before starting to work on your theme development.
  3. Explore the Sass partials in _s
  4. Configuration of the theme info
  5. Configuration of initial settings and functions


6. Automate the theme development with Gulp and other tools

Take the following steps:

  1. Create a folder with the name: 'gulp-dev-pre-underscores'
  2. Create a package.json file and place code 2.6.1 in it. Replace the name in the first line with the name of youw own theme folder (in case yours has a different name). Also replace the url from github with the url of your own repo if available.
  3. You can use the 'gulp-dev-pre-underscores' folder and all its files for every name theme you are going to develop. You use have to make a few adjustments according to the name of the folder and github repo you will be using.
  4. Make sure you have Gulp installed properly on your computer.
  5. Create a new javascript file, call it Gulpfile.js and place code 2.6.2 in it. Change the value of the themename variable (in line 2) to the name of the folder you are using (if it differs from mine). Also, in Gulpfile.js, change the name of the local server and port by the name of your own (see code 2.6.3)
  6. Now open your terminal, navigate to the 'gulp-dev-pre-underscores' folder and execute an npm install. (This will take a while)
  7. Finally execute the 'gulp' command. If everything goes well a browser window will open with a Wordpress website and the Underscores theme in place.

Now every time you make changes within your theme, the browser window will automatly update with the latest developments so far.


"name": "pre-underscores",
"version": "0.0.1",
"description": "Accessible WordPress theme utilizing flex layouts and modern development practices.",
"main": "index.php",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"repository": {
"type": "git",
"url": ""
"author": "Maarten von Kreijfelt",
"license": "GPL-3.0",
"bugs": {
"url": ""
"homepage": "",
"devDependencies": {
"autoprefixer": "^6.5.2",
"browser-sync": "^2.17.6",
"gulp": "^3.9.1",
"gulp-image": "^2.7.2",
"gulp-jshint": "^2.0.2",
"gulp-newer": "^1.3.0",
"gulp-postcss": "^6.2.0",
"gulp-sass": "^2.3.2",
"gulp-sourcemaps": "^2.2.0",
"jshint": "^2.9.4"
code 2.6.1. package.json
var themename = 'pre_underscores';
var gulp = require('gulp'),
  // Prepare and optimize code etc
  autoprefixer = require('autoprefixer'),
  browserSync = require('browser-sync').create(),
  image = require('gulp-image'),
  jshint = require('gulp-jshint'),
  postcss = require('gulp-postcss'),
  sass = require('gulp-sass'),
  sourcemaps = require('gulp-sourcemaps'),
 // Only work with new or updated files
  newer = require('gulp-newer'),
 // Name of working theme folder
  root = '../' + themename + '/',
  scss = root + 'sass/',
  js = root + 'js/',
  img = root + 'images/',
  languages = root + 'languages/';

// CSS via Sass and Autoprefixer
  gulp.task('css', function() {
  return gulp.src(scss + '{style.scss,rtl.scss}')
  outputStyle: 'expanded', 
  indentType: 'tab',
  indentWidth: '1'
  }).on('error', sass.logError))
  autoprefixer('last 2 versions', '> 1%')
  .pipe(sourcemaps.write(scss + 'maps'))
// Optimize images through gulp-image
  gulp.task('images', function() {
  return gulp.src(img + 'RAW/**/*.{jpg,JPG,png}')
// JavaScript
  gulp.task('javascript', function() {
  return gulp.src([js + '*.js'])

// Watch everything
  gulp.task('watch', function() {
  open: 'external',
  proxy: 'wordpress3:8888',
  port: 8888
  });[root + '**/*.css', root + '**/*.scss' ], ['css']); + '**/*.js', ['javascript']); + 'RAW/**/*.{jpg,JPG,png}', ['images']); + '**/*').on('change', browserSync.reload);

// Default task (runs at initiation: gulp --verbose)
  gulp.task('default', ['watch']);
code 2.6.2. Gruntfile.js
gulp.task('watch', function() {
open: 'external',
proxy: 'wordpress3:8888',
port: 8888

code 2.6.3.

7. The initial set up process before starting to work on your theme development.

  • First boot up your local server environments. That could be for for instance either Wampserver on Windows or Mamp on a Mac.
  • Make sure it's running by going to your browser and navigating to your site, in my case wordpress3:8888 and see everything works fine.
  • Next boot up your IDE, in my case Phpstorm. Inside the IDE navigate directly to your theme folder, so wp-content, themes and pre_underscores.
  • Then open terminal or command prompt and navigate to the folder that contains your WordPress project, and then the themes folder and gulp-dev-pre-underscores.
  • From here, run the gulp process by executing the gulp command. This boots up the watch process and browser sync and if everything works properly, browser sync will open a new tab in your browser that shows you the site. Now this tab is synced directly with my development site, meaning if I make changes on the development end, this page here in my browser will automatically update accordingly. That means I can close the original tab, and I'm left with just the tab I'm going to be working in.




8. Checking out the Sass partials in _s

If you want to change the appearance of your theme, you would do it in the file called style.css. However, in this tutorial we're using Sass to generate our css and we're using Gulp to auto-generate this file, style.css.

So, as we move forward, we will not be working in style.css directly, instead we'll be working in the sass folder and all the partials that are contained within that folder. Underscores ships with a fragmented Sass setup quite a lot of Sass partials. So, before we get started, it's important to understand how this all fits together, so you know where to go and how to navigate through these different files. It all starts with this file, style.scss. Opening the file, you'll see here we start in the exact same way we did with style.css.

In style.scss we have the Table of Contents and then in place of the actual styles, we have a series of @import that points at a folder and then a file name or just a file name. Seeing all these partials, you quickly realize you need some form of map to make sense of all this. I made this map for you. You'll find it here




9. Configuration of the theme info

When building a new custom theme from scratch, it's important to start out right. In this tutorial we're going to set up the core of the theme including the theme metadata, functions, web fonts and basic css to create a starting point for our design. I always like to start with a metadata to make my freshly downloaded version of underscores truly my own. The first metadata were are going to work on is in the style.css. At the very top we have this commented out section that contains all that metainformation that the theme needs to place all the essential information in the theme section of the Wordpress administration.

  Theme Name: Pre Underscores
  Theme URI:
  Author: Maarten von Kreijfelt
  Author URI:
  Description: A fabulous Wordpress theme based on Underscores
  Version: 1.0.0
  License: GNU General Public License v2 or later
  License URI: LICENSE
  Text Domain: pre_underscores
  Tags: custom-background, custom-logo, custom-menu, featured-images, threaded-comments, translation-ready
This theme, like WordPress, is licensed under the GPL.
  Use it to make something cool, have fun, and share what you've learned with others.
Pre Underscores is based on Underscores, (C) 2012-2017 Automattic, Inc.
  Underscores is distributed under the terms of the GNU GPL v2 or later.
Normalizing styles have been helped along thanks to the fine work of
  Nicolas Gallagher and Jonathan Neal
  # Normalize
  # Typography
  # Elements
  # Forms
  # Navigation
  ## Links
  ## Menus
  # Accessibility
  # Alignments
  # Clearings
  # Widgets
  # Content
  ## Posts and pages
  ## Comments
  # Infinite scroll
  # Media
  ## Captions
  ## Galleries

code 2.9. The header of the style.css

But be carefull: we are working with sass in this project and all of this is what sass generates, so instead of editing style.css, which will be overwritten in a second, we're going to work inside the sass folder. In the sass folder, there's a file called style.scss and when you open that you'll see it starts in the exact same way. This is the main style sheet for the entire sass setup, and it starts with the full metadata for your theme. So here we can make those changes and those changes, once compiled will move over to style.css


10. Configuration of initial settings and functions



In WordPress, the functions and functionalities of a theme are defined in a file aptly called functions.php. Here, you'll find the configuration settings for everything from HTML5 support to sidebars and menus to enqueuing of styles and scripts. Whenever you open a core file in Underscores, you'll notice there are a lot of these grayed-out comment areas. This is because Underscores is a starter theme, and as a starter theme, it gives you clear instructions on what to do and how to use the different components that are packaged inside the theme itself.

At the very top, we have the setup for what's known as a pluggable function.

if ( ! function_exists( 'pre_underscores_setup' ) ) :
  * Sets up theme defaults and registers support for various WordPress features.
  * Note that this function is hooked into the after_setup_theme hook, which
  * runs before the init hook. The init hook is too late for some features, such
  * as indicating support for post thumbnails.
  function humescores_setup() {


Let's exame first what a pluggable function is:

10.1 Plugable functions

So far, we have seen how to customize WordPress using action hooks and filter hooks. Another way to customize WordPress is to use Pluggable Functions. WordPress provides a small set of Core functions that can be replaced by our own custom functions. Here is the official list of Pluggable Core Functions. In the WordPress Core, these Pluggable Functions are located in a file named pluggable.php.The pluggable.php file is located in the wp-includes directory.

The functions contained in this file are meant to be redefined as needed, so developers can modify complex Core functionality in their plugins.

Here's how it works. Here, Let's say that we want functions.php to use a custom logout function. Here is the pluggable logout function currently used by WordPress.

if ( !function_exists('wp_logout') ) :
  * Log the current user out.
  * @since 2.5.0
  function wp_logout() {
  * Fires after a user is logged-out.
  * @since 1.5.0
  do_action( 'wp_logout' );

It simply logs the user out by destroying the session and clearing the authorization cookies. And it also fires the wp_logout hook. It's very straightforward. So what if we want to customize the default logout function? We could register a new function with the wp_logout hook. For example, we could add some custom functionality with a Callback function. Here is a basic example.

function myplugin_custom_layout(){ 
// Do somthing when the user logs out
add_action('wp_logout', 'myplugin_custom_layout')

We could then register this Callback function with the wp_logout action hook. Here we are using the wp_logout hook so our new function will be executed in the original logout function.

Right here. For most cases, using a hook is the best way to add any custom functionality, but if we need more control, we can modify the Pluggable Function without using the logout hook. To do so, we first copy the Pluggable Function from the WordPress Core file but without the function_exists condition. We want to paste the function into our functions.php (or plugin file), like so. With this replacement function included in our functions (or plugin file), WordPress will use it instead of the Pluggable Function. So now we can customize the function however is desired. Because we are now calling our custom logout function directly, we no longer need to register it with the wp_logout hook.

In general, Pluggable Functions enable greater customization than is possible using hooks alone. For example, if we wanted to use our own functions instead of these, it is easily done. So we could customize exactly what happens when the user logs out. Again, anything is possible. This is just an example that shows how to use the various Pluggable Functions provided by WordPress. Note that all Pluggable Functions are wrapped with a function_exists condition. These lines instruct PHP to use the function only if it is not already included. Effectively, this is what makes these Core WordPress functions pluggable.

10.2 Pluggable functiond and childthemes

Pluggable functions are also handy if you want to build a child theme later on top of the Underscorres child theme. Thenyou can choose to override these pluggable functions. So if a child theme sets up a function called pre_underscores_setup, then this if statement is triggered, and the parent theme function pre_underscores_setup simply will not run.

10.3 Exploring the pre_underscores_setup() function

The function in question, pre_underscores_setup, is the theme setup function. This is where you define all the main parameters of the theme that Wordpress will use to handle the theme and the content that's displayed within the theme.


At the very top of humescores_setup, we load the theme text domain. The text domain is used any time we want to translate the contents within a theme to a different language.

* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on Pre Underscores, use a find and replace
* to change 'pre_underscores' to the name of your theme in all the template files.
load_theme_textdomain( 'pre_underscores', get_template_directory() . '/languages' );

All those translations would be placed in the folder /languages. If you want to use another folder then this is the place to tell Wordpress.

10.3.2. add_theme_support( 'automatic-feed-links' ) and add_theme_support( 'title-tag' )

Next we add theme support for two core features, automatic feed links and title tags, so we don't have to worry about it in the theme. You should always leave these two in, don't ever change them.

// Add default posts and comments RSS feed links to head.
  add_theme_support( 'automatic-feed-links' );
  * Let WordPress manage the document title.
  * By adding theme support, we declare that this theme does not use a
  * hard-coded <title> tag in the document head, and expect WordPress to
  * provide it for us.
  add_theme_support( 'title-tag' );

Then we add theme support for post thumbnails.

10.3.2. add_theme_support( 'post-thumbnails' )

add_theme_support( 'post-thumbnails' )

Now, post thumbnails is the old nomenclature for what we now call featured images. If you want to add featured image support in your theme, meaning someone can go to a post or a page and add a featured image to that post or page, this line of code needs to be in your theme setup. If it's not there, that feature will not be available on the back end of Wordpress

10.3.3. register_nav_menus()

Underscores comes with one registered nav menu, that means there is one theme location where you can place a menu. That's done by registering a nav menu in an array, so currently the array holds one item, a primary menu with the human readable name Primary.

// This theme uses wp_nav_menu() in one location.
register_nav_menus( array(
'menu-1' => esc_html__( 'Primary', 'pre_underscores' ),

If you want to add additional menus, you simply copy out this line, add in another one in the array and give it a new label and a new human readable name, and now you'll have two theme locations for menus in your site.

// This theme uses wp_nav_menu() in one location.
register_nav_menus( array(
'menu-1' => esc_html__( 'Primary', 'pre_underscores' ),
'menu-2' => esc_html__( 'Footer', 'pre_underscores' ),

10.3.4. add_theme_support( 'html5', array())

Out of the box, Wordpress still outputs a lot of HTML4 content, so if you want to upgrade Wordpress to output HTML5 instead, you can add theme support for HTML 5 and then set up an array of features you want to upgrade. The array that ships with Underscores by default is the full array, and so these are all the available features.

* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
add_theme_support( 'html5', array(

They are search form, comment form, comment list, gallery, and caption. So for example, if you add theme support for HTML5 captions, any image with a caption will be wrapped inside a figure and the caption will be a fig caption. If you want to remove that feature, you simply remove this line in the array or you can remove the entire functionality, but I wouldn't recommend doing this because this is something you really should have in your theme and there are very few instances where you want to revert back to the old HTML4 way of doing things

10.3.5. add_theme_support( 'custom-background', array())

Then we add theme support for custom backgrounds.

This hooks in to the customizer feature that allows the admin of the site to set a custom background color and add a custom background image. We can set up defaults for both of them, so here you see the default background color is currently white and there is no default image. If you want to add a default image, you can do so here, but just add a URL, either an absolute or a relative URL. And if you don't want the admin of the site to be able to change the background color, simply remove this entire function. Humescore_setup is hooked into the after setup theme action, so that means after the theme has been set up, all of these functions are run and Wordpress will work with all the content we've defined here.

// Set up the WordPress core custom background feature.
  add_theme_support( 'custom-background', apply_filters( 'pre_underscores_custom_background_args', array(
  'default-color' => 'ffffff',
  'default-image' => '',
  ) ) );

10.3.6. add_theme_support( 'customize-selective-refresh-widgets')

Then we add theme support for customize-selective-refresh-widgets.

 // Add theme support for selective refresh for widgets.
  add_theme_support( 'customize-selective-refresh-widgets' );

10.3.7. add_theme_support( 'custom-logo', array() )

The last thing we do is add theme support for custom logos.

  * Add support for core custom logo.
  * @link
  add_theme_support( 'custom-logo', array(
  'height'      => 250,
  'width'       => 250,
  'flex-width'  => true,
  'flex-height' => true,
  ) );

Leave a comment