Изменение вывода хлебных крошек Yoast SEO
Я хочу настроить вывод хлебных крошек Yoast SEO. Вот мой текущий код, который отлично работает:
add_filter( 'wpseo_breadcrumb_single_link', 'ss_breadcrumb_single_link', 10, 2 );
function ss_breadcrumb_single_link( $link_output, $link ) {
$element = 'li';
$element = esc_attr( apply_filters( 'wpseo_breadcrumb_single_link_wrapper', $element ) );
$link_output = '<' . $element . ' typeof="v:Breadcrumb">';
if ( isset( $link['url'] ) && ( $i < ( count( $links ) - 1 ) || $paged ) ) {
$link_output .= '<a href="' . esc_url( $link['url'] ) . '" rel="v:url" property="v:title">' . esc_html( $link['text'] ) . '</a>';
} else {
if ( isset( $opt['breadcrumbs-boldlast'] ) && $opt['breadcrumbs-boldlast'] ) {
$link_output .= '<strong class="breadcrumb_last" property="v:title">' . esc_html( $link['text'] ) . '</strong>';
} else {
$link_output .= '<li class="breadcrumb_last" property="v:title">' . esc_html( $link['text'] ) . '</li>';
}
}
$link_output .= '</' . $element . '>';
return $link_output;
}
add_filter( 'wpseo_breadcrumb_output_wrapper', 'ss_breadcrumb_output_wrapper', 10, 1 );
function ss_breadcrumb_output_wrapper( $wrapper ) {
$wrapper = 'ol';
return $wrapper;
}
Следующий шаг - изменить эту строку:
return apply_filters( 'wpseo_breadcrumb_output', '<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">' . $output . '</' . $wrapper . '>' );
Я хочу добавить aria-атрибут aria-labelledby="breadcrumblabel"
к этому выводу. Для этого я создал эту функцию:
add_filter( 'wpseo_breadcrumb_output', 'ss_breadcrumb_output' );
function ss_breadcrumb_output() {
return apply_filters( 'ss_breadcrumb_output', '<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">' . $output . '</' . $wrapper . '>' );
}
Проблема в том, что $wrapper
, $id
, $class
и $output
возвращают null. Я думаю, понимаю почему они null, но как начинающий PHP-разработчик не могу это объяснить.
Буду благодарен, если кто-то подскажет правильное направление, чтобы я мог разобраться с этим.
Спасибо.

http://wpquestions.com/question/showChrono/id/8603
Я использовал первую функцию с применением str_replace
add_filter( 'wpseo_breadcrumb_output', 'custom_wpseo_breadcrumb_output' );
function custom_wpseo_breadcrumb_output( $output ){
if( is_page() ){
$from = '<a href="">...</a>'; // Отредактируйте это под свои нужды
$to = '';
$output = str_replace( $from, $to, $output );
}
return $output;
}

Все они равны null. Вы не установили ни одну из этих переменных. Вот ваша функция.
function ss_breadcrumb_output() {
return apply_filters( 'ss_breadcrumb_output', '<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">' . $output . '</' . $wrapper . '>' );
}
Все переменные в этой функции изолированы внутри неё. Переменные, установленные вне этой функции, не работают. Поскольку вы не установили никаких переменных (в функции), и они не передаются в функцию, они empty
. Это вопрос области видимости. Есть способы обойти это, например, глобализация, но это не критично для данного вопроса, так что оставлю это на ваше усмотрение.
Но к вашей проблеме... Посмотрите на фильтр где он применяется в плагине.
return apply_filters( 'wpseo_breadcrumb_output', '<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">' . $output . '</' . $wrapper . '>' );
Думаю, здесь может быть ваша ошибка. Вот это—'<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">' . $output . '</' . $wrapper . '>'
—это один параметр. Этот .
—оператор конкатенации строк, означающий, что всё это объединяется в одну строку. Когда это передаётся в фильтр, переменных уже нет. Они передаются в фильтр как простая строка.
Ваша функция могла бы перехватить и изменить эту строку, если бы вы добавили параметр, например:
function ss_breadcrumb_output($output) {
var_dump($output); // вы должны увидеть строку, упомянутую выше
return apply_filters( 'ss_breadcrumb_output', '<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">' . $output . '</' . $wrapper . '>' );
}
Я не понимаю эту часть: return apply_filters( 'ss_breadcrumb_output', '<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">' . $output . '</' . $wrapper . '>' );
Если вы пытаетесь передать вывод хлебных крошек в другой фильтр (вашего создания, я полагаю), вам нужно:
function ss_breadcrumb_output($output) {
return apply_filters( 'ss_breadcrumb_output', $output );
}
Но зачем? Всё, что вы могли бы сделать с этим, вы могли бы сделать с фильтром wpseo_breadcrumb_output
.
Думаю, вам просто нужно:
function ss_breadcrumb_output($output) {
$output = preg_replace('/([^>]+)>(.*)/','$1 aria-labelledby="breadcrumblabel" >$2',$output);
return $output;
}
Также отмечу, что регулярные выражения для разметки довольно ненадёжны. Легко ошибиться. Используйте с осторожностью.

Во-первых, спасибо за такой подробный ответ. Меня заинтересовало, что вы говорите о пустых переменных из-за вопроса области видимости. Но затем в последних двух примерах решения вы используете $output? Я попытался использовать var_dump($output)
внутри функции, но ничего не возвращается.

Обратите внимание на изменение, которое я внес в определение вашей функции: ss_breadcrumb_output($output)
. Вам нужно передать переменную внутрь, чтобы использовать её (с фильтрами и действиями передача переменных происходит за кадром). Думаю, именно здесь вы ошибаетесь.

Хорошо, кажется, я понимаю. Одна вещь, которую я не понимаю — это ваше использование $output. В оригинальном файле класса $output
находится внутри '<' . $wrapper . $id . $class . ' xmlns:v="http://rdf.data-vocabulary.org/#">'
. Я не понимаю, зачем мы изменяем $output? Я уже изменил то, что хотел, в переменной $output
в других функциях. Я собираюсь продолжить исследования, как видите, всё это для меня ново! Ещё раз спасибо.

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