5

Please note this is all "working" - the question is about the best practice and to try and work out why I need to include the PHP file which contains the class in two places for it to work correctly.

I'm working on a simple parent theme to speed up my own development cycle - and have got to the point of testing a simple child theme.

I understand that the functions.php file for the child is called up before the parent functions.php - which includes all the PHP functions and a class for adding CPT's.

I would like to build the CPT from the child theme - I want the parent to contain all the reusable and update-able functionality - but not to pre-build added features into each WP install it's used on.

To the code question:

I tried to include the class (which is in a separate PHP file) in the child functions.php and then instantiate an instance - for example:

require_once TEMPLATEPATH."/library/cpt/cpt.php"; // CPT class ##
$cpt_tree = new Custom_Post_Type( "tree" ); // New CPT - "tree" ##

Reloading the page gives an error:

Fatal error: Class 'Custom_Post_Type' not found in C:\xampp\htdocs\site\wordpress\wp-content\themes\child\functions.php on line 14

So, then I included the same PHP file in the parent functions.php file - and it all works - as an experiment I removed the class from the child theme - and it gives the same error.

I know this question is lacking lots of code examples - I'm hoping it will ring a bell with someone - or someone who understands more about using Classes will be able to give me some pointers - seems silly to require this file in two places and I'll like to keep the functions.php file as clean as possible.

1 Answer 1

5

Handle all the class loading in your parent theme on a predictable action (point in time) and hook in later in your child theme.

Example:

add_action( 'wp_loaded', 'parent_prefix_load_classes', 10 );

function parent_prefix_load_classes()
{
    $classes = [ 'Extra_Comment_Walker', 'Extra_Nav_Menu_Walker' ];

    foreach ( $classes as $class )
    {
        locate_template( "php/class.$class.php", TRUE, TRUE );
    }
}

Create instances in your child theme make sure your code runs after the classes are loaded:

// Priority 11 to run after the parent theme's loader.
add_action( 'wp_loaded', 'child_prefix_create_objects', 11 );

function child_prefix_create_objects()
{
    $nav_walker = new Extra_Nav_Menu_Walker;
}

Rules of thumb:

  • Never load anything just when the file (function.php) is called. Wait for wp_loaded.
  • Use the priority argument to control the order of execution.

Some notes:

  • Custom post types, taxonomies and shortcodes belong to plugins. They should never be part of a theme, because that would create a lock-in effect for the user. If a theme switch would break the content you did something wrong.
  • Do not use require_once in a theme. locate_template() is more flexible. You can overwrite the whole class now in your in child theme if you use the same directory structure.
2
  • excellent! - I'll give the a go now, the load order did come to mind, but I got lost in learning a bit more about classes.. BTW - I'm trying not to push things pre-loaded in the theme - but to include code to allow them - such as adding custom post types - using a plugin is a good answer, but what makes it better than including a class in a "framework" - which a developer can access in the theme, review, learn from and adapt to their requirements and of course fully control the output over?
    – Q Studio
    Commented Oct 29, 2012 at 15:11
  • 1
    The answer is a library in a separate plugin. Once the library has loaded all necessary files it fires do_action('library_loaded'); and the plugin can start here.
    – fuxia
    Commented Oct 29, 2012 at 16:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.