Việc sử dụng một tùy chỉnh Walker
thực sự không khó lắm, về cơ bản nó diễn ra như sau:
Tạo một lớp học ;
Một lớp là một tập hợp các biến và hàm làm việc với các biến này.
Bằng cách mở rộng một cái khác;
Lớp mở rộng hoặc dẫn xuất có tất cả các biến và hàm của lớp cơ sở [...] và những gì bạn thêm vào trong định nghĩa mở rộng.
Như thế này:
class Extended_Class extends Base_Class {
// code
}
Điều này cho bạn khả năng thay đổi / mở rộng các phương thức aka các hàm của lớp cơ sở đã được mở rộng. Ngoài ra, bạn có thể / có thể mở rộng bằng cách thêm các phương thức hoặc biến vào lớp mở rộng.
- Để hiểu đầy đủ và sử dụng các khả năng, cần phải tìm hiểu sâu hơn về các khía cạnh OOP: Classes và Object của PHP. Nhưng đó sẽ là quá nhiều ở đây và không phải là nơi thích hợp.
Vì vậy, hãy quay trở lại với WordPress và wp_list_pages()
. Lớp mà chúng ta muốn mở rộng để sử dụng với wp_list_pages()
, Walker_Page
lớp - nguồn -, chính nó đã được bắt nguồn bằng cách mở rộng nguồnWalker
- lớp .
Theo lược đồ được giải thích ở trên, chúng ta sẽ làm tương tự:
class Wpse159627_Walker_Page extends Walker_Page {
// code
}
Bây giờ Walker_Page
có hai biến - $tree_type
và $db_fields
- và bốn phương pháp - start_lvl()
, end_lvl()
, start_el()
và end_el()
. Các biến sẽ không liên quan đến chúng tôi, liên quan đến các phương pháp mà chúng tôi ít nhất phải xem xét kỹ hơn start_el()
và end_el()
.
Điều đầu tiên cần thấy là hai phương thức đó có tham số $page
:
@param object $ page Trang đối tượng dữ liệu.
Trong đó có chứa tất cả các dữ liệu có liên quan, chúng ta cần, giống như post_parent
, và khá nhiều WP_Post
/ $post
/" $page
" đối tượng. Trả lại bằng cách get_pages()
trả lại
Một mảng chứa tất cả các Trang phù hợp với yêu cầu hoặc sai khi thất bại. Mảng trả về là một mảng các đối tượng "trang".
bên trong các wp_list_pages()
chức năng.
Những gì chúng ta cần kiểm tra là trạng thái bài đăng của phụ huynh trang hiện tại, để thực hiện chức năng get_post_status()
này có sẵn. Giống như đã xác định, chúng ta có thể sử dụng đối tượng $ page có sẵn để làm như vậy.
$page_parent_id = $page->post_parent;
$page_parent_status = get_post_status( $page_parent_id );
Bây giờ chúng ta có thể sử dụng điều này để kiểm tra trạng thái của trang hiện tại:
if ( $page_parent_status != 'draft' ) {
// code
}
Hãy thực hiện nó trong lớp Walker mở rộng của chúng tôi:
class Wpse159627_Walker_Page extends Walker_Page {
function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
$page_parent_id = $page->post_parent;
$page_parent_status = get_post_status( $page_parent_id );
if ( $page_parent_status != 'draft' ) {
if ( $depth )
$indent = str_repeat("\t", $depth);
else
$indent = '';
extract($args, EXTR_SKIP);
$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 ( 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';
}
$css_class = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );
if ( '' === $page->post_title )
$page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
$output .= $indent . '<li class="' . $css_class . '"><a href="' . get_permalink($page->ID) . '">' . $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);
}
}
}
function end_el( &$output, $page, $depth = 0, $args = array() ) {
$page_parent_id = $page->post_parent;
$page_parent_status = get_post_status( $page_parent_id );
if ( $page_parent_status != 'draft' ) {
$output .= "</li>\n";
}
}
}
Lớp mới có thể được sử dụng wp_list_pages()
như thế này:
$args = array(
'sort_column' => 'menu_order',
'title_li' => '',
'post_status' => 'publish',
'walker' => new Wpse159627_Walker_Page
);
wp_list_pages( $args );
Biên tập:
Thêm điều này vì lý do đầy đủ, vì vậy để làm cho công việc này cho cây, tất cả con cháu, không chỉ trẻ em. Nó không phải là cách tối ưu để làm điều đó, đủ gợi ý khác đã được thực hiện.
Vì WordPress get_ancestors()
và các get_post_ancestors()
chức năng không được tạo để nhận bản nháp, tôi đã xây dựng một chức năng để nhận mọi tổ tiên:
function wpse159627_get_all_post_ancestors( $post_id ) {
$post_type = get_post_type( $post_id );
$post = new WP_Query(
array(
'page_id' => $post_id,
'include' => $post_id,
'post_type' => $post_type,
'post_status' => 'any',
'cache_results' => false,
'update_post_meta_cache' => false,
'update_post_term_cache' => false
)
);
$post = $post->posts[0];
if (
! $post
|| empty( $post->post_parent )
|| $post->post_parent == $post->ID
) {
return array();
}
$ancestors = array();
$id = $ancestors[] = $post->post_parent;
while (
$ancestor = new WP_Query(
array(
'page_id' => $id,
'include' => $id,
'post_type' => $post_type,
'post_status' => 'any',
'cache_results' => false,
'update_post_meta_cache' => false,
'update_post_term_cache' => false
)
)
) {
$ancestor = $ancestor->posts[0];
if (
empty( $ancestor->post_parent )
|| ( $ancestor->post_parent == $post->ID )
|| in_array( $ancestor->post_parent, $ancestors )
) {
break;
}
$id = $ancestors[] = $ancestor->post_parent;
}
return $ancestors;
}
Ngoài ra, nó là cần thiết để có được trạng thái của những tổ tiên. Có thể được thực hiện với chức năng sau:
function wpse159627_get_all_status( $ids ) {
$status_arr = array();
foreach ( $ids as $id ) {
$post_type = get_post_type( $id );
$post = new WP_Query(
array(
'page_id' => $id,
'include' => $id,
'post_type' => $post_type,
'post_status' => 'any',
'cache_results' => false,
'update_post_meta_cache' => false,
'update_post_term_cache' => false
)
);
$post = $post->posts[0];
$status_arr[] = $post->post_status;
}
return $status_arr;
}
Điều này có thể được sử dụng để thay thế điều kiện được giải thích ở trên:
$ancestors = wpse159627_get_all_post_ancestors( $page->ID );
$ancestors_status = wpse159627_get_all_status( $ancestors );
if ( ! in_array( 'draft', $ancestors_status ) ) {
// code
}
exclude_tree
tham số, để loại trừ toàn bộ các nhánh dự thảo.