Initialization Script for “Standard” Aspects of a WordPress Website?

As I mentioned I was going to be start working on this need immediately so I’m making headway. Given that I’m knocking these down I figured it’s best to start posting them. Still, if someone else can/will post (some of) the parts I haven’t done I’ll be happy to let you copy whatever I’d done you haven’t and select your answer as the best answer. Until then I’m going to start posting the code.

First Thing: Include wp-load.php:

Since we’re creating a standalone file in the root of the website to run initialization that will only be used to “bootstrap” a site (I called mine /my-init.php) we start by including /wp-load.php to load the WordPress API functions:

<?php
include "wp-load.php";

Creating Users for the Site

We’ll use the wp_insert_user() function located in /wp-includes/registration.php to create our users. This file is not loaded by default so we’ll have to load it ourselves with a call to require_once().

We’ll also use the get_user_by() function to first see if the user has already been created; no need to run the code twice if they haven’t. NOTE: This is a pattern will follow; e.g. our script should not duplicate or overwrite anything if called multiple times, especially after users have added or changed data for any of the items we plan to initialize.

require_once( ABSPATH . WPINC . '/registration.php');     
$user = get_user_by('slug','johnsmith');
if (!is_object($user)) {
  wp_insert_user(array(
    'user_login'        => 'johnsmith',
    'role'              => 'administrator',
    'user_email'        => '[email protected]',
    'user_url'          => 'http://example.com',
    'first_name'        => 'John',
    'last_name'         => 'Smith',
    'comment_shortcuts' => '',
    'use_ssl'           => '0',
    'user_pass'         => '12345',
  ));
}

Deleting the “Hello Dolly” Plugin

To delete the “Hello Dolly” plugin (sorry Matt) we’ll use the delete_plugins() function. delete_plugins() expects an array of file paths that are relative to the /wp-content/includes/ directory. For the Hello Dolly plugin the file path is simply hello.php since the Hello Dolly plugin isn’t stored in it’s own directory but for most plugins it will be in the form of {$subdir}\{$filename}.php; i.e. the file path for Akismet is akismet/akismet.php.

However, delete_plugins() is not available until we’ve included /wp-admin/includes/plugin.php and there’s also a dependency with wp-admin/includes/file.php so we require_once() both of those before we call delete_plugins(). Finally we use WP_PLUGIN_DIR constant combined with file_exists() to see if the main plugin file exists before we attempt to delete it (not that is would matter if we tried to delete a missing file, but it’s more elegant to actually check first and you might need to know how for some other reason):

require_once(ABSPATH . 'wp-admin/includes/plugin.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
if (file_exists(WP_PLUGIN_DIR . '/hello.php'))
  delete_plugins(array('hello.php'));

Note that sometimes delete_plugins() will fail because of file permissions or maybe the fact a plugin is currently activated or some other reason that you’ll first need to resolve but for our use-case Hello Dolly goes away without a fight.

Downloading, Installing and Activating Repository Plugins

I don’t actually need to download plugins from the repository right now (I was thinking it would just be a nice to have) we’re going to let this requirement slide and revisit it later.

Activating Your Plugins

Next up is activating our own custom plugins. We are assuming we have already uploaded them to the plugin directory and all we need to do it activate them for WordPress. (Note: This technique will work for activating repository plugins too, it just won’t download and install them first.)

We’ll use the activate_plugin() function which like delete_plugins() requires /wp-admin/includes/plugin.php to be included but does not need /wp-admin/includes/file.php in case you are only needing to automate activation and not deletion.

We’ll again test for existence (not need to activate if not there, eh?) and we’ll also verify using the is_plugin_active() function that the plugin has not already been activated. Note I used a few variables this time ($plugin_filepath and $plugin_dir) to keep from duplicating the plugin identifier numerous times.

Our example that follows activates the plugin my-custom-plugin.php which is located in the my-custom-plugin subdirectory:

require_once(ABSPATH . 'wp-admin/includes/plugin.php');
$plugin_filepath="my-custom-plugin/my-custom-plugin.php";
$plugin_dir = WP_PLUGIN_DIR . "/{$plugin_filepath}";
if (file_exists($plugin_dir) && !is_plugin_active($plugin_filepath))
  activate_plugin($plugin_filepath);

Activating Your Preferred Theme

Activating a theme is a bit easier than deleting or activating a plugin, comparatively speaking; one function call is all that is required: switch_theme(). The switch_theme() function accepts two (2) parameters: the template and the stylesheet. Well, at least that’s what the parameters are named. You might be more familiar with the terms Parent Theme and Child Theme.

Assuming you’ve created a Child Theme with the default TwentyTen theme that comes with WordPress being the Parent Theme and you called it “My Custom Theme” and placed it into the /wp-content/themes/my-custom-theme directory, you’d activate your theme using this call:

switch_theme('twentyten', 'my-custom-theme');

But what if it is not a child theme? That’s easy, just pass the directory slug/theme identifier (i.e. the name of subdirectory off of /wp-content/themes that contains your theme) as both parameters. Assuming you want to activate the Thematic theme by Ian D Stewart you’ve call switch_theme() like so:

switch_theme('thematic', 'thematic');

Personally I think it’s a bit whacky to have to keep track of both details here so I wrote a function called activate_my_theme() that first checks to make sure the the get_current_theme() function and if not activates it. You just need to tell it the child theme (aka the “stylesheet”) and it figures out the parent theme for you (aka the “template”) by grabbing the details from the get_theme() function.

activate_my_theme('My Current Theme');
function activate_my_theme($theme_name) {
  if ($theme_name!=get_current_theme()) {
    $theme = get_theme($theme_name);
    switch_theme(
      $theme['Template'],
      $theme['Stylesheet']
    );
  }
}

One key point to be aware of; the get_theme() function expects to be passed the name of the Child Theme, NOT it’s directory slug/theme identifier. (The name comes from the “Theme Name:” section in the header of the theme’s style.css file. Fortunately the get_current_theme() function returns the name too.)

Inspecting the header in the style.css file of the WordPress default theme Twenty Ten we see it’s name is in fact 'Twenty Ten':

/*
Theme Name: Twenty Ten
Theme URI: http://wordpress.org/
Description: The 2010 theme for WordPress is stylish, customizable, simple, and readable -- make it yours with a custom menu, header image, and background. Twenty Ten supports six widgetized areas (two in the sidebar, four in the footer) and featured images (thumbnails for gallery posts and custom header images for posts and pages). It includes stylesheets for print and the admin Visual Editor, special styles for posts in the "Asides" and "Gallery" categories, and has an optional one-column page template that removes the sidebar.
Author: the WordPress team
Version: 1.1
Tags: black, blue, white, two-columns, fixed-width, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style
*/

Deleting the “Hello World” Post

Next we want to delete the “Hello World” post. You may have seen that @Rarst has shown us how to use the wp_delete_post() function which is exactly what we need. As he explained the second parameter will fully delete the post as opposed to moving it to the trash and the first parameter is the $post->ID.

Of course it would be nice to be able to specify the slug instead of the $post->ID and so I decide to find a way to do that. After some spelunking I found that WordPress has an unfortunately named function called get_page_by_path() which actually allows us to look up any post type by its slug (it is unfortunately named because you might overlook it when trying to find something that works with post types other than 'page'.)

Since we passing get_page_by_path() the WordPress-defined constant OBJECT it will return to us a post in the form of an post object. For the third parameter we passed 'post' to indicate we wanted it to lookup post types of 'post'. Since get_page_by_path() will return the post object we need or return null if no post matches the slug we can check for existence and do a lookup at the same time:

$post = get_page_by_path('hello-world',OBJECT,'post');
if ($post)
  wp_delete_post($post->ID,true);

Note: We could have run code to delete every post in the database but if we had we would not be able to run this code again once we’ve added the posts we want to keep and that was one of our design constraints.

Next…

I’ll keep adding to this as I figure it out until I’m done or until someone else helps out.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)