Theme development・Framing with templates

Building an About page with page.php

Build page.php, which handles static pages like About and Access. Here we lock in why you write a loop even for just one item, and the basic form of the_title/the_content.

After the top page comes the handler for static pages like Aboutpage.php. The code you write here is actually almost identical to the single.php coming up. In this chapter you get the basic form of a template that “displays the content of a single item.”

The basic form of page.php

Create a new page.php in your theme folder. Your folder now looks like this.

shimaenagado/
├── footer.php
├── front-page.php
├── header.php
├── index.php
├── page.php   ← create this now
└── style.css
<?php get_header(); ?>

<main class="section">
  <?php while (have_posts()) : the_post(); ?>
    <article>
      <h1 class="page-heading"><?php the_title(); ?></h1>
      <div class="entry-content">
        <?php the_content(); ?>
      </div>
    </article>
  <?php endwhile; ?>
</main>

<?php get_footer(); ?>

the_title() is the page’s title, and the_content() outputs the entire body you wrote in the block editor. What you edited in the admin screen flows in through these two tags.

The “one item, yet a loop?” problem

A static page only shows one item, so wrapping it in a while loop looks odd, doesn’t it? This is the WordPress way: whether there’s one item to show or many, posts are always received via a loop.

  • The loop also serves as a warm-up (the_post sets the data into a usable state), so you don’t skip it even for one item
  • Thanks to that, both lists and detail views can be written in the same form—there’s less to learn

It’s enough to just remember “one item still gets a loop. The loop is a warm-up.”

Note the difference from front-page.php

Last time we placed our own order with WP_Query. This time there’s no order form. It still works because WordPress has prepared the post from the start according to the URL.

  • A request comes to the About URL → WordPress prepares the “About” static page → page.php just receives it with a loop
  • This is called the main loop. The order form (WP_Query) is only used “when you want something other than the main one”

Once you can tell these apart, theme code becomes much more readable.

CSS around the heading

Let’s add a little style for the About page.

.page-heading {
  background: #eaf4f6;
  padding: 28px 5%;
  margin: 0 0 24px;
  font-size: 24px;
  color: #2a6f7c;
  text-align: center;
}
.entry-content {
  max-width: 700px;
  margin: 0 auto;
}

Summary of this lesson

  1. page.php, the handler for static pages, has loop + the_title + the_content as its basic form—single.php is almost the same pattern
  2. Receiving even one item via a loop is the WordPress way (the loop doubles as a warm-up)
  3. Distinguish the main loop, which receives the post decided by the URL, from the sub-loop (WP_Query), where you place your own order

Try it: get the About page up and running

Let’s build Shimaenagado’s About page.

  1. Create page.php and save the code above. Append to style.css too
  2. In the admin screen, go to “Pages” → “Add New” and create a page titled “About”
  3. Write the body freely in the block editor—a heading “About Shimaenagado,” paragraphs, a list (location, founding, business details), and so on
  4. Publish and open it on the front side—success if the content you wrote with blocks has flowed into the template’s frame
  5. Rewrite the header nav’s “About” href=”#” to this page’s URL (turning it into a real menu comes in a later chapter)

That gets “Top” and “About” running. Next up: the news list and detail views.

FAQ

What causes the_content() to display nothing?
Most often it's a case where you've written the_content() outside the loop (while–endwhile). the_content() only works correctly inside the loop, after the post data has been set by the_post().
Which should I build first, page.php or single.php?
In this course we build page.php (for static pages) first. The basic form is almost the same for both, so once you get the pattern down with page.php, single.php only takes learning the difference.