Wordpress - Is it possible to make grandchild themes?
Yes and No.
You could create a child theme specifying another child theme as the parent, and WordPress would attempt to use it.
However
You will run into issues, not to mention that the core devs have explicitly stated that this is not desirable behaviour, and they will not make efforts to support grandchild themes.
For example, WP API's make a distinction between stylesheet and template URLs/directories, where stylesheet always refers to the active theme, and template refers to the parent theme, but if a grandparent theme is included, does get_template_directory_uri
reference the parent or the grandparent? Lots of API calls are now ambiguous, and different people would expect different behaviour, including code that's in core. You'd also need to load the functions.php
of either the parent or grandparent, and make sure that it's done in the correct order.
It's also considered very bad practice. If you have a need for grandchild themes then your approach has taken a wrong turn, and you need to step back and re-evaluate things.
I would advise you avoid the concept of grandchild themes, it will lead to more problems. Instead more hooks filters actions and modularity in your child theme should enable you to keep the child themes shared components the same, and let you branch/fork with little difficulty. Try moving common elements into an svn external/git submodule.
There's also the _s model where you have your child theme as a base, and fork it, rather than having it as a parent with the intention you work on the copy, rather than a child/override.
I did not fully tested the method described below , Nor a normal "grandchild" theme , But giving the functionality of the template_include filter :
/*
Plugin Name: Grandchild Themes
Plugin URI: http://www.who-cares.com/
Description: A concept for Grandchild themes Plugin
Author: See Plugin URI
Version: 0.0.0.0.1-Alpha
*/
add_action('wp_head', 'grnd_chld_add_headers', 0);
add_action('init', 'grnd_chld_add_css');
// Load template if exists.
function grandchild_template_include( $template ) {
if ( file_exists( untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/grnd_chld_templates/' . basename( $template ) ) )
$template = untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/grnd_chld_templates/' . basename( $template );
return $template;
}
// This is the actual filter that we want .
add_filter( 'template_include', 'grandchild_template_include', 11 );
function grnd_chld_add_headers () {
wp_enqueue_style('my_grandchild_style');
}
function grnd_chld_add_css() {
$stamp = @filemtime(plugin_dir_path(__FILE__).'/style.css'); // easy versioning
wp_register_style ('my_grandchild_style', plugins_url('style.css', __FILE__).'', array(), $stamp);
}
// From here , what you got is like a normal functions.php.
You can also, in a similar way , try more specific filters like for example archive_template
add_filter ('archive_template', create_function ('', 'return plugin_dir_path(__FILE__)."archive.php";'));
All that said and done , I am not sure it is the best way to do things .