isIndexable() ) {
return;
}
$languages = $this->settings->published();
/*
* Язык, на котором эту запись владелец не включил, версии страницы не
* имеет (там редирект на исходный язык): alternate на него был бы
* обещанием, которого нет. x-default (исходный язык) остаётся всегда.
*/
if ( null !== $this->pageLanguages ) {
$languages = array_filter( $languages, fn( Language $language ): bool => ! $this->pageLanguages->isHiddenOn( $language ) );
}
if ( count( $languages ) < 2 ) {
return;
}
foreach ( $languages as $language ) {
printf(
'' . "\n",
esc_attr( $language->bcp47() ),
esc_url( $this->urls->canonicalUrlFor( $language ) )
);
}
printf(
'' . "\n",
esc_url( $this->urls->canonicalUrlFor( $this->settings->defaultLanguage() ) )
);
}
/**
* Подставляет язык текущего запроса в атрибуты тега `html`.
*
* @param string $output Значение вида `lang="ru-RU"`.
*/
public function filterLanguageAttributes( $output ): string {
$output = (string) $output;
$lang = $this->resolver->current()->bcp47();
if ( 1 === preg_match( '/lang="[^"]*"/', $output ) ) {
return (string) preg_replace( '/lang="[^"]*"/', 'lang="' . esc_attr( $lang ) . '"', $output );
}
return trim( $output . ' lang="' . esc_attr( $lang ) . '"' );
}
/**
* {@inheritDoc}
*/
public function apply( HtmlDocument $document, Language $target ): void {
$root = $document->root();
if ( null !== $root && 'html' === strtolower( (string) $root->nodeName ) ) {
// Страховка на случай темы, которая не вызывает language_attributes().
$root->setAttribute( 'lang', $target->bcp47() );
}
$this->fixCanonical( $document, $target );
}
/**
* Приводит canonical к текущему языковому адресу.
*
* @param HtmlDocument $document Разобранный документ.
* @param Language $target Текущий язык.
*/
private function fixCanonical( HtmlDocument $document, Language $target ): void {
$url = $this->urls->canonicalUrlFor( $target );
$existing = $this->findCanonical( $document );
if ( array() !== $existing ) {
$first = array_shift( $existing );
$first->setAttribute( 'href', $url );
// Дубли canonical от нескольких SEO-модулей убираем.
foreach ( $existing as $extra ) {
$parent = $extra->parentNode;
if ( null !== $parent ) {
$parent->removeChild( $extra );
}
}
return;
}
if ( ! $this->isIndexable() ) {
return;
}
$head = $document->document()->getElementsByTagName( 'head' )->item( 0 );
if ( null === $head ) {
return;
}
$link = $document->document()->createElement( 'link' );
$link->setAttribute( 'rel', 'canonical' );
$link->setAttribute( 'href', $url );
$head->appendChild( $link );
}
/**
* Находит все теги canonical в документе.
*
* @param HtmlDocument $document Разобранный документ.
* @return list