Sử dụng Walker tùy chỉnh, start_el()
phương thức này có quyền truy cập vào $depth
param: khi đó là 0
elemnt là một ứng dụng hàng đầu và chúng ta có thể sử dụng thông tin này để duy trì bộ đếm nội bộ.
Khi bộ đếm đạt đến giới hạn, chúng ta có thể sử dụng DOMDocument
để lấy từ đầu ra HTML đầy đủ chỉ phần tử cuối cùng được thêm vào, bọc nó trong menu con và thêm lại vào HTML.
Biên tập
Khi số lượng phần tử chính xác là số lượng chúng tôi yêu cầu + 1, ví dụ: chúng tôi yêu cầu 5 phần tử hiển thị và menu có 6, sẽ không có ý nghĩa gì khi chia menu, bởi vì các phần tử sẽ là 6. Mã đã được chỉnh sửa để giải quyết điều đó.
Đây là mã:
class SplitMenuWalker extends Walker_Nav_Menu {
private $split_at;
private $button;
private $count = 0;
private $wrappedOutput;
private $replaceTarget;
private $wrapped = false;
private $toSplit = false;
public function __construct($split_at = 5, $button = '<a href="#">…</a>') {
$this->split_at = $split_at;
$this->button = $button;
}
public function walk($elements, $max_depth) {
$args = array_slice(func_get_args(), 2);
$output = parent::walk($elements, $max_depth, reset($args));
return $this->toSplit ? $output.'</ul></li>' : $output;
}
public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$this->count += $depth === 0 ? 1 : 0;
parent::start_el($output, $item, $depth, $args, $id);
if (($this->count === $this->split_at) && ! $this->wrapped) {
// split at number has been reached generate and store wrapped output
$this->wrapped = true;
$this->replaceTarget = $output;
$this->wrappedOutput = $this->wrappedOutput($output);
} elseif(($this->count === $this->split_at + 1) && ! $this->toSplit) {
// split at number has been exceeded, replace regular with wrapped output
$this->toSplit = true;
$output = str_replace($this->replaceTarget, $this->wrappedOutput, $output);
}
}
private function wrappedOutput($output) {
$dom = new DOMDocument;
$dom->loadHTML($output.'</li>');
$lis = $dom->getElementsByTagName('li');
$last = trim(substr($dom->saveHTML($lis->item($lis->length-1)), 0, -5));
// remove last li
$wrappedOutput = substr(trim($output), 0, -1 * strlen($last));
$classes = array(
'menu-item',
'menu-item-type-custom',
'menu-item-object-custom',
'menu-item-has-children',
'menu-item-split-wrapper'
);
// add wrap li element
$wrappedOutput .= '<li class="'.implode(' ', $classes).'">';
// add the "more" link
$wrappedOutput .= $this->button;
// add the last item wrapped in a submenu and return
return $wrappedOutput . '<ul class="sub-menu">'. $last;
}
}
Cách sử dụng khá đơn giản:
// by default make visible 5 elements
wp_nav_menu(array('menu' => 'my_menu', 'walker' => new SplitMenuWalker()));
// let's make visible 2 elements
wp_nav_menu(array('menu' => 'another_menu', 'walker' => new SplitMenuWalker(2)));
// customize the link to click/over to see wrapped items
wp_nav_menu(array(
'menu' => 'another_menu',
'walker' => new SplitMenuWalker(5, '<a href="#">more...</a>')
));
Walker_Nav_Menu
và có một ví dụ trong bộ mã . Ý bạn là gì với "Tôi không biết cách tạo Walker"?