Intereting Posts
WP_Query с пользовательским типом поиска постов, показывающим все результаты каждый раз Ссылка на изображение для публикации OOP: отображать предупреждение и деактивировать плагин, если версия PHP меньше 5.4 Запрос поисковых URL-запросов Woocommerce: дополнительное добавленное поле страны, не использующее ценность из базы данных Пользователь автора ограничивается сообщениями о таксономии Автоматическое форматирование исходного кода HTML Как изменить заголовки администратора Перенаправить страницу блога на последнее сообщение? Пользовательский пост не работает должным образом Multisite – сделать файлы доступными через сеть Запрос и отображение только первой буквой значения get_field Как изменить порядок категорий в панели управления администратора? Медленный WP_Query с 'OR' на meta_query Не удалось добавить ссылку «LoginLogout» с помощью логина входа в систему BAW

Отображать детей и внуков типа персонализированного сообщения

Как заставить внуков появиться на почте PARENT, сейчас я могу только заставить детей появиться на родительском посту и внуков на дочернем посту.

Я бы хотел сделать список таким образом:

Родительский пост (текущая страница)
-Читать 1
–grandchild 1
–grandchild 2
–grandchild 3
-Читать 2
–grandchild 1
–grandchild 2
–grandchild 3

Это мой код до сих пор

<?php $args = array( 'post_parent' => get_the_ID(), 'post_type' => 'series', 'posts_per_page' => -1 ); $childs = new WP_Query( $args ); while ( $childs->have_posts() ) : $childs->the_post(); ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> <?php endwhile; wp_reset_postdata(); ?> 

Любая помощь приветствуется, спасибо!

Обновить:

 <ul>Child1 title <li>grandchild</li> <li>grandchild2</li> <li>grandchild3</li> </ul> <ul>Child2 title <li>grandchild</li> <li>grandchild2</li> <li>grandchild3</li> </ul> 

Вы можете создать walker для wp_list_pages() эта функция использует Walker_Page, которую вы можете продлить .

Уокер, например, вы положили его в functions.php. Я добавил комментарии с именем класса No_Link_First_Child_Walker чтобы вы могли видеть, что я изменил, вы можете их искать.

 class No_Link_First_Child_Walker extends Walker_Page { public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } if ( $depth ) { $indent = str_repeat( $t, $depth ); } else { $indent = ''; } $css_class = array( 'page_item', 'page-item-' . $page->ID ); if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $css_class[] = 'page_item_has_children'; } if ( ! empty( $current_page ) ) { $_current_page = get_post( $current_page ); if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) { $css_class[] = 'current_page_ancestor'; } if ( $page->ID == $current_page ) { $css_class[] = 'current_page_item'; } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) { $css_class[] = 'current_page_parent'; } } elseif ( $page->ID == get_option('page_for_posts') ) { $css_class[] = 'current_page_parent'; } /** * Filters the list of CSS classes to include with each page item in the list. * * @since 2.8.0 * * @see wp_list_pages() * * @param array $css_class An array of CSS classes to be applied * to each list item. * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) ); if ( '' === $page->post_title ) { /* translators: %d: ID of a post */ $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID ); } $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before']; $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after']; $atts = array(); $atts['href'] = get_permalink( $page->ID ); /** * Filters the HTML attributes applied to a page menu item's anchor element. * * @since 4.8.0 * * @param array $atts { * The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored. * * @type string $href The href attribute. * } * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $atts = apply_filters( 'page_menu_link_attributes', $atts, $page, $depth, $args, $current_page ); /** * No_Link_First_Child_Walker * Here I removed the the attribute for the href if the depth equal to 1 */ if($depth == 1) { unset($atts['href']); } $attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } /** * No_Link_First_Child_Walker * Here I add a condition to check if depth is 1 so the tag will be span */ $output .= $indent . sprintf( '<li class="%s">'.(($depth == 1) ? '<span%s>%s%s%s</span>' : '<a%s>%s%s%s</a>'), $css_classes, $attributes, $args['link_before'], /** This filter is documented in wp-includes/post-template.php */ apply_filters( 'the_title', $page->post_title, $page->ID ), $args['link_after'] ); if ( ! empty( $args['show_date'] ) ) { if ( 'modified' == $args['show_date'] ) { $time = $page->post_modified; } else { $time = $page->post_date; } $date_format = empty( $args['date_format'] ) ? '' : $args['date_format']; $output .= " " . mysql2date( $date_format, $time ); } } } не class No_Link_First_Child_Walker extends Walker_Page { public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } if ( $depth ) { $indent = str_repeat( $t, $depth ); } else { $indent = ''; } $css_class = array( 'page_item', 'page-item-' . $page->ID ); if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $css_class[] = 'page_item_has_children'; } if ( ! empty( $current_page ) ) { $_current_page = get_post( $current_page ); if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) { $css_class[] = 'current_page_ancestor'; } if ( $page->ID == $current_page ) { $css_class[] = 'current_page_item'; } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) { $css_class[] = 'current_page_parent'; } } elseif ( $page->ID == get_option('page_for_posts') ) { $css_class[] = 'current_page_parent'; } /** * Filters the list of CSS classes to include with each page item in the list. * * @since 2.8.0 * * @see wp_list_pages() * * @param array $css_class An array of CSS classes to be applied * to each list item. * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) ); if ( '' === $page->post_title ) { /* translators: %d: ID of a post */ $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID ); } $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before']; $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after']; $atts = array(); $atts['href'] = get_permalink( $page->ID ); /** * Filters the HTML attributes applied to a page menu item's anchor element. * * @since 4.8.0 * * @param array $atts { * The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored. * * @type string $href The href attribute. * } * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $atts = apply_filters( 'page_menu_link_attributes', $atts, $page, $depth, $args, $current_page ); /** * No_Link_First_Child_Walker * Here I removed the the attribute for the href if the depth equal to 1 */ if($depth == 1) { unset($atts['href']); } $attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } /** * No_Link_First_Child_Walker * Here I add a condition to check if depth is 1 so the tag will be span */ $output .= $indent . sprintf( '<li class="%s">'.(($depth == 1) ? '<span%s>%s%s%s</span>' : '<a%s>%s%s%s</a>'), $css_classes, $attributes, $args['link_before'], /** This filter is documented in wp-includes/post-template.php */ apply_filters( 'the_title', $page->post_title, $page->ID ), $args['link_after'] ); if ( ! empty( $args['show_date'] ) ) { if ( 'modified' == $args['show_date'] ) { $time = $page->post_modified; } else { $time = $page->post_date; } $date_format = empty( $args['date_format'] ) ? '' : $args['date_format']; $output .= " " . mysql2date( $date_format, $time ); } } } 

Теперь вы вызываете функцию wp_list_pages() с этим ходоком тоже так.

 wp_list_pages(array('post_type'=>'series', 'walker'=>new No_Link_First_Child_Walker())); 

Или вы можете сделать еще один цикл внутри второго, пока для внуков.

Попробуй это

 class No_Link_First_Child_Walker extends Walker_Page { /** * Outputs the beginning of the current level in the tree before elements are output. * * @since 2.1.0 * * @see Walker::start_lvl() * * @param string $output Used to append additional content (passed by reference). * @param int $depth Optional. Depth of page. Used for padding. Default 0. * @param array $args Optional. Arguments for outputting the next level. * Default empty array. */ public function start_lvl( &$output, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $indent = str_repeat( $t, $depth ); // No_Link_First_Child_Walker check depth and remove <ul> for depth 0 if($depth !== 0) { $output .= "{$n}{$indent}<ul class='children'>{$n}"; } } /** * Outputs the end of the current level in the tree after elements are output. * * @since 2.1.0 * * @see Walker::end_lvl() * * @param string $output Used to append additional content (passed by reference). * @param int $depth Optional. Depth of page. Used for padding. Default 0. * @param array $args Optional. Arguments for outputting the end of the current level. * Default empty array. */ public function end_lvl( &$output, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $indent = str_repeat( $t, $depth ); // No_Link_First_Child_Walker check depth and remove </ul> for depth 0 if($depth !== 0) { $output .= "{$indent}</ul>{$n}"; } } public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } if ( $depth ) { $indent = str_repeat( $t, $depth ); } else { $indent = ''; } $css_class = array( 'page_item', 'page-item-' . $page->ID ); if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $css_class[] = 'page_item_has_children'; } if ( ! empty( $current_page ) ) { $_current_page = get_post( $current_page ); if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) { $css_class[] = 'current_page_ancestor'; } if ( $page->ID == $current_page ) { $css_class[] = 'current_page_item'; } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) { $css_class[] = 'current_page_parent'; } } elseif ( $page->ID == get_option('page_for_posts') ) { $css_class[] = 'current_page_parent'; } /** * Filters the list of CSS classes to include with each page item in the list. * * @since 2.8.0 * * @see wp_list_pages() * * @param array $css_class An array of CSS classes to be applied * to each list item. * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) ); if ( '' === $page->post_title ) { /* translators: %d: ID of a post */ $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID ); } $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before']; $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after']; $atts = array(); $atts['href'] = get_permalink( $page->ID ); /** * Filters the HTML attributes applied to a page menu item's anchor element. * * @since 4.8.0 * * @param array $atts { * The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored. * * @type string $href The href attribute. * } * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $atts = apply_filters( 'page_menu_link_attributes', $atts, $page, $depth, $args, $current_page ); /** * No_Link_First_Child_Walker * Here I removed the the attribute for the href if the depth equal to 1 */ if($depth == 1) { unset($atts['href']); } $attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } /** * No_Link_First_Child_Walker * Here I add a condition to check if depth is 1 so the tag will be h3 * remove the <li> too for this depth */ $output .= $indent . sprintf( (($depth == 1) ? '<h3 class="%s">%s%s%s</h3>' : '<li class="%s"><a%s>%s%s%s</a>'), $css_classes, $attributes, $args['link_before'], /** This filter is documented in wp-includes/post-template.php */ apply_filters( 'the_title', $page->post_title, $page->ID ), $args['link_after'] ); if ( ! empty( $args['show_date'] ) ) { if ( 'modified' == $args['show_date'] ) { $time = $page->post_modified; } else { $time = $page->post_date; } $date_format = empty( $args['date_format'] ) ? '' : $args['date_format']; $output .= " " . mysql2date( $date_format, $time ); } } public function end_el( &$output, $page, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } // No_Link_First_Child_Walker check depth and remove closing </li> for depth 1 if($depth !== 1) { $output .= "</li>{$n}"; } } } не class No_Link_First_Child_Walker extends Walker_Page { /** * Outputs the beginning of the current level in the tree before elements are output. * * @since 2.1.0 * * @see Walker::start_lvl() * * @param string $output Used to append additional content (passed by reference). * @param int $depth Optional. Depth of page. Used for padding. Default 0. * @param array $args Optional. Arguments for outputting the next level. * Default empty array. */ public function start_lvl( &$output, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $indent = str_repeat( $t, $depth ); // No_Link_First_Child_Walker check depth and remove <ul> for depth 0 if($depth !== 0) { $output .= "{$n}{$indent}<ul class='children'>{$n}"; } } /** * Outputs the end of the current level in the tree after elements are output. * * @since 2.1.0 * * @see Walker::end_lvl() * * @param string $output Used to append additional content (passed by reference). * @param int $depth Optional. Depth of page. Used for padding. Default 0. * @param array $args Optional. Arguments for outputting the end of the current level. * Default empty array. */ public function end_lvl( &$output, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } $indent = str_repeat( $t, $depth ); // No_Link_First_Child_Walker check depth and remove </ul> for depth 0 if($depth !== 0) { $output .= "{$indent}</ul>{$n}"; } } public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } if ( $depth ) { $indent = str_repeat( $t, $depth ); } else { $indent = ''; } $css_class = array( 'page_item', 'page-item-' . $page->ID ); if ( isset( $args['pages_with_children'][ $page->ID ] ) ) { $css_class[] = 'page_item_has_children'; } if ( ! empty( $current_page ) ) { $_current_page = get_post( $current_page ); if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) { $css_class[] = 'current_page_ancestor'; } if ( $page->ID == $current_page ) { $css_class[] = 'current_page_item'; } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) { $css_class[] = 'current_page_parent'; } } elseif ( $page->ID == get_option('page_for_posts') ) { $css_class[] = 'current_page_parent'; } /** * Filters the list of CSS classes to include with each page item in the list. * * @since 2.8.0 * * @see wp_list_pages() * * @param array $css_class An array of CSS classes to be applied * to each list item. * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) ); if ( '' === $page->post_title ) { /* translators: %d: ID of a post */ $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID ); } $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before']; $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after']; $atts = array(); $atts['href'] = get_permalink( $page->ID ); /** * Filters the HTML attributes applied to a page menu item's anchor element. * * @since 4.8.0 * * @param array $atts { * The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored. * * @type string $href The href attribute. * } * @param WP_Post $page Page data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of arguments. * @param int $current_page ID of the current page. */ $atts = apply_filters( 'page_menu_link_attributes', $atts, $page, $depth, $args, $current_page ); /** * No_Link_First_Child_Walker * Here I removed the the attribute for the href if the depth equal to 1 */ if($depth == 1) { unset($atts['href']); } $attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } /** * No_Link_First_Child_Walker * Here I add a condition to check if depth is 1 so the tag will be h3 * remove the <li> too for this depth */ $output .= $indent . sprintf( (($depth == 1) ? '<h3 class="%s">%s%s%s</h3>' : '<li class="%s"><a%s>%s%s%s</a>'), $css_classes, $attributes, $args['link_before'], /** This filter is documented in wp-includes/post-template.php */ apply_filters( 'the_title', $page->post_title, $page->ID ), $args['link_after'] ); if ( ! empty( $args['show_date'] ) ) { if ( 'modified' == $args['show_date'] ) { $time = $page->post_modified; } else { $time = $page->post_date; } $date_format = empty( $args['date_format'] ) ? '' : $args['date_format']; $output .= " " . mysql2date( $date_format, $time ); } } public function end_el( &$output, $page, $depth = 0, $args = array() ) { if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } // No_Link_First_Child_Walker check depth and remove closing </li> for depth 1 if($depth !== 1) { $output .= "</li>{$n}"; } } }