WordPress, WordPress Templates

Underscores Menu Exercise pt 3: Enqueuing Scripts

Other Values

If enqueueing scripts (or local stylesheets), it is a bit more complicated, but it’s learnable.

All URLs in WordPress are absolute, not relative, so when the theme is installed at a new domain, WordPress needs to figure out the path to resources, starting with the http://domain.com/ part.

If you look at the script enqueueing, you will see that this is done with the php concatenation operator (the dot). The get_template_directory() function retrieves the absolute URL of the theme, then we add the dot, then the remainder of the path to the local script.

The remaining values passed to the function are:

  • An Array: if needed we can list script dependencies here, by their handles. Don’t worry about that for now.
  • A number, typically today’s date, that will be appended to the URL for cache busting purposes. Don’t worry about that either
  • True or False: this determines whether the script loads in the before the close of the BODY rather than in the head of the page. True = bottom of page; False = header. Because our icons need to load quickly, we will load them in the header, so we set that value to false.


WordPress Templates

WordPress Bare Bones Theming Exercise: Common Template Tags

When we ended part 1 of this exercise, we saw a bunch of posts output to the screen.

Now inspect that page and make sure that the entire HTML skeleton is being output. In other words, make sure that the HTML HEAD is output at the top and that the closing tags are at the bottom of the document.

In this part of the exercise, we are going to edit our template files in order to grab more information from the site database and output it in appropriate places in the page generation process.


First, let’s edit header.php.

We’ll begin by making the title of all pages show the name of the page, followed by the name of the site. In a few classes from now, we will cover a better but more complicated way to do this, but we’re aiming for simplicity here in order to get used to a number of WordPress theming idioms.

In between the TITLE tags, add a call to the wp_title function and the bloginfo function:

<?php wp_title(' | ', true, 'right'); bloginfo('name'); ?>

There are three lines in the above snippet. Lines 1 and 3 are HTML; line 2 is PHP, so we need to include the opening and closing tags for PHP there. We will do a lot of this jumping in and out of PHP to make themes. In the order the three lines appear here:
we start the title, dynamically retrieve information from the database, then close the title.

Because we will do this process differently in a few classes, I don’t want to spend too much time on it, but in a nutshell, the wp_title() function is retrieving the title of the page, while bloginfo(‘name’) is returning the name of the site. With wp_title, the first parameter we pass to it is the separator that will appear between the site title and the page title ( | ). The second parameter determines whether the function displays the site name or just returns it (for use in further programming). The third parameter controls whether the site name appears to the right or to the left: it’s better on the right, so that the page name is completely visibile in a browser tab.

The bloginfo function can retrieve a lot of information from the Settings and User Profile areas of the dashboard. For more information on the parameters you can include in the function, consult the WordPress developer site page on bloginfo.

Test your site. The site name should now be the page title, followed by a pipe character ( | ), followed by the site name.

Now let’s add the site name and site description to a header area in the header.php file. After the opening BODY tag and before the opening .page-content DIV, add the following:

<h1 class="site-title"><?php bloginfo('name') ?></h1>
<div class="site-description"><?php bloginfo('description'); ?></div>

Here we see another parameter (description) we can pass to the bloginfo function. Test your site: you should now see the name and description output to the page, wrapped in semantically appropriate tags.

Finally, let’s add something very useful to the opening of the BODY tag:

<body <?php body_class(); ?>

Test your page. Now either Inspect the page, or view the Page Source. Notice all the classes that are now on the body tag? When we go to different parts of the site, those classes will change. They will reflect what part of the site your are on.

This will be invaluable when we write the CSS for the site.


Now we’ll edit footer.php.

In between the opening and closing footer tags, insert the following:

   <small>Copyright &copy; <?php echo date('Y'); ?> <?php bloginfo('name'); ?></small>

What are we doing here? Dynamically inserting the year, so that our copyright notice will always start with the year our site (theoretically) started and continuing into the present year. Then we again retrieve the name of the site. The reason we have two separate PHP operations here is that I wanted to have a space between the year and the site name (not the only way to do it, but it works…).

So why don’t we hard code the site name and descriptions in the above? We could, but if we changed either in the WordPress dashboard, we would then need to change the theme files.

Major Edits: Index.php

We learn in HTML classes that a file called index.html will load automatically when our URL ends at its parent directory.

The index.php file in WordPress can work like that, but it actually does more. Specifically, it is an all-purpose kind of file. It might generate the home page. It might generate all of them. It might not generate any (if there are more-specific template files in the theme). This is determined by the WordPress template hierarchy. We will examine the hierarchy more shortly. At this point, though, index.php will be generating all of our content regardless of where we are on the site..

Here’s our index.php starting point again:

    if ( have_posts() ) : while ( have_posts() ) : the_post();
    else :
        _e( 'Sorry, no posts matched your criteria.', 'textdomain' );

To this, add the_title, the_post_thumbnail, the_author, the_category, the_tags, and the_date WordPress functions:

    if ( have_posts() ) : while ( have_posts() ) : the_post();


    else :
        _e( 'Sorry, no posts matched your criteria.', 'textdomain' );

Test the page. Eureka! Tons of information pulled from the database with very little effort. Each post now has seven distinct pieces of content we can use in our page.

Is it pretty yet? No.

Do have a way to make it pretty? Yes.

It’s called HTML and CSS.

Each of these functions can be looked up in the WordPress codex or developer area. It’s as simple as googling them.


To start, let’s google the_category(). The first page that comes up in the search results is probably to the WordPress codex. Reading that page, we learn that category links are placed in an HTML LIST by default. Looking at our generated page confirms that.

However, if we pass a separator character to the function, the post’s categories will be separated by that character (put on a single line rather than being put into a list). So amend the call to display the category as follows:

 the_category(' ');

Here we use a space, but we could use commas, bullets, special characters, etc.

If we test the page, we will see that the Category is still a link, but it is no longer marked up as a list.

Go into the Dashboard and edit the first post in the posts area. Put it into another category. Now, when you test the page, you will see both categories, separated by a space.


Similarly, we will google the_tags().

IF we go to the WordPress Codex page link that is returned by google, we will learn that the_tags() can take three parameters as arguments: $before, $separator, and $after.

To demonstrate what these do, change the_tags in your index.php template file to the following, adding two of those parameters separated by a comma:

the_tags('Posted in ', ' | ' );

Or, if you want to get adventurous, slip in some HTML to the_tags() function.


That will output your tags in an unordered list. The first parameter comes before the outputting of the tags: it opens the list and then starts the first list item. The next parameter, the separator, comes first between tag1 and tag2 and then between each tag thereafter: so it closes the first list item and opens the next one (and so on). Finally the last parameter comes after the last tag: it closes both the final LI and the UL itself.

WordPress Templates

WordPress Bare Bones Theming Exercise

This exercise will demonstrate a number of important WordPress features, including

  • the WordPress template hierarchy
  • common template tags
  • the loop
  • conditions in WordPress
  • get_template_part

We will take a simplified approach, in order to get the broadest sense of how WordPress themes work and not get bogged down in too many details.

Some Sample Content

First of all, please download this zip archive. When you unpack the ZIP file, you will find a Duplicator installer and archive combination, and a single screenshot file.

Copy the installer and the archive from inside the DuplicatorPackage folder into your MAMP htdocs folder. Put them in a folder called iwillmakeatheme.

Then start up MAMP and make a new database called iwillmakeatheme.

Go to the root level of your local server (localhost:8888 on Mac), click the iwillmakeatheme folder and then run the Duplicator installer.

As part of the installation process (step two or three), create a new ADMIN account with your name as the user and password (for ease of recollection. This is just a lab exercise, so we are not worried about a site being hacked here).

Once you get through the Duplicator site installation, go to the front of your site. Viewing the content in the twentysixteen theme (the only theme included in this Duplicator package), you will see that you have a bunch of posts, mostly with lorem ipsum text, but with feature images, different authors, tags, categories, etc.

Theme Content

Create Your Theme

Inside the wp-content/themes folder inside your iwillmakeatheme installation, create a new folder. Name it iwillmakeatheme.

A basic WordPress theme requires only two or, arguably, three files.

The first of these must be called style.css(note that the name is not plural).

Inside that file add the following at the top, including the comment tags:

Theme Name: I Will Make A Theme
Author: your name...
Description: A theme I am building to learn about theme building.

Make Some Basic Template Files

One of the main reasons for the existence of Content Management Systems like WordPress is that they cut down on a lot of repetition. 

For example, the header and footer of most websites often don’t change at all. So, make three new files: 

  • header.php
  • footer.php
  • index.php

Inside header.php, add the following:

<?php ?>

<!DOCTYPE html>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  <div class="page-content">

Inside footer.php, add the following

<?php ?>

</div> <!-- end .page-content -->
  <small>Site by insert-your-name</small>

Apart for the opening PHP tag in each file, what’s clear if you look at them is that the two files together make a complete HTML document.

In other words, some of the tags that are started in the header file (html, body, .page-content) are not closed until the footer file.

The Index Template File and Our First WordPress Loop

Now make another template file called index.php

Inside that file, add the following:

    if ( have_posts() ) : while ( have_posts() ) : the_post();
    else :
        _e( 'Sorry, no posts matched your criteria.', 'textdomain' );

This is obviously a more complex file than the previous ones we’ve made, but what’s happening here is that when the user goes to a page that uses the index.php file (a process determined by the wordpress template hiearchy), the server starts building an html page to send to the user’s browser.

  • The first instruction in this template file ( get_header(); )is to put the contents of the header.php file into the html file being created.
  • The last instruction ( get_footer(); ) is to put the contents of the footer.php file into the html file being created.
  • Between the header and the footer in this template file is the most important code in a WordPress template: the loop.
  • The loop firsts asks the database: do we have posts? What comes next depends on the answer.
  • If we do have posts, the next code starts outputting them until there are no more left.
  • If we don’t have posts, the message “Sorry, no posts matched your criteria” is output to the file.

Make sure all your files are saved. Now activate your theme (in the Dashboard: Appearance > Themes).

Go to the front page of your site. You will see either a blank page, an error message, or a bunch of posts (with no images, authors, categories, etc yet, but that’s coming).

If you are not seeing a bunch of posts, check that all your files are saved, that they have the correct names and extensions, and that the syntax is exactly the same as shown above.

If you do see posts, congratulations: you’re ready for part two of this exercise: common template tags.

WordPress Templates

Jazz Icons 2017

Please download the Duplicator archive for this exercise, then download the screenshots package. The Duplicator archive contains all the site content, including the menus.

It also includes an UNDERSCORES starter theme with two modifications. The first modification makes post thumbnails already have their associated links. The second wraps all YouTube videos in a DIV to make it easier for them to be styled responsively.

Any sans-serif fonts used are the helvetica, arial, sans-serif font stack. Any serif fonts are the Google font LORA.

No page in the site will have a sidebar.

You can use SASS if you want to, or not use it if you don’t want to.

Make sure that you are testing the site with Google Chrome, as that is the browser I will mark with.

How To Hand In The Exercise

When you are done the exam, please make a Duplicator archive of the site. Make sure that you do this in Chrome.

Then hand it into the class handin folder, in a folder called JazzIcons. Inside that folder there needs to be a file called installer.php and a zip archive with a long name. Make sure that you did not accidentally unzip the zip file.

Marks Breakdown

Header 10%
Menu 15%
Article Styling 20%
Home, Archive, Search Layout 40%
404 Page Text Change 5%
Search Page Heading 10%
Single Post Bonus 50%

Header Area

The header on all pages will look like this. The Underscores starter theme has a button that appears at smaller widths in the header. Remove it.

Header screenshot


The menu will have the following items: a link to home, category links, and a link to a Contact page.

With the menu, make sure that the user’s current location in the site is indicated. In the above screenshot, the user is on an archive listing all posts about Saxophone players.

Menu: Responsive Strategy

The screenshot above shows menu items when they fit into one row. At smaller browser widths, the menu items reflow. Both rows in the menu will always take the full width of their content area. The menu items, in other words, automatically take whatever space is available to them.

menu screenshot menu screenshot menu screenshot


On the home page, category archives, and search results, each article will look like the screenshot below.  Think about what this means for your templating.

On those pages, each article will have the post title, the posted-on date, the post excerpt, the feature image, and the post and category links. ( A logged in user might also see the EDIT link as well ).

Article Screenshot

Home Page, Archive Pages, Search Results Layout

These pages will all behave the same way:

  • at full screen width, the articles sit three in a row (if available)
  • at medium width, the articles site two in a row (if available)
  • at small width, the articles sit in a single column, but with the main text still beside the image
  • at small phone width, the articles sit in a single column, but with the main text now underneath the image

Consult the downloaded screenshots to get what I mean here. You determine the breakpoints needed.

404 Page

For the 404 page, change the phrase It looks like nothing was found at this location. The new line will be We’re sorry: there appears to be no content at this location. 

Search Page

On the Search Results page, make the heading that shows the search results stand out like this:

Search Results


Single Posts

This part is for a 50% bonus.

When a user clicks on the title of post or the thumbnail, they will be taken to the single view of the post.

It will look like this. Click it for a bigger view, or consult the downloaded screenshot file.

The text will be in the middle of the screen. It will be prevented from getting too wide. The thumbnail will not appear. The video, which is the first thing in the content window, will be responsive.

WordPress Templates

WordPress: Film Festival Site: Remaining Tasks

Hopefully this exercise has given you some ideas about how to build WordPress templates.

A number of things, of course, remain to do.

There is a social menu, so please figure out how to add font-awesome icon fonts to each of the social links, while hiding the link text with underscores’ screen-reader-text class. The wordpress developer page on wp_nav_menu will be useful here.

Check that the site works on a phone.

A nice 404 page would be a good idea. With some research, you could add a more prominent search form, lists of recent posts or comments, another menu, etc.

Speaking of search, a more nicely-styled search box in the header should be on the agenda.

I did not do very much styling in this exercise. To get the design to look closer to what it does in the screenshots, you need to study the screenshots and then figure out how to implements what is done in them in CSS.

You should make major use of FLEX. Flex will be very helpful, for instance, in the sections where content has to appear in the page in a different order from the way it appears in the source. Places where that happens include the index loops, the header, the archives and the SINGLE view.

Check your PAGE template, since there are a couple pages in the site.

Test the search results page. Test the archives. Here are my search results from a sample search. (Click image for greater detail.)

Here I have specified a summary rather than the full content of the post, for example, and the order of content in each article is different from the order on other pages.


A nice feature to add would be some jQuery or JS to make the footer form collapse, but be “openable” with a (large) button click.

Be sure, also, to edit the list of font-weights coming from Google, once you have decided how many you are actually going to use.

WordPress Templates

WordPress Film Festival Site: template-parts (single)

For the SINGLE view, I am going to make another template-part by copying content-home and renaming it content-single.

A QUICK CAVEAT: another option, of course, is to just use conditions within the original template-part. If we did cover conditions in class, feel free to use them. They represent a better way to do this, in fact, because it means there will no repetition of code.

Anyway, for the SINGLE view, I want to have the following features in each article.

  • No Feature Image, since the Video will appear
  • The full text of the post
  • The title
  • Some film-related meta data

The meta-data is attached to each post with the ADVANCED CUSTOM FIELDS plugin, which is one of the most used plugins in the WordPress world. If you look at one of the posts in the dashboard editing window, you will see the additional fields (for Country, Director, and Year).

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

	<header class="entry-header">
			the_title( '<h1 class="entry-title">', '</h1>' );
	</header><!-- .entry-header -->

	<div class="entry-content">
               the_content( sprintf(
				/* translators: %s: Name of current post. */
				wp_kses( __( 'Continue reading %s <span class="meta-nav">&rarr;</span>', 'untouched' ), array( 'span' => array( 'class' => array() ) ) ),
				the_title( '<span class="screen-reader-text">"', '"</span>', false )
			) );
			wp_link_pages( array(
				'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'iff' ),
				'after'  => '</div>',
			) );
	</div><!-- .entry-content -->
        <div class="entry-meta-data">
                    <li><b>Country: </b><?php esc_html(the_field('country')); ?></li>
                    <li><b>Director: </b><?php esc_html(the_field('director')); ?></li>
                    <li><b>Year: </b><?php esc_html(the_field('year')); ?></li>                   
</article><!-- #post-## -->

To learn how to output data from Advanced Custom Fields, consult the developer’s Documentation.

You have likely noticed in the metadata section that I have wrapped the ACF calls ( the_field() ) inside the WordPress esc_html() function. This function, and others that are similar, is used throughout underscores. This is called SANITIZING.

The reason for using it is that if either malicious code ( small example: <script>alert(‘this site sucks!’)</script> ) or badly formed HTML is entered into a field, it can have embarrassing (or worse) consequences.

A couple tests make me suspect that ACF sanitizes user input anyway, but it is never a bad idea to sanitize on output as well as input.

Anyway, with some styling, the page looks like this (click image for larger, detailed, view):

( I should style the comment form so that it doesn’t take the full width of the page, but it’s late and I’m sure you get the idea anyway).

NEXT: remaining tasks

WordPress Templates

WordPress: Film Festival Site: do_shortcode()

Now let’s turn to the complex footer we have in the screenshot.

This is actually quite easy.

I have installed a highly-regarded FORMS plugin called Ninja Forms. That is why you see a FORMS section in the Dashboard (just below the COMMENTS menu item in the dashboard).

Using a WordPress feature called Shortcodes, we will insert a Ninja Form in our FOOTER.

If you have ever made a WordPress Gallery, you have used Shortcodes. If you look in the TEXT view of a gallery you will see a few words and numbers enclosed in square brackets.

Similarly, if you look in the Ninja Forms ALL FORMS area, you will see the shortcodes listed:

If you put a shortcode into a post or page (text mode only, not visual mode), the functionality triggered by the shortcode will appear there.

However, we can also use a WP function do_shortcode() to add functionality to template files.

Go to the NINJA FORMS area in the site you have setup. Copy the SHORTCODE for the REGISTRATION FORM.

Now open up the footer.php file.

Just beyond after the opening of the FOOTER tag, put in the following:

<?php echo do_shortcode( '[ninja_form id=3]' ); ?>

Test your page. Is that cool? Yah, that’s cool.

NEXT: another template-part

WordPress Templates

WordPress: Film Festival Site Home Page

Look at your home page. You will see the header and footer and sidebar area, hopefully well styled.

Look at the rest of the content on the page. The default home page loop outputs the title, the posting date, all the content, the categories and the tags, etc. Each article is essentially unstyled, so the content is taking up 100% of the browser width.

We will change that. Duplicate your index.php template file and rename the new one front-page.php then open it up in Netbeans:

Here is a screenshot of what we will build. Click the image for a much larger, more detailed, view:


In brief, here is what we will put in the front-page template file

  1. An h2: “Showing This Year”
  2. A number of articles, each with only the category, the feature image, and the title. These posts are tagged with high definition. 
  3. Another h2: “Hall of Fame”
  4. Another collection of articles, with category, feature image, and title. These posts are tagged with regular definition. 

The additional content on the page will output via edits to other template pages.

Creating the Custom Loops

If you need a review of wp_query, read my post on multiple loops in WordPress.

To begin this edit, go after the <main> element in the front-page.php file.

Add an H2. You are still in HTML right now, so you do not need to close a PHP tag.

  <h2 class="section-heading"><span>Showing This Year</span></h2>

If you are wondering why I have included the SPAN tag, it is because I might do the positioned-broken-border trick on this element.

Now add new WP Query object after the H2 you have just added

  $movies_query = new WP_Query( array(
                        'tag' => 'high-definition',
                        'posts_per_page' => '40',
                        'orderby' => 'rand',
                    ) );

Then modify your loop so that you are using this new WP_Query object instead of the default global WP_Query object. I removed the conditional part at the start of the loop: it is not needed here. I also removed a comment section.

One additional change is that I am going to want to customize the display of articles for this page. So amend the get_template_parts function, replacing the get_post_format() like this (only in the IF part: leave the ELSE part with the ‘none’):

     get_template_part( 'template-parts/content', 'home' );

This is the code I am left with for my first loop:

if ( $movies_query->have_posts() ) :
         /* Start the Loop */
	while ( $movies_query->have_posts() ) : $movies_query->the_post();

               get_template_part( 'template-parts/content', 'home' );



	else :

	get_template_part( 'template-parts/content', 'none' );

/* ============================================== */   

Before testing your page, go into the template-parts folder and duplicate content.php, renaming it content-home.php.

If the first section loop works, copy it and change a few words to get your second loop section. Here is my second section:

<h2 class="section-heading"><span>Hall of Fame</span></h2>  
/* LOW RES MOVIES QUERY ========================================== */   
        $low_res_movies_query = new WP_Query( array(
                        'tag' => 'regular-definition', 
                        'posts_per_page' => '6',
                        'orderby' => 'rand',
                    ) );
	if ( $low_res_movies_query->have_posts() ) :
		/* Start the Loop */
		while ( $low_res_movies_query->have_posts() ) : $low_res_movies_query->the_post();

			get_template_part( 'template-parts/content', 'home' );



	 else :
		get_template_part( 'template-parts/content', 'none' );
 /* ============================================== */   

Be sure at the end of each loop to call wp_reset_postdata() in order that the main WP_Query object is not affected by your custom loops.

For additional information on the various Methods and Properties of the WP_Query object, consult the WordPress Codex.

Once you do that, test the front page of your site. Hopefully, you are getting both sections output to the page, with the correct content. If you are not getting it to work, compare the code you have written to the loop that is in the index.php file: there may be something obvious. If that does not help and we’re in a lab, ask me to take a look at it.

NEXT: template-parts 1

WordPress Templates

WordPress: Film Festival Site Based on Underscores

In this exercise, we will make an Underscores-based WordPress site for the Imaginary Film Festival.

I am not going to cover every single styling component of the exercise. You can take care of those yourself. We will focus on the main templating activities instead.

First, download the sample content. This will be a Duplicator archive of the site at the start of the exercise.

Run the Duplicator installation process on your own computer.

Once you login to the new site and look in the Dashboard, you will see that I have put in about 50 posts, most of which contain a YouTube video of the trailer of a movie, as well as some text on each film from wikipedia.

There is a Contact page, and an About page, too.

In the Duplicator archive, I have supplied you with a downloaded Underscores package. It is the active theme.

Plugins Used In This Exercise

You will also likely notice that there are some additional items in the Dashboard:

  • a section for a Custom Post Type called Notices (I am not using it in this version of this exercise, but will likely add more to the exercise in the future…)
  • a Forms section
  • a Custom Fields section
  • a CPT UI section

These are created by the following plugins:

  • Custom Post Type UI
  • Ninja Forms
  • Advanced Custom Fields

The feature images for the movie posts were automatically generated by a plugin called Video Thumbnails. I highly recommend it if you have a bunch of video posts.

In theme-writing, it is very important to know what files you need to work with. For that reason, you should also install the Show Current Template plugin.

Site Features

The site will have the following features:

  • a header with two menus, one category-based and one for the ABOUT and CONTACT pages.
  • a sidebar with a Registration form and links to Social Media. Despite the name, this section will sit just above the site footer.
  • a home page with at least two custom loops. One will output the films playing this year at the festival, while the other will output a hall of fame of movies.
  • a single page template for the about and contact pages
  • a single category archives form
  • a search results page

The Main Template Files We Will Edit

  • front-page.php ( duplicated from index.php )
  • header.php
  • footer.php
  • functions.php

Template Part Files

A big part of what we are going to do here will depend on template-parts. These are called from within loops.  A template-part file generates one piece of content (in our example, an article) each time we go through the loop. If our loop has 10 posts, the template-part will be called 10 times in succession. The beauty of template parts is that you can call them from different templates. If you output a number of articles with the same (or similar) content, you could use a single template-part file for multiple loops (like in an archive or search result, for example)

SASS Underscores

We will use Underscores-generated SASS in this project. I like to simplify the structure a bit, so I don’t use all the partials that Underscores comes with. The main ones we will work with will be the following:

  • variables: typography, colors
  • typography: copy, headings
  • site: posts-and-pages, and a new partial called layout
  • navigation: links, menus

It is important to understand how Underscores SASS works. A single style.scss file imports a partial file from each of the folders inside the SASS folder. Each of these imported partials is named the same as its parent folder. I didn’t list those partials above, but they are obviously part of the partials import chain.


Go to Google fonts and select the following typefaces:

  • Fira Sans Extra Condensed, from 300 weight and up
  • Merriweather, 400 weight and up

From the EMBED  section, get the url of the font download:


While designing, we will have this wide range of weights. Don’t forget at the end of the project to delete any weights you are not using. Do not make your user download fonts they do not need to.

Now open up functions.php so you can enqueue the font. About 100 lines down you will come to the ENQUEUE SCRIPTS AND STYLES section.

First paste in the URL you got from Google. It doesn’t matter where you paste it, because we will move it in a second.

Now copy and past the wp_enqueue_style line.

Each enqueue function has a “handle”: a unique name with which WordPress keeps track of it. To reduce the chance of your functions conflicting with those in plugins etc, it is a best practice to have the handles start with your theme name. The theme I am building here is called IFF, so that’s why my handles start with that prefix.

Here’s the copied line (and the original):

wp_enqueue_style( 'iff-style', get_stylesheet_uri() );
wp_enqueue_style( 'iff-style', get_stylesheet_uri() );

Change it to this:

wp_enqueue_style( 'iff-google-fonts', 'https://fonts.googleapis.com/css?family=Fira+Sans+Extra+Condensed:400,400i,500,500i,600,600i,700,700i,800,800i,900,900i|Merriweather:400,400i,700,700i,900,900i' );
wp_enqueue_style( 'iff-style', get_stylesheet_uri() );

In other words, in the copied line you are replacing the get_stylesheet_uri() with the URI of the google font stylesheet.

Save the file, then go to the front page of your site. Inspect it, and go to the Console. If the file is not enqueued correctly, there will be an error reported in the console.

Test Your SASS Setup

Elsewhere on this site, I have written on how to use SASS with Netbeans. Make sure that you have a new Netbeans project whose SASS is correctly watching the wp-content/themes/iff/sass/style.scss file (outputting to wp-content/themes/iff/style.css). To test that, open up style.scss (the SASS file, not the CSS file) and add a comment in the top comment block. Save it, then open up the generated style.css file to see if the comment was in fact compiled into the style.css file. If not, review the SASS & Netbeans document on this site.

Set Some Variables

Inside the variables folder, open up the _typography.scss file.

Change the $font__main variable to include merriweather as the first font, then the georgia, times, “times new roman”, serif font stack.

Add a new variable: $font__sans: “Fira Sans Extra Condensed”, “arial narrow”, helvetica, sans-serif;

Open up the _colors.scss file. Change $color__background-body to BLACK, change $color__background-site to WHITE and add a new variable: $color__background-header-footer: #eef.

Change your link colors to something less ugly that the Underscores defaults. I used the following:

$color__text-screen: #21759b;
$color__text-input: #666;
$color__text-input-focus: #111;
$color__link: black;
$color__link-visited: lighten($color__link, 20%);
$color__link-hover: red;
$color__text-main: #404040;

Now let’s use some of these variables. Open _headings.scss and set the .site-title a style to $font__sans and set its height to 6rem. Here’s all the SCSS I used on the SITE-HEADER class:

.site-title {
    margin: 0;

.site-title::after {
    content: "✹";
    display: block;
    font-size: 16px;

.site-title a {
    font-family: $font__sans;
    text-transform: uppercase;
    font-weight: bold;
    font-size: 2rem;
    margin-bottom: 0;
    margin: -2rem 1% 0 1%;
    color: black !important;
    line-height: 1;
    text-align: center;
    @media screen and (min-width: 800px) {
        font-size: 6rem;

Notice how I have embedded the media query inside the .site-title a style? SASS lets you nest queries or descendent elements inside a style. This is very concise, but it can lead to wordy CSS if your selectors are too complex.

Save and test. If there are any errors in your code, the SASS compiler will output them to your Netbeans console (and the browser window, too).

A New SASS File

Here I want to make a new SASS file called _layout.scss. Save it in the site folder inside the sass folder. I like to handle the site’s layout in a single file rather than spread it through a bunch of SASS files. Because this is a new partial file, however, we need to import it into the _site.scss file that is inside the site file. You can do that by copying and then modifying a line in the _site.scss file:

@import "layout";

Add the following to the new _layout.scss file:

@media screen and (min-width: 600px) {
.site {
    padding: 24px

@media screen and (max-width: 600px) {
    .site {
        padding: 1%;

.site-header, .site-footer, .widget-area {
    background-color: $color__background-header-footer;

The idea here is that we will give the site a “border” effect by pushing the white-background site box in from the edge of the browser window. Since the body background is black, that will create this border effect.

Then we set our header, footer, and widget area to the “lilac” color that we set in the _colors.scss file.

Test the page. Then try to style the rest of the header and footer content as it is in the screenshot.

NEXT: Generating Home Page Content

WordPress Templates

Multiple Loops in WordPress

About Custom Loops

This will likely be the most complex topic we cover in this class, but knowing how to make multiple loops in a single template file gives you some amazing abilities.

The default loop gives you posts in order of most recent to least recent.

However, with custom loops, we can select from a wide range of possible criteria with which to assemble and output our content. Moreover, with multiple custom loops, we can:

  • have different sections on the page, each with their own content items. This content can be grouped by category, tag, author, date, reverse-chronology, tag etc.
  • have sections on the page with different numbers of content items
  • have random items
  • have different iterations of the loop call different template part files
  • etc

This depends on the WordPress wp_query object. Think of each new wp_query as a trip to the database pulling out the content you need for each particular part of the page.

To read about all of the various parameters available with wp_query, the WordPress Codex article on the subject is very, very helpful. A number of code snippets are provided as well.

To get a sense of what I mean here, examine the image below, a 2016 screenshot of LangaraPRM.com.

There are a number of  sections on that page: Features, Environment, Community, Art, Travel, Food, Blog, Team Photos, Advertisement.

Each is a custom loop. Features grabs the four most recent feature entries from the database, the next five sections get the single most recent post from each Category on the site that year, the Blog section grabs the three most recent blog custom post type entries, the Advertisement section grabs a random ad, and the Team section gets from the database three student custom post type entries.

Moreover, each entry in these different sections can have different content pulled out. For example, some have excerpts; some do not.  Some have larger feature images than others. The Team section gives social media links for each student—information stored with the post as a custom field.

( As an aside: to use custom fields, go to Screen Options in the post editing window and select it. Better yet, investigate one of the most widely used plugins in the WordPress world: Advanced Custom Fields).

In short, custom loops greatly expand the ability of WordPress to be a true Content Management System as opposed to just a blogging platform.



Some Sample Content

For this exercise, I have created a Duplicator archive of a small site. Please download the package and install it in your testing environment (typically MAMP or WAMPServer, etc). Please download with Chrome rather than Safari: Safari automatically unpacks ZIP files unless a preference setting is changed.

Unpack the zip file by double-clicking it (Mac), then open the duplicator-parts folder and put the files that are inside it into a new folder called pedalmania2017 inside the htdocs folder in your MAMP installation (assuming you’re using MAMP, of course).

Start MAMP, make a database called pedalmania2017 and and then run through the Duplicator process. Add a new Admin user (you) as part of that process.

Get Underscores

Go to underscores.me and generate a new starter theme called pedalmania. In the Advanced section, click _sassify! if we have done SASS in class yet.

Install the newly created pedalmania starter theme inside wp-content/themes.

Set up a new Netbeans project, this time with SASS support. Step-by-step instructions are here.

In the WordPress dashboard, set your new starter theme as the Active theme.

Start Theming

As I have likely mentioned in class, I like to duplicate index.php so that this fallback file is left untouched. That also means that I have a clean copy of the main template file if anything goes wrong.

Duplicate the file and name it front-page.php

Open front-page.php up in the Netbeans editing window. Our loop looks more or less like what is below (I have removed one conditional statement, and some comments, to save space).

get_header(); ?>

	<div id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

		if ( have_posts() ) : ?>
					<h1 class="page-title screen-reader-text"><?php single_post_title(); ?></h1>


			/* Start the Loop */
			while ( have_posts() ) : the_post();
				get_template_part( 'template-parts/content', get_post_format() );


		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; ?>

		</main><!-- #main -->
	</div><!-- #primary -->


If we test the page, we see that we get posts listed in this order:

  • Super Ring Tone Deluxe
  • Super Ringtone
  • Super Seek Wah
  • etc etc

This is the normal reverse chronological order. However, change your loop to look this this. We are changing what posts get shown. In this case, we are getting a single random post from the fuzz category (there are four categories in the sample site I have given you).

 <!-- LOOP ONE: FUZZ -->

                $fuzz_query = new WP_Query( array(
                        'category_name' => 'fuzz', 
                        'posts_per_page' => '3',
                        'orderby' => 'rand',
                    ) );

		if ( $fuzz_query->have_posts() ) :
			/* Start the Loop */
			while ( $fuzz_query->have_posts() ) : $fuzz_query->the_post();
				get_template_part( 'template-parts/content', 'home');
		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; ?>

Reload the page and you will see that you get three new random posts from that category.

Now duplicate the entire loop, and just change the name of the new query (in four places) to $modulation_query.

In the array passed to the new object constructor, change the category name to “modulation”. Here, then, are both loops:

<!-- LOOP ONE: FUZZ -->
                $fuzz_query = new WP_Query( array(
                        'category_name' => 'fuzz', 
                        'posts_per_page' => '3',
                        'orderby' => 'rand',
                    ) );
		if ( $fuzz_query->have_posts() ) :
			/* Start the Loop */
			while ( $fuzz_query->have_posts() ) : $fuzz_query->the_post();
				get_template_part( 'template-parts/content', 'home');

		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; ?>

     <!-- LOOP TWO: MODULATION -->
                $modulation_query = new WP_Query( array(
                        'category_name' => 'distortion', 
                        'posts_per_page' => '3',
                        'orderby' => 'rand',
                    ) );
		if ( $modulation_query->have_posts() ) :
			/* Start the Loop */
			while ( $modulation_query->have_posts() ) : $modulation_query->the_post();
				get_template_part( 'template-parts/content', 'home');

		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; ?>

Now if you test your home page, you will see that you now are getting 3 random posts from two separate categories.

In the example code above, we are selecting posts by category and in random order. We can, however, select by tag, by post format, by custom post type, by not being in a category, etc. And we can arrange our content in chronological or reverse chronological order. We can sort by number of comments, etc.

In short, getting comfortable with WP_Query allows you to easily pull practically anything you want from the site database. The WordPress Codex article in exceptionally helpful in figuring out how to retrieve that content.