Support » Developing with WordPress » Unhooking Parent Them Customizer and Load through Child Theme

  • John

    (@shadowcrown)


    No page link as it’s a login and admin development::

    I’ve cast a pretty wide net to find an answer but nothing seems to quite hit the mark.

    Process:: I Login to my site/dashboard and I decide I need to edit a portion of my theme through the customizer, so I do, pretty straight forward…

    In the mean time, I’ve built up my child theme and it seems to work pretty well for a novice/amature and have generally figured out how to duplicate and edit particular .php files such as the footer, header etc… and, change (template to stylesheet) to load child theme images; however!

    I wanted to change and add new social media links in my footer and had to scratch my head for a fews days before figuring out how the customizer works and where the .php files are stored, so I could change and add new fab fa-icons icon.

    Problem:: my child theme function.php is doing what it needs to be doing, likewise with my pages, and is safeguarded form theme/wordpress updates, however! not my new “customerizer” changes, so I have to go back in and change them time over…

    I have found the location of the directory for the customizer, hence the ability to edit it, but to safeguard it from being changed is another thing.

    So far, I have copied the necessary files over etc, and with assistance, I have implemented this in child functions.php:

    function remove_parent_customizer() {
         remove_action('customize_register', 'business_prime_settings_control',1);
    }
    	require_once dirname( __FILE__ ) . '/inc/business-prime-customizer.php';
    add_action( 'init', 'remove_parent_customizer');	
    add_action( 'business_prime_settings_control_child', 'business_prime_customizer_child',2);

    This in theme-child/inc/theme-customerizer.php:

    function business_prime_settings_control_child($wp_customize) {
        # child functions ::  SCS customizer settings code
    }
    add_action('customize_register', 'business_prime_settings_control_child');

    …and then had to block out the parent function.php:

    #require get_template_directory() . '/inc/business-prime-customizer.php';

    The problem I’m facing, is that while the code is recoginsed and works a charm, I still have to edit the parent functions.php as it’s not dequeueing the function automatically as the rest of my child function.php is with other .js or .css files.

    So how do I point my child function.php at that new customiser address/files and automatically ignore the parent ones; the doesn’t seem to be an if wrapper?

    I can explain more if needs be. Many thanks and greatly appreciated

    John

    Edit and Additional info::

    I have also tried,

    locate_template( array( '/inc/business-prime-customizer.php' ), true );

    It too also works, and admittedly is cleaner, but i’m still faced with the same issue, I have to block out the file in the parent functions.php file.

    • This topic was modified 5 months, 2 weeks ago by John.
    • This topic was modified 5 months, 2 weeks ago by John.
Viewing 9 replies - 1 through 9 (of 9 total)
  • Moderator bcworkz

    (@bcworkz)

    Are you sure your parent theme adds the ‘business_prime_settings_control’ callback with a priority of 1? When removing actions, this must match the argument used when adding or the removal will fail silently.

    John

    (@shadowcrown)

    Hi and thanks for coming back @bcworkz,

    I’ve also tried numbers/text variations of, 0, 1, 2, 10, 100, 640 and true/false; even without a priority number!

    If I don’t block out # the customizer.php address in the parent funtions.php, then I get this message.

    “The site is experiencing technical difficulties.”

    So the code is working, it just seems to me there’s a conflict in the background over priority, maybe – then it’s overcoming that.

    If it helps, this is the parent functions.php, you can see where the IF statements are and where the FUNCTIONS start and end. I’ve also highlighted my edits to the, require get_template_directory() . '/inc/business-prime-customizer.php';

    Funtions.php::

    
    <?php
    
    if ( ! function_exists( 'business_prime_setup' ) ) :
    function business_prime_setup() {
    	load_theme_textdomain( 'business-prime', get_template_directory() . '/languages' );
    	add_theme_support( 'automatic-feed-links' );
    	add_theme_support( 'title-tag' );
    	add_theme_support( 'post-thumbnails' );
        add_theme_support( 'custom-background', array( 'default-color' => 'f4f4f4' ));
    	register_nav_menus( array(
    		'primary' => esc_html__( 'Primary', 'business-prime' ),
    	) );
    	add_theme_support( 'html5', array(
    		'search-form',
    		'comment-form',
    		'comment-list',
    		'gallery',
    		'caption',
    	) );
    	add_theme_support( 'custom-logo', array(
    		'flex-height' => true,
    		'flex-width'  => true,
    		'header-text' => array( 'site-title', 'site-description' ),
    	));
    	add_theme_support( 'woocommerce' );
    	add_image_size( 'business-prime-825x350-crop', '825', '350', true);
    	add_image_size( 'business-prime-285x230-crop', '285', '230', true);
    	
    }
    endif;
    add_action( 'after_setup_theme', 'business_prime_setup' );
    
    function business_prime_content_width() {
    	$GLOBALS['content_width'] = apply_filters( 'business_prime_content_width', 640 );
    }
    add_action( 'after_setup_theme', 'business_prime_content_width', 0 );
    
    function business_prime_widgets_init() {
    	register_sidebar( array(
    		'name'          => esc_html__( 'Sidebar', 'business-prime' ),
    		'id'            => 'sidebar',
    		'description'   => esc_html__( 'Sidebar Widget Area', 'business-prime' ),
    		'before_widget' => '<div class="row widget sidebar-widget">',
    		'after_widget'  => '</div>',
    		'before_title'  => '<h3 class="widget-title">',
    		'after_title'   => '</h3>',
    	) );
    	
    	register_sidebar( array(
            'name' => esc_html__( 'Footer Widget Area', 'business-prime' ),
            'id' => 'footer-widget-area',
            'description' => esc_html__( 'footer widget area', 'business-prime' ),
            'before_widget' => '<div class="col-md-3 col-sm-6 widget footer-widget">',
            'after_widget'  =>  '</div>',
            'before_title'  =>  '<div class="row widget-heading"><h3>',
            'after_title'   =>  '</h3></div>',
        ));
    		
    }
    add_action( 'widgets_init', 'business_prime_widgets_init' );
    
    function business_prime_scripts() {
    	
    	
    	wp_enqueue_style( 'business-prime-google-fonts', 'https://fonts.googleapis.com/css?family=Alegreya+Sans:100,300,400,400i,700'); 
        wp_enqueue_style( 'business-prime-font-awesome',  get_template_directory_uri()."/css/font-awesome.min.css");
        wp_enqueue_style( 'business-prime-animate',  get_template_directory_uri()."/css/animate.min.css");
        wp_enqueue_style( 'business-prime-bootstrap',  get_template_directory_uri()."/css/bootstrap.min.css");
        wp_enqueue_style( 'business-prime-simplelightbox',  get_template_directory_uri()."/css/simplelightbox.min.css");
        wp_enqueue_style( 'business-prime-swiper',  get_template_directory_uri()."/css/swiper.min.css");
        wp_enqueue_style( 'business-prime-style', get_stylesheet_uri() );
    	wp_enqueue_style( 'business-prime-media',  get_template_directory_uri()."/css/media-screen.css");
        
        
        
    	if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) { wp_enqueue_script( 'comment-reply' ); 	}
    	wp_enqueue_script( 'business-prime-bootstrap', get_template_directory_uri() . '/js/bootstrap.min.js', array('jquery'), '20120206', true );
    	wp_enqueue_script( 'business-prime-wow', get_template_directory_uri() . '/js/wow.min.js', array('jquery'), '20120206', true );
    	wp_enqueue_script( 'business-prime-simple-lightbox', get_template_directory_uri() . '/js/simple-lightbox.min.js', array('jquery'), '20120206', true );
    	wp_enqueue_script( 'business-prime-swiper', get_template_directory_uri() . '/js/swiper.min.js', array('jquery'), '20120206', true );
    	wp_enqueue_script( 'business-prime-skip-link-focus-fix', get_template_directory_uri() . '/js/skip-link-focus-fix.js', array(), '20130115', true );
    	wp_enqueue_script( 'business-prime-custom-script', get_template_directory_uri() . '/js/custom-script.js', array('jquery'), '20120206', true );
    
    	wp_enqueue_script( 'business-prime-respond', get_template_directory_uri().'/js/respond.min.js' );
        wp_script_add_data( 'business-prime-respond', 'conditional', 'lt IE 9' );
     
        wp_enqueue_script( 'business-prime-html5shiv',get_template_directory_uri().'/js/html5shiv.js');
        wp_script_add_data( 'business-prime-html5shiv', 'conditional', 'lt IE 9' );
    	
    }
    add_action( 'wp_enqueue_scripts', 'business_prime_scripts' );
    
    remove_action('woocommerce_after_shop_loop', 'woocommerce_pagination');
    function business_prime_woocommerce_pagination() {
    ?>
            <div class="clearfix"></div>
            <div class="bp-pagination">
                <?php the_posts_pagination();?>
            </div>
    <?php
    }
    add_action('woocommerce_after_shop_loop', 'business_prime_woocommerce_pagination', 10);
    
    /*====================(this is the section I'm talking about)======================= */
    
    #require get_template_directory() . '/inc/business-prime-customizer.php';
    #require get_template_directory() . '/inc/business-prime-functions.php';
    require get_template_directory() . '/inc/business-prime-sanitize-cb.php';
    require get_template_directory() . '/inc/business-prime-walker.php';
    require get_template_directory() . '/inc/themefarmer-breadcrumbs.php';
    require get_template_directory() . '/inc/class-tgm-plugin-activation.php';
    require get_template_directory() . '/inc/theme-info.php';
    require get_template_directory() . '/inc/include-kirki.php';
    require get_template_directory() . '/inc/kirki-config.php';
    
    /*=========================(I've blocked the first two out)========================= */
    
    /**
     * Implement the Custom Header feature.
     */
    require get_template_directory() . '/inc/custom-header.php';
    
    /**
     * Custom template tags for this theme.
     */
    require get_template_directory() . '/inc/template-tags.php';
    
    /**
     * Custom functions that act independently of the theme templates.
     */
    require get_template_directory() . '/inc/extras.php';
    
    /**
     * Load Jetpack compatibility file.
     */
    require get_template_directory() . '/inc/jetpack.php';
    

    Without those # it creates the earlier mentioned conflict… Again any questions, please fire away.

    Edit, Additional Information::

    I received an internal email from my wp installation addressing wp-admin/customize.php

    …the error was caught (https://shadow-crown.co.uk/wp-admin/customize.php?url=https%3A%2F%2Fshadow-crown.co.uk%2F) and check for any visible issues.

    While child functions.php code seems to be written properly, do you reckon it’s not configure properly to conform to the wordpress requirements as opposed to the parent theme coding?

    • This reply was modified 5 months, 2 weeks ago by John.
    • This reply was modified 5 months, 2 weeks ago by John. Reason: additional information found
    Moderator bcworkz

    (@bcworkz)

    I don’t see where ‘business_prime_settings_control’ action callback is added in functions.php. I assume it’s added in business-prime-customizer.php. If so, and you’ve disabled loading of that file, then there is little point in removing the callback since it never gets added.

    Of course, editing the parent theme in any way is not good practice. If you are getting error messages when the files are not blocked, your child theme is causing PHP errors due to conflicts. You should unblock the files and resolve what errors are occurring. The PHP errors should be listed in your site’s error log.

    Removing a theme’s callbacks is a good way to stop it from doing something. Blocking its source code is not. To remove callbacks, you must use the exact same priority argument in remove_action() the theme used in add_action(). The default is 10, so if the theme does not provide an argument, your remove_action() call should not use one either.

    You must ensure your remove_action() call occurs after the theme adds the callback, but not so late that the action added to has already fired. How to do so depends on how the theme calls its own add_action() statements.

    John

    (@shadowcrown)

    Thanks once again @bcworkz,

    To clear up any missunderstandings first through a clear path::

    ../themes/parent-directory/..
    ../themes/child-directory/..

    I’ve not edited or tweaked any parent files to achieve the required design and perofrmance from my website. All styling files that have been edited such as style.css, bootstrap.js & css, etc have all been loaded to the child theme directory and gets edited from there; much the same with:

    ../header.php (more so for presevation of SEO)
    ../page.php (don’t really need it, but it completes the set)
    ../front-page.php (because it calls for the themes /template-parts/home-client.php, etc)
    ../footer.php (for own business, parent thanks, child presence and media icons)
    ../template-parts/home-clients.php, etc, etc

    Website page inspections show that theme-child/functions.php is also calling all child dependent files too.

    Everything has been conducted or built according to expressed requirements by many persons through many forums and wordpress, in some instances I maybe over protecting by duplicating not needed .php files, I call it continuity of present parts and will eventually start to scale back otherwise tidy up the child directory; however.

    Ok. While I agree completely about blocking out the parent functions.php to overcome the problem is a lazy way of doing things, currently i’m trying to figure out the best way of dequeueing or unregistering the parent get_template_directory() requirement.

    The coding I’ve now settled on is very clean and to the point and yeilds far better results on my lazy test:
    locate_template( array( 'inc/business-prime-customizer.php' ), true );

    I’ve also checked the theme-customizer.php file,

    Bear in mind, besides todate the fab fa-icons is the only thing I’ve edited in the parent customizer file, which is also now ready in the child file too.

    and error logs as per suggestion, and to get the latest results I triggered the conflict/error off again.

    [26-Jun-2019 09:26:49 UTC] PHP Fatal error: Cannot redeclare business_prime_customize_controls_scripts() (previously declared in /../../../wp-content/themes/business-prime-child/inc/business-prime-customizer.php:630) in /../../../wp-content/themes/business-prime/inc/business-prime-customizer.php on line 632

    While I can physically see the conflict now, and that wordpress core is reading both theme directories properly and attempting to fulfil child priority, what I’m gathering from this message again, is the parent theme is not letting go and in itself creating the argument; hence why I have to block it out.

    So one last recap, (sorry for this it sounds like a family fued now! lol)…
    – – If child is presense check directories (child theme permitted).

    Parent functions.php:
    require get_template_directory() . '/inc/business-prime-customizer.php';
    Child Functions.php:
    locate_template( array( 'inc/business-prime-customizer.php' ), true );
    Both parent and child customizer.php files are not edited, and this is the line/s (631-634) its talking about from the parent file:

    function business_prime_customize_controls_scripts(){
    	wp_enqueue_script( 'business-prime-customizer-controls', get_template_directory_uri() . '/js/customizer-controls.js', array('jquery'), '20151215', true );
    }
    add_action( 'customize_controls_enqueue_scripts',   'business_prime_customize_controls_scripts' );

    So if the child theme functions.php is successfully declaring its request to wordpress core, but I can’t edit the parent functions or customizer.php, what do I need to do stop the parent from redeclaring its script?

    At a guess, would I need to edit the child theme customizer.php and how would i it??

    • This reply was modified 5 months, 2 weeks ago by John.
    Moderator bcworkz

    (@bcworkz)

    “Family feud” LOL 🙂

    As you have discovered, the parent theme is still very much in play when you create a child theme. The child works by mainly overriding whatever you don’t like about the parent. Simple enough with CSS or JavaScript where you can override without errors. PHP of course is a different story. The only parent PHP you can really override are extensible classes and “pluggable” functions the are wrapped with if ( ! function_exists()): logic. Procedural parent functions that are not pluggable cannot be overridden. You have to work backwards to something you can change to avoid calling the offending function and to call your process instead.

    A well written theme will provide adequate hooks and pluggable functions to allow you to customize it in any way you like. Sadly, not all themes are so well written. If push comes to shove and there is no way to cleanly override a parent function, you are left with patching up the page after it loads with JavaScript and CSS. There is very little that you cannot hide with CSS or insert with JavaScript.

    John

    (@shadowcrown)

    It definately comes across as being a family affair, lol 🙂

    Ok, one last run as I’ve taken enough of your time now @bcworkz.

    The parent file structure does seem very basic for what it is making wordpress more of a limb rather than being a crutch.

    Alot of the .js files seem to be very short and basic with no real referencing to the customizer, then with .css files being what they are. The only thing I could find, taking into account folks talking about if ( function_exist()):, is this located right at the bottom of the customizer.php file; but it’s a “class” not a “function” there seems to be no “if (function)” anywhere other than in the wordpress core.

    
    if (class_exists('WP_Customize_Control')):
    
    	class Business_Prime_Info_Text extends WP_Customize_Control{
    
    	    public function render_content(){
    	    ?>
    		    <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
    
    			<?php if($this->description){ ?>
    				<span class="description customize-control-description">
    				<?php echo wp_kses_post($this->description); ?>
    				</span>
    			<?php }
    	    }
    
    	}
    

    When I do my block out test to see what impact the script is having on the site, it does seem to trigger a stack trace error, or a cascading problem across multiple core files.

    There is one one other class reference beneath it wrapped in the same opening IF statement calling for another, or second, public function…

    
    class Business_Prime_Page_Dropdown_Control extends WP_Customize_Control {
    
    		public function render_content() {
    			$pages = get_pages(array('hide_empty' => false));
    			if (!empty($pages)): ?>
    

    Hope this helps a little more… additionally I found this link to cross-reference against:

    Creating Your Own Theme Customiser Custom Controls

    Based on the links content and the above statement, is this what the parent theme is doing and what I will need to address to unhook the parent file?

    Greatly appreciated, John

    • This reply was modified 5 months, 2 weeks ago by John.
    Moderator bcworkz

    (@bcworkz)

    The class_exists() conditional has a different purpose in this context. It’s not useful in achieving your goal. It’s purpose here is to prevent errors should the code be called out of context where WP_Customize_Control would not be declared.

    I assume somewhere there is a $wp_customize->add_control() call related to the offending element. Use the ID used there in a call to $wp_customize->remove_control() to remove the same. You must ensure your removal code runs after the add_control() call. The action “after_setup_theme” with a large priority argument often manages this, but it all depends on when the original control is added.

    John

    (@shadowcrown)

    How do…

    In among my tussle with the parent theme model, browsing the net, and developing a few new white hairs in the process, lol.

    I though it best to drop in and first thanks for your patience and assistance @bcworkz, then give you an outline of what I’ve done.

    add_action( 'init', 'remove_parent_files' );	
    function remove_parent_files() {
    	remove_action('customize_register', 'parent_settings_control');
    	remove_action('admin_enqueue_scripts', 'parent_theme_info_page_css');
    }
    
    function run_child_files(){
    	include'inc/child-customizer.php';
    	include'inc/child-functions.php'; /*this still needs work*/
    	include'inc/theme-info.php';
    }
    add_action('init', 'run_child_files');

    The one that “still needs work”, is the one that has multiple functions and have no add_action() to latch on to or not enough arguments to work with, as well as needing to figure out how to remove a add_filter() where the add_action() usually is; unless I can find a way of just removing the whole file by file name.

    If you have any ideas or links then that would be greatly helpful too, otherwise…

    Again, thank you and greatly appreciative, John

    • This reply was modified 5 months, 2 weeks ago by John.
    • This reply was modified 5 months, 2 weeks ago by John. Reason: clearer understanding
    Moderator bcworkz

    (@bcworkz)

    There is a remove_filter() function that does the same thing for filters that remove_action() does for actions. It has the same caveats: you must remove using the exact priority argument the parent theme used to add, or don’t use one of the parent did not; you must remove after the parent has added, manage by using the proper actions and large priority arguments to dictate when your remove_filter() call actually happens.

    You cannot remove file references like you can with actions and filters. If the file was referenced by a WP file like template-loader.php, you can use filters to force a different file to be loaded. If the theme is using PHP statements like require or include, there is little you can do to prevent the file from being loaded. All you can hope to do is undo what it does through other means.

    As I mentioned earlier, if there seems to be no PHP solution, fixing up the page as it loads into the browser with CSS and JavaScript can resolve the most heinous PHP theme functions.

Viewing 9 replies - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.