I want to remove the
<link rel="canonical" href="/taxonomie_term_url">
From my <head>
section
and add
<link rel="next" href="base_url?page=1" />
on the first page
<link rel="prev" href="base_url" />
<link rel="next" href="base_url?page=2" />
on the second
and on the last page only
<link rel="prev" href="base_url?page={x}" />
I tried to do it in a page_attachment_alter() hook but there were no view attachments. Than I tried to do it in a view pre_render / post_render / pre_build / post_build hook. I'm pretty sure this is the false tendency, though.
if($view->current_display == 'block_pager') {
$links = $view->getBaseEntityType()->get('links');
if (array_key_exists('canonical', $links)) {
$links = array_filter($links, function ($link) {
return $link !== 'canonical';
}, ARRAY_FILTER_USE_KEY);
$view->getBaseEntityType()->set('links', $links);
}
}
But that gives me
Drupal\Core\Entity\Exception\UndefinedLinkTemplateException: No link template 'canonical' found for the 'node' entity type in Drupal\Core\Entity\Entity->toUrl() (line 214 of core/lib/Drupal/Core/Entity/Entity.php).
Drupal\node\Controller\NodeViewController->view(Object, 'full', NULL)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
call_user_func_array(Object, Array) (Line: 144)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 64)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 652)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
And adding those rel"next/prev" stuff I tried to include them in my html.html.twig but I have no pager context there.
I have found a solution about those next/prev stuff
global $pager_total, $pager_page_array;
$current_path = Url::fromRoute('<current>');
$path = $current_path->toString();
if ($path == '/startseite') {
$path = '/';
}
if ($pager_page_array[0] == 1) {
$prev = '';
}
else {
$prev = '?page=' . $page = $pager_page_array[0] - 1;
}
if ($pager_page_array[0] == 0) {
$attachments['#attached']['html_head'][] = [[
'#type' => 'html_tag',
'#tag' => 'link',
'#attributes' => [
'rel' => 'next',
'href' => $path . '?page=' . $next = $pager_page_array[0]+1,
],
], 'rel_next_first'];
}
if ($pager_page_array[0] != 0 && $pager_page_array[0]+1 != $pager_total[0]) {
$attachments['#attached']['html_head'][] = [[
'#type' => 'html_tag',
'#tag' => 'link',
'#attributes' => [
'rel' => 'next',
'href' => $path . '?page=' . $next = $pager_page_array[0]+1,
],
], 'rel_next'];
$attachments['#attached']['html_head'][] = [[
'#type' => 'html_tag',
'#tag' => 'link',
'#attributes' => [
'rel' => 'prev',
'href' => $path . $prev,
],
], 'rel_prev'];
}
if ($pager_page_array[0]+1 == $pager_total[0]) {
$attachments['#attached']['html_head'][] = [[
'#type' => 'html_tag',
'#tag' => 'link',
'#attributes' => [
'rel' => 'prev',
'href' => $path . $prev,
],
], 'rel_prev_last'];
}
if ($pager_page_array[0] > 0) {
$attachments['#attached']['html_head'][] = [[
'#type' => 'html_tag',
'#tag' => 'link',
'#attributes' => [
'rel' => 'canonical',
'href' => $path . '?page=' . $pager_page_array[0],
],
], 'canonical_url'];
}
This is the the point where this ghost <link rel="canonical">
is created. At Line 69 NodeViewController::view()
if ($this->currentUser->isAuthenticated() || $url->access($this->currentUser)) {
// Set the node path as the canonical URL to prevent duplicate content.
$build['#attached']['html_head_link'][] = [[
'rel' => $rel,
'href' => $url->toString(),
], TRUE,];
}
Now if I wrap this snippet with
if (rel !== 'canonical') {}
It works and that ghost attachment is gone. But hacking core is real evil, so how do I achieve this in a clean or almost clean way?