Introduction
A WordPress theme it’s a collection of php files, stylesheet and javascript that modify what people see in the front-end of the website. Themes are responsible for controlling everything from the site’s color scheme and typography to the layout of content on individual pages. Whether you’re building a blog, an e-commerce store, or a portfolio site, the theme you choose or create will define the user experience and visual appeal of your website.
In this post, we will discuss about classic WordPress theme and the difference between classic themes and block themes. We will understand the structure of classic WordPress theme and the essentials steps to building one. We also introducing how to setup our local development environment, and tips about better SEO and performance.
You can download the full project here, or checkout the code here.
Importance of Templates
Understanding the relationship between themes and templates is vital for effective WordPress development. While the theme provides the overarching design and layout for your site, templates allow you to customize the appearance of specific pages or content types.
Each template file corresponds to a specific type of content, such as pages, posts, or archives. WordPress uses the Template Hierarchy – systematic way of selecting which template to apply – to ensure that the correct layout and structure are used for each type of content. For example, the single.php
template is used to display individual blog posts. If a more specific template exists, like single-custom-post-type.php
, WordPress will use that instead, offering flexibility and control over the site’s design.
We’ll explore the Template Hierarchy further when we discuss the structure of classic WordPress themes.
This flexibility means you can create a consistent look and feel across your site while still tailoring certain pages to meet unique requirements. For instance, you might want a different layout for your homepage than your blog posts or a unique design for your product pages in an online store.
Templates enable you to implement these variations without altering the entire theme, offering both consistency and customization. As you delve deeper into WordPress theme development, mastering the use of templates will allow you to create more dynamic, user-friendly websites that meet the specific needs of your audience.
Now that we have a basic understanding of what WordPress themes are, let’s explore the differences between classic themes and the newer block themes introduced with the Gutenberg editor. Understanding these differences is crucial for developers who want to choose the right approach for their projects.
Classic themes vs. block themes
Classic themes are primarily PHP-based, relying on PHP functions and template tags to render content. Each template in a classic theme, like single.php or page.php, is a PHP file that controls how specific types of content are displayed.
In contrast, block themes introduced with the Gutenberg editor are HTML-based, with templates made up of blocks. These themes use HTML tags and the block editor’s interface to manage content, making it easier for non-developers to customize their sites.
We’ll explore how these differences manifest in the file structure and development practices of classic themes in the next section.
Example of a classic theme template tag:
<!-- classic theme template tag: -->
<?php get_header() ?>
Example of a block theme HTML block:
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
A classic theme allows front-end changes only through the Customizer panel. These changes are global, affecting all templates, and often require extensive code customization. In a block theme, everything is controlled by blocks and it can ben page-specific. Blocks manage every aspect of a theme, including typography, colors, margins, and padding.
Also, here is a comparison of the folders structure of a classic theme (Twenty Seventeen) and a block theme (Twenty Twenty-Four)
In classic themes, all template files are PHP-based. For instance, single.php is used for displaying individual posts, while page.php handles single pages. Unlike block themes, where HTML forms the backbone of the template structure, classic themes rely heavily on PHP to manage content rendering and site functionality. The functions.php file, which we will discuss further, plays a crucial role in adding custom features to the theme.
While block themes offer new ways of building WordPress sites, classic themes remain popular for their flexibility and control. Let’s take a closer look at what defines a classic WordPress theme and why many developers continue to use them.
What are classic WordPress theme?
It’s a collection of files, organized hierarchically, who define how WordPress show pages and posts.
Main aspects
- Files structure: classic theme is composed by php, css and js files.
- Template Hierarchy: In classic WordPress theme development, the Template Hierarchy determines how your theme displays content. For instance, the
single.php
template handles individual blog posts, whilepage.php
is used for single pages. If your theme includes a custom template, likesingle-custom.php
, WordPress will prioritize that template when displaying specific content types, giving you more control over the presentation. Understanding this hierarchy is crucial for effective theme customization. - Functions: this file is where you add custom functions and features to your WordPress theme. It is used to register widgets, menus, and other theme support functions like featured images. The code in
functions.php
is executed every time your theme is loaded. We will explore how to use this file in more detail when we start building our theme. - Customizer: a classic theme can be customized by the “Customizer” panel, allow users to modify font, colors, logo and many other aspect without coding. To give a lot of customizations, you need to use a lot of code.
- WordPress Loop: classic themes uses the Loop, a PHP function used for retrieve posts and pages.
Until a few years ago, it was the standard for WordPress themes.
With the Block Editor (Gutenberg), WordPress introduce a new era for building websites. Block-themes offers advantage in term of performance, scalability, design customization without the effort of writing PHP code.
Otherwise, many developer still using Classic theme because is easy to customize and offers more control and flexibility.
Understanding the essential components of a classic WordPress theme is the first step in developing your own. Let’s break down the basic structure of these themes, focusing on the key files and their roles.
Understanding the structure of classic WordPress theme
A classic WordPress theme need some mandatory files to be activated:
- index.php: The main template file. It is required in all themes.
- style.css: The main stylesheet. It is required in all themes and contains the information header for your theme.
Additional important files might include:
- functions.php
- header.php
- footer.php
- single.php
- page.php
- sidebar.php
For further reading, go to the dedicated page on WordPress.org.
Now that you know the core elements of a classic WordPress theme, it’s time to set up a development environment where you can start building and testing your theme safely.
Setting up your development environment
In a few words, a WordPress development environment is a private place where you can develop or editing your WordPress site. Usually is used during the building process of a website, but also during the update of a website. Is useful because the changes doesn’t go live immediately, and it’s important because a live website can lost traffic if something goes wrong.
For preparing the environment you will only need a code editor (my preferred is VSCode), a local server environment (like MAMP or Local), and a WordPress installation. For version control, you can use Git.
Install VSCode and Local on your machine, then open Local and create a new fresh WordPress installation.
Choose you preferred environment (leave default selected for now)
Add new admin user
Wait until the installation finish
Open your editor by clicking the icon VS Code on top of the screen
You can use version control like GIT for tracking code changes and rollback if something not working as expected.
If you have an account on github.com, you can use the Github desktop client for adding your project on version control. Once you have installed the client, open and go to Settings and click on Sign Into Github.com
Click on Continue with Browser, then you will ask to login into your github.com account, then go back to desktop app.
Your Github account is linked to the desktop app. Now you can add a new repository by clicking on File / Add Local Repository…
Navigate to your local WordPress installation
Choose the public folder and click to Open
If is the first time, you will ask to create a new repository
Configure the repo, give a name and description (optional) and click on Create Repository
Now you can publish the repository, and every changes will be tracked by GIT. It is important to commit the changes during the development, or they will be lost.
With your development environment ready, you’re all set to create your first classic WordPress theme. Let’s walk through the steps of bringing your theme to life, starting with setting up the essential files.
Essentials steps in WordPress themes development
To create a classic WordPress theme, you should be familiar with PHP, HTML and CSS.
1. Create a theme folder
Create a new theme folder in wp-content/themes directory, and name it my-classic-theme. All your files goes here.
2. Create style.css files
It’s a crucial file for handle the visual aspect of a WordPress theme. It also contain important data about the theme name, description, the author, the version that help WordPress to identify the theme in administration panel. Here’s a basic example, copy and paste on top of style.css file:
/*
Theme Name: Classic theme
Author: The author name
Author URI: https://robertodimarco.it
Description: Is a classic theme.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
Explanations
Theme Name: Name of the theme.
Author: The name of the individual or organization who developed the theme.
Author URI: The URL of the authoring individual or organization.
Description: A short description of the theme.
Version: The version of the theme, written in X.X or X.X.X format.
License: The license of the theme.
License URI: The URL of the theme license. For extended version, you can read WordPress dedicated page.
3. Create main template file
The index.php file is the main template of your theme. Create in root folder the file then copy and paste this code:
<?php get_header(); ?>
<main>
<!-- Main content goes here -->
</main>
<?php get_footer(); ?>
If you activate the theme and navigate through the website, you will see nothing, so we need to adjust the code for display information from the website. We using the get_header and get_footer functions, which retrieve respectively the header and the footer sections. WordPress handle this functions searching header.php and footer.php files, and show them. So, we need to create theme in root folder.
4. Create header.php file
A simple header.php file looks like this:
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
Functions explanation
The language_attributes() function set the language attributes for the document.
The wp_head() function is crucial because allow WordPress or plugins to inject elements like js scripts and stylesheets.
The body_class() function allows WordPress or plugins to add CSS classes to the body tag. It is important if you need to target specific page during the navigation or you need different style if we are in a specific page.
The wp_body_open() function is like wp_head() function, allow WordPress or plugin to inject code after the body open tag. It is important if we want to insert tracking script or something else.
Let’s analyze some use cases.
5. Adding the main stylesheet file
Now that we understand the purpose of the functions.php
file, let’s add some functionality to our theme. Here’s an example of how to enqueue styles in your theme:
<?php
function my_classic_theme_add_styles() {
wp_enqueue_style('my-classic-theme-style', get_stylesheet_uri());
}
add_action('wp_enqueue_scripts','my_classic_theme_add_styles');
This code tells WordPress to include the style.css
file in every page of your theme. Remember, the functions.php
file can also be used to register menus, widgets, and other theme features, which we’ll cover as we continue developing our theme.
Now the file style.css is included inside the head tag.
If we want to add the title tag inside it, we need to add this code:
<?php
function my_classic_theme_add_title_tag() {
add_theme_support( 'title-tag' );
}
add_action( 'after_setup_theme', 'my_classic_theme_add_title_tag' );
Thanks to the wp_head() function, the style and the title tag are injected inside the head tag of our website, in every page. Let’s create the footer.php file
6. Create footer.php file
A simple footer.php file looks like this:
<footer>
<p>Copyright © <?php echo esc_html( gmdate( 'Y' ) ); ?> - <?php echo esc_html( get_bloginfo( 'name' ) ); ?></p>
</footer>
<?php wp_footer(); ?>
</body>
</html>
Functions explanation
We have printed the copyright Year by the gmdate() function, the website name with the get_bloginfo() function, and according to Security sections in the WordPress Developer Handbooks, we have used the esc_html() escaping function to print the output.
The wp_footer() function is like wp_head() and allow WordPress and plugins to insert code or script inside the footer tag. For example, if we have the app.js file and we need to include it at the bottom of the page, we need to use this code:
<?php
function my_classic_theme_add_app_js() {
wp_enqueue_script( 'my-classic-theme-script', get_template_directory_uri() . '/app.js', array(), false, true );
}
add_action( 'wp_enqueue_scripts', 'my_classic_theme_add_app_js' );
the last parameter of wp_enqueue_script function can be set to false for including the script in the footer tag.
Now, let’s go back to the index.php file and see how to display the posts.
7. The Loop
The WordPress Loop is a core concept that controls how posts are displayed on your site. It’s used in almost every template file, including index.php, single.php, and page.php. Here’s the basic structure of the Loop:
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
// Display post content
endwhile;
endif;
?>
In our example, we want to show title and excerpt of the posts, so our index.php file will be:
<?php get_header(); ?>
<main class="content">
<?php
if ( have_posts() ) :
?>
<?php
while ( have_posts() ) :
the_post();
?>
<article class="post">
<h2 class="post-title">
<?php the_title(); ?>
</h2>>
<div class="post-content">
<?php the_excerpt(); ?>
</div>
</article>
<?php endwhile; ?>
<?php else : ?>
<p><?php esc_html_e( 'Sorry, no posts found.', 'my-classic-theme' ); ?></p>
<?php endif; ?>
</main>
<?php get_footer(); ?>
The Loop can display a lot of different elements, and the_title() and the_excerpt() functions are common template tags available but you can find a list of template tags in the codex.
Now, our front end looks like this. We can style it in the next step.
Our basic theme is ready to be published. You can activate it by the Appereance → Themes panel and click on Activate button on our theme card. Then you can navigate it in front end.
Now that you’ve built a basic theme, it’s time to customize and extend it to meet your specific needs. This is where you can add unique features and personal touches that make your theme stand out.
Customizing and extending your theme
As you can see there is a lot of work and code before to publish a theme. Now, let’s do some customization to our theme.
Adding a navigation menu
WordPress menu are a collection of links. You can create and manage it by administration panel, inside the Appearance → Menu panel. But before that, we need to adding some code in our functions.php
<?php
function my_classic_theme_register_menus() {
register_nav_menus(
array(
'primary' => esc_html__( 'Primary Menu', 'my-classic-theme' ),
'footer' => esc_html__( 'Footer Menu', 'my-classic-theme' ),
)
);
}
add_action( 'after_setup_theme', 'my_classic_theme_register_menus' );
The after_setup_theme hook fires after the theme is loaded, and it is generally used to perform basic setup for a theme. In this case, we have registered two menus with the register_nav_menus function. Now, go back to the administration panel and create the main menu:
To display this menu in the front-end, we need to edit our header.php file:
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<!-- Header -->
<header class="site-header">
<!-- Site title and navigation -->
<h1 class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php bloginfo( 'name' ); ?>
</a>
</h1>
<nav class="site-nav">
<?php
wp_nav_menu(
array(
'theme_location' => 'primary',
'menu_class' => 'primary-menu',
)
);
?>
</nav>
</header>
We have created the header tag with site title and navigation. For the menu we used the wp_nav_menu function that is used for display a navigation menu, and passed the key used in functions.php to register it, and a class name for styling it with the css.
Now in the front end we have a navigation menu:
Custom logo support
We also need to display logo, so copy this code in your functions.php to add support to custom logo
<?php
function my_classic_theme_add_custom_logo() {
add_theme_support(
'custom-logo',
array(
'height' => 100,
'width' => 400,
'flex-height' => true,
'flex-width' => true,
)
);
}
add_action( 'after_setup_theme', 'my_classic_theme_add_custom_logo' );
Now navigate to the Appearance Panel → Customize → Site Identity we can add our logo:
To display the logo in the front-end, we need to retrieve the logo uploaded, if we found it will be displayed, otherwise we display the site title
<header class="site-header">
<?php
if ( has_custom_logo() ) {
the_custom_logo();
} else {
?>
<h1 class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php bloginfo( 'name' ); ?>
</a>
</h1>
<?php
}
?>
<nav class="site-nav">
<?php
wp_nav_menu(
array(
'theme_location' => 'primary',
'menu_class' => 'primary-menu',
)
);
?>
</nav>
</header>
has_custom_logo() function return true if we have set a logo, false if not.
the_custom_logo() function display the custom logo, linked to the home.
Display single page
For display single page, according with the Template Hierarchy we need to create a specific template file. In the root of our theme, create the page.php file and copy this code:
<?php
get_header(); ?>
<main class="content">
<section>
<h1><?php the_title(); ?></h1>
<?php
the_content();
?>
</section>
</main>
<?php get_footer(); ?>
Display single post
When displaying a single post, we use the Loop within the single.php template to output the post’s title, content, and metadata. Here’s how it’s done:
<?php
get_header(); ?>
<main class="content">
<section class="single-post">
<article class="post">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail();
}
?>
<h2 class="post-title">
<?php the_title(); ?>
</h2>
<p class="post-meta">
Published on <?php echo esc_html( get_the_date() ); ?>
</p>
<div class="post-content">
<?php the_content(); ?>
</div>
</article>
</section>
</main>
<?php get_footer(); ?>
Adding some basic style
Now we need to adjust the visual aspect. Let’s give some basic style to our theme, you can change as you want later:
/*
Theme Name: Classic theme
Author: The author name
Author URI: https://robertodimarco.it
Description: Is a classic theme.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
/* Basic Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Body */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
background-color: #f4f4f4;
color: #333;
}
/* Header */
.site-header {
background-color: #333;
color: #fff;
padding: 20px 0;
display: flex;
align-items: center;
}
.site-title a {
color: #fff;
text-decoration: none;
font-size: 2em;
}
/* Custom Logo Link */
.custom-logo-link {
display: inline-block;
}
.custom-logo-link img {
max-width: 200px;
height: auto;
border-radius: 8px;
}
/* Navigation */
.primary-menu {
list-style: none;
padding: 0;
}
.primary-menu li {
display: inline-block;
margin: 0 15px;
}
.primary-menu a {
color: #fff;
text-decoration: none;
font-size: 1em;
}
.primary-menu a:hover {
text-decoration: underline;
}
/* Main Content */
.content {
max-width: 800px;
margin: 20px auto;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.post {
margin-bottom: 20px;
}
.post-title {
font-size: 1.5em;
margin-bottom: 10px;
color: #333;
}
.post-content {
font-size: 1em;
color: #555;
}
/* Footer */
footer {
text-align: center;
margin-top: 40px;
padding: 20px 0;
background-color: #333;
color: #fff;
border-radius: 8px;
}
footer p {
font-size: 0.9em;
}
As you continue to develop your theme, following best practices is crucial to ensure that your theme is secure, performant, and maintainable.
You can download the full project here, or checkout the code here.
Let’s explore some key guidelines that every WordPress developer should keep in mind.
Best practices in WordPress themes creation
When you’re building a classic WordPress theme, it’s essential to follow best practices to ensure your theme is secure, efficient, and easy to maintain. Here’s a practical guide to help you develop a high-quality theme:
Follow WordPress Coding Standards
Sticking to WordPress coding standards for PHP, HTML, CSS, and JavaScript is crucial. Clean, readable, and consistent code isn’t just about keeping things tidy—it makes your theme easier for others (and your future self) to understand and maintain. By following these standards, you’ll also improve the overall performance and compatibility of your theme.
Security Best Practices
- Sanitization and Validation: Always sanitize and validate user inputs to protect your theme from security risks like cross-site scripting (XSS) and SQL injection. For example, use
sanitize_text_field()
for processing text inputs andesc_html()
for output. - Nonces: Utilize nonces (number used once) to safeguard forms and URLs against CSRF (Cross-Site Request Forgery) attacks. This adds an extra layer of security by ensuring that actions are performed intentionally by the user.
Performance Optimization
- Minimize HTTP Requests: Reduce the number of HTTP requests by combining and minifying your CSS and JavaScript files. This can significantly improve your theme’s load times. Tools like Autoptimize or WP-Optimize can help automate this process.
- Lazy Loading: Implement lazy loading for images, which delays the loading of off-screen images until the user scrolls near them. This is especially useful for media-heavy pages and can be easily managed with plugins like a3 Lazy Load.
- Proper Script and Style Enqueuing: Always load your theme’s assets using
wp_enqueue_script()
andwp_enqueue_style()
. This not only ensures compatibility with other plugins and themes but also allows WordPress to manage dependencies effectively.
Accessibility
- Accessible Design: Follow the Web Content Accessibility Guidelines (WCAG) to ensure your theme is usable by everyone, including people with disabilities. This includes using semantic HTML, maintaining sufficient color contrast, and supporting keyboard navigation.
- ARIA Landmarks: Incorporate ARIA (Accessible Rich Internet Applications) landmarks to enhance navigation for users relying on assistive technologies. This helps improve the usability of your theme for a broader audience.
Responsive Design
- Mobile-First Approach: Design your theme with mobile devices in mind first. This approach ensures your theme looks great on all screen sizes. Use CSS media queries to adjust layouts and styles according to different screen sizes.
- Flexible Media: Use relative units (like percentages) for widths, and avoid fixed-width elements. This flexibility allows your design to adapt smoothly across various devices and screen sizes.
Maintainability
- Document Your Code: Always include comments in your code to clarify complex logic or decisions. This makes it easier for you or others to update or modify the theme later.
- Version Control: Utilize version control systems like Git to track changes and collaborate with other developers. Version control also simplifies the process of rolling back to a previous version if needed.
In addition to following best practices, optimizing your theme for search engines is essential for ensuring that websites built with your theme perform well in search results. Here are some important SEO considerations to keep in mind during development.
SEO considerations for classic WordPress themes
Optimizing your WordPress theme for SEO is key to ensuring that sites using your theme perform well in search engines. Here are some SEO-focused tips:
- Semantic HTML: Use HTML5 elements such as
<header>
,<nav>
,<article>
,<section>
, and<footer>
to structure content meaningfully. This helps search engines understand the hierarchy and context of your content, which can boost your SEO. - Proper Heading Structure: Use heading tags (
<h1>
,<h2>
,<h3>
, etc.) correctly. There should be only one<h1>
per page, typically for the main title, followed by<h2>
,<h3>
, etc., for subheadings. This improves readability for users and helps search engines better understand the content structure. - Optimized URLs: Ensure that your theme supports clean and descriptive URLs by leveraging WordPress’s permalink settings. Avoid special characters or unnecessary parameters in URLs.
- Schema Markup: Implement schema markup to give search engines more context about your content. For instance, use schema.org to enhance breadcrumbs, articles, and product information, making your site more likely to feature rich snippets in search results.
- Load Speed Optimization:
- Mobile-Friendly Design: A responsive design not only provides a better user experience but is also a ranking factor in Google’s mobile-first index.
- SEO Plugin Compatibility: Make sure your theme is fully compatible with popular SEO plugins like Yoast SEO or Rank Math. This includes supporting features like breadcrumbs, meta tags, and Open Graph data.
With a solid understanding of classic theme development, best practices, and SEO considerations, you’re now equipped to create powerful and effective WordPress themes. Let’s wrap up with a quick recap and some final thoughts.
Conclusion
With these best practices, you’re on your way to developing a WordPress theme that is not only visually appealing and functional but also secure, high-performing, and optimized for search engines. Remember, theme development is an ongoing process—keep refining and updating your theme based on user feedback and evolving web standards. Whether you’re building a theme for yourself, clients, or the WordPress community, the skills you’ve gained will help you create themes that stand out and provide an excellent user experience.
Leave a Reply