craftcms / craftcms/cms

Get localized url while rendering template in multiple locales

Open
#2,559 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug severity:minor
Dominant language
PHP
Stars
3.6k
Forks
705
Avg merge
1d 5h
Merged PRs (30d)
134

Description

Description

UrlHelper check $localeId != craft()->language to return url, but will return the old one if craft()->language has changed.

I want to send notifications in my app, those messages will be localized and sent to users in their prefferedLocale thus I am precompiling a message for every locale and then sending them to the targeted users.

Problem is I didn’t find any locale parameter to give to the craft()->templates->render() method and so I am updating the app language (craft()->setLanguage($locale);) before every rendering (craft email service behave like that).
Works well but now when I try to get the url I always end up with the English one.

And so my message is well translated but the url I save always links to the English page.

Steps to reproduce
function example($entryId) {
    $locales =   craft()->i18n->getSiteLocaleIds();
    $currentLocale = craft()->getLanguage();
    $localizedData = [];

    foreach ($locales as $locale) {
      craft()->setLanguage($locale);

      $criteria = craft()->elements->getCriteria(ElementType::Entry);
      $criteria->locale = $locale;
      $criteria->id = $entryId;
      $entry = $criteria->first();

      // this is working well, the rendering is done in the right locale
      $message = craft()->templates->render('a template', $messageParams);

      $url = $entry->getUrl(); // always same localized url

      $localizedData['notification'][$locale] = $notification;
    }
    // back to normal
    craft()->setLanguage($currentLocale);
  }

The thing is that if I do

craft()->setLanguage('yolo');
  $url->url = $entry->getUrl();
 craft()->setLanguage($currentLocale);

It will work well since $localeId != craft()->language and the url will be re-built.

I don't know if it's a bug, maybe I shouldn't modify craft()->language like that but I didn't find any other way for my template to be rendered in multiple locales. If it's not considered a bug, please advise on the correct way to do it.

Thanks

Additional info
  • Craft version: 2.6.3012
  • PHP version: 7.0.22
  • Database driver & version:
  • Plugins & versions:

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with UrlHelper's locale check and the interaction between craft()->setLanguage(), templates->render(), and $entry->getUrl(). Reproduce the loop from the issue across site locales, then trace why the URL remains cached or tied to the previous language. Done means each rendered notification receives the URL for its target locale without breaking the language restoration step.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend, localization
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.