Theme development・Wiring features in functions.php

Creating "products" with a custom post type

What lets you define a "third kind of article" beyond posts and pages is the custom post type. We add "products" to Shimaenagado and build all the way to dedicated list and detail templates.

The finished form of Shimaenagado had “product” pages. Products differ in character from date-ordered news and from a one-off company profile alike—they’re data you want to manage as an independent kind of article. What makes that possible is the highlight of this course, the custom post type.

Custom post type = adding kinds of articles yourself

The kinds of articles WordPress has from the start are the two “posts” and “pages.” A custom post type is the mechanism to add site-specific kinds there, like “products,” “case studies,” or “staff profiles.”

Once you add one, a dedicated item is born in the admin screen’s left menu, and you can manage articles in a box separate from posts. It’s a tool that shows up in nearly every corporate-site build.

Register “products” with register_post_type

We add to functions.php. This time’s leading player is register_post_type.

// Custom post type "products"
function shimaenagado_post_types() {
  register_post_type('shohin', [
    'labels' => [
      'name'          => 'Products',
      'singular_name' => 'Product',
      'add_new_item'  => 'Add Product',
    ],
    'public'       => true,              // display on the site
    'has_archive'  => true,              // have a list page
    'menu_icon'    => 'dashicons-cart',  // the menu icon
    'supports'     => ['title', 'editor', 'thumbnail'],
    'show_in_rest' => true,              // edit with the block editor
  ]);
}
add_action('init', 'shimaenagado_post_types');

Picking out just the important parts—

SettingMeaning
'shohin'The post type’s ID (shohin is Japanese for “product”). An important name that’s also used in template names
has_archiveAutomatically has a list page at /shohin/
supportsWhat to show in the editing screen (title, body, featured image)
show_in_restThe switch for block editor support (forget it and you get the old editor)

Save and a “Products” item with a cart icon appears in the admin screen’s left menu. Try registering two or three products (adding featured images too makes them look good later).

Dedicated templates: casting a named net

Here’s where the named responsibility we foreshadowed in the template hierarchy lesson comes in. Include the post type ID in the name and it becomes a dedicated template.

  • archive-shohin.php—in charge of the product list page
  • single-shohin.php—in charge of the product detail page

We create these two files fresh in the theme folder. Your folder will look like this.

shimaenagado/
├── 404.php
├── archive-shohin.php   ← the one we're making now
├── category.php
├── footer.php
├── front-page.php
├── functions.php
├── header.php
├── home.php
├── index.php
├── page.php
├── single-shohin.php    ← the one we're making now
├── single.php
└── style.css
<?php get_header(); ?>

<h1 class="page-heading">Products</h1>

<main class="section">
  <div class="cards">
    <?php while (have_posts()) : the_post(); ?>
      <a class="card" href="<?php the_permalink(); ?>">
        <?php the_post_thumbnail('medium', ['class' => 'card-thumb']); ?>
        <h2><?php the_title(); ?></h2>
      </a>
    <?php endwhile; ?>
  </div>
</main>

<?php get_footer(); ?>

the_post_thumbnail() is the function that displays the featured image we unlocked in functions.php. We add card-style CSS too.

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}
.card {
  background: #fff;
  border: 1px solid #eee;
  border-radius: 12px;
  overflow: hidden;
  color: #333;
  text-decoration: none;
}
.card-thumb {
  width: 100%;
  height: 140px;
  object-fit: cover;
  display: block;
}
.card h2 {
  font-size: 15px;
  margin: 10px 14px;
  border: none;
  padding: 0;
}

For the detail page (single-shohin.php), just copy single.php first and delete the date line—that’s all you need for now. Displaying product-like information (price, size) is what we finish off with custom fields in the next lesson.

Line up products on the top page too

Write one more WP_Query order sheet in front-page.php and products line up on the top page too. The way you write the order sheet is exactly the same as with news—you just change post_type to 'shohin'.

<section class="section">
  <h2>Products</h2>
  <?php
  $shohin = new WP_Query([
    'post_type'      => 'shohin',
    'posts_per_page' => 3,
  ]);
  ?>
  <div class="cards">
    <?php while ($shohin->have_posts()) : $shohin->the_post(); ?>
      <a class="card" href="<?php the_permalink(); ?>">
        <?php the_post_thumbnail('medium', ['class' => 'card-thumb']); ?>
        <h2><?php the_title(); ?></h2>
      </a>
    <?php endwhile; wp_reset_postdata(); ?>
  </div>
</section>

Summary of this lesson

  1. A custom post type is the mechanism to add kinds of articles yourself. register_post_type('shohin', […]) gives birth to a dedicated menu in the admin screen
  2. Dedicated templates are a named netarchive-shohin.php and single-shohin.php
  3. A 404 right after adding is fixed by just re-saving “Settings” → “Permalinks” (a standard move)

Try it: open the product corner for business

Let’s line up products at Shimaenagado.

  1. Add register_post_type to functions.php and confirm a “Products” menu appears in the admin screen
  2. Register 3 products (Shimaenaga cushion, snow mug, forest book cover, etc. Set featured images too—free stock is fine)
  3. Re-save at “Settings” → “Permalinks,” then open the /shohin/ list
  4. Create archive-shohin.php and the CSS and confirm the cards line up. Get the detail page working too with single-shohin.php (a copy of single.php is fine)
  5. Add a product section to front-page.php to bring the top page closer to the finished layout

The feeling of a “box you designed yourself” being added to the admin screen should be quite the sense of accomplishment. Next we give products a price and size.