• Resolved Contortion

    (@contortion)


    How can I override the main functions using a child theme?

    I have tried putting something like this in the child theme but it gives me a blank page :

    if ( ! function_exists( 'neutro_wrapper_attribute' ) ) :
    
    function neutro_wrapper_attribute(){
    	$attributes = '';
    
    	if(!is_singular() && !is_404() ){
    		$attributes = 'class="content" id="container" ';
    	}
    	else{
    		$attributes = 'class="single-content" ';
    	}
    
    	if(has_filter( 'add_neutro_wrapper_attribute') ){
    		$attributes = apply_filters( 'add_neutro_wrapper_attribute', $attributes );
    	}
    
    	echo $attributes;
    }
    
    endif;

    It’s strange because this method works with other themes I have installed, just not with the Neutro theme

Viewing 8 replies - 1 through 8 (of 8 total)
  • A child theme’s functions.php file loads before the functions.php file of the parent. So in your case the function neutro_wrapper_attribute is created by the child theme as it is loaded first.
    But this function in the functions.php of the parent theme doesn’t check if this function exists and straight away tries to create the function again which is causing the white screen.

    If you can share what you’re trying to achieve I can tell you alternate ways to do it.

    Thread Starter Contortion

    (@contortion)

    Thanks for the reply, I just want to know how to override any function in the ‘Neutro’ theme by using a child theme. Why does the method above work in some themes and not others? It says in Neutro functions.php

    If making customizations, users should create a child theme and make changes to its functions.php file (not this one). Friends don’t let friends modify parent theme files. 😉
    Child themes should do their setup on the ‘after_setup_theme’ hook with a priority of 11 if they want to override parent theme features. Use a priority of 9 if wanting to run before the parent theme.

    So it seems it can be done. What am I missing? Do I have to include all functions from the main functions.php in my child theme functions.php or just the ones I want to modify? What does the author mean by “Child themes should do their setup on the ‘after_setup_theme’ hook with a priority of 11 if they want to override parent theme features”? I’m lost

    Why does the method above work in some themes and not others?

    That is because those themes have a function_exists check before they define a function. Taking a function from the Twenty Thirteen theme as an example it has the following code in its functions.php file.

    if ( ! function_exists( 'twentythirteen_paging_nav' ) ) :
    /**
     * Display navigation to next/previous set of posts when applicable.
     *
     * @since Twenty Thirteen 1.0
     *
     * @return void
     */
    function twentythirteen_paging_nav() {
    //Some code here
    }
    endif;

    Now if you wanted to override this function all you have to do is to define this function in your Child Theme’s functions.php file. So the parent theme will check if this function exists and won’t run this block at all.

    From the functions.php file of Twenty Thirteen.

    When using a child theme (see http://codex.wordpress.org/Theme_Development and http://codex.wordpress.org/Child_Themes), you can override certain functions (those wrapped in a function_exists() call) by defining them first in your child theme’s functions.php file.

    Now for your other questions

    What does the author mean by “Child themes should do their setup on the ‘after_setup_theme’ hook with a priority of 11 if they want to override parent theme features”?

    Look at this line of your functions.php (parent theme)

    add_action( 'after_setup_theme', 'neutro_theme_setup' );

    This is where a function called neutro_theme_setup is hooked. This function loads several stylesheets, scripts, theme features etc.

    So inside this function we have this line

    add_action('wp_head', 'neutro_customizer_css');

    which loads a particular CSS file inside the <head>.

    So if you wanted to remove it using a child theme this is what you’d have in the functions.php (child theme).

    add_action( 'after_setup_theme', 'my_theme_setup', 11 );
    
    function my_theme_setup()
    {
    remove_action('wp_head', 'neutro_customizer_css');
    }

    Notice the third parameter of add_action 11. This makes the my_theme_setup function execute after neutro_theme_setup. So the parent theme will add this CSS while your child theme will remove it.

    Also the theme author says

    Child themes should do their setup on the ‘after_setup_theme’ hook with a priority of 11 if they want to override parent theme features.

    Notice the word “features” here, the author didn’t say that “functions” can be overridden.

    More info
    http://codex.wordpress.org/Function_Reference/remove_action
    http://codex.wordpress.org/Function_Reference/add_action

    Thread Starter Contortion

    (@contortion)

    I tried what you said about overriding the function before I even posted this question, and tried again, still no luck. This is my entire Neutro child theme function.php file which gives me a blank page :

    <?php
    
    if ( ! function_exists( 'neutro_wrapper_attribute' ) ) :
    
    function neutro_wrapper_attribute(){
    	$attributes = '';
    
    	if(!is_singular() && !is_404() ){
    		$attributes = 'class="content" id="container" ';
    	}
    	else{
    		$attributes = 'class="single-content" ';
    	}
    
    	if(has_filter( 'add_neutro_wrapper_attribute') ){
    		$attributes = apply_filters( 'add_neutro_wrapper_attribute', $attributes );
    	}
    
    	echo $attributes;
    }
    
    endif;
    
    ?>

    Now what is wrong with this? Like I said, I have done exactly this with other themes and it works, why not this one?

    The following

    /*
    Theme Name:     Neutro Child
    Theme URI:      http://example.com/twenty-thirteen-child/
    Description:    Neutro Child Theme
    Author:         John Doe
    Author URI:     http://example.com
    Template:       neutro
    Version:        1.0.0
    */
    
    @import url("../neutro/style.css");

    should go inside the style.css of your child theme.

    Now coming to the rest of the code I think you didn’t get my point.

    You cannot override a parent theme’s function if it doesn’t have a function_exists check.

    A workaround is to define your own function like

    function my_own_wrapper_attribute(){
    	$attributes = '';
    
    	if(!is_singular() && !is_404() ){
    		$attributes = 'class="content" id="container" ';
    	}
    	else{
    		$attributes = 'class="single-content" ';
    	}
    
    	if(has_filter( 'add_neutro_wrapper_attribute') ){
    		$attributes = apply_filters( 'add_neutro_wrapper_attribute', $attributes );
    	}
    
    	echo $attributes;
    }

    in the child theme’s functions.php.

    Then copy the loop.php from wp-content/themes/neutro/ to wp-content/themes/neutro-child and change the function

    <div <?php my_own_wrapper_attribute(); ?>>
    
    		<?php if ( have_posts() ) { ?>
    
    			<?php while ( have_posts() ) { ?>
    
    				<?php the_post(); // Loads the post data. ?>
    
    				<?php hybrid_get_content_template(); // Loads the content template. ?>
    
    			<?php } // End while loop. ?>
    
    		<?php } else { ?>
    
    			<?php get_template_part( 'loop-error' ); // Loads the loop-error.php template. ?>
    
    		<?php } // End if check. ?>
    
    	</div>
    Thread Starter Contortion

    (@contortion)

    what a horrid way to do things when all that the parent theme needs is for each function to be wrapped with if ( ! function_exists( 'whatever' ) ) : so I can override it if needed. Why don’t the theme authors just wrap them all, or WordPress be made to automatically override main functions if a child theme contains one with the same name? Anyway thanks for the help, much appreciated.

    Here is a much simpler way. Since this function uses apply_filters you can use add_filter in your child theme’s functions.php like this.

    add_filter( 'add_neutro_wrapper_attribute', 'modify_attributes' );
    
    function modify_attributes( $attr )
    {
    	//Modify the value of $attr and return it
    	return $attr;
    }
    Theme Author hxh90

    (@hxh90)

    Hello,

    Sorry for the issues around child theme, I’m still learning on supporting child theme on my theme. I’ll try to fix it on the next update.

    Thanks.

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘How can I override the main functions using a child theme?’ is closed to new replies.