在检索getText翻译之前设置电子邮件区域设置

时间:2021-08-11 作者:DevelJoe

我开发了几个插件,我使用标准方法对其进行了本地化__() 功能和.po 或者更确切地说.mo 文件。所有这些都很有魅力。

我现在想做的是为函数调用设置语言环境__(), 检索您在插件上定义的翻译.mo 对于与当前区域设置不同的翻译。示例:

假设您正在德国wp admin页面上的wp admin中为您的网站创建一个用户。

此用户需要英文配置文件。

  • 在您的wp admin中,您已经自动发送邮件,这样,当用户创建时,他/她会收到一封关于这一点的电子邮件,使用2)中所述的语言。

    问题:邮件内容使用__() 也因此,当我在德语管理页面上创建用户时,通知邮件的德语版本将发送给用户,而不是英语版本。因此,我正在寻找一种解决方案,将通过.mo 与当前区域设置不同的文件;并且仅限于此单个函数调用(例如,不会因此永久更改语言环境)。例如:

    __( \'get-this-translation\', \'of-this-text-domain\', \'of-this-locale\' );
    
    而不是

    __( \'get-this-translation\', \'of-this-text-domain\' );, 它显然总是默认为当前活动的区域设置;在上面的例子中,德语。

    我知道只需在管理端硬编码翻译字符串,而不是使用__() 在这里,可以解决问题;但我更希望我的译文都以同样的方式翻译,使用wordpress提供的相同逻辑。因此,我想通过__(), 如果可能的话。

  • 2 个回复
    SO网友:Sally CJ

    我现在想做的是为函数callof设置语言环境__(), 检索您在插件上定义的翻译.mo 对于与当前区域设置不同的翻译。

    我更希望我的翻译都以同样的方式翻译,使用wordpress提供的相同逻辑。因此,我想通过__(), 如果可能的话。

    __(), _e(), _n() 其他核心翻译/获取文本函数没有设置语言环境的参数,但与wp_new_user_notification() 做到了,你可以用switch_to_locale() 手动(只是暂时)切换到目标语言环境(如示例中的英语,它是用户定义的语言环境),然后调用__() 或者使用相关函数检索刚切换到的语言环境中的翻译。

    例如,您可以执行以下操作:

    $switched_locale = switch_to_locale( get_user_locale() );
    // Or explicitly specify the locale:
    //$switched_locale = switch_to_locale( \'of-this-locale\' );
    
    $foo = __( \'get-this-translation\', \'of-this-text-domain\' );
    error_log( $foo );
    // or do whatever necessary..
    
    if ( $switched_locale ) {
        restore_previous_locale();
    }
    

    更新

    请注意,在切换到其他语言环境以及恢复原始/以前的语言环境后,需要重新加载插件的翻译。

    所以你会打电话load_plugin_textdomain()load_muplugin_textdomain() 像这样:

    // So in your main plugin file, you might have something like:
    add_action( \'init\', \'your_plugin_load_textdomain\' );
    function your_plugin_load_textdomain() {
        load_plugin_textdomain( \'your-domain\', false,
            dirname( plugin_basename( __FILE__ ) ) . \'/languages\' );
    }
    
    // Then wherever you want to switch the current locale, call the above function
    // to re-load the plugin\'s translations.
    if ( $switched_locale = switch_to_locale( get_user_locale() ) ) {
        your_plugin_load_textdomain(); // call it here
    
        // do your gettext stuff, e.g.
        _e( \'Hello World!\', \'your-domain\' );
    
        restore_previous_locale();
        your_plugin_load_textdomain(); // and then here
    }
    
    如果你愿意,你可以尝试我下面的插件来测试上述功能(switch_to_locale()restore_previous_locale()):

    • WPSE 393178 DE — 该插件使用德语作为主要/基本语言,该插件附带两个MO文件,即wpse-393178-de-en_US.mowpse-393178-de-fr_FR.mo.

    • WPSE 393178 EN — 这个插件与上面的插件基本相同,只是主要语言是英语,MO文件是wpse-393178-en-de_DE.mowpse-393178-en-fr_FR.mo.

      因此,我希望这有助于检查本地化工作是否正确,只需将您的网站或配置文件语言设置为与这些插件的主语言相反的语言,然后访问插件管理页面(位于wp-admin → 工具→ "E;WPSE 393178 DE/EN“)。(两个插件可以同时激活)

    SO网友:DevelJoe

    好吧,尽管我想感谢莎莉·CJ的努力;不幸的是,他/她的解决方案对我的输出没有任何影响。在稍微挖掘并通读之后this 发帖后,我现在可以为您提供这个解决方案,它很有魅力(您可以将此代码作为sperate文件集成到您的plugins includes/php文件夹中,至少对我有用。我已经添加了名称空间等。所以只需使用尚未使用的名称空间名称,您就可以开始了):

    <?php
    // This script is used for special actions related to translations / locales
    namespace YourNamespace;
    
    /*########################################################
    ##  TABLE OF CONTENTS                                   ##
    ##------------------------------------------------------##
    ##  1. Switch locale used for muplugin translations     ##                           
    ##------------------------------------------------------##
    ##  2. Reset locale used for muplugin translations      ##
    ########################################################*/
    
    if ( ! class_exists( \'YourNamespace\\LocalizationFeatures\' ) ) {
    
      class LocalizationFeatures {
    
         /*########################################################
        ##  1. Switch locale used for muplugin translations      ##
        #########################################################*/
    
        /**
         * If you\'re on a plugin\'s page with a loaded textdomain (let\'s say for
         * ex. english), and you want to retrieve translations from that plugins\'
         * .mo files accessed via __(), _e(), etc. in another language (e.g. es)
         * you cannot achieve this via switch_locale() if your translations were
         * actually defined via a given text domain. What has to be done in this
         * case is to reload the textdomain in the targeted language, to update 
         * global $l10n variable, which is used as resource for the gettext
         * translations wp retrieves.
         *
         * @param   string  $domain   text domain to be reloaded in the specified
         *                            target language
         *
         * @param   string  $locale   two-digit locale which determines to which
         *                            locale the function shall temp. switch;
         *                            one of:
         *
         *                            "de" (which switches to root locale)
         *                            "en" (which switches to locale en_GB)
         *                            "fr" (which switches to locale fr_FR)
         *                            "it" (which switches to locale it_IT)
         *                            "es" (which switches to locale es_ES)
         *                            "pt" (which switches to locale pt_PT)
         *
         * @param   mixed   value of global $l10n[{domain}] before the switch; false
         *                  if it was not set by then (which is the case if the page
         *                  was previously loaded in the website\'s default language)
         *                  ALWAYS REMEMBER TO RESET $l10n[{domain}] after executing
         *                  whatever needed to be executed after the switch!!! If it
         *                  was not set (i.e. if this value is false); make sure to
         *                  unset it again instead of reassigning it.
         *                  To facilitate this whole procedure, a second callback is
         *                  created; always to be called after the use of this one.
         */
    
        public static function switch_textdomain( $domain, $locale, $answer ) {
    
          // First of all, before switching, get the previous state of $l10n:
          global $l10n;
          $previous_language = isset( $l10n[$domain] ) ? $l10n[$domain] : false;
    
          // Next, if the target locale is the default language, there will be no
          // associated .mo - file to be loaded. To switch the textdomain being used
          // in this case, we have to remove the $l10n[$domain] from the $l10n array
          if ( $locale === "de" ) {
    
            unset( $l10n[$domain] );
    
          } else {
    
            // If the target locale is different from the default language; load the
            // according text domain
            $target_locale = "";
    
            switch ( $locale ) {
    
              case \'en\':
                $target_locale = "en_GB";
                break;
    
              case \'fr\':
                $target_locale = "fr_FR";
                break;
    
              case \'es\':
                $target_locale = "es_ES";
                break;
    
              case \'pt\':
                $target_locale = "pt_PT";
                break;
    
              case \'it\':
                $target_locale = "it_IT";
                break;
    
            }
    
            if ( ! load_textdomain(
              $domain,
              WPMU_PLUGIN_DIR . "/{$domain}/languages/{$domain}-{$target_locale}.mo"
            ) ) {
    
              // output error feedback you may want
    
            }
    
          }
    
          return $previous_language;
    
        } // end of switch_textdomain() function definition
    
        /*##########################################################################
        ##  2. Reset locale used for muplugin translations (after calling 1.)     ##
        ##########################################################################*/
    
        /**
         * This function is ALWAYS to be used after using self::switch_textdomain(),
         * to always reset the textdomain\'s language back to its previous state
         * before switching it; as soon as the wanted tasks have been executed.
         *
         * @param   string  $domain         concerned text domain
         * @param   mixed   $previous_l10n  state of global $l10n[$domain] b4 switch
         *                                  corresponds to return value of
         *                                  self::switch_textdomain()
         */
    
        public static function reset_textdomain( $domain, $previous_l10n ) {
    
          global $l10n;
    
          // If $previous_l10n is === false, this means that , before using
          // self::switch_textdomain(), the default language was being used, so to
          // reset it, we need to re-unset it, as it was set via
          // self::switch_textdomain()
          if ( $previous_l10n === false ) {
    
            unset( $l10n[$domain] );
    
          } else {
    
            // If it was previously set to something, reset it back to that
            $l10n[$domain] = $previous_l10n;
    
          }
    
        } // end of reset_textdomain() function definition
    
      } // end of LocalizationFeatures class definition
    
    } // loop which opens if there\'s currently no YourNamespace\\LocalizationFeatures class defined
    ?>
    
    
    请注意,我的代码适用于MU插件;但是您应该能够通过使用WP_PLUGIN_DIR 常量而不是WPMU_PLUGIN_DIR.

    我详细阐述了我的研究总结出的想法;如果有任何错误,请随时更正。我也可以只做一个函数1。在执行任何操作后(例如,使用传递给1的附加参数),将重置回以前的textdomain区域设置。这是一个回调*args 或者别的什么。这个设计更适合我这个项目的插件。

    UPDATE

    这个解决方案似乎并不完美;一旦您使用本地化页面更改管理用户的语言;当涉及到从服务器动态检索本地化时,情况变得非常糟糕。实际上,我可以在一个不使用脚本的环境中重现这个问题;这就是为什么我认为这可能是一个无关的问题,但也可能是相关的;我很困惑tbh。更多详情;请在此检查:Changing wp admin user's language does not update all of the plugin localizations in backend.

    相关推荐

    如何清理wp-content/plugins/wordpress-seo中不必要的文件?

    我目前维护Wordpress网站7年。磁盘使用率最近已满,因此我需要定期检查自动备份并保存这些备份,然后将其从服务器中删除。当我检查时,插件文件夹中的wordpress seo文件夹(这是Yoast seo默认插件文件夹)占用了太多空间。据我所知,它充满了各种版本的插件文件。确切地说,它位于wordpress seo插件的js/dist文件夹中。它包含几种类型的小型javascript,每个名称的末尾都有某种序列或版本号,总容量约为250-300 MB。我可以清理这些文件吗?如果是,是否安全?如果我从以前