Инструкция по использованию jSQL Injection — многофункционального инструмента поиска и эксплуатации SQL-инъекций в Kali Linux. Вывод меню с помощью функции wp_nav_menu БЭМ меню с помощью фильтров

В этой статье я покажу, как можно создавать многоуровневое меню на PHP и MySQL . Безусловно, вариантов его создания можно придумать много, но, судя по количеству Ваших вопросов на эту тему, Вам нужен пример. И его я приведу в этой статье. Сразу отмечу, что данная статья имеет смысл только для тех, кто знает PHP и умеет работать с MySQL . Всем остальным сначала надо пройти этот , либо прочитать какие-нибудь книги по PHP и MySQL .

Для начала создадим таблицу в базе данных со следующими полями:

  • id - уникальный идентификатор.
  • title - анкор ссылки в меню.
  • link - адрес, на который будет вести пункт меню.
  • parent_id - родительский ID. Если родительского пункта нет, то здесь будет NULL (либо можно ещё 0 поставить).

С таблицей разобрались, теперь пришло время PHP-кода . Полный PHP-код приведён ниже:

$mysqli = new mysqli("localhost", "root", "", "db"); // Подключаемся к БД
$result_set = $mysqli->query("SELECT * FROM `menu`"); // Делаем выборку всех записей из таблицы с меню
$items = array(); // Массив для пунктов меню
while (($row = $result_set->fetch_assoc()) != false) $items[$row["id"]] = $row; // Заполняем массив выборкой из БД
$childrens = array(); // Массив для соответствий дочерних элементов их родительским
foreach ($items as $item) {
if ($item["parent_id"]) $childrens[$item["id"]] = $item["parent_id"]; // Заполняем массив
}
function printItem($item, $items, $childrens) {
/* Выводим пункт меню */
echo "

  • ";
    echo "".$item["title"]."";
    $ul = false; // Выводились ли дочерние элементы?
    while (true) {
    /* Бесконечный цикл, в котором мы ищем все дочерние элементы */
    $key = array_search($item["id"], $childrens); // Ищем дочерний элемент
    if (!$key) {
    /* Дочерних элементов не найдено */
    if ($ul) echo ""; // Если выводились дочерние элементы, то закрываем список
    break; // Выходим из цикла
    }
    unset($childrens[$key]); // Удаляем найденный элемент (чтобы он не выводился ещё раз)
    if (!$ul) {
    echo "
      "; // Начинаем внутренний список, если дочерних элементов ещё не было
      $ul = true; // Устанавливаем флаг
      }
      echo printItem($items[$key], $items, $childrens); // Рекурсивно выводим все дочерние элементы
      }
      echo "";
      }
      ?>

      Этот код полностью рабочий, однако, Вы должны понимать, что так никто не пишет (в частности, вывод через echo HTML-тегов ). И Ваша задача взять алгоритм из этого кода, но не сам код. А дальше этот алгоритм подключить к своему движку. Я постарался тщательно прокомментировать код вывода многоуровневого меню на PHP и MySQL , но, безусловно, он не самый прозрачный и требует уже неплохих начальных знаний. Если Вы ещё плохо знаете PHP и MySQL , то сначала настоятельно рекомендую пройти этот

      Поскольку она раскрывает содержание модуля menu.php . Ниже будет представлена собственная разработка меню на PHP, которая была написана с нуля в блокноте.

      Этот код особенно будет полезен для динамичных сайтов, которые имеют самописные движки . Я предложу два варианта кода, которые имеют незначительные отличия (в чем различие будет пояснено после).

      Для начала приведу примерную структуру сайта, для которого подойдет это меню. Структура сайта должна иметь следующий вид (классический вид):

      /index.html /razdel_1/ /razdel_1/articles_1.html /razdel_1/articles_2.html ... /razdel_2/ /razdel_2/articles_1.html /razdel_2/articles_2.html ... ... ... /razdel_N/articles_2.html

      Сайт может содержать у разделов еще и подразделы:

      /razdel_1/podzaderl_1/ /razdel_1/podzaderl_1/articles_1.html /razdel_1/podzaderl_1/articles_2.html ... /razdel_1/podzaderl_2/articles_1.html /razdel_1/podzaderl_2/articles_2.html

      Такая структура также будет работать для нашего меню лишь с небольшими отличиями.

      Я предлагаю создать отдельный файл для меню на php. Например, menu.php было бы отличным названием для такого файлика. Для реализации меню также представлен стиль меню в CSS, чтобы сразу сделать его более менее красивым. Естественно этот стиль дается только для ознакомления, поскольку дизайны у сайтов очень разные.

      Код для стиля меню в CSS:

      .menu { height:42px; padding:0 0 0 16px; background:url(images/spacer.png) repeat; } .menu li { display:block; float:left; } .menu li.active { background: #000011; } .menu a { color:#FFF; display:block; line-height:42px; text-decoration:none; padding:0 14px; } .menu a:hover { background:url(images/spacer.png) repeat; }

      Теперь, давайте рассмотрим первый вариант реализации меню на PHP, который является немного упрощенным.

      Первый вариант кода меню на PHP

      \n"; for ($i=0;$i": "
    • "; echo "".$array_menu[$i]["name"]."
    • \n"; } echo "
    "; ?>

    Меню можно разделить на две части. Первая содержит информационный массив $array_menu , в который заносятся названия наших разделов с ссылками на разделы. Есть вариант забить эти данные в базу данных mySQL, но особо смысла в этом нет, поскольку выборка совсем небольшая, поэтому на скорость работы это никак не повлияет.

    Вторая часть содержит вывод меню через цикл for . В цикле происходит сравнение адреса сайта с адресом из массива $array_menu . Если есть совпадение, то выводим очередной раздел меню со специальным классом active:

  • , иначе просто
  • . Это позволяет нам выделить каким-то цветом ту часть меню, в котором находится пользователь. На мой взгляд, это необходимая вещь для любого сайта, чтобы пользователь мог понимать в каком разделе он находится.

    Порядок следования в массиве будет сохранятся и при выводе меню на сайте. То есть массив надо заполнять в порядке, в котором нужно выводить меню.

    Примечание:
    В случае, если URL (адреса) заголовком разделов имеют вид:
    /razdel_1
    или такой
    /razdel_1/nazvanie_razdela.html
    то в array_menu нужно записывать точное совпадение:
    $array_menu[$i]["url"]="/razdel_1"
    или для второго случая:
    $array_menu[$i]["url"]="/razdel_1/nazvanie_razdela.html" ;

    Как работает первый вариант меню?
    Он подсвечивает меню только, если Вы находитесь по адресу заголовка раздела. Например, если адрес страницы будет /razdel_1/articles_1.html , то меню никак не будет подсвечиваться.

    Второй вариант кода является модифицированным вариантом первого и предусматривает возможность подсвечивания меню даже в статьях, которые находятся в разделах.

    Второй вариант кода меню на PHP

    "; for ($i=0;$i": "
  • "; echo "".$array_menu[$i]["title"]."
  • "; } else { echo ($URL) == ($array_menu[$i]["url"]) ? "
  • ": "
  • "; echo "".$array_menu[$i]["title"]."
  • "; } } echo ""; ?>

    Выводит произвольное меню, созданное в панели: "внешний вид > меню" (Appearance > Menus).

    Какое именно меню навигации выводить (их может быть несколько), указывается в параметре theme_location .

    Если не указан параметр theme_location , то меню для вывода будет подбираться в следующем порядке:

      Меню, подходящее по ID, слагу или описанию переданному в параметре "menu" и если в этом меню есть хоть одна ссылка (один элемент);

      иначе, первое не пустое меню;

      или, выведет значение возвращаемое функцией указанной в параметре "fallback_cb" (по умолчанию там указано функция wp_page_menu);

    1. если ничего не подошло, функция ничего и не выведет.

    Чтобы тема поддерживала меню, нужно включить эту возможность с помощью:
    add_theme_support("menus");

    Или можно зарегистрировать место для меню, с помощью register_nav_menu() , тогда поддержка меню темой включиться автоматически.

    Фильтры изменения элемента меню

    • add_filter("wp_nav_menu_args", "my_wp_nav_menu_args"); function my_wp_nav_menu_args($args = ""){ $args["container"] = false; return $args; }

      #4.1. Удалим контейнер, только у одного, выводимого меню

      "" ]); ?>

      #5 Удалим ul обертку

      Этот пример удалит обертку тега ul у меню:

      "%3$s" ]); ?>

      #6 Добавим слово в начало меню

      Этот пример показывает, как добавить слово в начало списка меню, в виде такого же элемента меню, только не ссылки. Добавим в начало меню, слово "Список", также укажем атрибут id созданному тегу li:

      "primary", "items_wrap" => "

      • Список:
      • %3$s
      " ]); ?>

      #7 Добавим CSS классы ко всем меню

      Используя хук, мы можем добавить свои CSS классы, если соблюдается нужное нам условие.

      Добавим CSS класс, если это пост и название элемента меню равно "blog":

      Add_filter("nav_menu_css_class", "special_nav_class", 10, 2); function special_nav_class($classes, $item){ if(is_single() && $item->title == "Blog"){ $classes = "special-class"; } return $classes; }

      #8 Использование своей функции для построения меню

      Во-первых нужно указать аргумент "walker" => new Your_Walker_Function .

      Your_Walker_Function - это наш новый класс, который строит меню. Чтобы не изобретать велосипед, её можно скопировать из оригинала, см. класс Walker_Nav_Menu . Копируем код класса и просто поправляем его там где нужно.

      Вот пример, добавляющий глубину меню и четные/нечетные CSS классы к элементам меню (обоим ul и li):

      // свой класс построения меню: class magomra_walker_nav_menu extends Walker_Nav_Menu { // add classes to ul sub-menus function start_lvl(&$output, $depth) { // depth dependent classes $indent = ($depth > 0 ? str_repeat("\t", $depth) : ""); // code indent $display_depth = ($depth + 1); // because it counts the first submenu as 0 $classes = array("sub-menu", ($display_depth % 2 ? "menu-odd" : "menu-even"), ($display_depth >=2 ? "sub-sub-menu" : ""), "menu-depth-" . $display_depth); $class_names = implode(" ", $classes); // build html $output .= "\n" . $indent . "

        " . "\n"; } // add main/sub classes to li"s and links function start_el(&$output, $item, $depth, $args) { global $wp_query; $indent = ($depth > 0 ? str_repeat("\t", $depth) : ""); // code indent // depth dependent classes $depth_classes = array(($depth == 0 ? "main-menu-item" : "sub-menu-item"), ($depth >=2 ? "sub-sub-menu-item" : ""), ($depth % 2 ? "menu-item-odd" : "menu-item-even"), "menu-item-depth-" . $depth); $depth_class_names = esc_attr(implode(" ", $depth_classes)); // passed classes $classes = empty($item->classes) ? array() : (array) $item->classes; $class_names = esc_attr(implode(" ", apply_filters("nav_menu_css_class", array_filter($classes), $item))); // build html $output .= $indent . "
      • } return $items; } function __nav_hasSub($item_id, $items){ foreach($items as $item){ if($item->menu_item_parent && $item->menu_item_parent == $item_id) return true; } return false; }

        #11 Добавление класса к отдельным элементам меню

        С версии 4.1.

        Появился специальных хук для этого: nav_menu_css_class . И теперь классы можно добавлять или удалять через него. Для примера давайте добавим класс my__class ко всем элементам меню:

        Add_filter("nav_menu_css_class", "add_my_class_to_nav_menu", 10, 2); function add_my_class_to_nav_menu($classes, $item){ /* $classes содержит Array( => menu-item => menu-item-type-post_type => menu-item-object-page => menu-item-284) */ $classes = "my__class"; return $classes; }

        До версии 4.1.

        Классы элементам меню добавляются функцией _wp_menu_item_classes_by_context(&$menu_items); . Но к сожалению в ней не предусмотрены никакие фильтры, чтобы добавить свой класс. Поэтому пойдем обходным путем и используем костыль str_replace() :

        // получаем а не выводим меню $menu = wp_nav_menu(array("echo" => 0,)); // добавляем ко всем пунктам класс my__class $menu = str_replace("class="menu-item", "class="menu-item my__class", $menu); // выводим на экран echo $menu;

        #12 Выводить меню, только если оно существует

        По умолчанию, если меню нет, то вместо него будут выведены страницы сайта. Но если нужно выводить меню, только в том случае когда оно создано в админ-панели, укажите параметр fallback_cb как "__return_empty_string" :

        Wp_nav_menu(array("theme_location" => "primary-menu", "fallback_cb" => "__return_empty_string"));

        #13 Вывод только подпункта меню

        Допустим, есть первый уровень и у каждого из элементов первого уровня, есть свое подменю. Нам нужно вывести такое подменю у пункта с классом menu-item-135:

        ## Вырезаем все LI нужного submenu и выводим их в своем UL блоке $menu = wp_nav_menu(array("theme_location" => "header_menu", "container" => "", "echo" => 0,)); $regex_part = preg_quote("menu-item-135"); // выведем подменю пункта "gotovye-resheniya" preg_match("~". $regex_part .".*sub-menu[^>]+>(.*?)

      ~s", $menu, $mm); if(!empty($mm)) echo "";

      Не очень оптимальный, но рабочий пример. Иногда может пригодится, для малопосещаемых сайтов где нужно быстро получить результат.

      CSS классы элементов меню

      Следующие CSS классы добавляются к элементам меню (разделение по условиям на каких страницах находится пользователь):

      Для всех элементов на всех страницах

        .menu-item - ко всем элементам меню;

        .menu-item-object-{object} - ко всем элементам, где {object} замениться на название типа записи или таксономии:
        .menu-item-object-category (для категорий)
        .menu-item-object-tag (для меток)
        .menu-item-object-page (для постоянных страниц)
        .menu-item-object-{custom}

      • .menu-item-type-{type} - ко всем элементам меню, где {type} замениться на тип ссылки (запись или таксономия). Группирует все типы ссылок:
        .menu-item-type-post_type (постоянная страница, произвольный тип записи)
        .menu-item-type-taxonomy (категория, метка или произвольная таксономия)

      Для элементов текущей страницы

      • .current-menu-item - если ссылка в меню совпадает с адресом просматриваемой страницы. Текущая страница.

      Для элементов родительских для просматриваемой страницы

      • .current-menu-parent
      • .current-{object}-ancestor
      • .current-{type}-ancestor

      Для элементов как-то связанных с просматриваемой страницей

      • .current-menu-ancestor
      • .current-{object}-ancestor
      • .current-{type}-ancestor

      Для элементов связанных с главной страницей сайта

      • .menu-item-home

      Совместимость с функцией wp_page_menu()

      • .page_item
      • .page-item-$ID
      • .current_page_item
      • .current_page_parent
      • .current_page_ancestor

      Объект $item

      Параметры $item

      В примерах часто используется элемент меню $item. Ниже показаны почти все параметры этого элемента:

      Поле Описание
      ID ID элемента меню
      menu_item_parent ID родительского элемента меню
      classes массив классов элемента меню
      post_date дата добавления
      post_modified дата последнего изменения
      post_author ID пользователя, добавившего этот элемент меню
      title заголовок элемента меню
      url ссылка элемента меню
      attr_title title атрибут ссылки
      xfn rel атрибут ссылки
      target target атрибут ссылки
      current равен 1, если это текущий элемент
      current_item_ancestor 1, если текущий элемент - это вложенный элемент
      current_item_parent 1 если текущим элемент - это родительский элемент
      menu_order порядковый номер в меню
      object_id ID объекта меню. Записи, термина и т.д.
      type тип объекта меню (такса, запись)
      object название таксы, типа записи: page, category, post_tag ...
      type_label локализованное название типа: Рубрика, Страница
      post_parent ID родительской записи
      post_title заголовок записи
      post_name ярлык записи
      Пример объекта $item
      WP_Post Object ( => 10 => 5 => 2019-02-11 13:33:39 => 2019-02-11 13:33:39 => => New => => publish => closed => closed => => new => => => 2019-02-11 23:10:19 => 2019-02-11 23:10:19 => => 0 => http://dh5.com/?p=10 => 1 => nav_menu_item => => 0 => raw => 10 => 0 => 10 => custom => custom => Custom Link => New => # => => => => Array => extra-sub-menu => menu-item => menu-item-type-custom => menu-item-object-custom => => => =>)

      Пример использования параметра walker

      В walker можно указать объект, который будет строить меню. В этом объекте можно описать HTML код получаемого меню.

      Если нужно создать меню для нестандартной верстки, то иногда проще переделать этот объект, чем переделывать верстку.

      В качестве примера walker объекта, возьмем класс Walker_Nav_Menu{} , который используется по умолчанию. В нём нас интересует только один метод start_el() . Именно он отвечает за HTML каждого элемента. Как правило, достаточно изменить только его. Для этого нужно создать свой класс, который будет расширять класс Walker_Nav_Menu и указать его в параметре walker при вызове меню.

      Смотрим на примере. Взят код метода start_el() без изменений. Используем в качестве шаблона:

      Class My_Walker_Nav_Menu extends Walker_Nav_Menu { /** * Starts the element output. * * @since 3.0.0 * @since 4.4.0 The {@see "nav_menu_item_args"} filter was added. * * @see Walker::start_el() * * @param string $output Passed by reference. Used to append additional content. * @param WP_Post $item Menu item data object. * @param int $depth Depth of menu item. Used for padding. * @param stdClass $args An object of wp_nav_menu() arguments. * @param int $id Current item ID. */ public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) { if (isset($args->item_spacing) && "discard" === $args->item_spacing) { $t = ""; $n = ""; } else { $t = "\t"; $n = "\n"; } $indent = ($depth) ? str_repeat($t, $depth) : ""; $classes = empty($item->classes) ? array() : (array) $item->classes; $classes = "menu-item-" . $item->ID; $args = apply_filters("nav_menu_item_args", $args, $item, $depth); $class_names = join(" ", apply_filters("nav_menu_css_class", array_filter($classes), $item, $args, $depth)); $class_names = $class_names ? " class="" . esc_attr($class_names) . """ : ""; $id = apply_filters("nav_menu_item_id", "menu-item-". $item->ID, $item, $args, $depth); $id = $id ? " id="" . esc_attr($id) . """ : ""; // создаем HTML код элемента меню $output .= $indent . ""; $atts = array(); $atts["title"] = ! empty($item->attr_title) ? $item->attr_title: ""; $atts["target"] = ! empty($item->target) ? $item->target: ""; $atts["rel"] = ! empty($item->xfn) ? $item->xfn: ""; $atts["href"] = ! empty($item->url) ? $item->url: ""; $atts = apply_filters("nav_menu_link_attributes", $atts, $item, $args, $depth); $attributes = ""; foreach ($atts as $attr => $value) { if (! empty($value)) { $value = ("href" === $attr) ? esc_url($value) : esc_attr($value); $attributes .= " " . $attr . "="" . $value . """; } } $title = apply_filters("the_title", $item->title, $item->ID); $title = apply_filters("nav_menu_item_title", $title, $item, $args, $depth); $item_output = $args->before; $item_output .= ""; $item_output .= $args->link_before . $title . $args->link_after; $item_output .= ""; $item_output .= $args->after; $output .= apply_filters("walker_nav_menu_start_el", $item_output, $item, $depth, $args); } }

      Теперь, при вызове меню указываем свой walker:

      Wp_nav_menu(array("theme_location" => "head_menu", "walker" => new My_Walker_Nav_Menu(),));

      Готово, теперь каждый элемент меню будет строиться по нужной нам HTML схеме.

      БЭМ меню с помощью фильтров

      Будет формироваться вёрстка по методологии БЭМ:

      Файл index.php или другой для вывода меню

      "header-menu", ]);

      Файл functions.php

      "Верхняя область", "footer-menu" => "Нижняя область", ]); }); // Изменяет основные параметры меню add_filter("wp_nav_menu_args", "filter_wp_menu_args"); function filter_wp_menu_args($args) { if ($args["theme_location"] === "header-menu") { $args["container"] = false; $args["items_wrap"] = ""; $args["menu_class"] = "menu menu--main menu-horizontal"; } return $args; } // Изменяем атрибут id у тега li add_filter("nav_menu_item_id", "filter_menu_item_css_id", 10, 4); function filter_menu_item_css_id($menu_id, $item, $args, $depth) { return $args->theme_location === "header-menu" ? "" : $menu_id; } // Изменяем атрибут class у тега li add_filter("nav_menu_css_class", "filter_nav_menu_css_classes", 10, 4); function filter_nav_menu_css_classes($classes, $item, $args, $depth) { if ($args->theme_location === "header-menu") { $classes = [ "menu-node", "menu-node--main_lvl_" . ($depth + 1) ]; if ($item->current) { $classes = "menu-node--active"; } } return $classes; } // Изменяет класс у вложенного ul add_filter("nav_menu_submenu_css_class", "filter_nav_menu_submenu_css_class", 10, 3); function filter_nav_menu_submenu_css_class($classes, $args, $depth) { if ($args->theme_location === "header-menu") { $classes = [ "menu", "menu--dropdown", "menu--vertical" ]; } return $classes; } // Добавляем классы ссылкам add_filter("nav_menu_link_attributes", "filter_nav_menu_link_attributes", 10, 4); function filter_nav_menu_link_attributes($atts, $item, $args, $depth) { if ($args->theme_location === "header-menu") { $atts["class"] = "menu-link"; if ($item->current) { $atts["class"] .= " menu-link--active"; } } return $atts; }

      Заказывайте очень дешевые лайки на публичную страницу в Facebook на данном сервисе и получайте возможность выбрать не только приятную цену, но и персональные условия для приобретения ресурса. Так, например, Вам будет доступен выбор скоростного режима поступления и качества подписываемых страниц. Кроме того, сервис предоставляет гарантии своим клиентам.

      Код wp nav menu : wp-includes/nav-menu-template.php WP 5.2.2

      "", "container" => "div", "container_class" => "", "container_id" => "", "menu_class" => "menu", "menu_id" => "", "echo" => true, "fallback_cb" => "wp_page_menu", "before" => "", "after" => "", "link_before" => "", "link_after" => "", "items_wrap" => "", "item_spacing" => "preserve", "depth" => 0, "walker" => "", "theme_location" => "",); $args = wp_parse_args($args, $defaults); if (! in_array($args["item_spacing"], array("preserve", "discard"), true)) { // invalid value, fall back to default. $args["item_spacing"] = $defaults["item_spacing"]; } /** * Filters the arguments used to display a navigation menu. * * @since 3.0.0 * * @see wp_nav_menu() * * @param array $args Array of wp_nav_menu() arguments. */ $args = apply_filters("wp_nav_menu_args", $args); $args = (object) $args; /** * Filters whether to short-circuit the wp_nav_menu() output. * * Returning a non-null value to the filter will short-circuit * wp_nav_menu(), echoing that value if $args->echo is true, * returning that value otherwise. * * @since 3.9.0 * * @see wp_nav_menu() * * @param string|null $output Nav menu output to short-circuit with. Default null. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $nav_menu = apply_filters("pre_wp_nav_menu", null, $args); if (null !== $nav_menu) { if ($args->echo) { echo $nav_menu; return; } return $nav_menu; } // Get the nav menu based on the requested menu $menu = wp_get_nav_menu_object($args->menu); // Get the nav menu based on the theme_location if (! $menu && $args->theme_location && ($locations = get_nav_menu_locations()) && isset($locations[ $args->theme_location ])) { $menu = wp_get_nav_menu_object($locations[ $args->theme_location ]); } // get the first menu that has items if we still can"t find a menu if (! $menu && ! $args->theme_location) { $menus = wp_get_nav_menus(); foreach ($menus as $menu_maybe) { if ($menu_items = wp_get_nav_menu_items($menu_maybe->term_id, array("update_post_term_cache" => false))) { $menu = $menu_maybe; break; } } } if (empty($args->menu)) { $args->menu = $menu; } // If the menu exists, get its items. if ($menu && ! is_wp_error($menu) && ! isset($menu_items)) { $menu_items = wp_get_nav_menu_items($menu->term_id, array("update_post_term_cache" => false)); } /* * If no menu was found: * - Fall back (if one was specified), or bail. * * If no menu items were found: * - Fall back, but only if no theme location was specified. * - Otherwise, bail. */ if ((! $menu || is_wp_error($menu) || (isset($menu_items) && empty($menu_items) && ! $args->theme_location)) && isset($args->fallback_cb) && $args->fallback_cb && is_callable($args->fallback_cb)) { return call_user_func($args->fallback_cb, (array) $args); } if (! $menu || is_wp_error($menu)) { return false; } $nav_menu = $items = ""; $show_container = false; if ($args->container) { /** * Filters the list of HTML tags that are valid for use as menu containers. * * @since 3.0.0 * * @param array $tags The acceptable HTML tags for use as menu containers. * Default is array containing "div" and "nav". */ $allowed_tags = apply_filters("wp_nav_menu_container_allowedtags", array("div", "nav")); if (is_string($args->container) && in_array($args->container, $allowed_tags)) { $show_container = true; $class = $args->container_class ? " class="" . esc_attr($args->container_class) . """ : " class="menu-" . $menu->slug . "-container""; $id = $args->container_id ? " id="" . esc_attr($args->container_id) . """ : ""; $nav_menu .= "<" . $args->container . $id . $class . ">"; } } // Set up the $menu_item variables _wp_menu_item_classes_by_context($menu_items); $sorted_menu_items = $menu_items_with_children = array(); foreach ((array) $menu_items as $menu_item) { $sorted_menu_items[ $menu_item->menu_order ] = $menu_item; if ($menu_item->menu_item_parent) { $menu_items_with_children[ $menu_item->menu_item_parent ] = true; } } // Add the menu-item-has-children class where applicable if ($menu_items_with_children) { foreach ($sorted_menu_items as &$menu_item) { if (isset($menu_items_with_children[ $menu_item->ID ])) { $menu_item->classes = "menu-item-has-children"; } } } unset($menu_items, $menu_item); /** * Filters the sorted list of menu item objects before generating the menu"s HTML. * * @since 3.1.0 * * @param array $sorted_menu_items The menu items, sorted by each menu item"s menu order. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $sorted_menu_items = apply_filters("wp_nav_menu_objects", $sorted_menu_items, $args); $items .= walk_nav_menu_tree($sorted_menu_items, $args->depth, $args); unset($sorted_menu_items); // Attributes if (! empty($args->menu_id)) { $wrap_id = $args->menu_id; } else { $wrap_id = "menu-" . $menu->slug; while (in_array($wrap_id, $menu_id_slugs)) { if (preg_match("#-(\d+)$#", $wrap_id, $matches)) { $wrap_id = preg_replace("#-(\d+)$#", "-" . ++$matches, $wrap_id); } else { $wrap_id = $wrap_id . "-1"; } } } $menu_id_slugs = $wrap_id; $wrap_class = $args->menu_class ? $args->menu_class: ""; /** * Filters the HTML list content for navigation menus. * * @since 3.0.0 * * @see wp_nav_menu() * * @param string $items The HTML list content for the menu items. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $items = apply_filters("wp_nav_menu_items", $items, $args); /** * Filters the HTML list content for a specific navigation menu. * * @since 3.0.0 * * @see wp_nav_menu() * * @param string $items The HTML list content for the menu items. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $items = apply_filters("wp_nav_menu_{$menu->slug}_items", $items, $args); // Don"t print any markup if there are no items at this point. if (empty($items)) { return false; } $nav_menu .= sprintf($args->items_wrap, esc_attr($wrap_id), esc_attr($wrap_class), $items); unset($items); if ($show_container) { $nav_menu .= "container . ">"; } /** * Filters the HTML content for navigation menus. * * @since 3.0.0 * * @see wp_nav_menu() * * @param string $nav_menu The HTML content for the navigation menu. * @param stdClass $args An object containing wp_nav_menu() arguments. */ $nav_menu = apply_filters("wp_nav_menu", $nav_menu, $args); if ($args->echo) { echo $nav_menu; } else { return $nav_menu; } }

    Если вас интересует ответ на вопрос как создать меню сайта, то вы пришли по верному адресу.

    Мы рассмотрим создание динамического меню на php, написанное специально для чайников в программировании, а также для тех, кто еще в танке.

    Урок 3. Меню на php для сайта делаем динамичным - чайникам

    Создадим будущий макет нашего сайта. Для этого нарисуем в фотошопе супер красивый сайт и разрежем на кусочки. Представим, что шапка, логотип, меню и подвал не написаны словами, как в данном примере, а это изысканно и красочно оформленные элементы сайта.

    Создадим для примера три страницы и назовем их Раздел 1, Раздел 2, Раздел 3

    Этот текст для разных страниц будет разный, но мы не будем на нем заморачиваться и оставим его как есть на всех страницах.

    Приступим к созданию сайта на php.

    1. Выделим блоки header, logo, menu, footer в отдельные файлы c расширением php или html

    header.html

    logo.html

    menu.html

    footer.html

    Добавим файл с этим текстом, чтобы видеть его на всех страницах. Назовем его text.html

    Примечание. С этого момента дальнейшие записи буду вести непосредственно в файле text.html

    2. Создадим шаблон для нашего сайта на php.

    Для этого поступим просто - сохраним настоящий файл, но уже с расширением php и сотрем все текстовое наполнение. Пусть это не профессионально, зато понятно, а усложнять все будем позже. Сейчас главное понять принцип верстки.

    3. Теперь файл template.html нам не нужен.

    Благодаря ему мы имеем представление о том, как будет выглядеть наш сайт.

    4. Нашим шаблоном является файл template.php

    В него мы сейчас вставим с помощью команды include все элементы сайта.

    5. Создадим три странички, как собирались изначально.

    Раздел 1 , назовем 1.php

    Раздел 2 , назовем 2.php

    Раздел 3 , назовем 3.php

    Для этого можно воспользоваться простейшей командой сохранить как...

    Для самых маленьких поясню: открываем файл template.php , затем нажимаем сохранить как... и сохраняем под названием 1.php , повторяем процедуру и последовательно сохраним страницы сайта 2.php , 3.php

    У нас получилось 3 страницы с одинаковым дизайном. Достаточно вставлять вместо файла text.html другой, дополнять разными картинками или какими-либо html кодами, скриптами и содержимое каждой страницы будет уникальным.

    Внимание!

    Если не будет создан файл index.php для главной страницы, то в браузере, набрав адрес сайта мы не увидим сам сайт, а всего лишь структуру директории (перечень папок).

    Можете посмотреть в денвере и убедиться. Исправим ситуацию - создадим файл index.php и назовем долго не мудрствуя Главная . Заодно создадим файл text-home.html и с помощью команды include вставим на только что созданную главную страницу сайта.

    6. Как просмотреть сайт на php?

    Что получилось - так просто не увидим. Это уже не шаблон с расширением html.

    Но и не проблема. Нам нужен собственный, т.е. локальный сервер на компьютере. Для этого установим денвер и результат своей работы будем смотреть в браузере, не выходя в интернет.

    Вот теперь порядок. Набрала адрес сайта и увидела все только что созданное в нормальном виде с дизайном.

    Теперь возьмемся за php меню сайта.

    1. Откроем файл menu.html и превратим раздел1, 2 и 3 в ссылки по сайту. Ссылки в php создаются по-разному.

    Наша задача - научиться чувствовать сайт, созданный на php. Поэтому ссылки будем делать, как на обычном статичном сайте Раздел 1 и т.д.

    Мне эта процедура создания ссылок безумно нравится в Macromedia Dreamweaver. Успевай жать ОК и пить кофе.

    2. Как сделать ссылку в меню неактивной, если посетитель находится на данной странице.

    Посетителю будет удобнее ориентироваться по сайту зная, на какой именно страинице он находится.

    Если вы выполнили все шаги строго по пунктам, то видите, что у нас все ссылки в меню активны постоянно. Как это исправить?

    Для начала вспомним определение что такое Условные операторы

    – это когда какое-то действие выполняется или не выполняется в зависимости от условий.

    Выполним следующие действия:

    • Нам понадобятся переменные и один условный оператор :

    if ($master == "Главная") // это условие. Если оно выполняется – то в данном месте меню с помощью команды echo вставляются обычные HTML-теги выводящие надпись «Главная».

    echo "

    Главная

    ";

    else //означает «иначе» - что произойдёт, если условие не выполняется. В данном случае при невыполнении условия надпись «Главная» будет ссылкой, ведущей на главную страницу.

    echo "

    Главная

    ";

    • Условие мы придумали, но чтобы проверить переменную нужно её задать.

    Для этого на всех страницах разместим такие блоки кода:

    $master ="Главная";

    $master ="Раздел 1";

    $master ="Раздел 2";

    $master ="Раздел 3";

    Как видно для каждой страницы свой код.

    Итак, наши практические шаги по созданию php меню будут следующие:

    1) Открываем файл index.php

    и вставляем код

    $master ="Главная";

    до места вставки кода, выводящего само меню сайта include "menu.html";
    ?>

    2) Открываем файл menu.html и вставляем код с условием вместо простой html ссылки на главную страницу.

    Смотрим в браузере и любуемся! Если зайдем на главную страницу, то ссылка перестала быть активной!

    3) Повторяем пункт 1 и 2 со страницами 1.php, 2.php, 3.php

    Повторение 1:

    1) Открываем файл 1.php и вставляем до кода, выводящего меню блок с заданной переменной

    $master ="Раздел 1";

    2) Открываем файл menu.html и вставляем код с условием вместо простой ссылки Раздел 1 , внеся следующие изменения:

    if ($master == "Раздел 1") // это условие. Если оно выполняется – то в данном месте меню с помощью команды echo вставляются обычные HTML-теги выводящие надпись «Раздел 1».

    echo "

    Раздел 1

    ";

    else //означает «иначе» - что произойдёт, если условие не выполняется. В данном случае при невыполнении условия надпись «Раздел 1» будет ссылкой, ведущей на главную страницу.

    echo "

    Раздел 1

    ";

    Чудо повторилось! Теперь, если мы находимся на странице Раздел 1 , ссылка в меню не активна.

    Повторенье - мать ученья! Или для тех, кто в танке! Еще раз

    Повторенье 2

    1) Открываем файл 2.php и вставляем код.

    $master ="Раздел 2";

    2) Снова откроем файл menu.html и вставляем код с условием

    if ($master == "Раздел 2") // это условие. Если оно выполняется – то в данном месте меню с помощью команды echo вставляются обычные HTML-теги выводящие надпись «Раздел 2».

    echo "

    Раздел 2

    ";

    else //означает «иначе» - что произойдёт, если условие не выполняется. В данном случае при невыполнении условия надпись «Раздел 2» будет ссылкой, ведущей на главную страницу.

    echo "

    Раздел 2

    ";

    Повторенье 3

    1) Открываем файл 3.php и задаем переменную.

    $master ="Раздел 3";

    2) В файл menu.html вставляем код с условием вместо ссылки Раздел 3 , изменения такие:

    if ($master == "Раздел 3") // это условие. Если оно выполняется – то в данном месте меню с помощью команды echo вставляются обычные HTML-теги выводящие надпись «Раздел 3».

    echo "

    Раздел 3

    ";

    else //означает «иначе» - что произойдёт, если условие не выполняется. В данном случае при невыполнении условия надпись «Раздел 3» будет ссылкой, ведущей на главную страницу.

    echo "

    Раздел 3

    ";

    Итог : мы вместо ссылок в меню такого вида

    Главная


    Раздел 1

    Раздел 2


    Раздел 3

    Этот урок о php был написан по многочисленным просьбам посетителей сайта и является практическим пособием по изучению создания динамического меню для сайта на php.

    Следующая шпрагалка вебмастера расскажет о том, как сделать на php уникальные заголовки, описания и ключевики для каждой страницы.

    Вы можете скачать архив со всеми файлами шаблона сайта и меню php. Новичкам в программировании рекомендуется.

    Если же вы готовы к серьезному изучению php, то лучше видео курса от Попова найти сложно. У него огромный опыт и хороший слог.

    ]]> ]]>

    Ни один сайт не обходится без навигации или как еще называют "меню сайта". Так вот меню сайта бывает одноуровневым и многоуровневым в виде дерева. Если с одноуровневым меню особых сложностей в плане реализации не возникает, то при создании многоуровневого меню нужно хорошо подумать.

    Самое главное в этой задаче это спроектировать базу данных для нашего многоуровневого меню. Создадим таблицу Categories с тремя полями id , title , parent где:

    • ID - идентификатор
    • Title - Название меню
    • Parent - Родитель категории по умолчанию 0

    За ветвление меню отвечает поле Parent если Parent = 0 , то эта категория является родительской. Для того чтобы добавить потомков к родительской категории нужно в поле parent указать ID нужного родителя. Например:

    Таблицы с категориями

    Как видно из таблицы, у родительской категории Автомобили есть два потомка - это Мазда и Хонда связанных по полю Parent . А у категории Мотоциклы два потомка - это Кавасаки и Харлей . При этом у категории Лодки нет потомков. Надеюсь, что Вы поняли,как связать категории.

    Далее переходим от слов к практике. Создадим таблицу Categories.

    CREATE TABLE IF NOT EXISTS `categories` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `parent` int(10) unsigned NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ; -- -- Дамп данных таблицы `categories` -- INSERT INTO `categories` (`id`, `title`, `parent`) VALUES (1, "Автомобили", 0), (2, "Мотоциклы", 0), (3, "Мазда", 1), (4, "Хонда", 1), (5, "Кавасаки", 2), (6, "Харлей", 2), (7, "Мазда 3", 3), (8, "Мазда 6", 3), (9, "Седан", 7), (10, "Хечбэк", 7), (11, "Лодки", 0), (12, "Лифтбэк", 8), (13, "Кроссовер", 8), (14, "Белый", 13), (15, "Красный", 13), (16, "Черный", 13), (17, "Зеленый", 13), (18, "Мазда CX", 3), (19, "Мазда MX", 3);

    Алгоритм работы состоит из следующего:

    Создаем соединение с базой данных

    query("SET NAMES "utf8""); /* * Это "официальный" объектно-ориентированный способ сделать это * однако $connect_error не работал вплоть до версий PHP 5.2.9 и 5.3.0. */ if ($mysqli->connect_error) { die("Ошибка подключения (" . $mysqli->connect_errno . ") " . $mysqli->connect_error); } /* * Если нужно быть уверенным в совместимости с версиями до 5.2.9, * лучше использовать такой код */ if (mysqli_connect_error()) { die("Ошибка подключения (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); }

    Пишем функцию получения данных из таблицы Categories

    //Получаем массив нашего меню из БД в виде массива function getCat($mysqli){ $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Создаем масив где ключ массива является ID меню $cat = array(); while($row = $res->fetch_assoc()){ $cat[$row["id"]] = $row; } return $cat; }

    Получаем массив вот такого вида, где ключ массива это ID категории.

    Функция построения дерева из массива от Tommy Lacroix

    //Функция построения дерева из массива от Tommy Lacroix function getTree($dataset) { $tree = array(); foreach ($dataset as $id => &$node) { //Если нет вложений if (!$node["parent"]){ $tree[$id] = &$node; }else{ //Если есть потомки то перебераем массив $dataset[$node["parent"]]["childs"][$id] = &$node; } } return $tree; }

    Получаем массив в виде дерева

    Скрипт целиком

    query("SET NAMES "utf8""); /* * Это "официальный" объектно-ориентированный способ сделать это * однако $connect_error не работал вплоть до версий PHP 5.2.9 и 5.3.0. */ if ($mysqli->connect_error) { die("Ошибка подключения (" . $mysqli->connect_errno . ") " . $mysqli->connect_error); } /* * Если нужно быть уверенным в совместимости с версиями до 5.2.9, * лучше использовать такой код */ if (mysqli_connect_error()) { die("Ошибка подключения (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); } //Получаем массив нашего меню из БД в виде массива function getCat($mysqli){ $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Создаем масив где ключ массива является ID меню $cat = array(); while($row = $res->fetch_assoc()){ $cat[$row["id"]] = $row; } return $cat; } //Функция построения дерева из массива от Tommy Lacroix function getTree($dataset) { $tree = array(); foreach ($dataset as $id => &$node) { //Если нет вложений if (!$node["parent"]){ $tree[$id] = &$node; }else{ //Если есть потомки то перебераем массив $dataset[$node["parent"]]["childs"][$id] = &$node; } } return $tree; } //Получаем подготовленный массив с данными $cat = getCat($mysqli); //Создаем древовидное меню $tree = getTree($cat); //Шаблон для вывода меню в виде дерева function tplMenu($category){ $menu = "
  • ". $category["title"].""; if(isset($category["childs"])){ $menu .= "
      ". showCat($category["childs"]) ."
    "; } $menu .= "
  • "; return $menu; } /** * Рекурсивно считываем наш шаблон **/ function showCat($data){ $string = ""; foreach($data as $item){ $string .= tplMenu($item); } return $string; } //Получаем HTML разметку $cat_menu = showCat($tree); //Выводим на экран echo "
      ". $cat_menu ."
    "; ?>

    Результат работы

    Многоуровневое меню на PHP + MySQL для админки

    Если Вы хотите использовать данное меню в админке своего сайта, то нужно переписать пару функций tplMenu() , showCat() .

    ".$category["title"].""; }else{ $menu = ""; } if(isset($category["childs"])){ $i = 1; for($j = 0; $j < $i; $j++){ $str .= "→"; } $i++; $menu .= showCat($category["childs"], $str); } return $menu; } /** * Рекурсивно считываем наш шаблон **/ function showCat($data, $str){ $string = ""; $str = $str; foreach($data as $item){ $string .= tplMenu($item, $str); } return $string; } //Получаем HTML разметку $cat_menu = showCat($tree, ""); //Выводим на экран echo ""; ?>

    Результат работы

    Выбери Автомобили → Мазда →→ Мазда 3 →→→ Седан →→→ Хечбэк →→ Мазда 6 →→→ Лифтбэк →→→ Кроссовер →→→→ Белый →→→→ Красный →→→→ Черный →→→→ Зеленый →→ Мазда CX →→ Мазда MX → Хонда Мотоциклы → Кавасаки → Харлей Лодки