Categories
WordPress Templates

WordPress Bare Bones Theming Exercise: Common Template Tags & Get Template Part

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

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.

Header.php

First, let’s edit header.php.

Here we’ll add a useful WordPress function that will help our styling of the site.

Modify the opening body tag, adding the body_class() function. Put the opening and closing PHP delimiters, with the body_class function inside it. Then make sure that you’ve closed the opening BODY tag:

<body <?php body_class(); ?>>

Now reload any page in your site and then use the Inspector to see the result.

The added classes indicate where where we are on the site. For example, home means that we are on the home page, and blog indicates that we have not set a static home page in the Dashboard.

This is a very powerful feature for our styling efforts: when we are in any part of the site, useful classes will appear on the body tag. For example, on a search results page, the classes search and search-results will be added to the body tag.

To demonstrate, add ?s=lorem to the end of the URL in the browser’s address field and then press return. This URL will return search results for the the word lorem. When the results page loads, there will be six articles found. Inspect the search results page and look at the body tag:

Similarly, if we went to a category listing, additional classes (such as category, category-name, and archive) would be added to the body tag.

Some Banner Information

Next, let’s add the following code to the header.php file, between the opening of the BODY tag and the opening of the DIV with a class of page-content:

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

Test your site’s front page. You should now have a header with the Site Name (Theming Basics) and the text from the WordPress description field (A Theme Building Exercise).

Every page of the site now will have that same information in the header.

(Incidentally, 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.)

A Search Field

After the site-description DIV, add the following line:

<?php get_search_form(); ?>

Test your site. We also now have a working search field on every page.

Link to Home

A practically mandatory UI pattern on site headers is to turn the site name into a link back to the site home page.

To do that, first wrap anchor tags around the call to bloginfo. Use a testing link (‘#’) as the HREF value:

<header class="site-header">
     <h1 class='site-name'><a href="#"><?php bloginfo('name'); ?></a></h1>

Test the page. You now should have a link, but it’s going to nowhere.

To fix that, we need to replace the # sign in the HREF value with the URL of the front page of our web site. In other words, inside the quotation marks enclosing the HREF value, we need to break into PHP to dynamically grab the site’s root URL.

To do this, we use the home_url() function. The complete line should now look like this:

<h1 class="site-title">
  <a href="<?php echo home_url(); ?>">
    <?php bloginfo('name') ?>
  </a>
</h1>

Test your site. The site name should now be a link back to the home page, from any location in your site.

(You’re likely wondering why we used the ECHO command. The reason for this common technique is that some WordPress functions only return data, rather than outputting that data to the screen. The reason for this is that we often will need to retrieve data to use programmatically rather than for inclusion in the page. For example, we might want to know how many comments a post has generated, and then take action depending on how high or low that number is).

As you explore writing themes, you will definitely get used to this technique of dynamically inserting attribute values with quick calls to WordPress functions.

If any of the above didn’t work, here is the completed code for the header element we just added:

<header class="site-header">
  <h1 class='site-name'>
    <a href="<?php echo home_url(); ?>">
     <?php bloginfo('name'); ?>
    </a>
  </h1>
  <div class="site-description">
   <?php bloginfo('description'); ?>
  </div>
           
  <?php get_search_form(); ?>
</header>

Footer.php

Now we’ll edit footer.php.

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

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

What are we doing here? Dynamically inserting the year, then we again retrieve the name of the site.

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.

Content Generation: 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).

That 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..

In the earlier exercise, we made the index.php file.

Into it, we copied the following code. This bulk of this code is known as The Loop. It is the fundamental way WordPress generates content.

<?php
    get_header();
    if ( have_posts() ) : 

        while ( have_posts() ) : 
          the_post();
          the_content();
        endwhile;

    else :
        echo 'Sorry, we have no posts for you.' );

    endif;

    get_footer(); 

The loop checks to see if there are posts available. If there are, it then outputs them. If there are no posts, it outputs an error message.

Additional Data from Each Post

Modify your loop: add WordPress functions the_title, the_post_thumbnail, the_author, the_category, the_tags, and the_date:

<?php
 get_header();
    
     if ( have_posts() ) : 
      while ( have_posts() ) : 
        the_post();
         
        the_title();
        the_author();
        the_date();
        the_post_thumbnail();
 
        the_content();
        the_category();
        the_tags();
 
       endwhile;

    else :
        Sorry, we have no posts for you.' );
    
    endif;
    
get_footer(); 

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

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

the_category()

To start, let’s google the_category(). The first page that comes up in the search results is probably to the WordPress developer pages. In such pages, 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 an additional category. Now, when you test the page, you will see both categories, separated by a space.

the_tags()

Similarly, google the_tags().

If we go to the WordPress developer handbook 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.

the_tags('<ul><li>','</li><li>','</li></ul>');

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.

Mixing HTML and PHP

Is the site pretty yet? Not at all.

Do we have a way to make it pretty? Yes: HTML and CSS.

Most of the post content that we just output is coming in as raw data, without HTML tags. To make our content more semantic and more easily styled, we need to add some HTML among our PHP.

Our HTML, in other words, will be used to give meaning and structure to the database content output by PHP.

Here’s one possible way to do that with our present content:

<?php
get_header();
if ( have_posts() ) : 
  while ( have_posts() ) : 
  the_post();
?>
     
<article>
 
    <h2><?php the_title(); ?></h2>
         
   <?php the_post_thumbnail(); ?>

    <div class="entry-meta">
      Written by: 
      <b><?php the_author(); ?></b> 
      on <?php the_date(); ?>
    </div>

    <div class="entry-category">
       Filed under: <?php the_category( ' '); ?>
    </div>
    
    <div class="entry-tags">Tagged: 
      <?php the_tags( '', ' | ', ''); ?>
    </div>
     
    <div class="entry-content">
       <?php the_content(); ?>
    </div>    
 
</article> 
 
<?php 
endwhile;

else :
    'Sorry, no posts available.';

endif;

get_footer();

The key thing to remember here is that when you want to add HTML, you need to close the PHP. For example, see how we leave PHP by closing it before we add the ARTICLE tag? And when we insert dynamic content via PHP inside a DIV, we open and close the PHP inside the HTML.

Turning Each Post Title into a Link to the Full Post

Finally, let’s make each post title be a link to the full post.

Like like we did with the site-title in the header.php file, wrap the_title in an a tag, nesting it inside the H2. Make the HREF value a testing link for now (if you use separate lines for each tag and php function, it can make what you’re doing clearer):

<h2>
  <a href="#">
    <?php the_title(); ?>
  </a>
</h2>

Test the page and make sure that your post titles are now shown as links.

If that’s working, change the # symbol to a dynamically created value. This is done with the the_permalink() function.

Don’t forget that you’re wrapping that call in the opening and closing PHP delimiters.

<h2>
  <a href="<?php the_permalink(); ?>">
    <?php the_title(); ?>
  </a>
</h2>

Test your page. Now your posts have links to the full content.

Get Template Part

Once we started adding template tags, and then putting HTML in and around it, though, the code very quickly got more and more like a plate of spaghetti.

If we have multiple loops on a page (which we’ll do in a future exercise), the logic of our template files can get confused or less easily discerned.

Moreover, in different parts of the site, we might want to have our articles take completely similar, quite similar, or very different forms.

For example, on the home page, we probably want the excerpt of the article rather than the full content. Conversely, on the single view of a story, we will want the content rather than the excerpt.

Fortunately, template parts can help.

Template parts allow us to abstract and reuse sections of template code.

To see what I mean, make a new folder inside your theme called template-parts. Inside that folder, make a file called article-short.php.

Cut the article from inside the loop and then paste it into article-short. Make two edits to that file:

  • make sure that the opening PHP delimiter is closed immediately
  • change the_content(); to the_excerpt();

Article-short should now look like this:

<?php ?>
    <article>
 
        <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
             
       <?php the_post_thumbnail(); ?>
        <div class="entry-meta">
           Written by: 
           <b><?php the_author(); ?></b> 
           on <?php the_date(); ?>
        </div>
        
        <div class="entry-category">
           Filed under: 
           <?php the_category( ' '); ?>
       </div>
        
       <div class="entry-tags">Tagged: 
         <?php the_tags( '', ' | ', ''); ?>
      </div>
         
      <div class="entry-content">
         <?php the_excerpt(); ?>
      </div>    
 
    </article> 

Now inside the loop in the index.php file, where you had the article, put a call to get_template_part instead:

<?php
get_header();
if ( have_posts() ) : while ( have_posts() ) : the_post();
 
   get_template_part('template-parts/article-short');
 
endwhile;
else :
    'Sorry, no posts available.';
endif;
get_footer();

In the next section of this exercise, we’ll make a template part called article-long and use it in different ways as we explore the WordPress Template Hierarchy.