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

Translating post type label and slug #46

Open
bonakor opened this issue Dec 8, 2022 · 22 comments
Open

Translating post type label and slug #46

bonakor opened this issue Dec 8, 2022 · 22 comments

Comments

@bonakor
Copy link

bonakor commented Dec 8, 2022

Hi,
I have this code in my poet.php file:
'calendar' => [ 'enter_title_here' => 'Enter calendar month or year', 'menu_icon' => 'dashicons-calendar-alt', 'supports' => ['title', 'revisions', 'page-attributes'], 'show_in_rest' => true, 'hierarchical' => true, 'has_archive' => false, 'labels' => [ 'singular' => __('Calendar', 'sage'), 'plural' => __('Calendars', 'sage'), ], ],

I've generated a pot file, and translated it, but it doesn't seem to work: slug and labels remain in english even on my french website

@SergiArias
Copy link

I have the same problem. In sage 10.3.1 (october 22) it worked flawlessly, but since 10.5.1 localization stopped working for me, maybe new acorn is the issue?

@Log1x
Copy link
Owner

Log1x commented Feb 23, 2023

This is very unlikely to be a regression/issue in Acorn, but this isn't something I've ever tested in Poet. In theory, it should work, though.

Does it work if calling register_extended_post_type outside of Poet?

@SergiArias
Copy link

Yes, it does work. It's definitely related to the boot process in Acorn, as it is getting all the poet config values before the localization is available.

I used a workaround in the same file by using a switch with get_option('WPLANG') and writing all the translations directly in the file (or ternary if there aren't many). Fortunately it's not a big deal to do it this way while a better solution is found.

@Log1x
Copy link
Owner

Log1x commented Feb 23, 2023

https://github.com/Log1x/poet/blob/master/src/Poet.php#L63 can you try messing with the init hook priority here? Maybe move the config property to inside of the init hook?

@SergiArias
Copy link

SergiArias commented Feb 23, 2023

yes, there is where I found more or less where the problem was located. I did move the config inside the init but didn't work. I think (and it is a guess as I don't understand acorn) the config is loaded by acorn as soon as acorn boots and thus the init hook doesn't apply.

@Log1x
Copy link
Owner

Log1x commented Feb 23, 2023

I'll look into this more when I get a chance.

@ouun
Copy link
Contributor

ouun commented Jul 24, 2023

@Log1x I am facing the same. Can't translate the labels for CPTs and Taxonomies.
Should we switch to register them the register_extended_post_type way or do you have a chace to have a look at this, soon?

Thanks!

@Log1x
Copy link
Owner

Log1x commented Jul 24, 2023

Not 100% sure what this would be. The best guess would be to play with the hook. I'm not sure why the translations wouldn't be loaded by time init hits though.

Could also be them not getting resolved from configs (try hardcoding the labels as a test maybe?) – I don't have a good test environment to dig deeper myself at the moment. :(

@ouun
Copy link
Contributor

ouun commented Jul 24, 2023

@Log1x thanks a lot for getting back to me so fast.
Had a closer look, too. The init hook has no effect on the translations in poet.php as the config is loaded here already:

$this->config = $this->collect($this->app->config->get('poet'))

Tried to move the config getter into the init hook, but that has no effect. IMO $this->app->config->get('poet') simply does not execute the i8n functions in the config as it returns the labels array with simple original strings.

Hardcoding the labels here works! But at this point the labels array from above with untranslated stings is passed. So that can't have any effect.

Wondering if get() shouldn't already do the translation work. Because I now realize that we have the same issue with all other packages that use l8n in config files. E.g. in Crumb.

@ouun
Copy link
Contributor

ouun commented Jul 25, 2023

@Log1x just wonderung if you agree, that the translations should get processed by acorn via get(). If yes, I will creat an issue there. Thanks!

@Log1x
Copy link
Owner

Log1x commented Jul 25, 2023

It's not a bad idea as it currently doesn't work, but I don't know how annoying it's going to be to handle it within Acorn. In an ideal world, we wouldn't have to extend/mess with illuminate/config directly, but I'm not seeing much hope in the config bootstrapping without extending Repository.

@ouun
Copy link
Contributor

ouun commented Jul 25, 2023

I think this will be very annoying as the config is also cached. So if it worked as expected, the config value of the current language would be cached as a string anyway.
Out of curiosity what do you think about executing __() each string here?
We could (optionally) allow the following syntax in the config file to support arrays that contain the value and textdomain:

'labels' => [
      'singular' => [ 'Example', 'textdomain' ],
      'plural' => [ 'Examples', 'textdomain' ],
  ],

This would also support simple strings. So it is backwards compatible.

@Log1x
Copy link
Owner

Log1x commented Jul 25, 2023

If you think that would work I am all for it.

As far as I know, you have to hardcode anything related to __() though, don't you?

I don't have much first-hand experience with multi-lang on WordPress.

@ouun
Copy link
Contributor

ouun commented Jul 25, 2023

OMG, wasn't aware of that. However I will test it and get back to you. Thanks

@ouun
Copy link
Contributor

ouun commented Jul 25, 2023

@Log1x it works as expected as long as the strings are registered:

    protected function translateLabels($labels)
    {
        return $this->collect($labels)->map(function ($label, $key) {
            if (is_array($label) && count($label) === 2) {
                return __($label[0], $label[1]);
            }

            return $label;
        })->toArray();
    }

However you are right that gettext needs to find the strings somewhere using __() to register them. Either somewhere else in the codebase or just next to the array just for registration:

'labels' => [
      'singular' => [ 'Example', 'textdomain' ],
      'plural' => [ 'Examples', 'textdomain' ],
  ],
'register' => [
      __('Example', 'textdomain' ),
      __('Examples', 'textdomain' ),
  ]

While this is not ideal, at least it allows us to translate the strings. Still I will open an issue for Acorn but wonder if you would be interested in a PR for this workaround.

Edit: Something like this could do it, too:

'labels' => [
      'singular' => [ 
          __('Example', 'textdomain' ), 
          'textdomain' 
      ],
      'plural' => [
          __('Examples', 'textdomain' ), 
          'textdomain' 
      ],
],

@oxyc
Copy link

oxyc commented Jul 29, 2023

@ouun Ill reply here instead of the acorn issue queue.

I haven’t checked if that part of the acorn bootstrap has changed in v3 but it did fix it in v2. What my gist did was re-evaluate the config files on each request, without it they’re only evaluated once and precompiled.

Edit: skimming the code it look’s like it has changed and you now need to swap out the kernel.

@ouun
Copy link
Contributor

ouun commented Aug 7, 2023

Tried another approach today: Regular usage of __() in config files and pass label strings through the function again when the config is loaded. However this is making it more complicated, too.


    protected function translateLabels($values, $key = null)
    {
       $textdomain = wp_get_theme()->get('TextDomain');

        if (is_array($values)) {
            $this->collect($values)->map(function ($label, $key) use ($textdomain) {
                if (is_array($label)) {
                    if($key === 'labels') {
                        foreach ($label as $labelKey => $labelValue) {
                            $label[$labelKey] = __($labelValue, $textdomain);
                        }
                    } else {
                        $this->translateLabels($label);
                    }
                } else  if (is_string($label) && $key === 'label') {
                    $label = __($label, $textdomain);
                }

                return $label;
            })->toArray();
        }

        return $values;
    }

Is someone aware of a possibility to get the value from the config that still contains whatever is set there? E.g.:

'labels' => [
      'singular' => __('Location', 'domain'),
      'plural' => __('Locations', 'domain'),
  ],

How would I get __('Location', 'domain') from the config file? If that would be possible, we could just lookup each label as above but with the function, from which we get the textdomain.

@teppokoivula
Copy link

teppokoivula commented Dec 4, 2023

Anyone figure this out yet? Ran into this issue after upgrading couple of sites from Acorn 2 to 3.

Edit: actually not entirely sure anymore if this was the same issue. In my case it was enough to make sure that theme textdomain was called before Poet config, so adding a _i18n.php config file (so that it gets loaded early) and moving load_theme_textdomain() there seems to have done the trick.

@SergiArias
Copy link

Anyone figure this out yet? Ran into this issue after upgrading couple of sites from Acorn 2 to 3.

Edit: actually not entirely sure anymore if this was the same issue. In my case it was enough to make sure that theme textdomain was called before Poet config, so adding a _i18n.php config file (so that it gets loaded early) and moving load_theme_textdomain() there seems to have done the trick.

This was my solution, but after updating Wordpress to 6.7, it triggers the Notice:
Funtion _load_textdomain_just_in_time has been called incorrectly. Translation loading for the sage domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Look /.../wp-includes/functions.php on line 6114

@slackday
Copy link

slackday commented Nov 18, 2024

Had the same issue but removing _18n.php from config/ and add to setup.php or create a mu-plugin "translations.php" with file content

///**
// * Register the theme text domain.
// */
//add_action('after_setup_theme', function () {
//    load_theme_textdomain('sage', get_template_directory() . '/resources/lang');
//});

then run wp acorn optimize:clear and wp acorn optimize seems to work for me.

Edit: This seem to be a wide issue with WordPress 6.7. I found the following snippet https://forum.bricksbuilder.io/t/solved-wrong-language-after-wordpress-6-7/27861/3 which I adjusted for sage and it works.

Create as a plugin with translations.php in the mu-plugins directory and add this code or anywhere in your theme:

<?php

/**
 * Register the theme text domain.
 */
add_action(
    'init',
    function() {
        global $l10n, $wp_textdomain_registry;
        $domain = 'sage';
        $lang_dir = get_template_directory() . '/resources/lang';
        $locale = get_locale();
        $wp_textdomain_registry->set($domain, $locale, $lang_dir);
        if (isset($l10n[$domain])) {
            unset($l10n[$domain]);
        }
        load_theme_textdomain($domain, $lang_dir);
    },
);

@SergiArias
Copy link

Had the same issue but removing _18n.php from config/ and add to setup.php or create a mu-plugin "translations.php" with file content

///**
// * Register the theme text domain.
// */
//add_action('after_setup_theme', function () {
//    load_theme_textdomain('sage', get_template_directory() . '/resources/lang');
//});

then run wp acorn optimize:clear and wp acorn optimize seems to work for me.

Edit: This seem to be a wide issue with WordPress 6.7. I found the following snippet https://forum.bricksbuilder.io/t/solved-wrong-language-after-wordpress-6-7/27861/3 which I adjusted for sage and it works.

Create as a plugin with translations.php in the mu-plugins directory and add this code or anywhere in your theme:

<?php

/**
 * Register the theme text domain.
 */
add_action(
    'init',
    function() {
        global $l10n, $wp_textdomain_registry;
        $domain = 'sage';
        $lang_dir = get_template_directory() . '/resources/lang';
        $locale = get_locale();
        $wp_textdomain_registry->set($domain, $locale, $lang_dir);
        if (isset($l10n[$domain])) {
            unset($l10n[$domain]);
        }
        load_theme_textdomain($domain, $lang_dir);
    },
);

For me it does the same as adding

add_action(
    'init',
    function() {
        load_theme_textdomain('sage', get_template_directory() . '/resources/lang');
    },
);

The Notice disappears, but everything created with poet doesn't get translations

@slackday
Copy link

slackday commented Nov 22, 2024

@SergiArias did you run wp acorn optimize:clear after adding it?

WordPress 6.7.1 has fixes to translations maybe it helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants