Skip to content

Creating a Theme

alex_prokopenko edited this page Jan 12, 2018 · 3 revisions

Creating a theme from a Boilerplate

You can find theme build example here: https://github.com/justcoded/wordpress-theme-boilerplate. This theme is fully working, has example of most features of current framework. It has full documentation explaining all aspects of file structure and how all things works together. We strongly recommend to use it if you are new to this framework.

As a part of WordPress Starter we have custom composer commands, which generates a theme with a custom name, namespace and textdomain.

Conecting framework to existing theme

We will not explain how to create a theme from scratch, because it's too time consuming. You can take some minimal starter theme like underscore or use a copy of standard Twenty Seventeen theme.

Inside this article we will explain how to connect framework to a theme and what aspects you will need to update to make it works.

Step 1: Prepare a usual theme

Imaging we generated a theme foo with underscore theme generator. Actually we will refactor 80% of the code... Make a copy of functions.php (like functions-old.php ) file and clean it up completely!

Step 2: Check requirements and setup Autoloader

Our theme won't work without Theme Framework plugin, so we need to be sure it's loaded. Copy requirements.php file from plugin folder to your theme.

functions.php

<?php
require_once get_template_directory() . '/requirements.php';
if ( ! Just_Theme_Framework_Checker::single()->check_requirements() ) {
	// terminate if titan plugin is not activated.
	return;
}

Let's assume that we will place all our custom code and components inside the {theme}/app folder. To not include each new file we create - we will register PSR-4 Autoloder for our namespace (let's call it BarCompany\Theme):

functions.php:

<?php
require_once get_template_directory() . '/requirements.php';
if ( ! Just_Theme_Framework_Checker::single()->check_requirements() ) {
	// terminate if titan plugin is not activated.
	return;
}

new \JustCoded\WP\Framework\Autoload( 'BarCompany\Theme', get_template_directory() . '/app' );

Now we don't need to write include() statements for any classes we will create inside /app/ folder.

Step 3: Theme setup / configuration

As we mentioned we use object-oriented code. And a framework is a collection of base classes to use inside a theme. The very first one is a Theme class.

app/Theme.php

<?php
namespace BarCompany\Theme;

/**
 * Theme main entry point
 *
 * Theme setup functions, assets, post types, taxonomies declarations
 */
class Theme extends \JustCoded\WP\Framework\Theme { // have to extends from base class.
	/**
	 * Register styles and scripts
	 *
	 * Called on 'wp_enqueue_scripts'
	 */
	public function register_assets() {
		// Stylesheets.
		$this->register_assets_css( array(
			'styles.css',
		) );

		// Scripts.
		$this->register_assets_scripts( array(
			'jquery.main.js',
		), array( 'jquery' ) );

		if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
			wp_enqueue_script( 'comment-reply' );
		}
	}
}

Now we need to create an instance of our Theme class to load it.

functions.php:

<?php
require_once get_template_directory() . '/requirements.php';
if ( ! Just_Theme_Framework_Checker::single()->check_requirements() ) {
	// terminate if titan plugin is not activated.
	return;
}

new \JustCoded\WP\Framework\Autoload( 'BarCompany\Theme', get_template_directory() . '/app' );
$theme    = \BarCompany\Theme\Theme::instance();

This class implements after_theme_setup hook and many other. You can check Theme Component documentation and try to move different theme settings from functions-old.php underscore file.

For example - register sidebar:

app/Theme.php

<?php
namespace BarCompany\Theme;

class Theme extends \JustCoded\WP\Framework\Theme {
	
	// ...
	
	/**
	 * Register theme sidebars
	 *
	 * Called on 'widgets_init'
	 */
	public function register_sidebars() {
		register_sidebar( array(
			'name'          => esc_html__( 'Sidebar', 'boilerplate' ),
			'id'            => 'sidebar-1',
			'description'   => '',
			'before_widget' => '<aside id="%1$s" class="widget %2$s">',
			'after_widget'  => '</aside>',
			'before_title'  => '<h2 class="widget-title">',
			'after_title'   => '</h2>',
		) );
	}
}

Step 4: Convert templates into Views

First of all read the documentation about views:

After reading the documentation you can try to reformat your templates.

  • Create views folder structure
├── views/                  # → Templates
│   ├── layouts/            # → Template wrapper templates
│   ├── partials/           # → Small template parts same for several sections. (Header, footer, etc.)
│   │
│   ├── page/               # → Page templates (like front-page, page-*, etc.)
│   ├── post/               # → Post templates (like index, archive, single, etc.)
│   └── search/             # → Search templates
  • Move all root templates inside page, post, search folders (even index.php)
  • Create theme root index.php with Views run() method

{theme}/index.php

<?php
/**
 * Main template in WordPress theme.
 * Used to load views engine
 *
 * @see /views/ folder instead
 * @var $template \JustCoded\WP\Framework\Web\View
 */

$template->run();
  • Create views/layouts/main.php as concatenation of header.php content, <?php echo $content; ?>, footer.php file content.
  • Update all templates inside page, post, search - remove duplicated code, add $this->extends() statement.
  • Move templates from /template-parts to /views/partials and replace all get_template_parts() with $this->include().

Step 4: Resolve errors

Of course noone can do all these steps without any error. My friend, I think you will spend 2-4 hours going back and forward through templates to correct all errors and find what else should be fixed to make it works.

And finally you will have a working theme example you can start adding features 😃

Step 5: Register Post Types and Taxonomies

If you need custom Post Types or Taxonomies, you can defined them by creating a simple classes.

Step 6: Checking required 3d-party plugins support

Check the documentation for available components for supporting of 3d-party plugins and configure them, if you need some of them: