Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strftime in the panel ignore local setting with toDate() #1872

Closed
yoanmalie opened this issue Jun 19, 2019 · 23 comments

Comments

@yoanmalie
Copy link

commented Jun 19, 2019

Describe the bug
With the strftime date handler, the date is not translated when used in the panel.

To Reproduce
Steps to reproduce the behavior:

  1. Clone the starterkit
  2. Change the date handler in the config for strftime
'date' => [
    'handler' => 'strftime'
],
  1. Edit the info key in the sections/notes.yml blueprint for:
    info: "{{ page.date.toDate('%A %d %B %Y') }}"

  2. Go to the panel and install it in French.

Expected behavior
Date should be translated in French, like Mercredi 31 octobre 2018, Vendredi 05 octobre 2018, Mercredi 26 Septembre 2018…

Screenshots
The notes list in the Kirby panel

Kirby Version
Tested on 3.1.3 and 3.1.4.

Additional context
The date handler with the same toDate() I used work well in a template.

@PaulMorel

This comment has been minimized.

Copy link

commented Jun 25, 2019

This might not be Kirby related. Do you have the language packs installed on the server? By default most servers don't come with french language packs, so strftime defaults to english.

For example in my setup, a Ubuntu 18.04 LTS LAMP Stack, I have to install the language-pack-fr package for french dates to work correctly with strftime.

It should be the same with other languages. Hopefully this helps! Bonne chance!

@yoanmalie

This comment has been minimized.

Copy link
Author

commented Jun 25, 2019

Hi @PaulMorel
Thank you for explaining! The fact is that if I use the same toDate() but in a page template, it work well. So that would say the language pack is here, right ?

@PaulMorel

This comment has been minimized.

Copy link

commented Jun 25, 2019

I would say if it works on the front-end, but doesn't on the back-end, it's not a language pack issue.

But, I can't reproduce your problem. Tested on 3.1.3

I added {{ page.date.toDate('%A %d %B %Y') }} in the panel and works for me, but only after I installed the Ubuntu language pack and restarted Apache.

Page

image

Section

image

Front-end

image

One last thing, what does your /site/languages/fr.php look like? Here's mine:

<?php
return [
  'code' => 'fr',
  'default' => true,
  'direction' => 'ltr',
  'name' => 'Français',
  'locale' => 'fr_CA.utf-8',
  'url' => '/'
];

The locale option is whats important for strftime to work correctly. I'm in Canada so I use fr_CA. So you the locale appropriate for you. fr_BE, fr_CH, fr_FR, etc.

@yoanmalie

This comment has been minimized.

Copy link
Author

commented Jun 26, 2019

Oh I missed this part, but there a new bug here?

By adding this I litterally have nothing:
image

site/languages/fr.php:

<?php
return [
  'code' => 'fr',
  'default' => true,
  'direction' => 'ltr',
  'name' => 'Français',
  'locale' => 'fr_FR.utf-8',
  'url' => '/'
];

also, in site/config/config.php:

<?php
return [
    'languages' => true,
];

I forget to mention it in the first post but my locale are also set like this:

return [
  'locale' => [
    LC_COLLATE => 'fr_FR.UTF-8',
    LC_MONETARY => 'fr_FR.UTF-8',
    LC_NUMERIC => 'fr_FR.UTF-8',
    LC_TIME => 'fr_FR.UTF-8',
    LC_MESSAGES => 'fr_FR.UTF-8',
    LC_CTYPE => 'fr_FRs.UTF-8'
  ]
]

This is not working yet with the new Kirby 3.2.0.

@PaulMorel

This comment has been minimized.

Copy link

commented Jun 26, 2019

If your website is only in french, you don't need 'languages' => true in your config.php. If I remember correctly 'languages' => true, is for multi-language websites.

Your locale should be in fr.php. Eithe

<?php
return [
  'code' => 'fr',
  'default' => true,
  'direction' => 'ltr',
  'name' => 'Français',
  'locale' => 'fr_FR.utf-8',
  'url' => '/'
];

or

<?php
return [
  'code' => 'fr',
  'default' => true,
  'direction' => 'ltr',
  'name' => 'Français',
  'locale' => [
    LC_COLLATE => 'fr_FR.utf-8',
    LC_MONETARY => 'fr_FR.utf-8',
    LC_NUMERIC => 'fr_FR.utf-8',
    LC_TIME => 'fr_FR.utf-8',
    LC_MESSAGES => 'fr_FR.utf-8',
    LC_CTYPE => 'fr_FR.utf-8'
  ]
  'url' => '/'
];

I think these two are equivalent.

@yoanmalie

This comment has been minimized.

Copy link
Author

commented Jun 26, 2019

I tried both solution, with or without'languages' => true.
As soon as I create a fr.php file, the dates in the panel disappear…

@texnixe

This comment has been minimized.

Copy link
Contributor

commented Jun 26, 2019

Just to clarify: A Kirby site with languages defined in the /languages folder is a multi-language installation. The config setting allows/prevents adding/deleting languages via the Panel.

@distantnative

This comment has been minimized.

Copy link
Contributor

commented Jul 18, 2019

@yoanmalie

Go to the panel and install it in French

Are you using the Panel in French (so your Panel user language is set to French in the user settings) or are you editing the French translation of your site?

@yoanmalie

This comment has been minimized.

Copy link
Author

commented Jul 18, 2019

@distantnative I use the panel in French, and it work. In the first screen, "Add" is well translated to "Ajouter".

@distantnative

This comment has been minimized.

Copy link
Contributor

commented Jul 18, 2019

The tricky part here is: Should the Panel call the API in the language

a) the Panel is used in, or
b) the content from the API should be in?

With your case it's a mixed thing: you are editing a content language and the API needs to respond to that but at the same time it should also reflect the lanuage of the Panel user...

not sure if we can get that.

@lukasbestle

This comment has been minimized.

Copy link
Contributor

commented Sep 14, 2019

I think it should always use the user language as it's a piece of UI, not a piece of raw content like the other multilang content.

@distantnative

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

But this is very hard: The Panel is not aware of the difference between a query like {{ page.date.toDate('%A %d %B %Y') }} and {{ page.subtitle }}. For the Panel both are a query to be evaluated by the backend. However, in the latter case it's clear that we want a result based on the current content translation – not based on the Panel user language. So having a different expectation for the former is a tricky exception to the rule.

Making toDate always react to the user language doe snot work either IMO. Imagine a frontend that works with logged in users but still wants to keep its site versions in language A and language B separated. Would be weird that the user gets its Panel language there no matter whether being on language A or language B site.

Conceptually, maybe adding a third parameter could work. Something then like {{ page.date.toDate('%A %d %B %Y', null, user.language.code) }}. What do you think?

@texnixe

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

@distantnative Your last suggestion sounds like a good idea, that would at least leave it to the developer to decide.

Personally, I would expect the info to be in the currently selected language, not the Panel user language. But that is probably really a question of everyone's perspective.

@lukasbestle

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

The Panel is not aware of the difference between a query like {{ page.date.toDate('%A %d %B %Y') }} and {{ page.subtitle }}. For the Panel both are a query to be evaluated by the backend.

But does the backend need to know about the intent of the specific query to be able to parse them?
The difference between a method call in the frontend and a query in the Panel is that the latter gets requested via the API. So what we could do is to set the PHP locale to the language of the current user whenever an API request is processed. The frontend would be completely unaffected.

@distantnative However, in the latter case it's clear that we want a result based on the current content translation – not based on the Panel user language. So having a different expectation for the former is a tricky exception to the rule.
@texnixe Personally, I would expect the info to be in the currently selected language, not the Panel user language. But that is probably really a question of everyone's perspective.

I think that's exactly the issue. I would expect the Panel to show the content of the language, but in the format of the UI while you would expect the format to match the content language as well.

So maybe the option to override the language would make sense here. I'm not sure however if this should be a param to the toDate() method, because that would then also be there for calls from the frontend (where such an override doesn't often make sense). Also it would need to be passed in every location where toDate() is used in queries.
What about a global Kirby option that defines whether locales in API requests should be set based on the content or user language? The option would default to "user language" (so that it works on single-lang sites as well), but could be set to "content language" if needed.

@distantnative

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

But I still get how you would differentiate {{ page.date.toDate('%A %d %B %Y') }} and {{ page.subtitle }} in your example. I assume that both types are used intermixed in projects. For the one you want to use the Panel user language, for the other the content translation language.

As I see it, we can run Kirby (as in running an API request) only in one language. There is no differentiation between, run it in language A for retrieving content and in language B in regard to date formats.

Also consider this potential case: the date field of {{ page.date.toDate('%A %d %B %Y') }} is actually translatable, so you have a different value for language A as for language B which the API has to deliver according to the current active content translation in the Panel. But then you want it also to format it according to the Panel user language, which could be language C.

@distantnative

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

Just to make it clear, I totally understand where you are coming from and think the intention makes sense (also as @texnixe pointed out, this might be a lot about taste as well). But my main point is that I don't think we can achieve this with the current Kirby architecture. Or at least I have no idea how we could.

@lukasbestle

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

But I still get how you would differentiate {{ page.date.toDate('%A %d %B %Y') }} and {{ page.subtitle }} in your example. I assume that both types are used intermixed in projects. For the one you want to use the Panel user language, for the other the content translation language.

I think you are mixing two things here:

  • The "language for retrieving content" should of course always be the language that is currently active in the Panel. For both query examples (querying a simple field or a date) it would be completely the same: For example if the Panel currently displays the German translation of the multilang site, the language would be German, so I would get the subtitle and date from the content.de.txt file.
  • The "language for formatting" (= PHP locale) can be completely different to that. I can get the date from the German text file and still display it in English – that doesn't change anything about the content the Panel is displaying, just the formatting.

So by setting the PHP locale for API requests based on the user language, we only ever change the "language for formatting". We do not change which data is retrieved from the content files. And because we don't change that, the Panel doesn't ever need to differentiate between querying simple fields or dates. In both cases it would get the content field from the currently active text file. The formatting happens later when the toDate() method is called.

@distantnative

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

But can we set a different PHP locale for API request that differs from the content language we request? My point was exactly that I don't think we can.

@lukasbestle

This comment has been minimized.

Copy link
Contributor

commented Sep 15, 2019

Why not? The API knows which user sent the request based on the session or basic auth and can therefore grab the user language.

@distantnative distantnative self-assigned this Sep 15, 2019
distantnative added a commit that referenced this issue Sep 15, 2019
@distantnative distantnative added this to the 3.2.5 milestone Sep 15, 2019
distantnative added a commit that referenced this issue Sep 15, 2019
@bastianallgeier

This comment has been minimized.

Copy link
Contributor

commented Sep 16, 2019

@lukasbestle think of this example:

The help text in a pages section might include some dynamic information – maybe such a date – which should be in the current interface language, but the content language could still be set to something different. Thus the page titles in the pages section should be in the content language. But we don't send two requests for that. It's a single API request, which fetches the section data and the section options.

@distantnative

This comment has been minimized.

Copy link
Contributor

commented Sep 16, 2019

@bastianallgeier
But I think Lukas is actually right: If we set the Panel user interface language as locale but still pull the content translation language, we achieve both: We get the content values for the currently edited content translation, but the format that is displayed via strftime is that of the interfact locale.

@lukasbestle

This comment has been minimized.

Copy link
Contributor

commented Sep 16, 2019

Yes, exactly. The only thing the PHP locale does is to change the format for strftime(). Everything else is unaffected and handled like before.

lukasbestle added a commit that referenced this issue Sep 16, 2019
bastianallgeier added a commit that referenced this issue Sep 17, 2019
@bastianallgeier

This comment has been minimized.

Copy link
Contributor

commented Sep 17, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.