如何编辑/替换子主题中的父函数.php函数以添加“Walker”类

时间:2017-02-12 作者:CoderScissorhands

我使用主题“Tesseract”作为父主题,我想使用walker类来获取菜单描述。然而,我很难理解如何编辑php,因为我不知道如何正确地替换父主题的函数。

我需要根据更改父主题的功能this page, 我应该找到的是找到wp_nav_menu(), 作者建议最有可能出现在标题中。php,并将该函数调用替换为。

<?php $walker = new Menu_With_Description; ?>

<?php wp_nav_menu( array( \'theme_location\' => \'primary\', \'menu_class\' => \'nav-menu\', \'walker\' => $walker ) ); ?>
问题是我的主题,wp_nav_menu() 正在父主题的函数中调用。php文件,不在头文件中。php,尽管包含函数(tesseract_output_menu) 在标头内部调用。php。这意味着我很可能必须替换父主题的函数,但我不确定如何正确地进行替换。

tesseract_output_menu 是父主题函数中的函数。在标头内部调用的php文件。php,我将尝试将其更改为一个名为child_tesseract_output_menu.

这是父主题函数:

function tesseract_output_menu( $cont, $contClass, $location, $depth ) {

    switch( $location ) :

        case \'primary\': $hblox = \'header\'; break;
        case \'primary_right\': $hblox = \'header_right\'; break;
        case \'secondary\': $hblox = \'footer\'; break;
        case \'secondary_right\': $hblox = \'footer_right\'; break;

    endswitch;

    $locs = get_theme_mod(\'nav_menu_locations\');

    $menu = get_theme_mod(\'tesseract_\' . $hblox . \'_menu_select\');

    $isMenu = get_terms( \'nav_menu\' ) ? TRUE : FALSE;
    $locReserved = ( $locs[$location] ) ? TRUE : FALSE;
    $menuSelected = ( is_string($menu) ) ? TRUE : FALSE;

    // IF the location set as parameter has an associated menu, it\'s returned as a key-value pair in the $locs array - where the key is the location and the value is the menu ID. We need this latter to get the menu slug required later -in some cases- in the wp_nav_menu params array.
    if ( $locReserved ) {
        $menu_id = $locs[$location]; // $value = $array[$key]
        $menuObject = wp_get_nav_menu_object( $menu_id );
        $menu_slug = $menuObject->slug;
    };
    $custSet = ( $menuSelected && ( $menu !== \'none\' ) );

    if ( empty( $isMenu ) ) : //Case 1 - IF THERE\'S NO MENU CREATED -> easy scenario: no location setting, no customizer setting ( this latter only appears if there IS at least one menu created by the theme user ) => display basic menu

        wp_nav_menu( array(
            \'theme_location\' => \'primary\',
            \'menu_class\' => \'nav-menu\',
            \'container_class\' => \'\',
            \'container\' => FALSE,
            \'depth\' => $depth
            )
        );

    elseif ( !empty( $isMenu ) ) : //Case 2 - THERE\'S AT LEAST ONE MENU CREATED

        if ( !$custSet && $locReserved ) { //no setting in customizer OR dropdown is set to blank value, location SET in Menus section => display menu associated with this location in Appearance ->
            wp_nav_menu( array(
               // \'menu\' => $menuSlug,
                \'menu\' => $menu_slug, 
                \'theme_location\' => $location,
                \'menu_class\' => \'nav-menu\',
                \'container_class\' => $contClass,
                \'container\' => $cont,
                \'depth\' => $depth
                )
            );

        } else if ( !$custSet && !$locReserved ) { //no setting in customizer OR dropdown is set to blank value, location NOT SET in Menus section => display basic menu

            wp_nav_menu( array(
                \'theme_location\' => \'primary\',
                \'menu_class\' => \'nav-menu\',
                \'container_class\' => \'\',
                \'container\' => FALSE,
                \'depth\' => $depth
                )
            );

        } else if ( $custSet ) { //menu set in customizer AND dropdown is NOT set to blank value, location SET OR NOT SET in Menus section => display menu set in customizer ( setting a menu to the given location in customizer will update any existing location-menu association in Appearance -> Menus, see function tesseract_set_menu_location() in functions.php )

            wp_nav_menu( array(
                \'menu\' => $menu,
                \'theme_location\' => $location,
                \'menu_class\' => \'nav-menu\',
                \'container_class\' => $contClass,
                \'container\' => $cont,
                \'depth\' => $depth
                )
            );

        }

    endif;

}
堆栈提供了一个示例,据我所知,我可能希望使用操作或过滤器来完成此操作,如中所示this question:How to override parent functions in child themes?

这个例子对我来说并不清楚,问题是我要遵循的例子没有得到充分的解释,我还不太了解过滤器是如何工作的。在该堆栈示例中,它们似乎删除了一个名为twentyten_auto_excerpt_more, 有一个叫osu_twentyten_auto_excerpt_more, 但他们使用的第一个参数是excerpt_more:

堆栈应答中的子覆盖函数:

// Override read more link
function osu_twentyten_continue_reading_link() {
 return \' <a href="\'. get_permalink() . \'">\' . __( \'Read on <span class="meta-nav">&rarr;</span>\', \'twentyten-child\' ) . \'</a>\';
}
function osu_twentyten_auto_excerpt_more( $more ) {
 return \' &hellip;\' . osu_twentyten_continue_reading_link();
}
remove_filter( \'excerpt_more\', \'twentyten_auto_excerpt_more\' );
add_filter( \'excerpt_more\', \'osu_twentyten_auto_excerpt_more\' );
因为我想改变tesseract_output_menu, 基于这个例子,我很确定我会调用我的子函数来替换父函数tesseract_output_menu 类似于child_tesseract_output_menu,我认为这很清楚。但我不明白的是,在我的例子中,第一个参数的等效/类比是什么,它与exerpt_more 在上述示例中。他们不说什么excerpt_more 是我需要知道remove_filter andadd\\u filter`需要在我的案例中。

为了让这更清楚

堆栈示例使用的函数:add filter, remove filtertwentyten_auto_excerpt_moreosu_twentyten_auto_excerpt_moreexerpt more

我的案例,v1:更换tesseract_output_menu:add filter, remove filtertesseract_output_menuchild_tesseract_output_menu第一个参数“添加筛选器”和“删除筛选器”:???我需要在第一个参数中输入什么函数我意识到我可能想以这种方式调整事情

我的案例,v2:更换wp_nav_menu:add filter, remove filterwp_nav_menuchild_wp_nav_menutesseract_output_menu如果我使用案例的v1,那么最好的方法是什么excerpt_more 就我而言?

2 个回复
SO网友:David Lee

转到您的functions.php 在子主题中添加以下内容:

function childtheme_override_tesseract_output_menu( $cont, $contClass, $location, $depth ) {
//tesseract_output_menu function code modified as you wish here    
}
在父主题中functions.php, 包装tesseract_output_menu 功能如下:

if (function_exists(\'childtheme_override_tesseract_output_menu\')) {

    /**
     * run the child override
     */
    function tesseract_output_menu() {
        childtheme_override_tesseract_output_menu();
    }

} else {
   /**
    * run the original parent function
    */
   function tesseract_output_menu( $cont, $contClass, $location, $depth ) {
     //original code untouched   
   }
}
这样你可以覆盖父主题函数,这是标准的方法,我不知道为什么父主题函数还没有像那样包装,你可以在wordpress附带的主题中看到相同的代码,因此可以替换该函数if ( ! function_exists( \'twentysixteen_setup\' ) ).

SO网友:CoderScissorhands

我意识到有一种更简单的方法,那就是编辑我孩子的标题。php文件

子标题内。php文件查找对wp_nav_menu 包含调用的函数tesseract_output_menu.tesseract_output_menu 一个新函数的child_tesseract_output_menu.

function child_tesseract_output_menu( $cont, $contClass, $location, $depth ) {

    switch( $location ) :

        case \'primary\': $hblox = \'header\'; break;
        case \'primary_right\': $hblox = \'header_right\'; break;
        case \'secondary\': $hblox = \'footer\'; break;
        case \'secondary_right\': $hblox = \'footer_right\'; break;

    endswitch;

    $locs = get_theme_mod(\'nav_menu_locations\');

    $menu = get_theme_mod(\'tesseract_\' . $hblox . \'_menu_select\');

    $isMenu = get_terms( \'nav_menu\' ) ? TRUE : FALSE;
    $locReserved = ( $locs[$location] ) ? TRUE : FALSE;
    $menuSelected = ( is_string($menu) ) ? TRUE : FALSE;

    // IF the location set as parameter has an associated menu, it\'s returned as a key-value pair in the $locs array - where the key is the location and the value is the menu ID. We need this latter to get the menu slug required later -in some cases- in the wp_nav_menu params array.
    if ( $locReserved ) {
        $menu_id = $locs[$location]; // $value = $array[$key]
        $menuObject = wp_get_nav_menu_object( $menu_id );
        $menu_slug = $menuObject->slug;
    };
    $custSet = ( $menuSelected && ( $menu !== \'none\' ) );

    if ( empty( $isMenu ) ) : //Case 1 - IF THERE\'S NO MENU CREATED -> easy scenario: no location setting, no customizer setting ( this latter only appears if there IS at least one menu created by the theme user ) => display basic menu

       $walker = new Menu_With_Description; 

        wp_nav_menu( array(
            \'theme_location\' => \'primary\',
            \'menu_class\' => \'nav-menu\',
            \'container_class\' => \'\',
            \'container\' => FALSE,
            \'depth\' => $depth,
            \'walker\' => $walker
            )
        );

    elseif ( !empty( $isMenu ) ) : //Case 2 - THERE\'S AT LEAST ONE MENU CREATED

        if ( !$custSet && $locReserved ) { //no setting in customizer OR dropdown is set to blank value, location SET in Menus section => display menu associated with this location in Appearance ->

$walker = new Menu_With_Description; 

 wp_nav_menu( array(
               // \'menu\' => $menuSlug,
                \'menu\' => $menu_slug, 
                \'theme_location\' => $location,
                \'menu_class\' => \'nav-menu\',
                \'container_class\' => $contClass,
                \'container\' => $cont,
                \'depth\' => $depth,
                \'walker\' => $walker
                )
            );

        } else if ( !$custSet && !$locReserved ) { //no setting in customizer OR dropdown is set to blank value, location NOT SET in Menus section => display basic menu
$walker = new Menu_With_Description; 


            wp_nav_menu( array(
                \'theme_location\' => \'primary\',
                \'menu_class\' => \'nav-menu\',
                \'container_class\' => \'\',
                \'container\' => FALSE,
                \'depth\' => $depth,
                \'walker\' => $walker
                )
            );

        } else if ( $custSet ) { //menu set in customizer AND dropdown is NOT set to blank value, location SET OR NOT SET in Menus section => display menu set in customizer ( setting a menu to the given location in customizer will update any existing location-menu association in Appearance -> Menus, see function tesseract_set_menu_location() in functions.php )

$walker = new Menu_With_Description; 

            wp_nav_menu( array(
                \'menu\' => $menu,
                \'theme_location\' => $location,
                \'menu_class\' => \'nav-menu\',
                \'container_class\' => $contClass,
                \'container\' => $cont,
                \'depth\' => $depth,
                \'walker\' => $walker
                )
            );

        }

    endif;

}

相关推荐

初学者问题:通过管理Web界面访问Functions.php以导入自定义帖子类型?

是否可以访问这些功能。php文件仅仅使用管理web界面?我正在尝试访问以前创建的(手动编码的)自定义帖子类型,我不得不跳过很多障碍,因为我无法访问函数中的代码。php文件。我已经浏览了很多帮助页面,但建议的步骤似乎总是涉及到函数。php文件(我无法访问)或使用插件中的导入/导出工具,该插件首先创建了自定义帖子类型(据我所知,没有使用任何插件)。这似乎是一个非常基本的问题,但我一辈子都想不出来。任何帮助都将不胜感激!