"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