
Designing a template for WordPress seems harder than it really is. If you are a front-end developer and you are completely at home with CSS, you will find it fairly easy.
I am not a developer or a designer, my speciality is marketing, and the reason I learnt to build a WordPress theme was to optimise the website’s speed.
Files you need
First of all, you need to create a folder and give it the name of our theme. Inside it, we will create a series of blank files, which will be:
- functions.php: this holds all the functions of our theme that will interact with our admin panel
- sidebar.php: the sidebar is intended for our theme’s plugins
- header.php: this file will be the header inserted into every page. It is where all the styles and JavaScript files will be loaded
- index.php: this is the main page of our theme, in other words, the homepage.
- footer.php: this is the file that will be loaded at the end of each page of our website.
- single.php: this file is responsible for displaying individual post pages.
- page.php: this file is responsible for displaying the pages of our WordPress site.
- style.css: this file is responsible for loading the CSS of our WordPress site
Once we have all these files, we need to add a header to each of them and fill in the details. Here is an example header you can copy and paste at the top of every file:
/*
Theme Name: Aquí el nombre de vuestro tema
Author: Aquí vuestro nombre de autor
Author URI: vuestra url con info del tema
Description: descripción del tema
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/After this, if we upload the folder to our themes directory at /wp-content/themes, we will be able to see it in our theme selector. In my case, I called the theme theme-wp:

Although the files mentioned above are the basic ones, for this tutorial I will add 2 more stylesheets:
- blog.css
- page.css
We will use these stylesheets for selective loading, using whichever CSS suits us best depending on the type of page, to limit the amount of code loaded.
functions.php
<?php /*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
// This function enqueues the Normalize.css for use.
//The first parameter is a name for the stylesheet, the second is the URL.
//Here we use an online version of the css file.
function add_normalize_CSS() {
wp_enqueue_style( 'normalize-styles',
"https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css");
}
// Creación de 'sidebar' para insertar widgets
function add_widget_Support() {
//Sidebar lateral derecho
register_sidebar( array(
'name' => 'Sidebar',
'id' => 'sidebar',
'before_widget' => '<div>',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>',
) );
//Sidebar para footer
register_sidebar( array(
'name' => 'Footer 1',
'id' => 'footer-1',
'before_widget' => '<div class="footer_w1">',
'after_widget' => '</div>',
'before_title' => '<h2>',
'after_title' => '</h2>',
) );
//Sidebar para footer
register_sidebar( array(
'name' => 'Footer 2',
'id' => 'footer-2',
'before_widget' => '<div class="footer_w2">',
'after_widget' => '</div>',
'before_title' => '<h2>',
'after_title' => '</h2>',
) );
//Sidebar para footer
register_sidebar( array(
'name' => 'Footer 3',
'id' => 'footer-3',
'before_widget' => '<div class="footer_w3">',
'after_widget' => '</div>',
'before_title' => '<h2>',
'after_title' => '</h2>',
) );
}
// Hook para iniciar el widget y ejecutar nuestra función
add_action( 'widgets_init', 'add_Widget_Support' );
// Crear menús de navegación
function add_Main_Nav() {
// Main menú
register_nav_menu('header-menu',__( 'Header Menu' ));
// Footer menú
register_nav_menu('footer-menu',__( 'Footer Menu' ));
}
// Hook para iniciar el menú y ejecutar nuestra función
add_action( 'init', 'add_Main_Nav' );
// thumbnails de las imágenes y tamaños
if ( function_exists( 'add_theme_support' ) )
add_theme_support( 'post-thumbnails' );
// especificación del tamaño de los thumbnails
set_post_thumbnail_size(300, 200);
?>sidebar.php
<?php /*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
?>
<?php if ( is_active_sidebar( 'sidebar' ) ) : ?>
<aside id="primary-sidebar" class="primary-sidebar widget-area" role="complementary">
<?php dynamic_sidebar( 'sidebar' ); ?>
</aside>
<?php endif; ?>header.php
<?php /*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>
<head>
<title>
<?php bloginfo('name'); ?> » <?php is_front_page() ? bloginfo('description') : wp_title(''); ?>
</title>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<?php
if( is_single()):?>
<link rel="stylesheet" href="
<?php echo esc_url( home_url() ); ?>/wp-content/themes/theme-wp/blog.css">
<?php ;
else:?>
<link rel="stylesheet" href="
<?php echo esc_url( home_url() ); ?>/wp-content/themes/theme-wp/pages.css">
<?php ;
endif;
?>
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<header class="my-logo">
<div class="cont_head">
<span>
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php bloginfo('name'); ?>
</a>
</span>
<?php wp_nav_menu( array( 'theme_location' => 'header-menu' ) ); ?>
</div>
</header>index.php
<?php /*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
?>
<?php get_header(); ?>
<main class="wrap">
<section class="content-area content-thin">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<article class="article-loop">
<header>
<h2>
<a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
<?php the_title(); ?>
</a>
</h2>
<div><?php the_post_thumbnail('medium');?></div>
<i><?php the_author(); ?></i>
</header>
<?php the_excerpt(); ?>
</article>
<?php endwhile; else : ?>
<article>
<p>Sorry, no posts were found!</p>
</article>
<?php endif; ?>
</section>
</main>
<?php get_footer(); ?>footer.php
<?php /*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
?>
<div class="widget-footer">
<div class="container">
<?php if ( is_active_sidebar( 'footer-1' ) ) : ?>
<?php dynamic_sidebar( 'footer-1' ); ?>
<?php endif; ?>
<?php if ( is_active_sidebar( 'footer-2' ) ) : ?>
<?php dynamic_sidebar( 'footer-2' ); ?>
<?php endif; ?>
<?php if ( is_active_sidebar( 'footer-3' ) ) : ?>
<?php dynamic_sidebar( 'footer-3' ); ?>
<?php endif; ?>
</div>
</div>
<footer>
<?php wp_nav_menu( array( 'theme_location' => 'footer-menu' ) ); ?>
</footer>
<?php wp_footer(); ?>
</body>
</html>single.php
<?php /*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
?>
<?php get_header(); ?>
<main class="wrap">
<section class="content-area content-full-width">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<article class="article-full">
<header>
<h1><?php the_title(); ?></h1>
<?php the_post_thumbnail('medium')?>
By: <?php the_author(); ?>
</header>
<?php the_content(); ?>
</article>
<?php endwhile; else : ?>
<article>
<p>Sorry, no post was found!</p>
</article>
<?php endif; ?>
</section><?php get_sidebar(); ?>
</main>
<?php get_footer(); ?>page.php
<?php /*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
?>
<?php get_header(); ?>
<main class="wrap">
<section class="content-area content-thin">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<article class="article-full">
<header>
<h2><?php the_title(); ?></h2>
By: <?php the_author(); ?>
</header>
<?php the_content(); ?>
</article>
<?php endwhile; else : ?>
<article>
<p>Sorry, no page was found!</p>
</article>
<?php endif; ?>
</section>
</main>
<?php get_footer(); ?>style.css
In our stylesheet, we will add some basic CSS so that we can see something
/*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
/*relleno interior de los bloques*/
* {
box-sizing: border-box;
margin:0px;
padding:0px;
}
/*Background*/
body {
margin: 0;
font-family: 'Lato', sans-serif;
}
/*****************************************************************/
/*****************************CABECERA****************************/
/*****************************************************************/
/*centrar header*/
.my-logo {
vertical-align: middle;
text-align: center; /* requerido para alineación horizontal */
background-color: #333;
}
.cont_head span{
float:right;
height: 48px;
padding: 5px 20px 5px 20px;
font-size:30px;
background-color: #4CAF50;
}
.cont_head span a{
color:white;
}
/*****************************************************************/
/*******************************MENU******************************/
/*****************************************************************/
.menu {
overflow: hidden;
background-color: #333;
display: flex;
list-style:none;
}
.menu li {
float: left;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
border-right: 1px solid white;
}
.menu li:hover {
background-color: #4CAF50;
}
.menu li:hover a {
color: white;
}
.menu li a {
color: #f2f2f2;
}
.current-menu-item {
background-color: #4CAF50;
color: white;
}
.sub-menu{
display:none;
position: absolute;
left: 0px;
margin-top: 14px;
width: 200px;
background-color: #333;
}
.sub-menu li{
width:100%;
}
.menu li:hover .sub-menu{
display:block;
}
@media all and (max-width: 500px) {
header, .menu{
flex-wrap: wrap;
}
.cont_head span{
float: none;
}
.menu li {
flex-basis: 100%;
}
}
/*****************************************************************/
/*****************************END MENU****************************/
/*****************************************************************/
/*****************************************************************/
/***************************END CABECERA**************************/
/*****************************************************************/
/*****************************************************************/
/*****************************CONTENIDO***************************/
/*****************************************************************/
/*****************************************************************/
/******************************TITULOS****************************/
/*****************************************************************/
h1{
font-size: 65px;
line-height: 80px;
text-align: center;
}
h1, h2, h3{
font-weight: bold;
margin: auto;
}
h2, h2 a{
font-size: 55px;
line-height: 46px;
text-align: center;
}
h3, h4, h5, h6{
text-align: left;
}
h3{
font-size: 30px;
line-height: 29px;
}
h4{ font-size: 25px;
}
h5{ font-size: 20px;
}
h6{ font-size: 15px;
}
/*****************************************************************/
/***************************END TITULOS***************************/
/*****************************************************************/
.content-area{
display: flex;
padding: 0 5% 0 5%;
margin-bottom: 30px;
}
.article-loop{
flex-wrap: wrap;
flex-basis: 33%;
background-color: #e5e5e5;
}
.article-loop h2{
color: #4CAF50;
background-color: #333;
margin-bottom: 10px;
padding: 20px 0 20px 0;
}
.article-loop h2 a{
color: #4CAF50;
text-decoration: none;
line-height: 55px;
}
.article-loop:hover h2 a{
color: white;
text-decoration: none;
}
.article-loop p{
margin-top: 10px;
}
img.attachment-medium.size-medium.wp-post-image{
width: 100%;
height: auto;
display: block;
margin-bottom: 10px;
}
@media all and (max-width: 500px) {
.content-area{
flex-wrap: wrap;
flex-basis: 100%;
}
.article-loop{
flex-basis: 100%;
}
}
/*****************************************************************/
/***************************END CONTENIDO*************************/
/*****************************************************************/
/*****************************************************************/
/****************************PRE FOOTER***************************/
/*****************************************************************/
.widget-footer{
padding-bottom: 60px;
padding-top: 45px;
background-color:#2B315E;
color: #fff;
padding-left: 20%;
padding-right: 20%;
}
.widget-footer .container{
margin: 0 auto;
display: flex;
}
.widget-footer .container div{
flex-wrap: wrap;
margin: auto;
}
.container:after {
content: "\0020";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
@media all and (max-width: 1200px) {
.widget-footer{
padding-left: 10%;
padding-right: 10%;
}
}
@media all and (max-width: 730px) {
.widget-footer{
padding-left: 0;
padding-right: 0;
}
}
@media all and (max-width: 683px) {
.widget-footer .container div{
flex-basis: 100%;
}
.widget-footer .container{
flex-wrap: wrap;
padding: 0 25% 0 25%;
}
}
/*****************************************************************/
/**************************END PRE FOOTER*************************/
/*****************************************************************/
/*****************************************************************/
/******************************FOOTER*****************************/
/*****************************************************************/
footer {
width: 100%;
padding-left: 1%;
background-color: #333;
vertical-align: middle;
text-align: center; /* requerido para alineación horizontal */
min-height:40px;
}
footer div{
display: inline-block;
margin: 30px 0 30px 0;
}
@media all and (max-width: 683px) {
footer .menu{
flex-wrap: wrap;
}
footer .menu li {
flex-basis: 100%;
}
}
/*****************************************************************/
/****************************END FOOTER***************************/
/*****************************************************************/blog.css
/*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
.content-thin {
width: 70%;
}
.primary-sidebar {
width: 25%;
padding: 1%;
vertical-align: top;
background-color: #ececec;
flex-basis: 35%;
padding: 0 250px 0 30px;
}
.article-loop {
width: 45%;
text-align: left;
margin: 5px;
padding: 10px;
}
.wrap{
display: flex;
flex-wrap: wrap;
}
.content-area {
flex-basis: 65%;
padding: 0 30px 0 250px;
}
.primary-sidebar h3{
margin: 20px 0 20px 0;
}
.primary-sidebar .menu li{
float:none;
}
.primary-sidebar .menu li a{
text-decoration: none;
}
.primary-sidebar .menu {
display: block;
}
#searchsubmit{
padding: 5px 20px;
background-color: #4CAF50;
border: none;
margin: 10px 0 0 0;
width: 100%;
color: white;
font-weight: bold
}
#searchsubmit:hover{
background-color: #f6933e;
color: black;
}
article p{
margin:30px 0;
font-size: 20px;
line-height: 30px;
}
article li{
margin-left: 20px;
font-size: 17px;
line-height: 40px;
}
article img{
margin:30px 0;
}
article ul{
padding-left: 50px;
list-style: square;
margin: 25px 0;
}
article h1{
margin: 20px 0 20px 0;
}
article a{
color: #4caf50;
}
.wp-block-code, .wp-block-preformatted{
background-color: black;
color: green;
padding: 20px 40px 20px 80px;
font-weight: bold;
font-size: 14px;
border: solid 3px green;
margin: 30px 0;
width: 950px;
}
iframe{
width: 100%;
}page.css
/*
Theme Name: theme-wp
Author: Queseo
Author URI: http://queseo.es/
Description: My first responsive HTML5 theme
Version: 1.0
License: GNU General Public License v3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
.content-thin {
width: 100%;
}
.content-area{
width: 100%;
}
.article-loop {
width: 32%;
text-align: left;
margin: 5px;
padding: 10px;
}How the hooks and functions work
Seeing all the code like this can be a little confusing. The code above is made up of HTML, CSS and PHP. With the PHP code, we use hooks and functions to retrieve information from our database and display it on our front end.
The basics
Below I will show you the hooks and functions I have used in the code above, with a brief explanation. For more help with them, I recommend you visit the reference page of WordPress for developers :
- language_attributes(): inserts the language.
- bloginfo(‘name’): inserts the name of the blog.
- is_front_page(): checks whether the page is a page or a post.
- bloginfo(‘description’): inserts the blog description.
- wp_title(»): displays the page title for all areas of the blog.
- bloginfo( ‘charset’ ): inserts the meta charset.
- bloginfo(‘stylesheet_url’): inserts the default stylesheet.
- is_single(): tells us whether the page is loaded with single.php.
- esc_url( home_url() ): esc_url checks and cleans the URL, while home_url returns the URL of the current website.
- wp_head(): writes scripts or data into the head tag.
- body_class(): displays the class for the body element.
- wp_nav_menu( array( ‘theme_location’ => ‘header-menu’ ) ): with wp_nav_menu we display the navigation menu, while with
array( ‘theme_location’ => ‘header-menu’ ) we specify the menu we want to use, which is declared in our functions.php. - get_header(): loads header.php.
- have_posts(): queries WordPress to check whether there are any posts.
- the_post(): iterates through the posts displayed within the loop.
- the_permalink(): displays the permalink for the current page.
- the_title_attribute(): displays the current title. Similar to the_title() function.
- the_title(): displays the current title.
- the_post_thumbnail(‘medium’): displays the featured image of the page or post at a medium size. There are also other sizes such as thumbnail, large, full, etc.
- the_author(): displays the author.
- the_excerpt(): displays the post excerpt.
- get_footer(): loads footer.php.
- the_content(): displays the post content.
- is_active_sidebar( ‘sidebar’ ): determines whether the sidebar is in use, in other words, it checks whether there are widgets in the sidebar.
- dynamic_sidebar( ‘sidebar’ ): displays the dynamic sidebar, in other words, the widgets included in the sidebar.
- get_sidebar(): loads the sidebar template (sidebar.php).
- wp_footer(): loads scripts and data before the closing body and html tags.
WordPress loops
The loop I use in WordPress is for displaying articles automatically:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<article class="article-loop">
<header>
<h2>
<a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
<?php the_title(); ?>
</a>
</h2>
<div><?php the_post_thumbnail('medium');?></div>
<i><?php the_author(); ?></i>
</header>
<?php the_excerpt(); ?>
</article>
<?php endwhile; else : ?>
<article>
<p>Sorry, no posts were found!</p>
</article>
<?php endif; ?>With this code we create a conditional loop: if there are blog articles, then for as long as there are, it will publish the title, the image, the author and a short introductory text, and if there are none, it will display a short error message in English.
Optimisation tip
In fact, as you can see, there is more code than necessary. I did this to optimise the code a little more, so that it would also be more convenient for me to work with the template in future,
Selective loading of CSS and JS
As you can see in the header.php file, I selectively load two different stylesheets, one for the blog and another for normal pages. This is the code in question:
<?php
if( is_single()):?>
<link rel="stylesheet" href="
<?php echo esc_url( home_url() ); ?>/wp-content/themes/theme-wp/blog.css">
<?php ;
else:?>
<link rel="stylesheet" href="
<?php echo esc_url( home_url() ); ?>/wp-content/themes/theme-wp/pages.css">
<?php ;
endif;
?>First, we check whether or not the page is a blog article, with if (is single()). If it is a blog article, it loads the blog.css file, and if it is not, it loads page.css.
What I do for this template is have three CSS files, one generic, another for blog articles and another for pages. This makes it easier for me to maintain a standard across the whole website, although the truly optimal approach would be to have a single CSS file for each page.
We can sort this out later with a plugin, as there will be other plugins that leave their own CSS, and it will still be necessary to merge them all in a practical way.
Conclusions
As you can see, making a theme for WordPress is fairly simple. I wanted to include a few more things, such as creating new page layouts and plugins, but I think all this is enough.
As you can see, the theme is still something of a beta, and the idea is to improve it bit by bit over time, so with patience and plenty of care, I will gradually shape the design of my blog.
I have put the files on Github in case anyone wants to download them and upload them straight to their website.
This article and its code are originally by Diana, whom I mention below, and I have left you a link to her post. The post is the same, although I made some changes to the code and added a few extra bits.
If you liked the post, I would be grateful if you shared it =)
Sources
How to create a responsive WordPress theme using HTML5? – Diana C.



