use __($str) to translate strings (symfony/twig)

I have my own implementation of twig in WordPress as plugin and my translations are working. You can check my code.

Keep in mind couple of things when when you will test the code:

  • be sure that your WordPress have set locale which you want translate to
  • be sure that you your mo file is compiled from newest version of po file
  • be sure that your mo file exist and is loaded by load_plugin_textdomain function

You can debug which translation files WordPress are loading using script below.

function wpse_287988_debug_mofiles( $mofile, $domain ) {

    var_dump($mofile);

    return $mofile;
}

add_filter( 'load_textdomain_mofile', 'wpse_287988_debug_mofiles', 10, 2);

function wpse_287988_terminate() {
    die();
}

add_filter( 'wp_loaded', 'wpse_287988_terminate' );

Working twig implementation:

/**
 * Load composer autloader
 */
require_once dirname(__FILE__) . '/vendor/autoload.php';

// Main class

class WPSE_287988_Twig {

    /**
     * Templates path
     */
    private $templates_path;

    /**
     * Templates path
     */
    private $options;

    /**
     * Twig instance
     */
    private $twig;

    /**
     * Twig class constructor
     */
    public function __construct() {

        $this->templates_path = array();
        $this->options = array();

        $this->initialize_twig_options();
        $this->initialize_twig();
        $this->initialize_twig_functions();

        $this->define_hooks();
    }

    /**
     * Render method
     */
    public function render( $template, $variables = array() ) {

        return $this->twig->render( $template, $variables );
    }

    /**
     * Initialize twig options
     */
    private function initialize_twig_options() {

        /**
         * Resolve twig templates path
         */
        $plugins_dir = plugin_dir_path( __FILE__ );

        $this->templates_path[] = $plugins_dir;
        $this->templates_path[] = $plugins_dir . 'templates';

        foreach ($this->templates_path as $path) {

            if ( ! file_exists($path) ) {
                mkdir($path);
            }
        }

        /**
         * Resolve twig env options, disable cache
         */
        $this->options['cache'] = false;
    }

    /**
     * Initialize twig 
     */
    private function initialize_twig() {

        $loader       = new Twig_Loader_Filesystem( $this->templates_path );
        $this->twig   = new Twig_Environment($loader, $this->options );
    }

    /**
     * Initialize additional twig funcitons
     */
    public function initialize_twig_functions() {

        /**
         * Add gettext __ functions to twig functions.
         */
        $function = new Twig_Function('__', '__');

        $this->twig->addFunction($function);
    }

    /**
     * Load the plugin translations
     */
    public function load_plugins_textdomain() {

        $textdomain = 'wpse_287988';

        load_plugin_textdomain( $textdomain, false, basename( dirname( __FILE__ ) ) . '/languages' );
    }

    /**
     * Define hooks required by twig class
     */
    private function define_hooks()  {

        add_action( 'plugins_loaded', array( $this, 'load_plugins_textdomain' ) );
    }
}

// End of main class

// Initialize class

function wpse_287988_twig() {

    static $plugin;

    if ( isset( $plugin ) && $plugin instanceof WPSE_287988_Twig ) {
        return $plugin;
    }

    $plugin = new WPSE_287988_Twig();

    return $plugin;
}

wpse_287988_twig();

// End of class initialization

// Testing code

function wpse_287988_test_render() {

    $twig = wpse_287988_twig();
    echo $twig->render('template.html.twig');

    die();
}

add_action('init', 'wpse_287988_test_render');

// End of testing code

My template.html.twig file:

{% set text = "Foo" %}

{{ __(text, 'wpse_287988') }}

I keep my translations in languages directory in the main directory of my plugin. My translations files are named from textdomain and locale: wpse_287988-pl_PL.po and wpse_287988-pl_PL.mo.