Этот рабочий код является типичным решением этой проблемы.
Он принимает многомерный массив, который содержит категории и их подкатегории (без подразумеваемого ограничения на глубину, на которую он проходит), и создает из него неупорядоченный список HTML, выводя его на страницу изнутри рекурсивной функции.
Подуровни просматриваются путем рекурсивной передачи значения ключа 'children' каждого элемента массива изнутри исходной функции обратного вызова с именем _category_list () _.
Как можно изменить этот метод вывода, чтобы весь HTML-код существовал в шаблоне вне функции?
Вот краткое изложение кода:
Этот многомерный массив содержит многоуровневое дерево категорий.
Важными ключами для использования в HTML являются «category_id», «name» и «children». Для простоты другие ключи были удалены из приведенного ниже массива, но если они полезны, это: 'parent_id' и 'level' (начиная с уровня 1).
<?php
// the array containing the tree
$categories = array (
'category_id' => '2',
'name' => 'Top Category Name',
'children' => array (
0 => array (
'category_id' => '188',
'name' => 'Category Name',
'children' => array (
0 => array (
'category_id' => '159',
'name' => 'Category Name',
'children' => array (),
),
1 => array (
'category_id' => '160',
'name' => 'Category Name',
'children' => array (),
),
2 => array (
'category_id' => '166',
'name' => 'Category Name',
'children' => array (),
),
),
),
1 => array (
'category_id' => '4',
'name' => 'Category Name',
'children' => array (
0 => array (
'category_id' => '141',
'name' => 'Category Name',
'children' => array (),
),
1 => array (
'category_id' => '142',
'name' => 'Category Name',
'children' => array (),
),
),
),
),
)
?>
.
Эта следующая функция производит большую часть вывода HTML, но она блокирует HTML внутри себя.
Однако вместо того, чтобы выводить его прямо из функции, я ищу способ передать эти данные обратно в шаблон представления таким образом, чтобы дизайнеры могли его настроить.
<?php
// separate the HTML from this function,
// passing $v to the view template for handling
function category_list($v, $k){
switch ($k) {
case 'category_id':
echo "<li id="$v">";
break;
case 'name':
echo "$v";
break;
case 'children':
if(count($v) > 0){
echo "<ul>";
foreach($v as $k=>$v)
array_walk($v, 'category_list');
echo "</ul>";
}
echo "</li>";
break;
}
}
?>
.
Следующий блок кода - это текущий шаблон html / php с вызовом для обхода первого уровня массива через array_walk () и ссылкой на рекурсивную функцию выше. Затем сама функция обрабатывает рекурсию и итерацию более глубоких категорий с 1 или более дочерними элементами. Конечно, это типичный подход.
Этот код должен содержать все теги HTML, а не только внешние теги.
<ul>
<?php array_walk($tree,'category_list'); ?>
</ul>
.
Идеальное решение:
Конечная цель здесь - найти способ для дизайнеров шаблонов создать свою идеальную структуру навигации, не создавая и не изменяя функцию рекурсии (которая недоступна), и не требуя использования цикла foreach для каждого уровня многомерный массив. Решение не должно быть привязано к каким-либо конкретным ограничениям глубины.
Примеры настроек HTML могут варьироваться от размещения дополнительных атрибутов внутри тегов ul / li или даже оборачивания новых тегов вокруг выходного текста, таких как теги span, которые обычно используются в навигации для достижения эффекта раздвижных дверей с помощью CSS , Поэтому я думаю, что соответствующее решение должно как минимум поддерживать эти сценарии.
Итерирование по массиву из шаблона с использованием array_walk () все равно будет в порядке, если его можно использовать таким образом, чтобы функция обратного вызова передавала нужные переменные обратно в шаблон для использования с HTML-кодом дизайнера.
В идеале, если array_walk_recursive () знает, на сколько уровней на самом деле находится его итератор, я думаю, что это умение было бы гораздо проще решить. Но если кто-то не знает обходного пути к этой проблеме, решение может быть совершенно другим.
Я также хочу избегать использования методов javascript для построения дерева. И если есть способ избежать использования переключателя, я тоже открыт для предложений.