"locale" setting is ignored on routes

I don’t know if I made a mistake or if it is an issue of Kirby 3.

Describe the issue
I have an issue on a page like https://getkirby.com/docs/guide/virtual-pages/simple-virtual-page, which is a route. The ‘locale’ setting like https://getkirby.com/docs/reference/system/options/locale in the config is ignored there.

It is a ONE language website with German language settings (and at the moment English language texts).

My development system is XAMPP 7.3.16 [Apache/2.4.41 (Win64) PHP/7.3.16] on a Win10 64 bit laptop computer.
On XAMPP 7.2.15 with PHP/7.2.15 it is the same.

To Reproduce
Steps to reproduce the behavior:

  1. Install a fresh Kirby Starterkit 3.3.5.

  2. Change the file site\config\config.php to:

<?php // \site\config\config.php
return [
  'debug' => true,
  'locale' => r((strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'), // set 'locale' to '' for Windows servers and to 'de_DE.utf8' for the rest
              [ // the server is runing on Windows OS
                LC_ALL      => '',
                LC_COLLATE  => '',
                LC_MONETARY => '',
                LC_NUMERIC  => '',
                LC_TIME     => '',
                LC_CTYPE    => ''
              ],
              [ // this may have to be adapted to your server !!!
                LC_ALL      => 'de_DE.UTF8',
                LC_COLLATE  => 'de_DE.UTF8',
                LC_MONETARY => 'de_DE.UTF8',
                LC_NUMERIC  => 'de_DE.UTF8',
                LC_TIME     => 'de_DE.UTF8',
                LC_CTYPE    => 'de_DE.UTF8'
              ]
              ),
  'routes' => [
    [
      'pattern' => 'virtual',
      'action'  => function () {
        return Page::factory([
          'slug' => 'virtual',
          'template' => 'virtual',
          'model' => 'virtual',
          'content' => [
            'title' => 'This is not a real page',
            'date'  => '2019-03-15', // changed to easy see the issue!!!
            'text'  => 'The Big Oxmox advised her not to do so, because there were thousands of bad Commas, wild Question Marks and devious Semikoli, but the Little Blind Text didn’t listen.'
          ]
        ]);
      }
    ]
  ],
];

  1. Change the file site\snippets\header.php to:
<?php // site\snippets\header.php ?>
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title><?= $site->title() ?> | <?= $page->title() ?></title>
  <?= css(['assets/css/index.css', '@auto']) . "\n" ?>
</head>
<body>
  <div class="page">
    <header class="header">
      <a class="logo" href="<?= $site->url() ?>"><?= $site->title() ?></a>
      <nav id="menu" class="menu">
        <?php
        foreach ($site->children()->listed() as $item): ?>
        <?= $item->title()->link() . "\n" ?>
        <?php endforeach ?>
        <a href="<?= $site->url() ?>/virtual">Virtual page</a><?php // :added for easier access ?>
      </nav>
    </header>
<?php // added for troubleshooting: ?>
    <p>LC_TIME: "<code><?php echo setlocale(LC_TIME, 0) ?></code>"</p>
    <p>real "date" field: "<code><?php echo $page->date(); ?></code>"</p>
    <p>localized "date" field: <code><?= utf8_encode (strftime("%A, %d. %B %Y", $page->date()->toDate())) ?></code></p>

  1. Add a new file site\templates\virtual.php like:
<?php snippet('header') ?>
<main>
  <article class="note">
    <header class="note-header intro">
      <h1><?= $page->title() ?></h1>
      <time class="note-date"><?= utf8_encode (strftime("%A, %d. %B %Y", $page->date()->toDate())) ?></time>
    </header>
    <div class="note-text text">
      <?= $page->text()->kt() ?>
    </div>
  </article>
</main>
<?php snippet('footer') ?>

  1. In the file site\templates\note.php change the line:
      <time class="note-date"><?= $page->date()->toDate('d F Y') ?></time>

to

      <time class="note-date"><?= utf8_encode (strftime("%A, %d. %B %Y", $page->date()->toDate())) ?></time>

  1. If I now go e.g. to “http://yourdomain.com/notes/chasing-waterfalls” (in the menu: “NOTES” and then “Chasing waterfalls”).
    The date line in the article is
Freitag, 05. Oktober 2018

and the info block in the header shows:

LC_TIME: "German_Germany.1252"
real "date" field: "2018-10-05 10:40"
localized "date" field: Freitag, 05. Oktober 2018

This shows, that the locale setting is ok and running.
Hint: The info after “LC_TIME: ” may be different for you, e.g. like “de_DE.UTF8”.

  1. If I now go e.g. to “http://yourdomain.com/virtual” (click at “VIRTUAL PAGE” in the menu).
    The date line in the article is
Friday, 15. March 2019

and the info block in the header shows:

LC_TIME: "C"
real "date" field: "2019-03-15"
localized "date" field: Friday, 15. March 2019

The line “LC_TIME: "C"” shows the problem. The config setting is ignored on the routed page.


Expected behavior
The ‘locale’ setting from the ‘config’ file is also evaluated for routed pages.

Hint
I know that I can force the necessary settings in each affected page by calling something like

<?php
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
    $localeCode = '';
else
    $localeCode = 'de_DE.UTF8';
$typ = setlocale(LC_TIME, $localeCode);
?>

But this should not be necessary from my point of view.

You can prevent this by registering the page with the pages extension instead of using a route. Alternatively, you can set the locale inside the route.

Can you please show me the needed code in my example. Thank you very much.

I wrote the example in the top article as a simplified version of my problem.
On the real website, this problem occurs in the results of a search which is a route. So I can use this at serval points of my site pages.

          'pattern' => 'virtual',
          'action'  => function () {
              setlocale(LC_TIME, 'de_DE.UTF-8');  
              return Page::factory([
                // props
              ]);
           }
1 Like

I want to push this up a bit because I seem to meet the same problem. Its certainly only a small thing but I fail to apply the solution above. The respective part in my config.php looks that way.

`'routes' => [
        [
            'pattern' => '(:any)',
            'action'  => function($uid) {
                $page = page($uid);
                if(!$page) $page = page('inhalt/' . $uid);
                if(!$page) $page = site()->errorPage();
                return site()->visit($page);
            }
        ],
        [
            'pattern' => 'inhalt/(:any)',
            'action'  => function($uid) {
                go($uid);
            }
        ]
    ]
`

Everything works fine without the routes. the locale handler is set to intl. Kirby 3.9.

What do you mean? You can set the locale in your config, or you can set the date handler to intl, but those are two different things.

And what exactly is your problem? What do the routes have to do with the locale?

My apologies, of course the date handler:

'date'  => [
    'handler' => 'intl'
  	],

The problem is the same as described above: With the “routes” in my config.php the date is displayed in English instead of German. But without the routes definition the date is displayed as I wish, which is German in my case. I tried to put the locale inside the route, but obviosuly I don’t know how.

Hm, I can’t reproduce this in a 3.9.1 starterkit.

I have these settings in config:

   'locale' => 'de_DE',
    'routes' => [
        [
            'pattern' => '(:any)',
            'action'  => function($uid) {
                if($page = kirby()->page('notes/' . $uid)) {
                    return $page;
                }
                $this->next();
            }
        ],
        [
            'pattern' => 'notes/(:any)',
            'action'  => function($uid) {
                go($uid);
            }
        ]
    ],
    'date' => [
        'handler' => 'intl'
    ],

Date format set to this in note.php

<?= $page->date->toDate('d MMMM Y') ?>

Result:

Yes, that is strange. I copied your code one-to-one and it’s still the same. Also tried different browsers. I also checked my headers to see whether there might be a different reason. I read in one of the forum posts that it might help th refresh the page like 15 times or so (Firefox can be pretty stubborn), but no, no results.

So, as far as I can see in your example the date handler is outside the routes defintion. How do I set the date handler inside the routes definition?

That wouldn’t make sense.

Is your project a multi-language site?

And is the intl extension even available? Check phpinfo.

I am referring thereto (Post #4). Here you made a suggestion with a locale inside the routes definition. I don’t know how to apply that.

Yes, intl is enabled. I found also this information: “intl.default_locale: no value”. And no, it is not a multi-language site.

I sent you a link to a test project that works in my local environment. Maybe test that.

1 Like