How to build a 404 page with a custom search form

There could be many reasons why a particular user could end up on a 404 error page of a website.

Maybe the user entered an invalid URL. Maybe the user is trying to access an article from your site via google search results but you recently deleted the article. 

The list goes on and on. 

The bottom line is, it is important that we style 404 error page properly and send the user in a proper direction after the mishap.

And, WordPress gives us, the theme developers, a chance to craft a perfect 404 page by letting us create a template file called:

404.php

Yep, all we have to do is create the 404.php file and put whatever we want to in it.

No Loop. We can’t use the Loop inside the 404.php template file because we are not creating a page inside the admin dashboard to host the content of 404 error page, right?

So, if you want to put some error message inside your 404 pages, one option is to hard-code it.

The other option is using the theme options to let the client edit the errors messages.

For now, we will go hard-coding the static text. In the next module, we will learn how to use WordPress customizer to make this hard-coded text editable in the admin dashboard.

Common, go ahead and create the 404.php template file at the root level of our theme directory and put the following code in it:


<?php
/**
 * The template for displaying 404 pages (Not Found)
 *
 * @package Dosth
 */
get_header();
?>
<div class="content-container">
    <h1 class="page-title"><?php _e( 'OOPS! You took a wrong turn :(', "nd_dosth" ); ?></h1>
    <div class="container">
        <div class="row">
            <div class="col-md-12">
                <div class="big-404-page">
                    <?php _e( '404', "nd_dosth" ); ?>
                </div>
                <p><?php _e( "But that's totally ok, Can't blame yourself.", 'nd_dosth' ); ?></p>
                <p><?php _e( "Anyway, the page you are looking for doesn't exist any more or might never existed.", 'nd_dosth' ); ?></p>
                <div class="menu-button">
                    <a href="<?php echo esc_url( t ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home">
                        <?php _e( 'Go Home', 'nd_dosth' ); ?>
                    </a>
                </div>
                <div class="or"><?php _e( 'or', 'nd_dosth' ); ?></div>
                <?php get_search_form(); ?>
            </div>
        </div>
    </div>
</div>
<?php get_footer(); ?>

As you can see, except for two dynamic functions, the above code is Just plain HTML with some hard-coded text wrapped inside WordPress translations.

To test out a 404 page, all you have to do is try to access a page that doesn’t exist on your site. For example:

http://localhost:8888/dosth/wow

We did not create any page called wow, right? So WordPress is redirecting us to the 404 error page! 

Anyway, If you observe the above code, we are facilitating the user to go back to the Homepage by providing a link to the Homepage using the home_url('/') function and then asking the user to try the search form with the help of:


get_search_form()

Introducing get_search_form()

The only responsibility of the get_search_form() function is to output the search form. We generally use this function if we want to output a search form with the help of the Search Widget.

But, what if you want to customize the markup of the search form?

The secret is, the get_search_form() function first looks for the searchform.php template file inside active theme to output the form code, and only if it can not find it, it outputs the default code. 

If you take a look at the source code of get_search_form() function, you can see exactly what is going on. The source code is located inside /wp-includes/genetal-template.php file:

As you can see, first, it is looking for the searchform.php template, if the template file is not found, it is outputting HTML5 Form if our theme supports HTML5, otherwise, it is simply outputting the HTML4 Form.

What’s interesting here is, If you observe the HTML Form code that WordPress is outputting in the absence of template file, it is a very simple piece of code and we can just copy and paste this code inside the searchform.php template file and then customize it according to our needs.

And the best thing here is, It just works great!

Let’s create a custom search form

Common, go ahead and create the searchform.php template file at the root level of our theme directory and put the following code in it:


<?php
/**
 * Template for displaying search forms in Dosth
 *
 * @package Dosth
 */
?>
<form role="search" method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
    <label>
        <span class="screen-reader-text"><?php _x( 'Search for:', 'label', 'nd_dosth'); ?></span>
        <input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Search Articles', 'placeholder', 'nd_dosth' ); ?>" value="<?php echo get_search_query(); ?>" name="s" />
    </label>
    <input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button', 'nd_dosth' ); ?>" />
</form>

All I did is:

  1. Copied the HTML5 form code from the get_search_form() function definition
  2. Replaced PHP concatenation with the PHP tags
  3. Modified the “placeholder” text for the search field and added the translation text domain.

That’s all. It is not wrong at all to copy the code this way from the WordPress core. In fact, if you observe the searchform.php template file from the “Twenty Sixteen” default theme, you’ll find exactly the same code. 

Now that we have created the searchform.php template file, from now on, whenever you call the get_search_form() function, WordPress will output whatever the code inside this template file. So, careful!

Anyway, let’s break the above code.

The most important aspect of any HTML form is the “method” and “action” attributes.

Because this is a search form, we are using the “GET” method. Just like Google.

<form role="search" method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ) ?>">

And for the action attribute, we are outputting the URL of the Homepage. I honestly don’t know the reason behind this, but this is the way WordPress works!

<input type="search" value="<?php echo get_search_query(); ?>" name="s" />

Next, WordPress named the search field as “s” and then using the get_search_query() function to output the query that the user has previously has searched for. 

Finally, there is a simple submit button.

Pretty short and easy to understand search form, right?

And, this is pretty much how we create a custom search form in WordPress.

If you now look at the search form inside the “Page not found” page, the placeholder of the search form will now read “Search Articles” instead of “Search …” because WordPress is using the code inside the searchform.php template file to render the search form.

Get it? 

Now, add the following CSS to the end of the style.css file to style the “Page not found” error page:


/*-------------------------------------------------------------------------------
  23.404 Page Styling
-------------------------------------------------------------------------------*/
.big-404-page{
    font-size:100px;
    text-align:center;
}
.error404 .page-title{
    background-color:#dc3545;
}
.error404 p{
    text-align: center;
}
.error404 .menu-button{
    text-align: center;
    height: auto;
    margin-top:30px;
}
.error404 .menu-button a{
    display:inline-block;
}
.error404 .or{
    text-align: center;
    margin-bottom:20px;
}
.error404 .search-form{
    max-width:300px;
    margin:0 auto 30px;
}

Here is the updated style outline of the style.css file:

And here is how 404 error page looks like in the frontend:

Wait! There is a side-effect

Don’t worry! It is a positive side effect!

Remember? We have placed a Search widget inside the sidebar of our Blog page and other archive pages, right?

This Search widget also uses the same get_search_form() function internally!

So, the Search Widget is now outputting the form code inside the searchform.php file. 

Because of this, If you update the code inside the searchform.php file, all the search forms on the site will get updated too!

How convenient? I really love this. 

And, that’s pretty much how you deal with the search forms in WordPress.

In the next module, We will start creating some theme options for our Dosth site using the WordPress Customizer and its API.