Как загрузить parent_theme functions.php перед child_theme?

12

У меня проблема с тем, что мне нужно загрузить functions.phpфайл моей родительской темы до загрузки файла моей дочерней темы functions.php. Это необходимо для процедуры установки и инициализации. Я посмотрел на хуки внутри /wp_core_root/wp-settings.php (по имени:) do_action('setup_theme');.

Проблема в том, что я не знаю, как туда попасть, потому что первый файл, который я получаю, это дочерняя тема functions.php, так что не add_action( 'setup_theme', 'my_init_function' );будет работать.

Изменить:
а) Я знаю, что плагины загружаются раньше, чем тема и, следовательно, могут получить доступ даже к первоначальному запросу, но я не хочу полагаться на плагин.
б) Вот код (сокращенный) из файла wp-settings.php

// happens a lot earlier:  
do_action( 'plugins_loaded' );

// localize stuff happening here
    do_action( 'setup_theme' );

        // Load the functions for the active theme, for both parent and child theme if applicable.
        if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) )
            include( STYLESHEETPATH . '/functions.php' );
        if ( file_exists( TEMPLATEPATH . '/functions.php' ) )
            include( TEMPLATEPATH . '/functions.php' );
    // first available hook, *after* functions.php was loaded
    do_action( 'after_setup_theme' );

Я хочу избежать двух вещей: сначала много объяснений для пользователей. Во-вторых, вероятность того, что кто-нибудь что-нибудь сломает, если перережет веревку, случайно удалив родительскую процедуру инициализации. Люди должны просто играть внутри functions.php, не рискуя что-то сломать, не зная об этом.

Другими словами: как сохранить мой файл functions.php дочерних тем в чистоте, но завершить ли загрузку родительских тем?

Есть идеи? Большое спасибо!

кайзер
источник
Вы не можете просто включить это?
wyrfel
Мой вопрос: откуда? Первый загружаемый файл в контексте темы - это дочерняя тема functions.php. Взгляните на wp-settings.phpфайл "molto loko" в ядре (строка: 275-279 @wp 3.1 rc) ... выглядит так: if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) include( STYLESHEETPATH . '/functions.php' ); if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) include( TEMPLATEPATH . '/functions.php' );я не вижу шансов ... И я не хочу использовать плагин для загрузки моей темы.
Кайзер
Я мог бы что-то здесь упустить, но если вы вставляете include(/path/to/parent/themes/functions.php)в начало своих дочерних тем functions.php, то все, что там, загружается раньше. Не?
wyrfel
@wyrfel: я обновил Q, чтобы сделать его более понятным
kaiser
Понятно, спасибо, теперь стало намного понятнее. Плюс я предположил, что вы просто делаете это для одной установки.
wyrfel

Ответы:

11

Джастин Тэдлок недавно написал отличный пост о создании лучшего файла functions.php, в
котором (если я правильно помню) он занимается именно этой проблемой.

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

Вы на правильном пути с after_setup_themeкрюком.

  1. Насколько я помню, хитрость заключается в том, чтобы обернуть ваши фильтры и действия в его функции.
    Смотрите пример ниже.
  2. Вы делаете , что в обоих родительских и дочерних functions.phpфайлов.
  3. Тогда вы можете играть с приоритетом этих двух хуков.

Немного кода стоит тысячи слов - ваша родительская тема function.phpдолжна выглядеть так:

add_action( 'after_setup_theme', 'your_parent_theme_setup', 9 );
function your_parent_theme_setup() {    
    add_action(admin_init, your_admin_init);
    add_filter(the_content, your_content_filter);
}

function your_admin_init () {
...
}

function your_content_filter() {
...
}
Михал Мау
источник
Эмм, спасибо за запись (+1). У тебя впечатляющий мозг;). Проблема в том, что after_setup_themeслишком поздно, потому что файлы functions.php уже были загружены.
Кайзер
РЕДАКТИРОВАТЬ: После переосмысления вашего кода и чтения «сделайте это как в родительских, так и в дочерних функциях. Php» и «играть с приоритетом», оно начинает обретать смысл. Все еще в поисках лучшего решения, которое пользователь не может сломать так просто, но это имеет смысл! Спасибо!
Кайзер
Никакого реального решения здесь нет, поэтому я отмечаю это, поскольку вы были первым, кто предложил это.
Кайзер
9

Во-первых, вы не можете. Functions.php дочерней темы всегда загружается первым, точка.

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

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

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

эфирное масло
источник
Спасибо за Ваш ответ. Я понимаю необходимость загружать плагины перед темами и уже осознал этот факт (см. Выше: «И я не хочу использовать плагин для загрузки моей темы».). Чтобы прояснить мой случай: я получил INI-файл, который заботится о загрузке всех частей моего фреймворка, который начинается с функций php родительских тем с требованием файла и загрузки класса init. InitClass заботится о загрузке а) и массива данных из дочерних тем .ini-файлов, а затем передает их в различные классы для дальнейшей обработки ex. мета-боксы, пользовательские типы
записей
Моя проблема в том, что я должен инициировать все это из файла моих родителей functions.php, поэтому обычный пользователь не может его сломать, когда играет в дочерней теме. Моя вторая проблема заключается в том, что все эти классы недоступны в файле functions.php дочерней темы, поэтому они бесполезны ... но, возможно, я получил большую ошибку мышления прямо здесь. Есть идеи или предложения, как сделать это лучше?
Кайзер
3
.... Я думаю, вы просто должны будете принять тот факт, что если пользователь ломает вещи, то это действительно их проблема. Итог: нет способа сначала загрузить файл functions.php родительской темы и оставить дочернюю тему «чистой». Если вам нужно, чтобы что-то в дочерней теме запускалось после загрузки файла functions.php родительской темы, тогда вы помещаете это в функцию, подключенную к after_setup_theme. Это запускается после загрузки обоих файлов functions.php.
Отто
ОК. Это не такая большая проблема. Я просто заинтересован, если есть возможность. Вопрос: Зачем «фреймворк стоит своей соли», затем имеет ловушку после процедуры инициализации, а не просто использует after_setup_themeловушку? Просто чтобы не «спамить» крючок, или потому что он более «предприимчивый» или «крутой»? Я имею в виду: является ли идея «наилучшей практики» за параллельными хуками, характерными для темы, «оставить хуки для плагинов»? (Вот как я справляюсь с этим в настоящее время.)
kaiser
«Если вы собираетесь к этому, не беспокойтесь дополнительным действием. Просто подключитесь к after_setup_theme». ОК. Спасибо. +1
кайзер
4

Итак, вы пытаетесь выполнить код из дочернего functions.php, но после загрузки родительской темы. Просто, просто используйте настраиваемое действие:

В конце parent/functions.php:

do_action('parent_loaded');

В child/functions.php:

function parent_loaded() {
    // do init stuff
}
add_action('parent_loaded', 'parent_loaded');

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

scribu
источник
Я стараюсь избегать как можно большего количества инструкций. Это одна из причин, по которой я переключился с файла config.php в папке дочерней темы и теперь вместо него использую файлы ini. В одном предложении: я пытаюсь отойти от своего старого / вашего решения и максимально приблизиться к ядру и кодексу. Моя проблема в том, что я не могу доставить одну функцию из дочерней темы, потому что ни один класс или что-либо из моей начальной загрузки не доступно внутри файла functions.php дочерних тем (не говоря уже о тегах шаблонов пользовательских / фреймворка).
Кайзер
Смотрите обновленный ответ.
scribu
Я тоже обновил Q. После прочтения этих 2/3 ответов указывают мне на тот же источник (тематический, перед вашим редактированием), я чувствую, что есть только метод включения «Джастин Тэдлок», но я хочу убедиться.
Кайзер
2
Если вы собираетесь к этому, не беспокойтесь о дополнительных действиях. Просто подключитесь к after_setup_theme.
Отто
0

Почему бы вам не включить functions.phpфайл родительской темы в файл дочерней темы functions.php, например так:

В functions.phpфайле дочерней темы :

if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( TEMPLATEPATH . '/functions.php' ) )
            include( TEMPLATEPATH . '/functions.php' );

// code of child theme's functions.php file continues here

Таким образом, functions.phpфайл родительской темы не изменяется (иногда это важно).

Ань Чан
источник
как упомянуто в вопросе: «Другими словами: как я могу сохранить мой файл functions.php дочерних тем в чистоте, но сделать начальную загрузку родительских тем?» Еще лучше: как мне избежать вызова из любого файла functions.php? Почему: люди привыкли просто разбивать каждую хрень, которую они не хотят иметь в файлах шаблонов. Так что есть большая вероятность, что кто-то случайно удалит некоторые строки. Мой опыт: никто не читает комментарии, readme или документацию.
Кайзер
0

У меня раньше была похожая проблема, и я исправил ее, создав дополнительный пустой «child-functions.php» в parent и включив в «functions.php» (тоже parent) сразу после файлов / функций, которые я хочу использовать в child, затем в дочерней теме я создаю файл «child-functions.php», и там я могу начать имитировать запуск дочерних функций. php после того, как parent не является элегантным решением, но сделал свою работу.

Softmixt
источник