In this exercise, you will use custom fields and custom post types to make a restaurant website. The aim is to create a theme that gives a site owner a more intuitive UI with which to manage his or her content.
The first parts of the exercise will focus on setting up and outputting the content. The last part will focus on the CSS.
A video demonstration of how the site will behave and look can be found in my Loom video channel.
Initial Setup
First please download the new starter files (March 2022).
(If you’re not using PHP8 in MAMP, the installation may not work. If that’s the case, try using the old starter files).
Then download the screenshots.
In the starter files download, there is a folder containing a duplicator archive and installer. Install that in a new development environment. It contains about twenty images we’ll use in the exercise.
Plugin Installation
To save time, I have already installed the following plugins in the theme:
- Show Current Template
- Advanced Custom Fields
- Custom Post Type Ui
- PublishPress Blocks (formerly known as Advanced Gutenberg Blocks)
- Duplicate Page
Please also install the Unsplash and Ninja Forms plugins. If you have any issues with Ninja Forms, consult this document.
The Advanced Custom Fields and Custom Post Type UI plugins are going to give us a relatively easy and quick way to create intuitive and easy to use custom fields and custom post types.
PublishPress Blocks was installed when I made this exercise, just after the Gutenberg editor was introduced. It had a feature that Gutenberg at the time did not have that I needed for the exercise.
But this isn’t an endorsement of the plugin: if this were a live site, I would rebuild the content because Gutenberg now supports the feature I needed. One less plugin is always a good thing.
Starter Theme
Now please download this starter theme, unzip it, rename it eatery-your-initials and install it in the WordPress site you’ve just installed (inside wp-content/themes).
In the wp-config.php file that is in the top level of your WordPress site, set wp_debug to true.
SASS Setup
If you haven’t used SASS before, ignore any sass-related instructions in this section, and make any requested code changes to style.css.
If you have used SASS before, I’ve made a SASS folder in the theme. Feel completely free to modify its structure for the specific needs of this project. You will need to add files.
What To Name Your Theme
Please make sure that you do the next step: it makes my marking much easier.
Your main stylesheet file will either be style.scss or style.css, depending on whether you are using sass or not.
Into that file, copy the WordPress styles.css template code and change the theme name field value to eatery your first name and the author field value to your full name.
If I have asked you to do the exercise in teams, make the theme name one person’s name, but in the author field list each team member.
In that same area, delete the lines for theme uri, and author uri.
Change the Description to Theme for learning custom post types and custom fields.
Delete the Tags line.
Change the Text Domain field to eatery-your-initials.
Getting SASS Compiling
Inside the reset folder, make a sass partial with the code from normalize.css or modern css reset and import it into the style.scss file:
@import "reset/reset";
Make a media partial, inside the media folder. Import it into style.scss.
Set the responsive img code: max-width: 100%; height: auto.
Open the Terminal in Visual Studio Code, then navigate into the sass folder and start a sass watch process:
cd sass
sass --watch style.scss:../style.css
Save the stylesheet.
You should see a message at the bottom of the Visual Studio Window in the Terminal panel. Hopefully, it announced a successful compilation.
Now go to Appearance > Themes and activate your theme.
If you go to the front page of the site, you’ll see that little content is being output. We’ll change that soon.
Functions.php Setup
Open functions.php.
Everywhere you see the word THEMENAME, change it to the theme name (eatery_first_name).
Enable Feature Images
Add theme support for post thumbnails by editing the theme setup function. Without this addition, we won’t be able to add feature images to our posts.
function eatery_km_setup() {
add_theme_support( 'automatic-feed-links' );
add_theme_support( 'title-tag' );
add_theme_support( 'post-thumbnails' );
}
Enable Custom Site Logos
Now add theme support for custom site logos.
For more details about what we will do in this section, consult the WordPress Theme Developer Handbook.
First of all, we need to call add_theme_support with an argument of custom-logo.
Here, though, we will add a second argument to the function call, in the form of an array we will use to pass a series of name-value pairs.
add_theme_support('custom-logo', array());
First, we’ll set a max height and width for the element. Then we will tell WordPress to allow those values to shrink if needed.
The last line here (header-text) accepts either a string or an array. It is used to pass one or more (hence the array) css class names.
Specifically, it tells WordPress the css classes we will use on the site name and site description in our header. This is so that if the user has the logo active, WordPress can hide that text with CSS.
function eatery_km_setup() {
add_theme_support( 'automatic-feed-links' );
add_theme_support( 'title-tag' );
add_theme_support( 'post-thumbnails' );
add_theme_support( 'custom-logo', array(
'height' => 800,
'width' => 800,
'flex-height' => true,
'flex-width' => true,
'header-text' => array( 'site-title', 'site-description' ),
) );
}
Go to the Customizer in the Site Identity section. If you see an option for Logo, then your code is working
Now, add the logo and the site icon. The site icon is a WordPress term for favicon.
Inside the site I’ve given you are some images. We’ll use the logo image in the media library for both the logo and the favicon, but we’ll use different crops of the image.
NOTE 2021:
The procedure below, which worked when I made this exercise in 2020, might require a small workaround. Let me explain:
Normally, we will just select the logo, skip the cropping, then select the site icon and crop it to 500px. But for some reason, WordPress is not letting me crop the site icon. I’ve added an extra step that will allow us to work around this issue.
First, click select logo. You will be taken to the media library. Choose the image with text in it.
When prompted to crop the image, move the crop handles to crop it to the word eat, like this:
Then click Crop Image.
This will save a cropped version of the file into the media library: that is the one will we shortly designate as our site icon.
However, it will also set as our site logo the cropped version: we actually want the original uncropped one.
This is the workaround, in other words: now click Change Logo and choose the original wide logo:
Finally, select the site icon. Choose the cropped version of the image, the one with just the word eat.
Click Publish then get out of the Customizer.
Test the page. You should now see the favicon (“eat”) in the browser tab, but not yet see the full logo on the page. We will output it once we’ve made our menus.
Make Menu Locations
Now, inside the theme setup function, let’s add three menu locations. Make sure that you write this code inside the function, not after it: in other words, the curly brace that begins the setup function ends after our menu registration.
Type the code: just copying and pasting will prevent you from getting comfortable with PHP syntax.
function eatery_km_setup() {
add_theme_support( 'automatic-feed-links' );
add_theme_support( 'title-tag' );
add_theme_support( 'post-thumbnails' );
add_theme_support( 'custom-logo', array(
'height' => 800,
'width' => 800,
'flex-height' => true,
'flex-width' => true,
'header-text' => array( 'site-title', 'site-description' ),
) );
register_nav_menus(array(
'menu-meals' => 'Meal Menus',
'menu-social' => 'Social Menu',
'menu-footer' => 'Footer Menu'
));
}
In the Dashboard, you should now see that there is a Menus section in the Customizer.
Check that your menu locations are showing up. You should see this:
Output the Custom Logo via header.php
Open header.php. Now we’ll output the custom logo, testing to see if the user has selected one first, of course.
Before we do that, though, notice that the name of the page in the browser tab is Document. In functions.php, I added support for the title-tag feature, which makes WordPress automatically generate page titles that reflect where on the site the user is.
This feature does not work, however, if you have a title tag in your header file. So delete that <title> line from header.php and save. Reload the site, and you will see a more appropriate title in the browser tab.
Now, inside the header we will want to output the following:
- the custom logo, but only if the user has selected one
- the site-title and site-description, if the user does not want to use a custom logo
To do that, add this code inside the .site-header element.
<div class="site-branding">
<?php the_custom_logo(); ?>
<h1 class="site-title">
<a href="<?php home_url(); ?>">
<?php bloginfo('name'); ?>
</a>
</h1>
<div class="site-description">
<?php bloginfo('description'); ?>
</div>
</div> <!-- .site-branding -->
In order to make our later styling easier, we’re here wrapping this construction in a DIV with a class of site-branding.
Test the page: you should see this if a custom logo was used.
Now go to the Customizer and remove the custom logo. You should now see that only the footer content is shown.
Notice the user has the option to Display Site Title and Tagline?
This option will appear in the dashboard only if you have used the header-text option in the array passed to add_theme_support for custom logos.
If the user does click that button and has not specified a custom logo, the site title and description will be displayed as text instead:
Now restore the logo and icon.
Task: Output Our Header and Footer Menus
Please now make two menus in the Dashboard:
- Main Menu, with custom links for #breakfast, #lunch, and #dinner. The hash creates an in-the-page link (also known as a jump link).
- Social Menu, with links to Twitter, FaceBook, Instagram, and one other social site.
- Just link to the front pages of these sites: normally, of course, we would link to specific pages.
Later, to make our in-page links work, we’ll need to output the title of the post as an ID attribute in the template-part for our food menus.
In the Dashboard, put the Main Menu into the Meal Menus and Footer Menu locations. Put the Social menu into the Social Menu location.
In your header.php template file, output the Main and Social menus after the site-branding DIV.
Output them in two NAV elements, one with a class of menu-meals and one with a class of menu-social.
And put those two NAV elements inside a DIV with a class of site-navigation.
Make sure that site-navigation comes after .site-branding (not inside it).
Once you’ve done that, please move on to part two of this exercise.