Я не понимаю, как работает этот параметр..?
Хорошо, у меня есть этот простой код для простого плагина, который предваряет заголовки сообщений словом ТЕСТИРОВАНИЕ.. Мне действительно непонятно, как здесь работает этот параметр. Я понимаю, как работают параметры в PHP, но внутри этого параметра ничего не было передано для WordPress, чтобы знать, что переменная - это название.. если это имеет смысл?? Не понимаю, как это работает.
Я все еще довольно плохо разбираюсь в разработке WordPress - мне всегда кажется, что я начинаю, застреваю и не очень далеко.
add_filter('the_title', 'cm_title');
/**
* Modify the title prepending the article title with the word 'TESTING'
*/
function cm_title($text) {
return 'TESTING ' . $text;
}
2 answers
Давайте посмотрим, сможем ли мы разбить его так, чтобы его было легко понять.
У вас есть функция PHP с именем 'cm_title':
function cm_title($text) {
return 'TESTING ' . $text;
}
Он делает только 1 вещь. Он берет то, что ему дано, "$text", и возвращает этот $текст со словами "Тестирование", добавленными к нему.
Как WordPress узнает, что такое "$text"?
Он знает/присваивает данные параметру $text из-за этого фильтра WP:
add_filter('the_title', 'cm_title');
Этот фильтр проверяется WP при создании "the_title". Так что как раз перед тем, как WP выплевывает "the_title", он проверяет, есть ли фильтр для использования. В этом случае мы просим WP применить этот фильтр (функцию "cm_title"), прежде чем выплевывать заголовок.
Все, что можно сказать, WP отправляет то, что у него есть до сих пор, для "the_title" (т. Е. "Это пост обо мне") и пропускает его через этот фильтр, прежде чем выплюнуть.
Таким образом, в данном случае "Это сообщение обо мне" - это данные в параметре $text в функции cm_title.
Ваш конечный результат становится "ПРОВЕРКА, это пост обо мне".
Помогает ли это прояснить ситуацию?
WordPress использует крючки , чтобы помочь разработчикам делать то, что им нужно, относительно простым способом. Некоторые из этих крючков apply_filter()
и do_action()
, которые определяются WordPress. Давайте посмотрим, что именно произойдет, когда мы вызовем the_title()
до тех пор, пока он не попадет на определенный вами крючок.
<?php the_title(); ?>
Ресурсы разработчика - the_title()
function the_title($before = '', $after = '', $echo = true) {
$title = get_the_title();
if ( strlen($title) == 0 )
return;
$title = $before . $title . $after;
if ( $echo )
echo $title;
else
return $title;
}
Прямо вверху он вызывает get_the_title()
, где мы найдем наш фильтр. Давайте взглянем на это:
Разработчик Ресурсы - get_the_title()
function get_the_title( $post = 0 ) {
$post = get_post( $post );
$title = isset( $post->post_title ) ? $post->post_title : '';
$id = isset( $post->ID ) ? $post->ID : 0;
if ( ! is_admin() ) {
if ( ! empty( $post->post_password ) ) {
/**
* Filter the text prepended to the post title for protected posts.
*
* The filter is only applied on the front end.
*
* @since 2.8.0
*
* @param string $prepend Text displayed before the post title.
* Default 'Protected: %s'.
* @param WP_Post $post Current post object.
*/
$protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ), $post );
$title = sprintf( $protected_title_format, $title );
} else if ( isset( $post->post_status ) && 'private' == $post->post_status ) {
/**
* Filter the text prepended to the post title of private posts.
*
* The filter is only applied on the front end.
*
* @since 2.8.0
*
* @param string $prepend Text displayed before the post title.
* Default 'Private: %s'.
* @param WP_Post $post Current post object.
*/
$private_title_format = apply_filters( 'private_title_format', __( 'Private: %s' ), $post );
$title = sprintf( $private_title_format, $title );
}
}
/**
* Filter the post title.
*
* @since 0.71
*
* @param string $title The post title.
* @param int $id The post ID.
*/
return apply_filters( 'the_title', $title, $id );
}
Вы заметите прямо внизу функции, которую она вызывает apply_filters()
и передает в function_name
в виде строки , $title
как строка и $id
как int затем возвращает все, что возвращает apply_fitlers()
, что является вашим крючком. Давайте взглянем на apply_filters()
:
Ресурсы разработчика - apply_filters()
function apply_filters( $tag, $value ) {
global $wp_filter, $merged_filters, $wp_current_filter;
$args = array();
// Do 'all' actions first.
if ( isset($wp_filter['all']) ) {
$wp_current_filter[] = $tag;
$args = func_get_args();
_wp_call_all_hook($args);
}
if ( !isset($wp_filter[$tag]) ) {
if ( isset($wp_filter['all']) )
array_pop($wp_current_filter);
return $value;
}
if ( !isset($wp_filter['all']) )
$wp_current_filter[] = $tag;
// Sort.
if ( !isset( $merged_filters[ $tag ] ) ) {
ksort($wp_filter[$tag]);
$merged_filters[ $tag ] = true;
}
reset( $wp_filter[ $tag ] );
if ( empty($args) )
$args = func_get_args();
do {
foreach( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) ){
$args[1] = $value;
$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
}
} while ( next($wp_filter[$tag]) !== false );
array_pop( $wp_current_filter );
return $value;
}
Это выглядит сложным, но прежде чем мы перейдем к этому, давайте перейдем к самой важной части этой функции, $wp_filter
. Теперь этот маленький засранец содержит ВСЕ фильтры, добавленные как вами, так И WordPress. Вы можете распечатать его прямо под своим wp_head()
, чтобы увидеть полный список. Это выглядит примерно так (тонны больше, я только что выбрал the_title
, так как это по теме!)
[the_title] => Array
(
[10] => Array
(
[wptexturize] => Array
(
[function] => wptexturize
[accepted_args] => 1
)
[convert_chars] => Array
(
[function] => convert_chars
[accepted_args] => 1
)
[trim] => Array
(
[function] => trim
[accepted_args] => 1
)
)
[11] => Array
(
[capital_P_dangit] => Array
(
[function] => capital_P_dangit
[accepted_args] => 1
)
)
)
Таким образом, это многомерный массив фильтров, индексированный тегом , затем приоритетом и, наконец, именем функции . Довольно аккуратно, я думаю! Фильтр, который вы добавили, так как вы не передали приоритет, является по умолчанию индексируется 10 и будет добавлен прямо под trim
, а затем дополнительно проиндексирован по имени функции cm_title
.
Давайте немного вернемся назад. Если мы посмотрим на конец функции get_the_title()
выше, мы увидим, что она передает три переменные в функцию apply_filters
, но, как мы ясно видим, она принимает только два параметра! Мне пришлось немного вникнуть в это, и похоже, что эта маленькая функция func_get_args()
, которую мы видим замусоренной внутри apply_filters()
, на самом деле захватит все, что угодно и все перешло к нему. Вот пример, кодовый ключ также хорош. Теперь, несмотря на то, что все может быть передано, если мы вернемся к нашему многомерному массиву, там есть параметры accepted_args
, так что технически вы вроде как не можете, хотя это позволяет вам это сделать.
ФУ
Наконец, он проходит через каждый из этих фильтров, используя массив $wp_filters
:
do {
foreach( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) ){
$args[1] = $value;
$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
}
} while ( next($wp_filter[$tag]) !== false );
Итак, давайте соберем все это вместе!
-
the_title()
вызовыget_the_title()
-
get_the_title()
возвращаетapply_filters()
, передавая: 'the_title' (имя функции),$title
(заголовок строки),$id
(идентификатор записи int). -
apply_filters()
просматривает глобальный массив, содержащий все добавленные фильтры, затем запускает их, передавая информацию, которая была передана ему ($title
, и$id
).
Функция, которую вы вызываете add_filter
, фактически добавляет ваше имя функции, приоритет и аргументы в глобальный массив $wp_filters
. Вы можете увидеть это ниже:
Разработчик Ресурсы - add_filter()
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
global $wp_filter, $merged_filters;
$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
$wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
unset( $merged_filters[ $tag ] );
return true;
}
Действительно, это вызывается до того, как the_title()
когда-либо будет вызван. Ваши функции загружаются с помощью wp_head()
, и поэтому любые фильтры, которые вы добавляете с помощью плагинов или functions.php
, также будут добавлены в этот глобальный массив.
Это было длинно, но, надеюсь, теперь это имеет немного больше смысла, если у вас есть какие-либо вопросы, задавайте в комментариях!