WordPress кэширует меню с Transient API

Я хочу просто кэшировать меню страницы, которое занимает около 50 запросов при загрузке страницы.

На данный момент у меня есть код установки кеша с Transient API

 $housemenu = get_transient('housemenu_key'); if (!$housemenu) { $housemenu = wp_nav_menu( array( 'menu' => '', 'menu_class' => 'sf-menu', 'menu_id' => 'nav', 'walker' => new description_walker() ) ); echo 'not-set'; set_transient( 'housemenu_key', $housemenu, 60*60*3 ); } echo $housemenu; 

$housemenu = get_transient('housemenu_key'); возвращает ничего. Если я задал следующее:

 $housemenu = 'return corrent'; echo 'not-set'; 

Все работает отлично. Почему это меню не работает? Меню может быть переходным?

Использование: WordPress 3.8

Solutions Collecting From Web of "WordPress кэширует меню с Transient API"

wp_nav_menu() по умолчанию ничего не возвращает, он просто отгоняет форматированный html.

Чтобы wp_nav_menu() возвращал значение, вам нужно передать 'echo' => false в его аргументы, например:

 $housemenu = wp_nav_menu( array( 'menu' => '', 'menu_class' => 'sf-menu', 'menu_id' => 'nav', 'walker' => new description_walker(), 'echo' => 'false' )); 

Следует отметить, что путем кэширования всего меню в переходном режиме вы потеряете его динамическую природу. Например, если он кэшировал его на домашней странице, все активные классы, применяемые к пунктам меню, ВСЕГДА отражают домашнюю страницу. Таким образом, если бы вы посетили другую страницу, активные классы в пунктах меню были бы неправильными.

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

По умолчанию wp_nav_menu() результат и ничего не возвращает. Вам нужно установить 'echo' => false в своих аргументах, чтобы перевернуть поведение и уметь назначать результат переменной.

одна проблема существует там … WordPress имеет встроенное обнаружение страницы, чтобы дать классы CSS текущей странице в меню … и если вы кешировали, то ваши пункты меню навигации никогда не получат класс «текущая страница» или т. д. ,

однако есть два решения:

Решение 1

Перед кэшированием, один раз, добавьте классы в элементы <a> :

 function add_menu_atts( $atts, $item, $args ) { $atts['class'] = $item->type.'-'.$item->ID; return $atts; } add_filter( 'nav_menu_link_attributes', 'add_menu_atts', 8, 3 ); 

а затем кешировать меню … он будет иметь такой вывод:

 <ul class="..." id="..."> <li class="........"><a class="post_type-312" href="......">Post titleee (it's id is 312)</a></li> <li class="........"><a class="taxonomy-42" href="....">Category titleee (it's id is 42)</a></li> </ul> 

поэтому добавьте класс «current-item» из javascript (в тело страницы вы должны передать переменную javascript, чтобы узнать, находитесь ли вы на странице, странице, категории и т. д.) … т.е.:

 <script> var CurrentPageType="post_type"; //or "taxonomy"(for categories); or author or etc... var CurrentItemId=612; var element = document.getElementsByClassName(CurrentPageType +'-'+ CurrentItemId)[0]; element.className +=" current-menu-item"; </script> 

решение 2

для типичных, не wp-сайтов. Я попытался закодировать JS-скрипт, который может решить проблему. Итак, если вы кешируете меню и хотите получить класс «current-menu-item», тогда поместите эту функцию в исходный / кеш страницы (лучше быть в конце тела):

 <script> Highlight_Current_Menu_link("current_item__from_JS", "parent_div_id" ); </script> or <script> Highlight_Current_Menu_link("current_item__from_JS"); </script> 

сначала добавьте этот код в заголовок (лучше внутри .js-файла):

 <script> function Highlight_Current_Menu_link(Added_class_name, Ancestor_to_search_in, link_to_find){ var Added_class_name = Added_class_name || "current_item__from_JS"; var link_to_find = link_to_find || window.location.pathname; var Ancestor_to_search_in = typeof Ancestor_to_search_in === "undefined" ? document.body : getElementById(Ancestor_to_search_in); var A_elements = Ancestor_to_search_in.getElementsByTagName("a"); for(var i=0; i<A_elements.length; i++){ var condition=false; var href=A_elements[i].href.replace(window.location.origin,""); if(href.indexOf('#')>-1 && href==link_to_find) {condition=true;} else if( RemoveHashString(link_to_find).indexOf(RemoveHashString(href)) >- 1 && href.substring(0, href.lastIndexOf("/")).trim() == link_to_find.substring(0, link_to_find.lastIndexOf("/")).trim() ) { condition= true; } if (condition) { A_elements[i].className += " "+Added_class_name; } } } function RemoveHashString(str){ var hash=str.split("#")[1]; return str.replace("#"+hash,''); } </script> 

и определите свой желаемый стиль прилагаемому классу

 <style> .current_item__from_JS{background:red;} </style>