I am having trouble with sub theming, and any help I can get would be greatly appreciated. This is going to take some explaining...

I am using a custom theme originally created by another company. The way they set up their template system is by setting up a series of broken out template pages in a 'templates' subdirectory, and then including them. So for example, we have a templates/template.preprocess.php and template/template.form.php files. Then in the template.php file, it has something like:

$theme_include_files = drupal_system_listing('.php$', path_to_theme() . '/templates', 'name', 0);
foreach($theme_include_files as $theme_include_file) {
  require_once('./' . $theme_include_file->filename);
}

So any .php file thrown into the templates directory gets loaded in by template.php, and this way the theme functions are grouped and organized.

(Likewise, .tpl.php files are in a tpl/ directory, with type subdirectories, i.e. tpl/page/page.tpl.php and tpl/block/block.tpl.php.)

Now we want to create a sub-theme of this parent theme. We want to inherit all the parent theme functions, so any future modifications/additions to the parent theme will be carried down to the subtheme unless specifically overridden. But it is not working well.

First, the template pages in the 'templates' subdirectory weren't being loaded. So in the subtheme's template.php I did a lookup of the subtheme->base_theme, and make sure I included the same files the parent's template.php is. This helped me define all the parent theme functions, but they still weren't being run.

So I then tried a very kludgey hack of getting all the defined functions of the parent theme, and defining new functions with the subtheme that call the parent functions. For example, if I had the function parenttheme_preprocess_block(), and !function_exists('subtheme_preprocess_block'), I defined

function subtheme_preprocess_block(&$a0 = NULL, &$a1 = NULL){
  return parenttheme_preprocess_block($a0, $a1);
}

And this more or less got my subtheme's functions defined. But again, they still weren't executing.

I finally looked at the theme registry array. And when the parenttheme was the theme, I got something like this:

    [block] => Array
        (
            [template] => block
            [path] => sites/all/themes/parenttheme/tpl/block
            [type] => theme_engine
            [theme path] => sites/all/themes/parenttheme
            [arguments] => Array
                (
                    [block] => 
                )

            [theme paths] => Array
                (
                    [0] => modules/system
                    [1] => sites/all/themes/parenttheme/tpl/block
                )

            [preprocess functions] => Array
                (
                    [0] => template_preprocess
                    [1] => template_preprocess_block
                    [2] => parenttheme_preprocess
                    [3] => parenttheme_preprocess_block
                )

        )

But when the subtheme was the active theme, it looked like this:

    [block] => Array
        (
            [template] => block
            [path] => sites/all/themes/parenttheme/tpl/block
            [type] => theme_engine
            [theme path] => sites/all/themes/parenttheme
            [arguments] => Array
                (
                    [block] => 
                )

            [theme paths] => Array
                (
                    [0] => modules/system
                    [1] => sites/all/themes/parenttheme/tpl/block
                )

            [preprocess functions] => Array
                (
                    [0] => template_preprocess
                    [1] => template_preprocess_block
                )

        )

The parenttheme was still the theme path, and the preprocess functions no longer had parenttheme_preprocess or parenttheme_preprocess_block in the list (let alone subtheme_preprocess or subtheme_preprocess_block.)

So what am I missing? What do I need to do to get my subtheme's functions into the theme registry? (Or what other approach can I use to get subtheming to work, given the parent theme's template structure?)

Comments

hferree’s picture

You've probably already tried this but I didn't see any mention of this and in the off chance that you haven't hear goes:

Have you tried treating the main template as a CSS framework theme such as blueprint, zen, etc? With those (or at least blueprint which is all I've used so far) you have 2 folders in the theme directory which are completely separate (ex: a blueprint folder and a mysubtheme folder), but you create your mysubtheme with the mysubtheme.info file with the text:

name = My NAME_OF_MAIN_THEME Subtheme
description = My description
core = 6.x
base theme = NAME_OF_MAIN_THEME
see http://drupal.org/taxonomy/term/6182

(I'm sorry for your headache. One of my first experience with a subtheme was a folder within a folder and it also had yet another folder...still don't know how it was made to work...I've had the best of luck with technique listed above. You can update your main theme or subtheme as much as you want and as long as all the code works -- all the files will be happy).

Good Luck,

Holly Ferree
designbyholly.com

Matt-H’s picture

Thanks Holly. That's a good idea, and at this point, I do think it would have been nice if the original theme was based on a starter/framework theme like zen or blueprint. (Hindsight is 20/20.) But to use a starter theme now, it would mean re-building the theme we have, which would be a lot of work that my company might not go for. I'm not going to completely rule that option out, but at this point in the project, we would rather get sub-theming working with the theme we already have if possible.

Matt-H’s picture

I was looking at old posts of mine and saw this thread. Since I figured it out a while ago, I thought I should post the solution. The real problem I had was that I was using path_to_theme(). When in the sub theme, path_to_theme() gave the path of the sub theme, so it wouldn't load the proper broken out template pages, even though the parent template.php was being run.

The solution then was to use drupal_get_path() to get the path of the parent theme instead.

$theme_include_files = drupal_system_listing('.php$', drupal_get_path('theme', 'parenttheme') . '/templates', 'name', 0);
foreach($theme_include_files as $theme_include_file) {
  require_once('./' . $theme_include_file->filename);
}