如何自定义wp_list_pages()的输出,以便可以将链接包装在自己的HTML中?

时间:2019-04-11 10:34:16

标签: php wordpress wordpress-theming

我是WordPress的新手,想创建一个菜单。使用wp_list_pages(),可以生成包裹在<li>标签中的链接列表。

这很好,但是我想在这些类中添加自己的类(也许还要更改包装它们的元素)。

我浏览了https://developer.wordpress.org/reference/functions/wp_list_pages/和一些论坛帖子,但没有找到指向正确方向的任何内容。

如何自定义wp_list_pages的输出?

2 个答案:

答案 0 :(得分:0)

您可以通过覆盖.page-item类来实现此目的。在此处查看更多详细信息,https://developer.wordpress.org/reference/functions/wp_list_pages/#more-information

如果您需要添加自定义类或更改列表的呈现方式,则可以附加walker函数https://developer.wordpress.org/reference/classes/walker/

可以在https://developer.wordpress.org/reference/classes/walker_nav_menu/

找到一个示例
• Could not deduce (Foo a2 a0) arising from a use of ‘foo’
      from the context: (Bar a1 b, Foo a2 a1)
        bound by the type signature for:
                   f :: forall a1 b a2. (Bar a1 b, Foo a2 a1) => a2 -> b
        at catdog.lhs:32:3-39
      The type variable ‘a0’ is ambiguous
      Relevant bindings include
        x :: a2 (bound at catdog.lhs:33:5)
        f :: a2 -> b (bound at catdog.lhs:33:3)
      These potential instance exist:
        instance Foo (A a) a -- Defined at catdog.lhs:17:12
    • In the first argument of ‘bar’, namely ‘(foo x)’
      In the expression: bar (foo x)
      In an equation for ‘f’: f x = bar (foo x)
   |
33 | > f x = bar (foo x)    |              ^^^^^
        mDashboardAdapter = new DashboardAdapter(getActivity(), mDashBoardList, imageId);
        RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 4);
        grid.setLayoutManager(mLayoutManager);
        grid.addItemDecoration(new GridSpacingItemDecoration(4, 10, true));
        grid.setItemAnimator(new DefaultItemAnimator());
        grid.setAdapter(mDashboardAdapter);



    public static class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {

        private int spanCount;
        private int spacing;
        private boolean includeEdge;

        public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
            this.spanCount = spanCount;
            this.spacing = spacing;
            this.includeEdge = includeEdge;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            int position = parent.getChildAdapterPosition(view); // item position
            int column = position % spanCount; // item column

            if (includeEdge) {
                outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
                outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

                if (position < spanCount) { // top edge
                    outRect.top = spacing;
                }
                outRect.bottom = spacing; // item bottom
            } else {
                outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
                outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
                if (position >= spanCount) {
                    outRect.top = spacing; // item top
                }
            }
        }
    }

答案 1 :(得分:0)

我发现了两种方法,

使用过滤器和正则表达式

在主题functions.php文件中添加以下内容。

function clean_wp_list_pages($menu) {
    // Remove redundant title attributes
    $menu = remove_title_attributes($menu);
    // Remove protocol and domain name from href values
    $menu = make_href_root_relative($menu);
    // Give the list items containing the current item or one of its ancestors a class name
    $menu = preg_replace('/class="(.*?)current_page(.*?)"/','class="sel"',$menu);
    // Remove all other class names
    $menu = preg_replace('/ class=(["\'])(?!sel).*?\1/','',$menu);
    // Give the current link and the links to its ancestors a class name and wrap their content in a strong element
    $menu = preg_replace('/class="sel"><a(.*?)>(.*?)<\/a>/','class="sel"><a$1 class="sel"><strong>$2</strong></a>',$menu);
    return $menu;
}
add_filter( 'wp_list_pages', 'clean_wp_list_pages' );

使用自定义沃克功能

与上面相同。将此添加到您的functions.php文件中:

class Clean_Walker extends Walker_Page {
    function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul>\n";
    }

    function start_el(&$output, $page, $depth, $args, $current_page) {
        if ( $depth )
            $indent = str_repeat("\t", $depth);
        else
            $indent = '';
        extract($args, EXTR_SKIP);
        $class_attr = '';
        if ( !empty($current_page) ) {
            $_current_page = get_page( $current_page );
            if ( (isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors)) || ( $page->ID == $current_page ) || ( $_current_page && $page->ID == $_current_page->post_parent ) ) {
                $class_attr = 'sel';
            }
        } elseif ( (is_single() || is_archive()) && ($page->ID == get_option('page_for_posts')) ) {
            $class_attr = 'sel';
        }
        if ( $class_attr != '' ) {
            $class_attr = ' class="' . $class_attr . '"';
            $link_before .= '<strong>';
            $link_after = '</strong>' . $link_after;
        }
        $output .= $indent . '<li' . $class_attr . '><a href="' . make_href_root_relative(get_page_link($page->ID)) . '"' . $class_attr . '>' . $link_before . apply_filters( 'the_title', $page->post_title, $page->ID ) . $link_after . '</a>';

        if ( !empty($show_date) ) {
            if ( 'modified' == $show_date )
                $time = $page->post_modified;
            else
                $time = $page->post_date;
            $output .= " " . mysql2date($date_format, $time);
        }
    }
}

要使用此功能,您需要使用walker参数调用wp_list_pages。

<?php
$walker = new Clean_Walker();
wp_list_pages( array(
    'title_li' => '',
    'walker' => $walker,
    ) );
?>

来源:here