Miawa
Miawa

Reputation: 312

Initialize second theme only for blog in Wordpress

I developed a website with blog using wordpress. After I had my theme ready the website owner asked me to use other theme which he bought only for the website's blog.

How can I initialize this second theme without setting it as website theme on the options table?

I could do it defining the constant TEMPLATEPATH in wp-includes/default_constants.php

function 'wp_templating_constants':
define('TEMPLATEPATH', get_theme_root() . '/theme-name');

And setting filters for:

pre_option_template, template, pre_option_current_theme, stylesheet_directory_uri, stylesheet_directory in the functions.php of the theme.

But of course, I want to do it dynamically after knowing if the user is or is not on a blog page. Does anyone have any idea how to do it?

Upvotes: 0

Views: 384

Answers (1)

Miawa
Miawa

Reputation: 312

Here is the code for a plugin to set a theme to a list of categories which is not the theme defined on the database.

new SetTheme('[THEME_NAME]', array('[CAT_NAME]', [CAT_ID], [CAT_OBJECT]));

class SetTheme {
    private $theme_name = '';
    private $categories = array();

    public function __construct($theme_name, $categories) {
        // define original theme location for any reason
        define('ORIGTEMPLATEPATH', get_template_directory());
        define('ORIGTEMPLATEURI', get_template_directory_uri());

        // init class parameters
        $this->theme_name = $theme_name;

        foreach ($categories as $cat) {
            if (is_string($cat))
                $cat = get_category_by_slug($cat);

            $category = get_category($cat);
            $this->categories[$category->term_id] = $category;
        }

        // apply action to setup the new theme only on action 'setup_theme'
        // because some functions are not yet loaded before this action
        add_action('setup_theme', array($this, 'setup_theme'));
    }

    public function setup_theme() {
        // if the current post or category is listed, apply the new theme to be initialized
        if ($this->is_category_theme())
            $this->set_theme();
    }

    private function is_category_theme() {
        // get category from current permalink
        // and check if is listed to apply the new theme
        $current_cat = get_category_by_path($_SERVER["HTTP_HOST"] . $_SERVER['REQUEST_URI'], false);
        if (isset($this->categories[$current_cat->term_id])) return true;

        // get post from current permalink
        // and check if it belongs to any of listed categories
        $current_post = url_to_postid($_SERVER['REQUEST_URI']);
        $post_categories = wp_get_post_categories($current_post);
        foreach ($post_categories as $cat_id)
            if (isset($this->categories[$cat_id])) return true;

        return false;
    }

    private function set_theme() {
        // apply the filters to return the new theme's name
        add_filter('template', array($this, 'template_name'));
        add_filter('stylesheet', array($this, 'template_name'));
    }

    public function template_name() {
        // return new name
        return $this->theme_name;
    }
}

The parameters of the class are the theme name and an array of categories (ids, slugs or category objects).

Of course, this is what i need, probably for other themes it will be required other filters in the function 'set_theme'.

It needs to be a plugin because plugins are loaded before the theme and even before WP class.

With this plugin the original plugin will never be called (at least on my case).

Upvotes: 1

Related Questions