WordPress Themes

Build and activate a minimal classic theme

Description: Make a theme folder my-first-theme with a style.css (with the theme name) and an index.php that prints the site name in an h1 tag. Activate it and check the home page.

Hint:

  • The theme name goes in a comment at the top of style.css.
  • Use bloginfo( 'name' ) to print the site name.

Solution

/*
Theme Name: My First Theme
*/
<h1><?php bloginfo( 'name' ); ?></h1>
Terminal output

$ wp theme activate tc-my-first-theme
Success: Switched to 'My First Theme' theme.
$ wp theme list –status=active –fields=name,title
name title
tc-my-first-theme My First Theme
$ curl -s http://example.com/
<h1>Demo Site</h1>

How it works

  • WordPress finds a theme when there is a folder with a style.css which has a Theme Name.
  • index.php is the fallback template, so it is used for every page.

Read Theme Files and Functions.

Show the three latest posts with WP_Query

Description: In the front-page.php of a theme, show a list (ul) of the titles of the three latest posts, each as a link.

Hint:

  • Use new WP_Query( array( 'posts_per_page' => 3 ) ).
  • Call wp_reset_postdata() at the end.

Solution

<?php get_header(); ?>
<?php $latest = new WP_Query( array( 'posts_per_page' => 3 ) ); ?>
<ul class="latest">
<?php while ( $latest->have_posts() ) : $latest->the_post(); ?>
	<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; wp_reset_postdata(); ?>
</ul>
<?php get_footer(); ?>
Terminal output

$ curl -s http://example.com/ | sed -n '/<ul class="latest">/,/<\/ul>/p'
<ul class="latest">
<li><a href="http://example.com/post-four/">Post four</a></li>
<li><a href="http://example.com/post-three/">Post three</a></li>
<li><a href="http://example.com/post-two/">Post two</a></li>
</ul>

How it works

  • WP_Query gets the newest three posts, because the default order is by date, newest first.
  • the_post() sets the data of each post, so the_title() and the_permalink() work.
  • wp_reset_postdata() gives the global post data back.

Read WP_Query.

Load a stylesheet with wp_enqueue_style and a version

Description: Add a file css/custom.css in your theme and load it with the version 2.0. Check the tag which WordPress prints in the page.

Hint:

  • Use the hook wp_enqueue_scripts and the function wp_enqueue_style().

Solution

<?php
add_action( 'wp_enqueue_scripts', function () {
	wp_enqueue_style(
		'tc-custom',
		get_template_directory_uri() . '/css/custom.css',
		array(),
		'2.0'
	);
} );
Terminal output

$ curl -s http://example.com/ | grep "tc-custom" | sed 's/^[ \t]*//'
<link rel='stylesheet' id='tc-custom-css' href='http://example.com/wp-content/themes/tc-theme/css/custom.css?ver=2.0' media='all' />

How it works

  • wp_enqueue_style() adds the stylesheet to the queue, and WordPress prints the link tag in wp_head().
  • The version 2.0 becomes ?ver=2.0. When you change the file, change the version, so the browsers load the new file.

Read Enqueue Scripts and Styles.

Register a sidebar and show a widget in it

Description: Register a sidebar with the ID footer-area, show it in footer.php, add a Search widget to it and check the output.

Hint:

  • Use register_sidebar() on the widgets_init hook and dynamic_sidebar() in the template.
  • wp widget add adds a widget from the command line.

Solution

<?php
add_action( 'widgets_init', function () {
	register_sidebar( array(
		'name'          => 'Footer Area',
		'id'            => 'footer-area',
		'before_widget' => '<div class="widget">',
		'after_widget'  => '</div>',
		'before_title'  => '<h3>',
		'after_title'   => '</h3>',
	) );
} );
Terminal output

$ wp sidebar list –fields=name,id
name id
Footer Area footer-area
Inactive Widgets wp_inactive_widgets
$ wp widget add search footer-area 1 –title="Search the site"
Success: Added widget to sidebar.
$ curl -s http://example.com/ | grep -o '<div class="widget"><h3>[^<]*'
<div class="widget"><h3>Search the site

How it works

  • register_sidebar() creates the widget area, and dynamic_sidebar( 'footer-area' ) prints the widgets which are placed in it.
  • The HTML around the widget and the title comes from the parameters we gave.

Read Register Sidebar.

Show a message only on the front page

Description: Print the text Welcome to our site! at the end of the home page only. The text must not show on posts or pages.

Hint:

  • Use the wp_footer action and the conditional tag is_front_page().

Solution

<?php
add_action( 'wp_footer', function () {
	if ( is_front_page() ) {
		echo '<p class="welcome">Welcome to our site!</p>';
	}
} );
Terminal output

$ curl -s http://example.com/ | grep -o '<p class="welcome">[^<]*</p>'
<p class="welcome">Welcome to our site!</p>
$ curl -s http://example.com/hello-world/ | grep -c 'class="welcome"'
0

How it works

  • The function is attached to wp_footer, which runs on every front page.
  • is_front_page() is true only on the front page, so the message is missing on the post (the count is 0).

Read Conditional Tags.

Create a child theme which changes the footer

Description: Use the demo theme as parent. Create a child theme which has its own footer.php with the text Footer from the child theme. Activate the child and check the output.

Hint:

  • The child style.css needs a Template: line with the folder name of the parent.

Solution

/*
Theme Name: My Child Theme
Template: tc-theme
*/
<footer><p>Footer from the child theme</p></footer>
<?php wp_footer(); ?>
</body>
</html>
Terminal output

$ wp theme activate tc-child
Success: Switched to 'My Child Theme' theme.
$ wp eval 'echo get_template() . " is the parent, " . get_stylesheet() . " is the active theme";'
tc-theme is the parent, tc-child is the active theme
$ curl -s http://example.com/ | grep "<footer>"
<footer><p>Footer from the child theme</p></footer>

How it works

  • Template: tc-theme makes tc-theme the parent. WordPress loads every file from the child first, and from the parent when the file is missing in the child.
  • All other templates (header, index) still come from the parent.

Read WordPress Child Theme.