Closed milesjbland closed 3 years ago
This is correct behavior. SEOmatic intentionally does not link to paginate pages, but rather to the root index page.
The reason is that content on the paginated pages changes, and so may be different depending on a variety of factors.
See: https://github.com/nystudio107/craft-seomatic/issues/375#issuecomment-488369209
Thanks for the response and the link @khalwat, that's good to know!
I still have the problem that the hreflang links on paginated custom route pages are using the current site's URI for each link.
I'm logging $metaTag->href
just before this line and getting the following results:
The links for the page, both paginated and non-paginated, work correctly as you described:
# http://foo.test/en/resources/blog
# http://foo.test/en/resources/blog/p2
array (
0 => 'http://foo.test/en/resources/blog',
1 => 'http://foo.test/en/resources/blog',
2 => 'http://foo.test/fr/ressources/blog',
)
The links for the page with a custom route are correct on page 1, but it looks like it generates two arrays, with the last one being the correct one:
# http://foo.test/en/resources/blog/promote
array (
0 => 'http://foo.test/en/resources/blog/promote',
1 => 'http://foo.test/en/resources/blog/promote',
2 => 'http://foo.test/fr/resources/blog/promote',
)
array (
0 => 'http://foo.test/en/resources/blog',
1 => 'http://foo.test/en/resources/blog',
2 => 'http://foo.test/fr/ressources/blog',
)
A similar thing happens on the page with a custom route after page 1, but it generates three arrays, with the first and last being incorrect:
# http://foo.test/en/resources/blog/promote/p2
array (
0 => 'http://foo.test/en/resources/blog/promote',
1 => 'http://foo.test/en/resources/blog/promote',
2 => 'http://foo.test/fr/resources/blog/promote',
)
array (
0 => 'http://foo.test/en/resources/blog',
1 => 'http://foo.test/en/resources/blog',
2 => 'http://foo.test/fr/ressources/blog',
)
array (
0 => 'http://foo.test/en/resources/blog/promote',
1 => 'http://foo.test/en/resources/blog/promote',
2 => 'http://foo.test/fr/resources/blog/promote',
)
For context, the custom routes are setup like so:
'englishSite' => [
'resources/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
],
'frenchSite' => [
'ressources/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
],
When you say "it generates" what do you mean? Can you give me more context in terms of where you are breaking to inspect these values?
Sorry, I think that was just a poor choice of words.
I'm inspecting those values here just after the foreach
loop: https://github.com/nystudio107/craft-seomatic/blob/v3/src/helpers/DynamicMeta.php#L522
I forgot to mention, in our twig file we're updating the meta data like so for topic pages:
{% set entry = craft.entries.section('blogIndex').one() %}
{% set topic = topicSlug is defined ? craft.entries.section('topic').slug(topicSlug).one() : [] %}
{# SEOMatic for topic sub-pages #}
{% if topic|length %}
{% do seomatic.helper.loadMetadataForUri(entry.uri) %}
{# Append topic title to SEO Title etc... #}
{% endif %}
It looks like the twig above is the reason we're getting the correct second array on the topic pages. (Removing it causes us to only get the first incorrect one.)
For some reason, on paginated pages we're seeing a third incorrect array. Not sure if it's a clue, but the third appears just before the closing </body>
tag, whilst the first two appear just after the opening <body>
tag.
Hey @khalwat! Please let me know if there is any more information you need from me on this.
@milesjbland I've tried reproducing this, but am so far unable to.
Can you show me the actual code you're using here, as well as the code you're using to have a look at these various values? You say, for example, there are 3 arrays, but where are you seeing these arrays? Are they all in one value?
It looks to me like it's adding a tag each time through, but that doesn't seem possible based on the code -- it should just overwrite the existing tag.
I've tried doing this:
{% do seomatic.helper.loadMetadataForUri('/blog') %}
{% dd seomatic.link.container %}
And I see all of the links in the container, and the alternate
link has in it what I'd expect:
nystudio107\seomatic\models\MetaLinkContainer#1
(
[data] => [
'canonical' => nystudio107\seomatic\models\metalink\CanonicalLink#2
(
[crossorigin] => ''
[href] => '{seomatic.meta.canonicalUrl}'
[hreflang] => ''
[media] => ''
[rel] => 'canonical'
[sizes] => ''
[type] => ''
[yii\base\Model:_errors] => null
[yii\base\Model:_validators] => null
[yii\base\Model:_scenario] => 'default'
[yii\base\Component:_events] => []
[yii\base\Component:_eventWildcards] => []
[yii\base\Component:_behaviors] => []
[include] => true
[key] => 'canonical'
[environment] => null
[dependencies] => null
)
'home' => nystudio107\seomatic\models\metalink\HomeLink#3
(
[crossorigin] => ''
[href] => '{{ seomatic.helper.siteUrl(\"/\") }}'
[hreflang] => ''
[media] => ''
[rel] => 'home'
[sizes] => ''
[type] => ''
[yii\base\Model:_errors] => null
[yii\base\Model:_validators] => null
[yii\base\Model:_scenario] => 'default'
[yii\base\Component:_events] => []
[yii\base\Component:_eventWildcards] => []
[yii\base\Component:_behaviors] => []
[include] => true
[key] => 'home'
[environment] => null
[dependencies] => null
)
'author' => nystudio107\seomatic\models\metalink\AuthorLink#4
(
[crossorigin] => ''
[href] => '{{ seomatic.helper.siteUrl(\"/humans.txt\") }}'
[hreflang] => ''
[media] => ''
[rel] => 'author'
[sizes] => ''
[type] => 'text/plain'
[yii\base\Model:_errors] => null
[yii\base\Model:_validators] => null
[yii\base\Model:_scenario] => 'default'
[yii\base\Component:_events] => []
[yii\base\Component:_eventWildcards] => []
[yii\base\Component:_behaviors] => []
[include] => true
[key] => 'author'
[environment] => null
[dependencies] => [
'frontend_template' => [
0 => 'humans'
]
]
)
'publisher' => nystudio107\seomatic\models\MetaLink#5
(
[crossorigin] => ''
[href] => '{seomatic.site.googlePublisherLink}'
[hreflang] => ''
[media] => ''
[rel] => 'publisher'
[sizes] => ''
[type] => ''
[yii\base\Model:_errors] => null
[yii\base\Model:_validators] => null
[yii\base\Model:_scenario] => 'default'
[yii\base\Component:_events] => []
[yii\base\Component:_eventWildcards] => []
[yii\base\Component:_behaviors] => []
[include] => true
[key] => 'publisher'
[environment] => null
[dependencies] => [
'site' => [
0 => 'googlePublisherLink'
]
]
)
'alternate' => nystudio107\seomatic\models\MetaLink#6
(
[crossorigin] => null
[href] => [
0 => 'http://craft3.test/en/blog'
1 => 'http://craft3.test/en/blog'
2 => 'http://craft3.test/es/blog'
3 => 'http://craft3.test/to-to/blog'
]
[hreflang] => [
0 => 'en-us'
1 => 'x-default'
2 => 'es'
3 => 'to-to'
]
[media] => null
[rel] => 'alternate'
[sizes] => null
[type] => null
[yii\base\Model:_errors] => null
[yii\base\Model:_validators] => null
[yii\base\Model:_scenario] => 'default'
[yii\base\Component:_events] => []
[yii\base\Component:_eventWildcards] => []
[yii\base\Component:_behaviors] => []
[include] => true
[key] => 'alternate'
[environment] => null
[dependencies] => null
)
]
[yii\base\Model:_errors] => null
[yii\base\Model:_validators] => null
[yii\base\Model:_scenario] => 'default'
[yii\base\Component:_events] => []
[yii\base\Component:_eventWildcards] => []
[yii\base\Component:_behaviors] => []
[name] => 'General'
[description] => 'Link Tags'
[class] => 'nystudio107\\seomatic\\models\\MetaLinkContainer'
[handle] => 'general'
[include] => true
[dependencies] => []
[clearCache] => false
)
Thanks for looking into it! Here's the current contents of my files:
<?php
return [
'default' => [
'resources/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
],
'frenchSite' => [
'ressources/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
],
'germanSite' => [
'ressourcen/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
],
'italianSite' => [
'risorse/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
],
'portugeseSite' => [
'recursos/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
],
'spanishSite' => [
'recursos-practicos/blog/<topicSlug:{slug}>' => ['template' => '_resources/blog/index.twig'],
]
];
{% extends '_layouts/default' %}
{# We set this because topic pages otherwise won't know #}
{% set entry = craft.entries.section('blogIndex').one() %}
{% set topic = topicSlug is defined ? craft.entries.section('resourceTopic').slug(topicSlug).one() : [] %}
{% if topicSlug is defined and topic|length == 0 %}
{% exit 404 %}
{% endif %}
{% paginate craft.entries.section('blogArticle').relatedTo(topic).limit(5) as pageInfo, pageEntries %}
{% if topic|length %}
{% do seomatic.helper.loadMetadataForUri(entry.uri) %}
{% do seomatic.meta.canonicalUrl(entry.url ~ '/' ~ topicSlug) %}
{% do seomatic.meta.seoTitle(seomatic.meta.seoTitle ~ ' - ' ~ topic.title) %}
{% endif %}
{% block content %}
{# Page content goes here. #}
{% endblock %}
I'm adding this code just before this line and immediately after the foreach loop to inspect the values:
echo '<pre>'.var_export($metaTag, true).'<pre>';
I now get one of two possible outputs when loading a paginated topic page (http://foo.test/resources/blog/promote/p2
):
nystudio107\seomatic\models\MetaLink::__set_state(array(
'crossorigin' => NULL,
'href' =>
array (
0 => 'http://foo.test/en/resources/blog/promote',
1 => 'http://foo.test/en/resources/blog/promote',
2 => 'http://foo.test/fr/resources/blog/promote',
3 => 'http://foo.test/de/resources/blog/promote',
4 => 'http://foo.test/it/resources/blog/promote',
5 => 'http://foo.test/pt/resources/blog/promote',
6 => 'http://foo.test/es/resources/blog/promote',
),
'hreflang' =>
array (
0 => 'en',
1 => 'x-default',
2 => 'fr',
3 => 'de',
4 => 'it',
5 => 'pt',
6 => 'es',
),
'media' => NULL,
'rel' => 'alternate',
'sizes' => NULL,
'type' => NULL,
'_errors' => NULL,
'_validators' => NULL,
'_scenario' => 'default',
'_events' =>
array (
),
'_eventWildcards' =>
array (
),
'_behaviors' =>
array (
),
'include' => true,
'key' => 'alternate',
'environment' => NULL,
'dependencies' => NULL,
))
nystudio107\seomatic\models\MetaLink::__set_state(array(
'crossorigin' => NULL,
'href' =>
array (
0 => 'http://foo.test/en/resources/blog',
1 => 'http://foo.test/en/resources/blog',
2 => 'http://foo.test/fr/ressources/blog',
3 => 'http://foo.test/de/ressourcen/blog',
4 => 'http://foo.test/it/risorse/blog',
5 => 'http://foo.test/pt/recursos/blog',
6 => 'http://foo.test/es/recursos-practicos/blog',
),
'hreflang' =>
array (
0 => 'en',
1 => 'x-default',
2 => 'fr',
3 => 'de',
4 => 'it',
5 => 'pt',
6 => 'es',
),
'media' => NULL,
'rel' => 'alternate',
'sizes' => NULL,
'type' => NULL,
'_errors' => NULL,
'_validators' => NULL,
'_scenario' => 'default',
'_events' =>
array (
),
'_eventWildcards' =>
array (
),
'_behaviors' =>
array (
),
'include' => true,
'key' => 'alternate',
'environment' => NULL,
'dependencies' => NULL,
))
nystudio107\seomatic\models\MetaLink::__set_state(array(
'crossorigin' => NULL,
'href' =>
array (
0 => 'http://foo.test/en/resources/blog/promote',
1 => 'http://foo.test/en/resources/blog/promote',
2 => 'http://foo.test/fr/resources/blog/promote',
3 => 'http://foo.test/de/resources/blog/promote',
4 => 'http://foo.test/it/resources/blog/promote',
5 => 'http://foo.test/pt/resources/blog/promote',
6 => 'http://foo.test/es/resources/blog/promote',
),
'hreflang' =>
array (
0 => 'en',
1 => 'x-default',
2 => 'fr',
3 => 'de',
4 => 'it',
5 => 'pt',
6 => 'es',
),
'media' => NULL,
'rel' => 'alternate',
'sizes' => NULL,
'type' => NULL,
'_errors' => NULL,
'_validators' => NULL,
'_scenario' => 'default',
'_events' =>
array (
),
'_eventWildcards' =>
array (
),
'_behaviors' =>
array (
),
'include' => true,
'key' => 'alternate',
'environment' => NULL,
'dependencies' => NULL,
))
In both instances, the hreflangs are always set as:
<link href="http://foo.test/es/resources/blog/promote" rel="alternate" hreflang="es">
<link href="http://foo.test/pt/resources/blog/promote" rel="alternate" hreflang="pt">
<link href="http://foo.test/it/resources/blog/promote" rel="alternate" hreflang="it">
<link href="http://foo.test/de/resources/blog/promote" rel="alternate" hreflang="de">
<link href="http://foo.test/fr/resources/blog/promote" rel="alternate" hreflang="fr">
<link href="http://foo.test/en/resources/blog/promote" rel="alternate" hreflang="x-default">
<link href="http://foo.test/en/resources/blog/promote" rel="alternate" hreflang="en">
Do we have this sorted @milesjbland ?
All sorted. I think it was an issue my side, in the end. Thank you for your help and time on this!
Hello from the future, @milesjbland. I think I'm having a similar issue with custom routes and the hreflang
links for a multi-site (multi-language) set up. Like the Output 2 example you posted, my hreflang
links all use the route pattern as defined in routes.php
for the current site.
I know this issue was a long time ago, but any chance you remember how you solved this?
Question
On our multisite setup, we have a blog index template that lets you filter by topic. The topics use custom routes set in
routes.php
.I'm running into a couple of issues with both custom routes and paginated pages.
hreflang
links are using the correct site URLs, but it is stripping out the page segment:hreflang
links are using the correct site URLs, but are stripping out the custom segment:I can solve both these problems by writing some twig that uses the link meta object function to manually set the links for each site with the custom segment and paginated segment added on the end.
The problem is that this doesn't work for any paginated pages after page 1. It strips the page segment and uses the English URIs for each site:
Is there a best practice approach to achieve the result I'm after?
Additional context
Craft:
3.4.30
SEOmatic:3.3.8
This might be related to https://github.com/nystudio107/craft-seomatic/issues/342