Custom Landing Pages in WordPress How-to Series, Part 4

Part 4: How to Enable Users to Edit Custom Page Content in WordPress

This is the fourth article in a five-part series about planning and implementing custom landing pages in WordPress. Each article is intended to be useful in its own right and applicable beyond landing pages, but taken together the series walks through the whole process of planning and implementing a custom landing page that integrates cleanly into a WordPress-powered web site. The resulting page will be easily editable with familiar forms in the WordPress admin system.

Custom Landing Pages in WordPress

  1. Planning a Custom Landing Page for a WordPress Web Site
  2. How to Make a Child Theme for WordPress
  3. How to Get Pages with Custom Designs into WordPress
  4. How to Enable Users to Edit Custom Page Content in WordPress
  5. Coming Soon: How to Customize Menus and Title Text for Custom Pages in WordPress

 


 

Editable Content – What Makes a Template a Template

There are two significant advantages to using templates for web pages, whether in WordPress or otherwise: reuse and sensible separation of concerns.

Reuse: Templates allow the same designs to be used across multiple pages.

Separation of Concerns: With templates, people creating or managing content can benefit from high-quality design and development without having to be designers or developers themselves. They can be, but they don’t have to be.

In WordPress there are of course various types of content that can be made editable, but there are also multiple methods for doing so. For our landing pages we’ll allow our users to edit page content via standard page, featured image, and widget forms. To determine which method to use where we’ll take a content-first approach, first looking at what content needs to be editable then determining which method is most appropriate for each case.

Which content do we want to be editable?

For the purposes of this exercise, let’s say we have been told that copywriters should be able to edit text and the main feature image, but the icons and buttons are being left to the front-end developers. Thus, the copywriters should only have to see the things they can change; they shouldn’t have to find what they need within markup that they might break.

Here’s a mockup showing the content we’ll need to make editable:

landing page mockup of editable areas

From a content perspective there are three general areas that need to be editable:

  1. the page header – where our page title will be displayed
  2. the calls to action – prompts and links for potential customers
  3. the main content – further information for potential customers

So which parts of these sections should we make editable for our copywriters via those standard WordPress forms?

For our page header we’ll make the page title editable.

For our calls to action we’ll make the headings and copy editable.

For our main content we’ll make the body copy, its heading, and the featured image editable.

With our content in mind we can break down our implementation like so:

  1. The page title, body copy, body copy heading, and featured image can all be made editable via various parts of the standard post form.
  2. The headings and copy for the calls to action can be made editable via standard WordPress widgets.

Now that we know what content we need to make editable and how to go about it we can get started in earnest.

Our First Real Page Template

Enough jibber jabber. It’s time to create our first real page template. We’ll start simple with something very similar to our templates from the previous tutorial in this series. Let’s call this file something like landing-page-template-a.php and save it directly within our theme folder, which should itself be inside of wp-content/themes.

landing-page-template-a.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
/*
Template Name: Landing Page Template A
Template Post Type: post, page
*/
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Landing Page Template A</title>
</head>
<body>
    <div class="content">
        <div class="splash">
            <h1>Landing Page Template A</h1>
        </div>
        <div class="customer-options">
            <!-- The customer options will go here. -->
        </div>
        <main>
            <!-- The featured image will go here. -->
            <!-- The main text content will go here. -->
        </main>
    </div>
</body>
</html>

As you can see, I have included the beginnings of some body HTML for us to build upon as well as some comments to show where we’ll add the code to pull in our main text content, featured image, and customer options. None of that is actually required for WordPress, though; you can structure your page however you like.

Basic WordPress Template Functions

WordPress offers many, many functions to help you get your content onto pages and into posts through templates, but the first function calls you should add to your template are to wp_head() and wp_footer(). As their names suggest, they should be called from your HTML head element and the bottom of your body element respectively.

You may have noticed that those function names are nouns rather than verbs. That is common with WordPress, so be careful to not confuse functions for variables. You don’t need to print a return value from functions like wp_head() and wp_footer(). Just call them like so:

<?php wp_head(); ?>
<?php wp_footer(); ?>

When you call wp_head() WordPress will automatically insert a title element for you, so go ahead and remove the hard-coded version from your HTML.

There are a few other WordPress functions that are particularly useful at the top of a template page: language_attributes(), bloginfo(), and body_class(). They are used like so:

<html <?php language_attributes(); ?>>
<meta charset="<?php bloginfo('charset'); ?>">
<body <?php body_class(); ?>>

Now let’s put that all together.

landing-page-template-a.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
/*
Template Name: Landing Page Template A
Template Post Type: post, page
*/
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
    <div class="content">
        <div class="splash">
            <h1>Landing Page Template A</h1>
        </div>
        <div class="customer-options">
            <!-- The customer options will go here. -->
        </div>
        <main>
            <!-- The featured image will go here. -->
            <!-- The main text content will go here. -->
        </main>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

Making the Main Heading Editable

An easy way to make the main heading editable is to simply use the title of a page or a post as its main heading. The WordPress function the_title() makes that very easy indeed:

20
<h1><?php the_title(); ?></h1>

Note that the_title() will print only the title text you enter when composing a page or a post, not anything extra such as the site name, which is often included in a page’s title element. Here, “title” corresponds to the content, not necessarily to the title of the HTML document.

Making the Main Content and Featured Image Editable

With the foundations of our template in place, we can now add the main WordPress loop like so:

landing-page-template-a.php
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        <main>
<?php
    while(have_posts()) : the_post();
        // The featured image will go here.
        // The main text content will go here.
    endwhile;
?>
        </main>

That loop is special in WordPress: it allows you to use special functions to refer to page- or post-specific content.

OK, now for the main text content! Do you have a fresh cup of coffee and an hour to spare? Well, enjoy your spare 59 minutes then because showing the main content is as simple as this:

38
the_content();

Yep, one line. Showing the featured image is just as easy, but let’s wrap it in a div to give it some extra responsive styling flexibility later.

36
print '<div class="featured-image">' . get_the_post_thumbnail() . '</div>';

Time for a Test Drive!

At this point, our template should be functional. Let’s create a test page to use it.

  1. Start a new page (e.g., via New > Page in the WordPress Toolbar or Pages > Add New in the admin sidebar.
  2. Type or paste a title and some body copy. The latter can include headings if you like.
  3. Select a template in the “Page Attributes” box.
  4. Click the “Publish” button.

Page Attributes - Landing Page Template A

Making the Customer Options Editable

Our non-technical users such as copywriters may want an easy way to edit the calls to action—the three options. We can give it to them with widgets. In this case, we’ll use the standard WordPress Text Widget.

Implementing standard widget support is as simple as calling the dynamic_sidebar() function with an identifying parameter—either an id integer or a name string. You can also check is_active_sidebar() first with the same parameter. We’ll use three strings as our identifying parameters:

  1. lp-opt-set-1-try-section
  2. lp-opt-set-1-buy-section
  3. lp-opt-set-1-more-info-section

The name values are arbitrary, so feel free to use values that are meaningful for your template.

landing-page-template-a.php
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<div class="try">
    <?php if (is_active_sidebar('lp-opt-set-1-try-section')) : ?>
        <?php dynamic_sidebar('lp-opt-set-1-try-section'); ?>
    <?php else: ?>
    <div class="body">
        <h2><img src="https://via.placeholder.com/56.png/555/fff?text=T" alt="Try icon"> Try</h2>
        <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor.</p>
        <p>Donec id elit non mi porta gravida at eget metus.</p>
    </div>
    <?php endif; ?>
    <footer><button type="button">Request a Sample</button></footer>
</div>
<div class="buy">
    <?php if (is_active_sidebar('lp-opt-set-1-buy-section')) : ?>
        <?php dynamic_sidebar('lp-opt-set-1-buy-section'); ?>
    <?php else: ?>
    <div class="body">
        <h2><img src="https://via.placeholder.com/56.png/555/fff?text=B" alt="Buy icon"> Buy</h2>
        <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
        <p>Curabitur blandit tempus porttitor.</p>
    </div>
    <?php endif; ?>
    <footer><button type="button">Place an Order</button></footer>
</div>
<div class="more-info">
    <?php if (is_active_sidebar('lp-opt-set-1-more-info-section')) : ?>
        <?php dynamic_sidebar('lp-opt-set-1-more-info-section'); ?>
    <?php else: ?>
    <div class="body">
        <h2><img src="https://via.placeholder.com/56.png/555/fff?text=MI" alt="More Info icon"> More Info</h2>
        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Aenean lacinia bibendum nulla sed consectetur.</p>
        <p>Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
    </div>
    <?php endif; ?>
    <footer><button type="button">Read More</button></footer>
</div>

Assigning and Using Widgets

Widgets are managed through Appearance > Widgets or Live Preview. These standard WordPress features are well documented elsewhere, so we won’t cover them extensively here, but let’s look at how to associate the above identifiers with friendly names then take a look at the results.

Associations between widget identifiers and their various attributes are established through the use of the register_sidebar() function in functions.php. Let’s add a widget-initialization function to our functions.php file from How to Make a Child Theme for WordPress.

functions.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
// Shared PHP for Landing Page Child Theme
// Hooks and Filters
add_action('widgets_init', 'lp_example_theme_widgets_init');
add_action('wp_enqueue_scripts', 'lp_example_theme_enqueue_assets');
// Functions
function lp_example_theme_enqueue_assets()
{
    $parent_style = 'twentyseventeen-style';
    wp_enqueue_style($parent_style, get_template_directory_uri() . '/style.css');
    wp_enqueue_style('landing-page-style',
        get_stylesheet_directory_uri() . '/style.css',
        array($parent_style),
        wp_get_theme()->get('Version')
    );
}
function lp_example_theme_widgets_init()
{
    register_sidebar(array(
        'name' => 'LP Option Set 1 - Try Section',
        'id' => 'lp-opt-set-1-try-section',
        'description' => 'Use a text widget to customize the "Try" section title and text.',
        'before_widget' => '<div class="body">',
        'after_widget' => '</div>',
        'before_title' => '<h2><img src="https://via.placeholder.com/56.png/555/fff?text=T" alt="Try icon"> ',
        'after_title' => '</h2>'
    ));
    register_sidebar(array(
        'name' => 'LP Option Set 1 - Buy Section',
        'id' => 'lp-opt-set-1-buy-section',
        'description' => 'Use a text widget to customize the "Buy" section title and text.',
        'before_widget' => '<div class="body">',
        'after_widget' => '</div>',
        'before_title' => '<h2><img src="https://via.placeholder.com/56.png/555/fff?text=B" alt="Buy icon"> ',
        'after_title' => '</h2>'
    ));
    register_sidebar(array(
        'name' => 'LP Option Set 1 - More Info Section',
        'id' => 'lp-opt-set-1-more-info-section',
        'description' => 'Use a text widget to customize the "More Info" section title and text.',
        'before_widget' => '<div class="body">',
        'after_widget' => '</div>',
        'before_title' => '<h2><img src="https://via.placeholder.com/56.png/555/fff?text=MI" alt="More Info icon"> ',
        'after_title' => '</h2>'
    ));
}
?>

Once that’s done users of your theme should be able to place widgets and edit widget content like so:

Putting It All Together

Your wp-content/themes directory should now contain at least the following files:

  • functions.php
  • landing-page-template-a.php – or whatever you named your template file
  • screenshot.png
  • style.css

landing-page-template-a.php should now look something like the following:

landing-page-template-a.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php
/*
Template Name: Landing Page Template A
Template Post Type: post, page
*/
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
    <div class="content">
        <div class="splash">
            <h1><?php the_title(); ?></h1>
        </div>
        <div class="customer-options">
            <div class="try">
                <?php if (is_active_sidebar('lp-opt-set-1-try-section')) : ?>
                    <?php dynamic_sidebar('lp-opt-set-1-try-section'); ?>
                <?php else: ?>
                <div class="body">
                    <h2><img src="https://via.placeholder.com/56.png/555/fff?text=T" alt="Try icon"> Try</h2>
                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor.</p>
                    <p>Donec id elit non mi porta gravida at eget metus.</p>
                </div>
                <?php endif; ?>
                <footer><button type="button">Request a Sample</button></footer>
            </div>
            <div class="buy">
                <?php if (is_active_sidebar('lp-opt-set-1-buy-section')) : ?>
                    <?php dynamic_sidebar('lp-opt-set-1-buy-section'); ?>
                <?php else: ?>
                <div class="body">
                    <h2><img src="https://via.placeholder.com/56.png/555/fff?text=B" alt="Buy icon"> Buy</h2>
                    <p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
                    <p>Curabitur blandit tempus porttitor.</p>
                </div>
                <?php endif; ?>
                <footer><button type="button">Place an Order</button></footer>
            </div>
            <div class="more-info">
                <?php if (is_active_sidebar('lp-opt-set-1-more-info-section')) : ?>
                    <?php dynamic_sidebar('lp-opt-set-1-more-info-section'); ?>
                <?php else: ?>
                <div class="body">
                    <h2><img src="https://via.placeholder.com/56.png/555/fff?text=MI" alt="More Info icon"> More Info</h2>
                    <p>Nullam quis risus eget urna mollis ornare vel eu leo. Aenean lacinia bibendum nulla sed consectetur.</p>
                    <p>Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
                </div>
                <?php endif; ?>
                <footer><button type="button">Read More</button></footer>
            </div>
        </div>
        <main>
<?php
    while(have_posts()) : the_post();
        print '<div class="featured-image">' . get_the_post_thumbnail() . '</div>';
        the_content();
    endwhile;
?>
        </main>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

A Few Thoughts on Project Structure

Although we have thus far kept our new page template PHP and HTML in a single file for the sake of simplicity in learning about templates, it is quite common and often desirable to store template source code across multiple PHP files. Doing so can enable conceptual separation as well as the ability to easily replace whole page sections.

For landing pages, being able to mix and match different headers, footers, sidebars, and other page areas can be especially important in delivering content variation for tailored campaigns and A/B testing. We won’t go into these options in this tutorial, but keep in mind that they are possible.

Structure Built, Time for Style!

Now that our template is fully functional it’s time to style it up. Since this tutorial is about producing a template, not designing the look of a page that will use that template, go ahead and apply whatever style rules you like in style.css. You can follow the example of the mockup if you like, but feel free to make it your own.

When you’re styling your template, don’t forget the icons! We used placeholder images from Placeholder.com, but you could easily use your own custom images or an icon font such as Font Awesome, which is what we used for the mockup.

Next in This Series

In the final article in this series, How to Customize Menus and Title Text for Custom Pages in WordPress, we’ll apply some finishing touches to how we present our templated pages, helping them look and rank their best.

Let’s Work Together

From web design, CMS websites, applications, ecommerce, motion graphics and multimedia, graphic design, and print, to Internet marketing solutions, we’ve got you covered.