4

For news entries I want both URL's www.example.com/news/678 (where 678 stands for the entry id) and www.example.com/news/some-slug to load the same entry.

www.example.com/news/some-slug works fine because 'Entry URL Format' is used for this so the news entry contains a readable slug for SEO.

Is there a way to generate www.example.com/news/678 (with entry id) for the same entry, to display the same news entry? Is it possible to handle this with Dynamic Routing? Or generate multiple URL Formats?

2
  • 1
    You probably don't want to do this. Duplicate content will give you a SEO penalization. Commented Mar 15, 2017 at 20:17
  • I need the url's with entry id for external usage. No problem to change to www.example.com/**some-other-text**/678 for example and disallow it in robots.txt to prevent a SEO penalty. Commented Mar 15, 2017 at 20:27

2 Answers 2

2

Setup a dynamic route that points to the same template that you have set up in the section settings for your "slug URLs". Use a pattern like so: news/<id>, which passes the 2rd URL segment as a variable named id to the template.

Add this snippet to the top of your template.

{% if not entry and id %}
    {% set entry = craft.entries.id(id).first() %}
{% endif %}

{% if not entry %}
    {% exit 404 %}
{% endif %}

If Craft finds a route for your entry slug (routing case 3), that code does nothing at all, because the entry model is already set.

When no route was found that matches an entry slug, your dynamic route comes into play (routing case 4), which routes the request to the same template. But now there is no entry variable set and we can go ahead and try to grab it manually using the id variable passed in.

Update:
as already mentioned in the comments, don’t forget to setup canonical meta tags to avoid duplicate content penalties.

<link rel="canonical" href="{{ entry.getUrl() }}">
2
  • Thanks carlcs! With the pattern 'news/<id>' added in cp --> routes, it gives a 404. When I add 'newsid/(?P<id>\d{3})' => 'news/_entry' it works fine for 3-digits id's. I'd like to accept all digits, but when removing \d{3} this route gives a 404 again. Commented Mar 16, 2017 at 8:36
  • Ahh… that <id> syntax wasn’t meant to be actual code, sorry. I thought there was a draggable ID token available in the UI. I never actually use that interface and setup my routes with the craft/config/routes.php file. Where I would use the following: 'news/(?P<id>\d+)' => 'news/_entry'.
    – carlcs
    Commented Mar 16, 2017 at 8:45
0

I'm not seeing how this could be done through routes.

Maybe you could do it with a custom plugin that listened to the getElementRoute hook, though.

There is a feature request here you might want to thumb-up/comment on that would seem to do what you're looking for: https://github.com/craftcms/cms/issues/1189

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.