Этот рабочий код кажется типичным решением этой проблемы.
Он берет многомерный массив, который содержит категории и их подкатегории (без подразумеваемых ограничений на то, на сколько уровней он идет) и создает из него неупорядоченный список HTML, выводя его на страницу изнутри рекурсивной функции.
Подуровни обходятся путем рекурсивной передачи значения для каждого дочернего ключа элемента массива в array_walk () из исходной функции обратного вызова с именем _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 для построения дерева. И если есть способ избежать использования переключателя, я тоже открыт для предложений.