Creating Native Starter Content for WordPress Themes

Using starter content, we natively preconfigure our clean WordPress install and achieve a better user experience for our theme users.

Lately, we started to develop a free theme for WP, and one of our main inspiration in the code was the Twenty Seventeen theme where we found this great solution (which is a core feature but we didn’t use it until now). The feature was introduced in version 4.7.

There is some unique solution to generate starter content in WordPress; the most popular is the default importer. It is an excellent and advanced tool – based on XML – if we want to create a great overall result. For a primary user importing these settings aren’t the best experience in some case. So we need a cleaner, more natural and more WordPress way method.

The need for a starter content is self-evident. In case of a clean install, our theme settings will be set to default so it really can’t show its true shine and purpose. Using the starter-content option we can easily set a default state and some default content for our theme easily.

Let’s check out how it works and why it is useful!

Why Use The Native Starter Content

  • The main advantage of this method is that it is shown in the customizer so when we browse the theme through the wordpress.org we can see the config in the preview (and of course we also see it in our site’s customizer).
  • It is easy to configure, just a few lines if we want to use the predefined elements.
  • It is cover most of our needs.
  • We can set a static front and blog page; this is handy if we design a site with a unique front page and want to push the default blog functionality back.
  • Our user will get a better starting point if they turn it on.
Note that we mostly need this function if we develop a theme for public sharing, for a client job this is unnecessary.

How to enable the starter content

The starter content only appear on a fresh install if the site hasn’t any change in post, page, widget or customizer; this watched through the fresh_site setting in the options table which has a default value 1. If we want to test or debug our code in a “used” WP install reset it to 1 from 0, mostly the result will be the same.

Currently, there isn’t any way to reset this setting from the user side or to revoke it after it is applied through customizer.

After the theme is installed and enabled, we have to navigate to the customizer where we can see the starter content is populated. Here we can publish it with a simple save.

To enable the starter-content we have to define the add_theme_support( ‘starter-content’, [] ); in the after_setup_theme hook like the following:

$starter_content = array();
add_theme_support( 'starter-content', $starter_content );

It gets one array parameter where we set our defaults in the needed complexity. A simpler example will look something like this:

$starter_content = array(
    'posts' => array(
        'home',
        'about',
        'contact',
        'blog',
    ),
    'options' => array(
        'page_on_front' => '{{home}}',
        'page_for_posts' => '{{blog}}',
    ),
    'nav_menus' => array(
        'header' => array(
            'name' => __( 'Header Menu', 'ourtheme' ),
            'items' => array(
                'link_home',
                'page_about',
                'page_contact',
                'page_blog',
            ),
        ),
    ),
);

add_theme_support( 'starter-content', $starter_content );
For a great example check out Twenty Seventeen theme’s funcitons.php file.
Here you can see the Twenty Seventeen theme’s default content settings.

The Starter Content Types

Using this method, we can set posts, pages, attachments, nav_menus, options, theme_mods and widgets so basically everything which is necessary for a theme.

The core symbols are translated well so it will appear in the default site language.

Post and Pages

The most basic types are the posts and the pages (and any custom post types). We have predefined symbols like home, about, contact, blog, news, and homepage-section. We can use these values as a keyword like a shorthand.

We can also define custom pages too. The available fields are: post_type, post_title, post_excerpt, post_name (slug), post_content, menu_order, comment_status, thumbnail (featured image ID), and template.

add_theme_support( 'starter-content', array(
    'posts' => array(
        'custom' => array(
            'post_type' => 'post',
            'post_title' => 'Custom Post','post_content' => file_get_contents(get_template_directory_uri() . 'content/pages/custom.html'),
            'template' => 'custom-page-template.php',
        ),
    ),
);

For the post_content we can use a separate template if we don’t want to mix the content in our markup.

Attachments

We can create attachments in a complex format and use the defined symbols to set a thumbnail for our posts. The path for the file is theme root relative.

add_theme_support( 'starter-content', array(
    'attachments' => array(
        'featured-about' => array(
            'post_title' => 'About Cover Image',
            'post_content' => 'Attachment Description',
            'post_excerpt' => 'Attachment Caption',
            'file' => 'assets/images/about.jpg',
        ),
    ),
    'posts' => array(
        'about' => array(
            'thumbnail' => '{{featured-about}}',
        ),
    ),
);

Nav Menus

From our predefined pages or custom links, we can build up navigation and set its theme position.

add_theme_support( 'starter-content', array(
    'nav_menus' => array(
        'header' => array(
            'name' => __( 'Header Menu', 'ourtheme' ),
            'items' => array(
                'link_home',
                'page_about',
                'page_contact',
                'page_blog',
            ),
        ),
    ),
);

Options, Theme Mods

It is a great feature if we design a theme with a static front-page. If so we can set which predefined page should be this static page (which will automatically get the front-page.php template) like so:

add_theme_support( 'starter-content', array(
    'options' => array(
	'page_on_front' => '{{home}}',
	'page_for_posts' => '{{blog}}',
    ),
);

Widgets

We can target a specific widget area and add the core supported ones like archives, calendar, categories, meta, recent-comments, recent-posts, search and two more named text_business_info and text_about.

We can also register custom widgets too, but this is plugin territory. The later calls will overwrite the add_theme_support() in case of the starter content.

add_theme_support( 'starter-content', array(
    'widgets' => array(
	'sidebar-1' => array(
	    'text_business_info',
	    'search',
	    'text_about',
	),
    ),
);

Summary of WordPress starter-content

The starter-content is a feature in development. In my opinion, it is pretty cool and advanced, and we can achieve a lot with it. A cool feature would be a delete feature for all of the applied content, but it is still manageable without it. I think we shouldn’t create a lot of material in this way but to show our true theme characteristic. For this, it is a fantastic tool.