У меня есть переменная в header.php, например:
$page_extra_title = get_post_meta($this_page->ID, "_theme_extra_title", true);
Как только я сделаю:
var_dump($page_extra_title);
Я всегда получаю NULL
за пределами header.php (var_dump работает правильно только в header.php). Я вставляю одну и ту же переменную везде, где она мне нужна (page.php, post.php, footer.php и т. Д.), Но это безумие и делает все практически невозможным для обслуживания.
Мне интересно, как лучше всего передать переменную через все файлы в моей теме? Я думаю, что использование functions.php вместе с "get_post_meta" может быть не лучшей идеей? :)
global
, правда? Но об этом не может быть и речи по уважительным причинам. Кроме того, вам нужно «вызвать»global
переменные, используя ключевое слово, чтобы сделать их доступными. В зависимости от варианта использования сессии могут быть решением. В противном случае - как уже упоминалось - я думаю, что функция или класс, выполняющие эту работу за вас, - это путь.Ответы:
Основные разделенные структуры данных
Для передачи данных вы обычно используете Модель (это «M» в «MVC»). Давайте посмотрим на очень простой интерфейс для данных. Интерфейсы просто используются как «Рецепты» для наших строительных блоков:
Выше, что мы передаем: общий идентификатор и «ярлык».
Отображение данных путем объединения атомарных частей
Далее нам нужно некоторое представление, которое согласовывает нашу модель и ... наш шаблон.
В основном этот интерфейс говорит
Наконец, нам нужно реализовать выше и построить фактический вид . Как видите, конструктор говорит, что обязательным элементом нашего представления является шаблон и что мы можем его отобразить. Для простоты разработки мы даже проверяем, присутствует ли файл шаблона на самом деле, чтобы мы могли сделать жизнь других разработчиков (и наших тоже) намного проще и отметим это.
На втором этапе функции рендеринга мы используем Closure, чтобы построить фактическую оболочку шаблона и
bindTo()
модель для шаблона.Разделение вида и рендеринга
Это означает, что мы можем использовать очень простой шаблон, подобный следующему
сделать наш контент. Соединяя части, мы получим что-то вроде следующих строк (в нашем контроллере, посреднике и т. Д.):
Что мы получили?
Таким образом, мы можем
Объединение ООП PHP с WP API
Конечно, это вряд ли возможно при использовании базовой функциональности тем, например
get_header()
,get_footer()
и т. Д., Верно? Неправильно. Просто назовите свои классы в любом шаблоне или части шаблона, которую вы хотите. Визуализируйте его, преобразуйте данные, делайте что хотите. Если вы действительно хороши, вы даже просто добавляете свою собственную группу пользовательских фильтров и имеете некоторый посредник, чтобы позаботиться о том, что визуализируется каким контроллером, по какому маршруту / условному шаблону загружается.Вывод?
Вы можете работать с такими вещами, как указано выше, в WP без проблем, и при этом придерживаться базового API и повторно использовать код и данные, не вызывая ни единого глобального, ни испортить и загрязнить глобальное пространство имен.
источник
Это альтернативный подход к ответу @kaiser , который я нашел довольно хорошим (+1 от меня), но требует дополнительной работы для использования с основными функциями WP, и он сам по себе интегрирован с иерархией шаблонов.
Подход, которым я хочу поделиться, основан на одном классе (это урезанная версия из того, над чем я работаю), который заботится о визуализации данных для шаблонов.
У него есть (IMO) интересные особенности:
$this
ключевого слова: это дает вам возможность избежать уведомлений в производстве в случае неопределенных переменныхEngine
Класс(Доступно здесь как Gist .)
Как пользоваться
Единственное, что нужно, это вызвать
Engine::init()
метод, вероятно, на'template_redirect'
крючке. Это можно сделать в темеfunctions.php
или из плагина.Это все.
Ваши существующие шаблоны будут работать как ожидается. Но теперь у вас есть возможность доступа к данным пользовательских шаблонов.
Данные пользовательских шаблонов
Для передачи пользовательских данных в шаблоны есть два фильтра:
'gm_template_data'
'gm_template_data_{$type}'
Первый запускается для всех шаблонов, второй специфичен для шаблона, фактически, димамическая часть
{$type}
- это базовое имя файла шаблона без расширения файла.Например, фильтр
'gm_template_data_single'
может использоваться для передачи данныхsingle.php
шаблон.Обратные вызовы, прикрепленные к этим хукам, должны возвращать массив , где ключами являются имена переменных.
Например, вы можете передавать метаданные как данные шаблона так:
И тогда внутри шаблона вы можете просто использовать:
Режим отладки
Когда обе константы
WP_DEBUG
иWP_DEBUG_DISPLAY
верны, класс работает в режиме отладки. Это означает, что если переменная не определена, генерируется исключение.Когда класс не находится в режиме отладки (возможно, в рабочей среде), доступ к неопределенной переменной выведет пустую строку.
Модели данных
Хороший и удобный способ организовать ваши данные - использовать классы моделей.
Это могут быть очень простые классы, которые возвращают данные, используя те же фильтры, что описаны выше. Нет конкретного интерфейса для подражания, они могут быть организованы в соответствии с вашими предпочтениями.
Ниже приведен только пример, но вы можете делать это по-своему.
__invoke()
Метод (который работает , когда класс используется как обратный вызов) возвращает строку , которые будут использоваться для<title>
тега шаблона.Благодаря тому, что второй передаваемый аргумент
'gm_template_data'
является именем шаблона, метод возвращает пользовательский заголовок для домашней страницы.Имея код выше, можно использовать что-то вроде
в
<head>
разделе страницы.Partials
В WordPress есть функции, подобные
get_header()
илиget_template_part()
которые можно использовать для загрузки партиалов в основной шаблон.Эти функции, как и все другие функции WordPress, могут использоваться в шаблонах при использовании
Engine
класса.Единственная проблема заключается в том, что внутри партиалов, загруженных с использованием основных функций WordPress, невозможно использовать расширенную функцию получения пользовательских шаблонных данных
$this
.По этой причине в
Engine
классе есть метод,partial()
который позволяет загружать частичные (полностью совместимые с дочерними темами) и по-прежнему иметь возможность использовать частичные данные пользовательских шаблонов.Использование довольно просто.
Предполагая, что файл находится в папке
partials/content.php
theme (или child theme), его можно включить с помощью:Внутри этой части будет возможен доступ ко всем данным родительской темы таким же образом.
В отличие от функций WordPress,
Engine::partial()
метод позволяет передавать определенные данные частям, просто передавая массив данных в качестве второго аргумента.По умолчанию у партиалов есть доступ к данным, доступным в родительской теме, и к передаваемым данным.
Если некоторая переменная, явно переданная частичному, имеет то же имя родительской переменной темы, то переменная, явно переданная, побеждает.
Однако также возможно включить частичное в изолированном режиме, то есть частичное не имеет доступа к данным родительской темы. Для этого просто передайте в
true
качестве третьего аргументаpartial()
:Вывод
Даже если все довольно просто,
Engine
класс довольно завершен, но, безусловно, может быть улучшен. Например, нет способа проверить, определена ли переменная или нет.Благодаря 100% совместимости с функциями WordPress и иерархией шаблонов вы можете без проблем интегрировать его с существующим и сторонним кодом.
Тем не менее, обратите внимание, что это только частично протестировано, поэтому возможно, есть проблемы, которые я еще не обнаружил.
Пять баллов в разделе «Что мы получили?» в ответе @kaiser :
все действительны для моего класса, а также.
источник
Простой ответ: никуда не передавайте переменные, так как воняет от использования глобальных переменных, что является злом.
Из вашего примера кажется, что вы пытаетесь провести раннюю оптимизацию, еще одно зло;)
Используйте WordPress API для получения данных, которые хранятся в БД, и не пытайтесь перехитрить и оптимизировать их использование, поскольку API делает больше, чем просто извлекает значения и активирует фильтры и действия. Удаляя вызов API, вы лишаете других разработчиков возможности изменять поведение вашего кода без его изменения.
источник
Хотя технически правильный ответ Кайзера, я сомневаюсь, что это лучший ответ для вас.
Если вы создаете свою собственную тему, то я думаю, что это действительно лучший способ установить какую-то платформу с использованием классов (и, возможно, пространств имен и интерфейсов, хотя это может быть слишком много для темы WP).
С другой стороны, если вы просто расширяете / корректируете существующую тему и вам нужно передать только одну или несколько переменных, я думаю, вам следует придерживаться
global
. Посколькуheader.php
она включена в функцию, переменные, которые вы объявляете в этом файле, могут использоваться только в этом файле. Сglobal
вами сделать их доступными во всем проекте WP:В
header.php
:В
single.php
(например):источник
$wp_theme_vars_page_extra_title
или,$wp_theme_vars['page_extra_title']
например. Это было просто объяснение, почему глобальный будет работать здесь. ОП спросил способ передачи переменной через все файлы, используяglobal
способ сделать это.but it is really bad practice diving into the global scope
Я бы хотел, чтобы кто-нибудь рассказал об этом разработчикам ядра WP. Я действительно не понимаю смысла использования пространств имен, абстракции данных, шаблонов проектирования, модульного тестирования и других передовых методов / методов программирования в коде, написанном для Wordpress, когда ядро Wordpress изобилует плохими методами кодирования, такими как глобальные переменные (например, виджеты). код).Простое решение - написать функцию для получения дополнительного заголовка. Я использую статическую переменную, чтобы сохранить вызовы базы данных только к одному. Поместите это в ваши functions.php.
За пределами header.php вызовите функцию, чтобы получить значение:
источник