Reputation: 312
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
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