The Underscores (_s) theme with Sass and Gulp Part 11: the archive template

==================================================================

On this page:

  1. Get to know the index template hierarchy.
  2. Identify when you are on an archive page.
  3. Customize index and archive templates.
  4. Add a custom Read More link to index posts.
  5. Display excerpts in indexes and archives.
  6. Customize the excerpt output.
  7. Add featured images to index and archive pages.
  8. Add more meaningful archive navigation.
  9. Highlight sticky posts.
  10. Customize archive pages.
  11. Customize the search results page.
  12. Customize the 404 error page and empty search results.

==================================================================

57. Get to know the index template hierarchy.

Github repo branch: part11_57

The Wordpress template hierarchy is visualized on https://wphierarchy.com/, where you can also interact by clicking on an element. For instance, clicking on the archive.php element leads you to https://codex.wordpress.org/Creating_an_Archive_Index#The_Archives_Page

The Wordpress Developer Page is to be found on https://developer.wordpress.org/themes/basics/template-hierarchy/.

The Template hierarchy controls how WordPress knows which template to use for what content. Every time you visit a page or a post or other type of content in a WordPress site, the application works with the database to figure out what template file should be used. That process starts on the left of the diagram and ends on the right and the first appropriate available template is selected for each view.

So for example, if you're visiting a single post and your theme has a template file called single.php, that template file is used to display that single post in the browser. Here's how that process works step by step. You enter some sort of URL in the browser, that sends a query to the database. Now WordPress needs to know what type of content this is. The content is identified as a singular page, meaning it can be either a post or a static page. In this case it's a post so now we have to figure out what type of post it is. It can be either an attachment, a custom post type or a standard blog post. It's a blog post so now WordPress looks for the single-post.php template in the theme. When it can't find single-post.php, it looks for single.php instead and if it can't find that, it looks for singluar.php and if it can't find that, it goes to the default which is index.php. In fact, no matter where you go on the site, if no template is available, WordPress always defaults to index.php.

Knowing how to use the WordPress Template Hierarchy means you can quickly identify what template is currently in use for a page or a post or index or archive or anything else on your site. It also means you can create custom templates that kick in for specific scenarios. This works the same way in child themes as it does in regular themes. Looking at the template hierarchy, you'll notice that for categories, you can create custom template files for individual categories logs or IDs. You have custom single templates for custom post types. You can create various custom templates for your front page and the list goes on and on and on.

In underscores, there are three index templates:

  1. archive.php. Based on how the visitor interacts with WordPress, a number of different archive indexes can be generated. If there are no more-specific archive template files, the requests are handled by archive.php. In Underscores, archive.php handles categories, tags, dates, author archives and optional archives from custom post types and taxonomies. That means that in underscores this archive.php has to handle all of these different types of archives.
  2. index.php. As you can see from the template hierarchy, everything leads eventually back to index.php (that is, when Wordpress cannot find a right template file before reaching index.php, the ultimaste fallback). What isn't so obvious from this display is that index.php is also the template WordPress uses to display the blog index, which is usually the front page. So when you want to do something to the front page, if it is displaying the blog index, chances are you want to be working with index.php. In fact you can actually make an entire WordPress theme with just three files, style.css, functions.php and index.php.
  3. search.php. It shows the search results. Search results have their own template, because they have to account for searches that return no results and searches that are somehow broken

In addition to these three, there's also a template named 404.php, which handles errors. This template appears when a visitor enters or follows a link that goes nowhere.

==================================================================

58. Identify when you are on an archive page.

Github repo branch: part11_58

Before we start working with the archive templates, I need a simple method to find out if I'm currently on an index or archive page, or if I'm on a single post or single page. Now you'll remember from Part 7.37 Detect when the sidebar has widgets, we went in and augmented the classes associated with the body element on the page, to tell us whether or not there was a sidebar present, we're going to do the same thing for archive pages. Inside the inc/template-functions.php folder, we have the file extras.php, and if you scroll down here, under the pre_underscores_body_classes() you'll see we're actually already running a test to see if we're on a singular page, that would be either a post or a page, right now all that happens is the 'hfeed' class is associated with the body if we're not on a singular page.

 
function pre_underscores_body_classes( $classes ) {
  // Adds a class of hfeed to non-singular pages.
  if ( ! is_singular() ) {
  $classes[] = 'hfeed';
  }
 // Add a class telling us if the sidebar is in use.
  if ( is_active_sidebar( 'sidebar-1' ) ) {
  $classes[] = 'has-sidebar';
  } else {
  $classes[] = 'no-sidebar';
  }
 return $classes;
  }
  

I'm going to extend this, and in addition put in another class, called 'archive-view'.

 
function pre_underscores_body_classes( $classes ) {
  // Adds a class of hfeed to non-singular pages.
  if ( ! is_singular() ) {
  $classes[] = 'hfeed';
	$classes[] = 'archive-view';
  }
 // Add a class telling us if the sidebar is in use.
  if ( is_active_sidebar( 'sidebar-1' ) ) {
  $classes[] = 'has-sidebar';
  } else {
  $classes[] = 'no-sidebar';
  }
 return $classes;
  }
  

Now I can test this on my site, so here I am on the index page. I'll go inspect the content, here we have the body element and as you can see, archive-view is a class in the body element.

 
<body class="blog wp-custom-logo hfeed archive-view has-sidebar">

And then if I want to, I can also test something like a search so put in ?s=post, under a search for post, and here again it says archive-view. That means as we move forward, I can use that archive-view class to target styles for just archive pages and not single posts and pages.

==================================================================

59. Customize index and archive templates.

Github repo branch: part11_59

So far in the course, we've focused squarely on a single post and making sure the contents of that single post looks great. There's a good reason for this. Once you've styled the contents for a single post and then move onto archive pages and the index page, all that styling comes with the post. Now there's a pretty obvious reason for this. An archive page like the index page here is just a list of separate posts. So here we see the first post, the second post, the third post, and so on. Because we've already styled the content itself, once we get to this stage, we can focus on making the archive page structure look good,

but before I can start working with the archive page, I have to fix a problem I caused earlier. Notice how on the bottom here I have a scroll bar, and I can scroll way outside of the content of my post? That's because right now, we have inherited a style that shouldn't be applied to the index page. Let me show you what I mean. If I inspect the post element here and go up to the archive element, you'll see this article is currently a flex box. That's because the index page is inheriting that style we created earlier, has-sidebar .hentry, but this style should only be applied to single posts, not archive pages, so basically, my style roll was not specific enough.

So before I do anything else, let's fix this problem. You probably remember the styling question sits under sass/layout/_global.scss.

 
@media screen and (min-width: $query__medium) {
  .has-sidebar {
 .hentry {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
 .entry-header {
  width: 100%;
  flex: 1 0 100%;
  }
 .post-content {
  width: $size__ratio-large;
  }
 .widget-area {
  width: $size__ratio-small;
  }
  }
 }
  }

@media screen and (min-width: $query__medium) {
  .no-sidebar {
 .post-content__wrap {
  display: flex;
  justify-content: space-between;
 .entry-meta {
  width: 20%;
  }
 .post-content__body {
  width: 70%;
  }
  }
 }
  }

On line 2 and line 24 I add an extra class .single so that the flexbox is onluy attached to single pages with a sidebar and not on archive pages

 
@media screen and (min-width: $query__medium) {
  .single {
  &.has-sidebar {
 .hentry {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
 .entry-header {
  width: 100%;
  flex: 1 0 100%;
  }
 .post-content {
  width: $size__ratio-large;
  }
 .widget-area {
  width: $size__ratio-small;
  }
  }
 }
  }
  }

@media screen and (min-width: $query__medium) {
  .single { 
  &.no-sidebar {
 .post-content__wrap {
  display: flex;
  justify-content: space-between;
 .entry-meta {
  width: 20%;
  }
 .post-content__body {
  width: 70%;
  }
  }
 }
  }
  }
  

The first thing I want to do furter is add a gray background to the body element so everything is gray and then put a white background behind each of the posts to create clear separation between each post. Because we're now working with archives, I would like a separate partial in my Sass setups so that I can easily find it later. I'll create a new folder inside the sass/site folder, called archive. Inside archive, I'll create a new file called _archive.php. Then I'll go into _site.scss and call in the new file. See line 4 till 7 in the code below

 
/*--------------------------------------------------------------
  ## Global layouts
  --------------------------------------------------------------*/
  @import "../layout/global";

/*--------------------------------------------------------------
  ## Archives
  --------------------------------------------------------------*/
  @import "archive/archive";
/*--------------------------------------------------------------
  ## Header
  --------------------------------------------------------------*/
  @import "header/header";
/*--------------------------------------------------------------
  ## Posts and pages
  --------------------------------------------------------------*/
  @import "primary/posts-and-pages";
/*--------------------------------------------------------------
  ## Comments
  --------------------------------------------------------------*/
  @import "primary/comments";

/*--------------------------------------------------------------
  ## Footer
  --------------------------------------------------------------*/
  @import "footer/footer";
code 11.59.3. The new sass/site/_site.scss file

So I want to make the next changes in the index and archive template:

  1. Change the backgroun color to grey
  2. Put a white background behind each of the posts to create clear separation between each post
  3. Create padding around the post content because right now, this looks pretty tight and weird. But I'm not going to do that just to the post element because I know in the future, I'll want to add featured images, and I want the featured images to span the full width of this white box, so I'm going to add a wrapper around the post elements.
  4. I want to get rid of the tags on the bottom of the posts. So I'll go back to content.php and find the tags. I know that they're housed inside the pre_underscores_entry_footer() function. So I'll just take out the footer entirely.
  5. Finally, I want to add the sidebar next to the content because we're on a wide screen. So right now, the sidebar is setting all the way down here. I want to float it up, and the good news is unlike in the single posts where we had a crazy layout and we had to restructure everything, here the layout is pretty straightforward. If I inspect the article, you'll see the article sits inside a div with id primary and a class content area.

59.1 Change the background color to grey.

In sass/site/archive/_archive.scss, I add the following rule:

.archive-view {
  background-color: #eee;
}
  

59.2 Change the background color of the posts to white.

In sass/site/archive/_archive.scss, I add the following rule:

.archive-view {
  background-color: #eee;
 .post {
  position: relative;
  background: white;
  }
}

59.3 Create padding around the post content.

To do that I need to find a file that generates these posts. So I'll go to index.php. That's the current template I'm using. Here, I call template-part/content.php. That's the file we looked at previously. So inside content.php, I'll just add a new div for the class post_content. Then I'll indent all the stuff here all the way down to the footer and close my div.

 <?php
  /**
  * Template part for displaying posts
  *
  * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
  *
  * @package Pre_Underscores
  */
 ?>
 <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
  <div class="post__content"
  <header class="entry-header">
  <?php pre_underscores_the_category_list();?>
  <?php
  if ( is_singular() ) :
  the_title( '<h1 class="entry-title">', '</h1>' );
  else :
  the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
  endif;
 if ( 'post' === get_post_type() ) : ?>
  <div class="entry-meta">
  <?php pre_underscores_posted_on(); ?>
  </div><!-- .entry-meta -->
  <?php
  endif; ?>
  </header><!-- .entry-header -->
 <?php pre_underscores_post_thumbnail(); ?>
 <div class="entry-content">
  <?php
  the_content( sprintf(
  wp_kses(
  /* translators: %s: Name of current post. Only visible to screen readers */
  __( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'pre_underscores' ),
  array(
  'span' => array(
  'class' => array(),
  ),
  )
  ),
  get_the_title()
  ) );
 wp_link_pages( array(
  'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'pre_underscores' ),
  'after'  => '</div>',
  ) );
  ?>
  </div><!-- .entry-content -->
 <footer class="entry-footer">
  <?php pre_underscores_entry_footer(); ?>
  </footer><!-- .entry-footer -->
  </div>
  </article><!-- #post-<?php the_ID(); ?> -->
  

Then I can go back to _archive.scss and add the 'post__content' class:

 .archive-view {
   background-color: #eee;
  .post {
   position: relative;
   background: white;
   }
  .post__content {
   padding: 2em 2em 3em;
   }

59.4 Get rid of the tags on the bottom of the posts.

So I'll go back to content.php and find the tags. I know that they're housed inside the pre_underscores_entry_footer() function. So I'll just take out the footer entirely. Now template-parts.php looks like:

<?php
  /**
  * Template part for displaying posts
  *
  * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
  *
  * @package Pre_Underscores
  */
 ?>
 <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
  <div class="post__content"
  <header class="entry-header">
  <?php pre_underscores_the_category_list();?>
  <?php
  if ( is_singular() ) :
  the_title( '<h1 class="entry-title">', '</h1>' );
  else :
  the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
  endif;
 if ( 'post' === get_post_type() ) : ?>
  <div class="entry-meta">
  <?php pre_underscores_posted_on(); ?>
  </div><!-- .entry-meta -->
  <?php
  endif; ?>
  </header><!-- .entry-header -->
 <?php pre_underscores_post_thumbnail(); ?>
 <div class="entry-content">
  <?php
  the_content( sprintf(
  wp_kses(
  /* translators: %s: Name of current post. Only visible to screen readers */
  __( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'pre_underscores' ),
  array(
  'span' => array(
  'class' => array(),
  ),
  )
  ),
  get_the_title()
  ) );
 wp_link_pages( array(
  'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'pre_underscores' ),
  'after'  => '</div>',
  ) );
  ?>
  </div><!-- .entry-content -->
 
  </div>
  </article><!-- #post-<?php the_ID(); ?> -->

59.5 Add the sidebar next to the content.

If I inspect the article, you'll see the article sits inside a div with id='primary' and a class content-area. And this div sits next to the .secondary element.

<div id="content" class="site-content">
 	<div id="primary" class="content-area">
     </div><!-- #primary -->

 	<aside id="secondary" class="widget-area">
	 </aside><!-- #secondary -->
</div>

That means if I take the .site-content element and set that to display:flex, then the items within site-content should flex left and right, and then I just set the content-area width and the widget area width, and I should be good to go.

.archive-view {
  background-color: #eee;
 .post {
  position: relative;
  background: white;
  }
 .post__content {
  padding: 2em 2em 3em;
  }
 @media screen and (min-width: $query__medium) {
  &.has-sidebar {
  .site-content {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  }
 .content-area {
  width: $size__ratio-large;
  }
 .widget-area {
  width: $size__ratio-small;
  }
 }
  }
  }
 

Save again, go back in the browser, and now we have a nice responsive layout with a sidebar on the right hand side and the content on the left hand side, and if I reduce the width of the screen, sidebar drops down to the bottom, everything still works the way it's supposed to, and because I did this only in content.php and the archive styles that apply to all archives.

 

==================================================================

60.Add a custom Read More link to index posts.

Github repo branch: part11_60

Now we can start customizing our index and archive pages. And I want to start with navigation. When you go to typical blogs, or websites in general, you'll find that the only way of getting to a post is by clicking directly on the post title. Now, we know that's the way it works, but that's jut because we're used to it. It's not actually a good design pattern, because it doesn't tell people explicitly, "click here, go to the post". So what I want to do is add a link at the bottom of each of these containers down here in the right-hand corner that says something like "continue reading," but I have to make sure that link is fully accessible so that people who are accessing my site using a screen reader will also be able to get the necessary information to understand where that link is pointing.

Each of the posts in the archive and index pages are generated using content-php, so that's where I'll add my button. I want the button to be at the very bottom, so I'll go down here, just above </div><!-- .post__content --> and add the following code:

<div class="continue-reading">

<a href="<?php echo esc_url( get_permalink() ) ?>" rel="bookmark">
<?php echo $read_more_link; ?>
</a>

</div><!-- .continue-reading -->

Save, go back in the browser. Now I have a link here, and if I click on the link, I'm taken to the post.

Great, but there's a bit of a problem. If you can image accessing this site using a text-to-speech browser right now. When you got to this post, you would first get "uncategorized, "Link", "template", "Link", "Theme demos", "Link", "January 7th, 2012", "Link", "Edit", "Link", "Post class", "Link", "Continue reading", "Link". The problem here is "continue reading" doesn't tell the visitor enough about what is actually going on. So I need to upgrade the text within this button to also contain extra information for people who are also using screen readers. The good news is, this problem has already been solved in this template. If you look up here to the function called the_content, that outputs the content, it's set up to account for situations where someone has put the "more" tag in the content.

Meaning the content gets truncated and you get a link at the end of the content that says "continue reading." See, down here it says "continue reading." But if you look at the mark-up here, you see there's something else going on. It says "continue reading %s" and this "dollar sign s" points at the next element in the set-up, which happens to be the title. The title is put inside a span with a class "screen reader text," and then output. So if you use a screen reader, you would get "continue reading," and then the title. That's exactly what I want.

So I copy the following code

sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers */
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'pre_underscores' ),
array(
'span' => array(
'class' => array(),
),
)

Copy it, go into 'continue reading.' and paste the code as follows

<div class="continue-reading">
<?php
$read_more_link = sprintf(
/* translators: %s: Name of current post. */
wp_kses( __( 'Continue reading %s', 'pre_underscores' ), array( 'span' => array( 'class' => array() ) ) ),
the_title( '<span class="screen-reader-text">"', '"</span>', false )
);
?>

<a href="<?php echo esc_url( get_permalink() ) ?>" rel="bookmark">
<?php echo $read_more_link; ?>
</a>
</div><!-- .continue-reading -->

Save that, go back to the browser one more time, and now we can inspect this element and you'll see there's been a subtle change. Inside the anchor, we now have the text "continue reading" that you can see in the browser, and then we have a span with a class screen reader text that is hidden from the browser that spells out the title of the post, for instance "Hello World."

Now we have the mark-up we want. That means it's time to put styles to it. To sass/site/archive/_archive.scss I added the following rules:

.continue-reading {
  position: absolute;
  right: 0;
  bottom: 0;
  font-family: $font__sans;
 a {
  display: block;
  padding: .5em 1em;
  font-size: 90%;
  text-decoration: none;
  background: hsl(0, 0%, 85%);
 &:focus,
  &:hover {
  color: white;
  background: $color__interactive;
  }
  }
}

Back in the browser a final time, scroll down and here we find the button in the bottom right-hand corner. Hover over it, turns red. Click on it, takes you to the post.

==================================================================

61. Display excerpts in indexes and archives.

Github repo branch: part11_61

The index and archive templates and underscores are set up to display the full post content for each post. That's fine for some designs and not so fine for others. In my design, I only want to display an excerpt for each post and then you have to click on continue reading to see the entire post. Now this is a design decision. Some people agree with this and some people disagree, so I'll give you both options here. I'll show you how to do this with excerpts and then you can choose if you want to keep the content intact or if you want to just show excerpts. Out of the box, underscores uses the_content to display the content.

If you want to show excerpts instead, you swap out the_content for the_excerpt. It's really that simple. Inside content.php, I find the call to the_content and remove the codesection as in code 11.61.1 below

the_content( sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers */
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'pre_underscores' ),
array(
'span' => array(
'class' => array(),
),
)
),
get_the_title()
) );
code 11.61.1. remove this code from content.php

And replace it with:

the_excerpt();

Save. Back in the browser. And now the posts are much shorter, because we are now displaying excerpts

Now, like I said, this is a design decision. You'll find that a lot of magazine-style themes will do this. They'll only display an excerpt while other types of themes, usually blog-centric themes, will display the full content. Personally, I prefer themes that display just excerpts, because otherwise you have to scroll past huge amounts of content to get to the next item, but that is just a personal preference. Now that you know that both of these functions exist, you can choose to use them side by side.

There are several different ways you can do that. One is to create a customizer function that toggles either the excerpt or the content on and off, so the site owner can choose whether they want to display all of the content or just the excerpts. Another is to say display the first post on an index page as full content, and then display the excerpts for the next ones and so on. Because you have both of these functions available, you can come up with pretty much any configuration you want. Just make sure you don't use the_excerpt and the_content at the same time, otherwise they'll be duplicating content.

==================================================================

62. Customize the excerpt output.

Github repo branch: part11_62

While we're on the topic of excerpts, let me show you two things you can do to customize the excerpt output. The first is to change the truncation mark that appears at the end of an excerpt, when the post is longer than the default excerpt length. You see that by default it displays this square bracket then an ellipses and then another square bracket, which is fine but I think it looks a little bit weird so I want to replace that with just an ellipsis. To do that I need to hook into an existing filter, so I'll open the inc/template-tags.php file. I Scroll all the way to the bottom. Scroll all the way to the bottom.

/**
  * Customize ellipsis at end of excerpts.
  */
  function pre_underscores_excerpt_more( $more ) {
  return "…";
  }
  add_filter( 'excerpt_more', 'pre_underscores_excerpt_more' );

  

And of course you could also pass a function, so if you don't have the continue reading link down at the bottom here, you could create a function that outputs a continue reading link and then that would be displayed in its place.

That was the first customization. The second has to do with the length of the excerpt. By default, the excerpt length in Wordpress is 55 words. That means if the post is longer than 55 words, it'll get this truncation at the end and you'll have to go into the post to read the rest of the content. However, if the post is shorter than 55 words, it'll just be displayed in its entirety like you can see down here in the Hello world! post.

To change the excerpt length, I need to hook into another filter. Back in template tags, I'll create a new section. Then just like before I'll create a function, humesscores_excerpt_length. humesscores_excerpt_length. humesscores_excerpt_length. Here I'll grab the length property and return an actual length. So that will be a number. In my case that is 100. Then just like before, I add a filter.


/**
  * Filter excerpt length to 100 words.
  */
  function pre_underscores_excerpt_length( $length ) {
  return 100;
  }
  add_filter( 'excerpt_length', 'pre_underscores_excerpt_length');
  

Go back in the browser, and now you'll see the excerpt up here is much longer.

Now there's one important thing to keep in mind here. The excerpt length does not impact custom excerpts. So if I go into a post, and then click 'edit post', and go to screen options to make sure excerpt is available. If I then type in an excerpt in the exerpt form that is much longer than 100 words it will still display in its entirety, because once you fill out this excerpt form, that text overrides the native functionality of Wordpress. However, if the excerpt is auto-generated it'll be truncated at whatever number you put in that custom function. So now you know two simple but powerful ways of customizing the excerpt output to make it fit with your specific needs.

==================================================================

63. Add featured images to index and archive pages.

Github repo branch: part11_63

In the posts on our index pages is one obvious missing component. If I go into this single post (also see Part 9: all about featured images) you'll see here we have that giant featured image we added. And I want that featured image to appear in the posts on the index pages as well.

In content.php, I first need to figure out where I'm going to place the featured image and in this case, I want it to be outside the

container so that it floats up and fills out the entire space. Then, I'll change the call to the specific featured image 'pre_underscores-index-img' because I don't want the size that we'd created for that full-bleed display like in the content-single.php. I also need to change the featured image class . So here, instead of saying full-bleed, I'll call it index-image.

<?php
if ( has_post_thumbnail() ) { ?>
<figure class="featured-image index-image">

<?php
the_post_thumbnail('pre_underscores-index-img');
?>

</figure><!-- .featured-image full-bleed -->
<?php } ?>

And now I can test to make sure this actually works. So I'll just save, go back to the browser and the featured image appears. Now I need to change its behavior because once you add a featured image to a post like this, people will expect to be able to click or touch the image and go to the post, so I need to wrap the image in a link. Back in content.php, I already have the link established, just go all the way to the bottom. You'll remember we created the link when we created that continue-reading button. So I'll just grab the link from here, copy, then go up and place it inside the figure, so that it wraps around the image, indent image and the anchor.

<?php
if ( has_post_thumbnail() ) { ?>
<figure class="featured-image index-image">
<a href="<?php echo esc_url( get_permalink() ) ?>" rel="bookmark">
<?php
the_post_thumbnail('pre_underscores-index-img');
?>
</a>
</figure><!-- .featured-image full-bleed -->
<?php } ?>

Save that, go back in the browser, and now I'll be able to click on the image to go to the post.

That leaves only two steps.

  1. First, I need to specify a custom size for this image so that we are not loading in way too big images to be displayed inside this container. That means I need to figure out how wide the image is at its widest when it's being loaded into the page. If I inspect this element here, then I can mess around with the browser to find out roughly where the breakpoint is, somewhere around here, and then see how big this image is right now. So it's almost 900 pixels wide.Then I'll go into functions.php and find where I defined my image sizes. I'll add a new image_size, call it pre_underscores-index-img. I'll set the width to 9800 pixels and the height to 450 and set the crop value to true. Save that.
    add_image_size( 'pre_underscores-index-img', 900, 450, true );
    
    Now of course, once I generate a new custom image size, I also have to tell WordPress to generate that image size for me. So I'll go to the back in the WordPress, go to Tools and Regenerate Thumbnails, click Regenerate All Thumbnails, so we get all the new image sizes we need. When the process is done, we can jump back to the front page to make sure it's displaying properly.
  2. And then the final step is to apply some basic CSS, because here we have to make sure that if the image is not wide enough to fill out the available space, it still centers properly. While we're at it, I'll also add a little hover effect so when you hover over the image, you can clearly see that you are, in fact, hovering over the image. I'll add those styles under archive, so I'll go to sass/site/archive/_archive.scss and add it. All I need is .index-image.
    .index-image {
    img {
    display: block;
    margin: 0 auto;
    }
    
    a {
    &:focus > img,
    &:hover > img {
    opacity: .8;
    }
    }
    }
    

That really is all there is to it. Now we have featured images that take us directly to the post and they'll always be displayed correctly no matter what the screen size.

==================================================================

64. Add more meaningful archive navigation.

Github repo branch: part11_64

Scroll to the bottom of any index or archived page in WordPress, and if more posts are available you'll get some form of navigation. Out of the box, underscores will display this link that says simply "Newer posts" or Older posts" It's styled exactly like the post navigation. You'll remember inside a single post, you'll have navigation to the previous and next posts, and if you click on Older posts, you're taken to page number two of the index. This works fine, and this is the standard way of doing it in WordPress themes.

However, I don't think this is a good user experience. It doesn't tell the visitor anything about how many pages are available, nor does it say anything about where you are in the chronology. Ideally, what I would want is some sort of navigation that tells me how many pages are available and allows me to click on any of those pages, so one, two, three, four, five, six, seven, and then maybe even has a link on either end that says older or newer posts.The good news is, WordPress can do this out of the box, we just have to call the correct function. That function is this one the_posts_pagination(), also see https://developer.wordpress.org/reference/functions/the_posts_pagination/.

So let's see how that works. The navigation for the index page is managed from index.php. Hete I'll change:

the_posts_navigation();

into:

the_posts_pagination();

Save it, go back and reload the page, and scroll to the bottom. And here you see a completely different experience, so now it says Previous 1 2 3 4 and Next.

This is exactly the navigation that I want, but before I select it, I need to make sure this looks good even if there are a lot of pages, so I'm going to change a setting in WordPress, so that we get more links down here. First go to the backend, and then go to Settings, and Reading. Here I can decide how many posts to show in any index page, and the default is set to 10. I'll change that to one. That way for each index page, we just get one post, and that should give us a lot of navigation links on the bottom. Jump back to the front page, scroll to the bottom, and here we now have, 1 2 ... 39 and Next

Now I just need to customize the function, so I control what these buttons say, Previous and Next, and so that these strings are translatable. The the_post_pagination(), can take an array of arguments, and those arguments include the text that is inside the buttons that point to the previous and next posts. The naming of the arguments for the previous and next buttons, and quite frankly, the previous and next buttons themselves is a bit counterintuitive, so let me show you how to get this right. The button on the left that brings you forward in the chronology of posts to newer posts says previous by default and has the name prev_text. We'll change that to Newer, so it's much clearer what's going on here, and I'll make that translatable. The button on the right, which takes you backwards in the chronology to older posts says next by default and has the name next_text. We'll change that to Older.

the_posts_pagination( array(
'prev_text' => __( 'Newer', 'pre_underscores' ),
'next_text' => __( 'Older', 'pre_underscores' ),
'before_page_number' => '<span class="screen-reader-text">' . __( 'Page ', 'pre_underscores' ) . '</span>',
));

While I'm in this array, I'm also going to use an additional argument to make this more accessible. I want to add a span before the current page number and add in the text "Page" next to it, so someone with a screen reader will hear the words, "Page two," or "Page 25," when they're on page two or page 25. I can do this using the argument before_page_number. Here I would need to insert a span with a class screen-reader-text. Then a translatable string, and the string should say "page space" and finally just close the span. If you want the fullest of arguments, you can pass to the_post_pagination(), go check out the developer reference for this function.

All right. Save this code, go back in the browser, and now it says Newer and Older at the beginning and end of this navigation, which makes a lot more sense when you think about the posts as a chronology.

I can add styles to it, which I will add in the sass/navigation/_content-navigation.scss file.

.pagination {

	font-family: $font__sans;

	.nav-links {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	}

	a,
	span {
	padding: .5em 1em;
	background: white;
	}

	a {
	text-decoration: none;

	&:focus,
	&:hover {
	color: white;
	background: $color__interactive;
	}
	}

	.current {
	font-weight: 600;
	color: $color__interactive;
	}
}

Pagination is the class name that wraps around this pagination navigation that's injected automatically by WordPress, and these styles will ensure it lays out properly. All I've done here is aligned the nav-links using flex box, so they lay out nicely, and then I've highlighted the focus and hover states for each of the links and the current button with the interactive color, so it matches with the styling for the rest of the site. Save that. Go back in the browser, and now we have proper navigation, styled to match the rest of the site that's easy to use and easy to understand and that's fully accessible to anyone.

==================================================================

65. Highlight sticky posts.

Github repo branch: part11_65

You may have noticed that the first post on the index page is called Template: Sticky, and the publishing date for it is January seventh, 2012. When I scroll down, the next post is published on November 29th, 2016, and this is the blog page which should be displaying the latest posts first.

This literally means the post has been stuck to the front page. You can stick as many posts as you want to the front page and they will always display above the regular reverse chronological order. But there's no way you wouldn't know this was a sticky post except for the fact that the title literally says it's a sticky post. And normally when you create a sticky post you do not say, "This is a sticky post, here's the title." So we need to add some sort of feature into our theme that indicates this is a sticky post in a subtle and nice looking way. And here I want to add a folded corner to the top right hand corner. To do so, I need to be able to target the sticky post. And the good news is this post, the <article> element has a class sticky appended to it. Looking in the code inspector I see:

<article id="post-1241" class="post-1241 post type-post status-publish format-standard has-post-thumbnail sticky hentry category-uncategorized tag-sticky-2 tag-template">
code 1.65.1. code inspector: article element has a .sticky class.

I want to create a pseudo element and shove it up in the corner, and then apply some styling to make it into a folded corner.To sass/site/archive/_archive.scss I add the following rule:

.sticky::before {
content: "";
display: block;
width: 2em;
height: 2em;
position: absolute;
top: 0;
right: 0;
border-width: 0 2em 2em 0;
border-color: #eee #eee white;
border-style: solid;
box-shadow: -1px 2px 2px hsla(0, 0%, 10%, .1);
}

Now, everyone can see that there's something special about this post and it looks like it's been stuck on the page so clearly, it's a sticky post.

==================================================================

66. Customize archive pages.

Github repo branch: part11_66

So far, we've been working with single posts and the index template. Now, let's take a look at the archive templates. There are many different archives available: category archives, post author archives, date archives and so on, and they all have pretty much the same structure. When you go to any archive page, you get the archive title at the top, so, for example: category: uncategorized, author:somebody, tag: something, etc. In some cases, the categories or tags will have descriptions associated with them that display directly under the title. Now that the index page is working the way we want, we need to fix up this archive page, because, as you can see, it looks a little disjointed, with the title on to the left-hand side, and then the sidebar on the right is not lining up right.

I want the archive title to span the full width of the screen, and also, the archive description if it's available, and we can do that by changing a little bit of the markup in archive.php. This is the file that powers all the archive pages, except for the index page, and when we go into this template, you'll see, it looks pretty much identical to the index.php template, the only difference is, the page header that displays the archive title, right here:

<header class="page-header">
<?php
the_archive_title( '<h1 class="page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );
?>
</header><!-- .page-header -->

and the archive description in the bovenstaande <header> element. The reason why this title and description are currently nested along with the rest of the content is because it is literally nested inside the container that holds the content area. That means, all I need to do to move it outside is just take this content, copy it, paste it outside the container, like so:

<?php
  /**
  * The template for displaying archive pages.
  *
  * @link https://codex.wordpress.org/Template_Hierarchy
  *
  * @package Humescores
  */
get_header(); ?>
<?php
  if ( have_posts() ) : ?>
 <header class="page-header">
  <?php
  the_archive_title( '<h1 class="page-title">', '</h1>' );
  the_archive_description( '<div class="archive-description">', '</div>' );
  ?>
  </header><!-- .page-header -->
<?php endif; ?>
 <div id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
 <?php
  if ( have_posts() ) : ?>
 <?php
  /* Start the Loop */
  while ( have_posts() ) : the_post();
 /*
  * Include the Post-Format-specific template for the content.
  * If you want to override this in a child theme, then include a file
  * called content-___.php (where ___ is the Post Format name) and that will be used instead.
  */
  get_template_part( 'template-parts/content', get_post_format() );
 endwhile;
 the_posts_pagination( array(
  'prev_text' => __( 'Newer', 'humescores' ),
  'next_text' => __( 'Older', 'humescores' ),
  'before_page_number' => '<span class="screen-reader-text">' . __( 'Page ', 'humescores' ) . '</span>',
  ));
 else :
 get_template_part( 'template-parts/content', 'none' );
 endif; ?>
 </main><!-- #main -->
  </div><!-- #primary -->
<?php
  get_sidebar();
  get_footer();
  

Now, the title and description take up the full width of the screen, but it's shifted off to the right-hand side. Now, that has a simple explanation. If we go up here, until we find the site content container, you'll see that this is applying display flex to everything, and justifying the content. So this item is trying to flex with the rest of the content, and not doing a very good job at it. That's easy enough to fix, we just have to tell it it's supposed to be full width.

Then I'll put in a new rule for the page header, set width to 100 percent, and flex to one, so it can grow, zero so it can never shrink, and flex base is to 100, so it'll take up the full available space. Save, go back, and now, the title and description take up the full width. Then, I can style these elements just a little bit to make it look less messy. Back in archive.scss, I'll scroll down past that first section and then create a new rule for page header. Set the font family to font sans, then I'll create rules for the page title, set margin to zero at the top, zero left and right, and .5 ems on the bottom. That cleans it up a little bit, and then I also have to deal with this description down here. I'll take a look and see, that one has the class archive description. Let's set margin for that one to maybe minus one on top, zero and two ems on the bottom, let's just try and see what that looks like. That looks okay,

.archive-view {
	background-color: #eee;

	.post {
	position: relative;
	background: white;
	}

	.post__content {
	padding: 2em 2em 3em;
	}

	@media screen and (min-width: $query__medium) {
	&.has-sidebar {
	.site-content {
	display: flex;
	justify-content: space-between;
	flex-wrap: wrap;
	}

	.page-header {
	width: 100%;
	flex: 1 0 100%;
	}
	.content-area {
	width: $size__ratio-large;
	}

	.widget-area {
	width: $size__ratio-small;
	}

	}
	}
}
code 11.66.3 The new .archive-view class added to sass/site/archive/_archive.scss

==================================================================

67. Customize the search results page.

Github repo branch: part11_67

There's one more archive page we have yet to address. That is the search results page. Now the search results page needs its own template because it's generated in a different way from all the other archives. It's generated based on user input, so you type in your search, and then you get a search result. You can get to the search result archive in two ways, either add the search widget to the sidebar and then type in a search, or simply go to the address bar, and type in '?s=' , and then whatever your search is going to be. So first, I'll search for the word post, because I know there's a bunch of posts in the theme unit test data that have the word post in them. So I enter '?s=post' into the location bar

This gives me the search results page, and right away you see there's something really wrong here. First of all, we have that same problem where the search title not spanning the full width. That's easy enough to fix. Go to the theme, go to search.php, which is the template we're currently looking at, then just grab the header here, which is pretty much identical to what we had in the archive.php page, paste it up above the rest of the content. Now search.php looks like:

<?php
  /**
  * The template for displaying search results pages.
  *
  * @link https://developer.wordpress.org/themes/basics/template-hierarchy/#search-result
  *
  * @package pre_underscores
  */
get_header(); ?>
<?php
  if ( have_posts() ) : ?>
 <header class="page-header">
  <h1 class="page-title"><?php printf( esc_html__( 'Search Results for: %s', 'humescores' ), '<span>' . get_search_query() . '</span>' ); ?></h1>
  </header><!-- .page-header -->
<?php
  else :
 get_template_part( 'template-parts/content', 'none' );
  return;
endif; ?>
 <section id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
 <?php
  /* Start the Loop */
  while ( have_posts() ) : the_post();
 /**
  * Run the loop for the search to output the results.
  * If you want to overload this in a child theme then include a file
  * called content-search.php and that will be used instead.
  */
  get_template_part( 'template-parts/content' );
 endwhile;
 the_posts_pagination( array(
  'prev_text' => __( 'Newer', 'pre_underscores' ),
  'next_text' => __( 'Older', 'pre_underscores' ),
  'before_page_number' => '<span class="screen-reader-text">' . __( 'Page ', 'pre_underscores' ) . '</span>',
  ));
 ?>
 </main><!-- #main -->
  </section><!-- #primary -->
<?php
  get_sidebar();
  get_footer();
code 11.67.7 The new search.php

That puts the header where it's supposed to be, but it doesn't solve the bigger problem of the post looking all weird. Now you probably think that there's something wrong with the css. Bit that's not what's happening. Take a look at the markup for search dot php and look at where it's getting its content from: from template- part/content-search.php. And inside content-search.php, there's a significant difference.

You'll remember that in content.php, we added a new container: <div class="post__content">. That creates that padding around the content. That's missing in content-search.php, of course, cause we haven't edited yet. But that doesn't answer the more important question. Why does underscore have a separate template for search content if it's displaying the same content on the front end? Well, it has a really simple reason. You'll remember that content.php originally displayed the full content using the function the_content().

By contrast, content search displays an entry summary using the_excerpt(). So this is how underscores differentiated between regular archive pages, where the full content is displayed, and search results, where you only see the excerpt. In our theme, we don't need a separate template for this because the content is already being displayed as an excerpt in all archives, so I'm just going to get rid of this entire file. I'll delete content-search.php. When I do so, and go back, you'll see the page still works just fine, and now we have the correct template.

That's because this function here inside search dot php says get the template part called template parts slash content search if it exists. If content search does not exist, then fall back to just content, which is the one we already have. But, I don't need to refer to this search anymore, 'cause I'm not using it, so I'm just going to delete that out of the template so that it's nice and uncluttered.

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

That changes nothing on the front end. Now posts display exactly as we want them in search results. But, search results can also return pages. So let's change the search to '?s=page", and see what happens. And here things are not okay. As you can see, the page is sort of formatted the same. We have the same styling on it, but the continue reading button is all the way over here on the right hand side. There's no white box behind the content, and it just looks kind of wonky. This time, the problem is in the css.

If we go to the styles for the archive, you'll remember that we targeted post, then set the position to relative, and the background to white. These aren't posts. They're pages. So if we inspect this <article> element, you'll see the article has the class .page.Easy enough to fix. We'll just add it to this rule here, page.

.post,
.page {
position: relative;
background: white;
}

Save. And now the pages look okay. Of course, it looks a little bit different. That's because pages don't have the meta content, like author and date, and that's fine: content.php is already accounting for that. So when we scroll down, you'll see it says:

if ( 'post' === get_post_type() ) : ?>
<div class="entry-meta">
<?php pre_underscores_posted_on(); ?>
</div><!-- .entry-meta -->
<?php
endif; ?>

if get_post_type is post, then display entry meta. Otherwise, don't. So we're a page, we don't display the meta data at all. Alright, so now our search results look good for both posts and pages.

But if we scroll down to the bottom, wouldn't you know it? Here we have that old older posts, newer posts navigation again. Now, you already know how to fix this, and it's pretty straight forward. Go back to the code editor and search.php. Here, if you scroll down, we'll find that old familiar the_posts_navigation() function. And we can replace this with the code we put in, either archive.php or index.php: namely the_post_pagination() function. So copy it out, paste it into search.php, just like we did before. And, as a result, we get proper pagination navigation at the bottom of the search page.

And because this code is now in search dot php, you can now change the words in the pagination here if you want to to make it match better with your search. But I'm going to leave that alone.

With the pagination navigation in place, we are almost done with the search page. But there's one scenario we have yet to account for. What happens if we make a search that returns nothing? It's easy enough to test. You go up in the address bar and just type in some garbage and hit enter. And then, instead of that regular search archive, we get this really boring page that says "nothing found". Sorry, but nothing matched your search terms. Please try again with some different keywords. And there's a basic search field beneath it. Now, where's this coming from?

If we go up to our (plugin Show Current Template in the Wordpress administration toolbar) menu, you can see that this content is generated by a file in template parts called content-none.php.

Back in search.php, you can see exactly how this works. So, as we started a top of the template, we ask WordPress, do we have posts? And if we have have posts, we loop through each of the posts and output them through template parts content dot php, and then put in post pagination.

<?php
  if ( have_posts() ) : ?>
 <?php
  /* Start the Loop */
  while ( have_posts() ) : the_post();
 /*
  * Include the Post-Format-specific template for the content.
  * If you want to override this in a child theme, then include a file
  * called content-___.php (where ___ is the Post Format name) and that will be used instead.
  */
  get_template_part( 'template-parts/content', get_post_format() );
 endwhile;
 the_posts_pagination( array(
  'prev_text' => __( 'Newer', 'pre_underscores' ),
  'next_text' => __( 'Older', 'pre_underscores' ),
  'before_page_number' => '<span class="screen-reader-text">' . __( 'Page ', 'pre_underscores' ) . '</span>',
  ));
 else :
 get_template_part( 'template-parts/content', 'none' );
 endif; ?>

But, if we don't have any posts, instead we go to

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

If we go to archive.php, you'll see the same exact structure. If have posts, while have posts, the post, and then we loop through template part navigation. Then, if we don't, we get content-none.php. And again, same for index.php.

Looking at content-none.php, you can see that output we saw on the front end. Here we start by setting up a page header that spells out nothing found. Then there's some different fallbacks for different kinds of content, depending on what scenario you're in. So if you're on search, it says nothing found for you search terms. If you haven't posted anything on the site yet, it'll ask you, are you ready to publish your first post, and give you a link to the post editor. And if there's some other scenario where something goes wrong, you just get the message: It seems we cannot find what you're looking for. Try making a search.

<?php
  /**
  * Template part for displaying a message that posts cannot be found
  *
  * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
  *
  * @package Pre_Underscores
  */
?>
<section class="no-results not-found">
  <header class="page-header">
  <h1 class="page-title"><?php esc_html_e( 'Nothing Found', 'pre_underscores' ); ?></h1>
  </header><!-- .page-header -->
 <div class="page-content">
  <?php
  if ( is_home() && current_user_can( 'publish_posts' ) ) : ?>
 <p><?php
  printf(
  wp_kses(
  /* translators: 1: link to WP admin new post page. */
  __( 'Ready to publish your first post? <a href="%1$s">Get started here</a>.', 'pre_underscores' ),
  array(
  'a' => array(
  'href' => array(),
  ),
  )
  ),
  esc_url( admin_url( 'post-new.php' ) )
  );
  ?></p>
 <?php elseif ( is_search() ) : ?>
 <p><?php esc_html_e( 'Sorry, but nothing matched your search terms. Please try again with some different keywords.', 'pre_underscores' ); ?></p>
  <?php
  get_search_form();
 else : ?>
 <p><?php esc_html_e( 'It seems we can&rsquo;t find what you&rsquo;re looking for. Perhaps searching can help.', 'pre_underscores' ); ?></p>
  <?php
  get_search_form();
 endif; ?>
  </div><!-- .page-content -->
  </section><!-- .no-results -->
  

This works. But as you can see from the front end, it's pretty boring. So in the next movie, we'll look at how to change this entire functionality around handling search results with no results, and we'll also bundle in other things, like 404 pages and other errors that may occur in the theme.

==================================================================

68. Customize the 404 error page and empty search results

Github repo branch: part11_68

Compared to the rest of the templates you get from underscores, the Nothing Found template leaves a little bit to be desired. So, in this part I provided a radically different approach to this entire problem. There are a couple of different situations where we may end up with this Nothing Found template.

  1. When you make a search that returns nothing.
  2. when you try to go to a page that doesn't exist, so you put in an incorrect URL
  3. The very rare case where you set up a Wordpress site that has absolutely no content and they need to be notified, hey, there's no content here, maybe you should actually build some content.

The way underscores deals with this out of the box is by testing to see if there is available content, and if not, we still set up the overall structure of the page, but we redirect the actual content section to a file called content-none.php. But that returns the mentioned 'boring' page. Structurally, it's very hard to work with that approach, because we want this title here to break out above the rest of the content, and we also don't really have any contextual information. So here's what I want to do instead, when you don't find anything, you should get notified, you didn't find anything and you should get a search box, but you should also get the six most recent posts because chances are, if people are coming to your site and just randomly looking for something, they're probably looking for the most recent content you published.

What does that look like? Well, let's take a look. ?s=randomsearch, and here is the result of my approach.

Nothing found for, and then your actual search term, then you get a red box at the top, sorry, but nothing matched your search terms. Please try again with some different keywords. Here you have a search field, and when you scroll down, you get a list of the six most recent posts. To get this to work, I've completely rewired the entire functionality for this.

So in search.php, I start out by testing if have_posts(), if we do, then I display the page header, if I don't, I get down where we say else, then I go get the template-part/content-none.php, and return. That means the rest of this template never runs at all. What I've done here is move the else statement out of the overall post content, you'll remember, it used to be down here below the loop, and then instead, I generate the entire post in content-none.php.

So when you look at content-none.php, you'll see here we have all the sections that we normally have over both the index template and the content template. We start with a header, and here we have a bunch of conditions that output different types of headers depending on where we are, so if it's on a 404 page, we get page not available, if it's on a search, we get nothing found for, and then the search, and if it's something else we just get nothing found, then below we have a section that's just a primary section and the content area, and we add additional classes through, so if it's a 404 page, we get error 404, if it's a search page, we get no results, and otherwise we get not found.

Then we populate a box with the class page-content, and here we output the actual text, so either "ready to publish your first post", or "sorry, but nothing matched your search terms", or "you seem to be lost, to find what you are looking for", or something else. Then, if we are either on the 404 page or on the search results page, we set up a new section. Here, it starts with an <h2> with a class secondary-title that just outputs the text most recent posts. This is followed by a new query, where we ask the database for the six most recent posts, we run that query and use our regular template-parts/content to display the content. Finally, we reset the post data, post main and section, and display the sidebar and footer like normal.

Again, the result is what you see in the image above, nothing found for search term, and a box telling you what's going on, followed by the six most recent posts. And this also works if you just put in a garbage URL, you get page not available, customized message and then the search box. Now because I rewired this completely, I also have to rewire all the other index templates.

So if we look into the ones we already worked with, you'll see that archive.php now has the same structure at the top, we test to see if we have the post, if not, we get the template part content none, and return, and in index.php, I've rewired it slightly differently, so we start out by asking, do we have posts? If so, we run the regular template all the way down, then I've moved the else statement out from inside the content down here to the bottom, then I say, if we don't have any content, then bypass this entire template, and just output content none and step. Like I said, this is a fundamentally different approach from what underscores serves up, and it's highly opinionated.

Finally I added a new rule in sass/site/primary/_posts-and-pages.scss

 
.no-results .page-content{
 background-color: $color__interactive;
  color: white;
  padding:1em;
 
  }
code 11.68.1 Rule added to sass/site/primary/_posts-and-pages.scss
<?php
  /**
  * The template for displaying search results pages.
  *
  * @link https://developer.wordpress.org/themes/basics/template-hierarchy/#search-result
  *
  * @package pre_underscores
  */
get_header(); ?>
<?php
  if ( have_posts() ) : ?>
 <header class="page-header">
  <h1 class="page-title"><?php printf( esc_html__( 'Search Results for: %s', 'pre_underscores' ), '<span>' . get_search_query() . '</span>' ); ?></h1>
  </header><!-- .page-header -->
 <?php
  else :
 get_template_part( 'template-parts/content', 'none' );
  return;
endif; ?>
 <section id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
 <?php
  /* Start the Loop */
  while ( have_posts() ) : the_post();
 /**
  * Run the loop for the search to output the results.
  * If you want to overload this in a child theme then include a file
  * called content-search.php and that will be used instead.
  */
  get_template_part( 'template-parts/content' );
 endwhile;
 the_posts_pagination( array(
  'prev_text' => __( 'Newer', 'pre_underscores' ),
  'next_text' => __( 'Older', 'pre_underscores' ),
  'before_page_number' => '<span class="screen-reader-text">' . __( 'Page ', 'pre_underscores' ) . '</span>',
  ));
 ?>
 </main><!-- #main -->
  </section><!-- #primary -->
<?php
  get_sidebar();
  get_footer();
  
code 11.68.2 The new search.php
<?php
  /**
  * Template part for displaying a message that posts cannot be found.
  *
  * @link https://codex.wordpress.org/Template_Hierarchy
  *
  * @package pre_underscores
  */
?>
  <header class="page-header">
  <h1 class="page-title">
  <?php
  if ( is_404() ) { esc_html_e( 'Page not available', 'pre_underscores' );
  } else if ( is_search() ) {
  /* translators: %s = search query */
  printf( esc_html__( 'Nothing found for &ldquo;%s&rdquo;', 'pre_underscores'), get_search_query() );
  } else {
  esc_html_e( 'Nothing Found', 'pre_underscores' );
  }
  ?>
  </h1>
  </header><!-- .page-header -->
 <section id="primary" class="content-area <?php if ( is_404() ) { echo 'error-404'; } else { echo 'no-results'; } ?> not-found">
  <main id="main" class="site-main" role="main">
 <div class="page-content">
  <?php if ( is_home() && current_user_can( 'publish_posts' ) ) : ?>
 <p><?php printf( wp_kses( __( 'Ready to publish your first post? <a href="%1$s">Get started here</a>.', 'pre_underscores' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( admin_url( 'post-new.php' ) ) ); ?></p>
 <?php elseif ( is_search() ) : ?>
 <p><?php esc_html_e( 'Sorry, but nothing matched your search terms. Please try again with some different keywords.', 'pre_underscores' ); ?></p>
  <?php get_search_form(); ?>
 <?php elseif ( is_404() ) : ?>
 <p><?php esc_html_e( 'You seem to be lost. To find what you are looking for check out the most recent articles below or try a search:', 'pre_underscores' ); ?></p>
  <?php get_search_form(); ?>
 <?php else : ?>
 <p><?php esc_html_e( 'It seems we can&rsquo;t find what you&rsquo;re looking for. Perhaps searching can help.', 'pre_underscores' ); ?></p>
  <?php get_search_form(); ?>
 <?php endif; ?>
  </div><!-- .page-content -->
 <?php
  if ( is_404() || is_search() ) {
  ?>
  <h2 class="page-title secondary-title"><?php esc_html_e( 'Most recent posts:', 'pre_underscores' ); ?></h2>
  <?php
  // Get the 6 latest posts
  $args = array(
  'posts_per_page' => 6
  );
  $latest_posts_query = new WP_Query( $args );
  // The Loop
  if ( $latest_posts_query->have_posts() ) {
  while ( $latest_posts_query->have_posts() ) {
  $latest_posts_query->the_post();
  // Get the standard index page content
  get_template_part( 'template-parts/content', get_post_format() );
  }
  }
  /* Restore original Post Data */
  wp_reset_postdata();
  } // endif
  ?>

 </main><!-- #main -->
  </section><!-- #primary -->
<?php
  get_sidebar();
  get_footer();
  
code 11.68.3 The new content-none.php
<?php
  /**
  * The template for displaying archive pages.
  *
  * @link https://codex.wordpress.org/Template_Hierarchy
  *
  * @package pre_underscores
  */
get_header(); ?>
<?php
  if ( have_posts() ) : ?>
 <header class="page-header">
  <?php
  the_archive_title( '<h1 class="page-title">', '</h1>' );
  the_archive_description( '<div class="archive-description">', '</div>' );
  ?>
  </header><!-- .page-header -->
 <?php
  else :
 get_template_part( 'template-parts/content', 'none' );
  return;
endif; ?>
 <div id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
 <?php
  /* Start the Loop */
  while ( have_posts() ) : the_post();
 /*
  * Include the Post-Format-specific template for the content.
  * If you want to override this in a child theme, then include a file
  * called content-___.php (where ___ is the Post Format name) and that will be used instead.
  */
  get_template_part( 'template-parts/content', get_post_format() );
 endwhile;
 the_posts_pagination( array(
  'prev_text' => __( 'Newer', 'pre_underscores' ),
  'next_text' => __( 'Older', 'pre_underscores' ),
  'before_page_number' => '<span class="screen-reader-text">' . __( 'Page ', 'pre_underscores' ) . '</span>',
  ));
 ?>
 </main><!-- #main -->
  </div><!-- #primary -->
<?php
  get_sidebar();
  get_footer();
  
code 11.68.4 The new archive.php
<?php
  /**
  * The main template file.
  *
  * This is the most generic template file in a WordPress theme
  * and one of the two required files for a theme (the other being style.css).
  * It is used to display a page when nothing more specific matches a query.
  * E.g., it puts together the home page when no home.php file exists.
  *
  * @link https://codex.wordpress.org/Template_Hierarchy
  *
  * @package pre_underscores
  */
get_header(); ?>
<?php if ( have_posts() ) : ?>
 <div id="primary" class="content-area">
  <main id="main" class="site-main" role="main">
 <?php
 if ( is_home() && ! is_front_page() ) : ?>
  <header>
  <h1 class="page-title screen-reader-text"><?php single_post_title(); ?></h1>
  </header>
 <?php
  endif;
 /* Start the Loop */
  while ( have_posts() ) : the_post();
 /*
  * Include the Post-Format-specific template for the content.
  * If you want to override this in a child theme, then include a file
  * called content-___.php (where ___ is the Post Format name) and that will be used instead.
  */
  get_template_part( 'template-parts/content', get_post_format() );
 endwhile;
 the_posts_pagination( array(
  'prev_text' => __( 'Newer', 'pre_underscores' ),
  'next_text' => __( 'Older', 'pre_underscores' ),
  'before_page_number' => '<span class="screen-reader-text">' . __( 'Page ', 'pre_underscores' ) . '</span>',
  ));
 ?>
 </main><!-- #main -->
  </div><!-- #primary -->
 <?php
  get_sidebar();
  get_footer();

else :
 get_template_part( 'template-parts/content', 'none' );
  return;
endif;
code 11.68.5 The new index.php

Leave a comment