Localization of Blade templates

Hi there,

How can we translate template strings with Blade? Looks like <?php ?> tags are needed. Neither WPML or PoEdit find my strings when written like this: {{__('string', 'domain')}}.

Thanks in advance.


Just use <?php ?> tags. ¯\_(ツ)_/¯

Edit: I should clarify that I have no experience with localization, but if using <?php ?> works, then just do that. You can use normal <?php ?> tags in .blade.php files.


Another option should be to put your data in the top of the view (or somewhere else) inside <?php ?> tags and then echo variables using {{}}? Good question - try it out and let us know how it goes.

1 Like

Thanks for bringing this up. Reported issue: https://github.com/roots/sage/issues/1875



Too bad we have to use workarounds like these, Blade templates loose their interest if our files become obfuscated again. That being said, I can confirm that <?php _e('...', '...') ?> is correctly seen by PoEdit in .blade.php files.

I followed this guide but couldn’t get it to work without the workaround above though: http://framework.themosis.com/docs/master/blade/ (end of page).

My clients translate their website themselves, so I’d like to be able to use WPML plugins to translate strings in the WP admin for instance. Did anyone figure it out? Doesn’t seem to work at all here, the “scanning in templates” button spins forever (XHR timeout, no change in PHP config helped).

I think it’s a important tradeoff that should be noted somewhere in the Sage 9 readme. If I can’t find a simple solution, it could question my choice of using Sage for future multilingual projects…


I managed to get it working with those instructions!


By default, Poedit cannot find strings to translate from Blade templates. Here is a list of parameters to add to your Poedit software preferences so it can detect translation strings from your Blade views:

  1. Open Poedit
  2. Go to Preferences -> Extractors
  3. Add a new Extractor with following settings:
    • Language: Blade
    • Extension: *.scout.php, *.blade.php
    • Parser command: xgettext --language=Python --add-comments=TRANSLATORS --force-po -o %o %C %K %F
    • An item in keyword list: -k%k
    • An item in input files list: %f
    • Source code charset: --from-code=%c
  4. Click Ok

In order for this to work, you must have a poedit project correctly setup pointing to the languages folder of either your theme or custom plugin and define the gettext methods and resources base path. From the catalog preferences, set the sources paths like so:

  • Base path: sage theme folder
  • Paths:
    • .
  • Excluded Paths:
    • node_modules/
    • vendor/
    • resources/assets/

as well as adding the following gettext methods to the source keywords catalog tab:

  • __
  • _e
  • _x
  • esc_html__
  • esc_html_e
  • _n
  • _nx
  • _n_noop
  • _nx_noop
  • _ex

and more if needed.


Many thanks for the Poedit setup guide.

In my case I have to set resources/ directory as a root probably because it is now the theme root folder (where style.css is placed).
Because of that the directory with translations langs/ also has to be placed inside resources/.

I was using Sage 9.0.0-beta.4.

I finally created a script in package.json:

"pot": "mkdir -p ./lang && find ./templates -iname \"*.php\" | xargs xgettext --language=Python --add-comments=TRANSLATORS --force-po --from-code=UTF-8 --default-domain=yourdomain -k__ -k_e -k_n -k_x -k_ex -k_nx -kesc_attr__ -kesc_attr_e -kesc_attr_x -kesc_html__ -kesc_html_e -kesc_html_x -k_n_noop -k_nx_noop -o ./lang/yourtheme.pot"

So a .pot file is generated, and you can use it in Poedit, then generate the .mo/.po files in /wp-content/languages/themes/nameOfYourTheme.mo. That way I’m sure WPML find it… Tried different folders, it sometimes fails to use the translation files…

The only issue left is that __() functions won’t be seen in HTML attributes, like <a href="..." title="{{__('title')}}"></a>. So you have to duplicate it anywhere: {{-- __('title') --}} to force it.

More infos here: https://github.com/roots/sage/issues/1875#issuecomment-305179782 (and following comments).


The pot build command created a new directory ./resources/lang/ with sage.pot inside.
I downloaded language files from the https://github.com/roots/sage-translations repository
and placed it in same ./resources/lang/ folder. However, the sage9 related strings are still not translated.

Edit: Also saved a new translation using the generated sage.pot as template,
but the resulting .po isn’t used by the site either.

I think there’s a misunderstanding here. We were trying to get strings from our own custom theme (written in Blade) translated. We were not trying to get official Sage translations into WordPress. The .pot file created by this NPM script is meant to be a base to create .po and .mo files in a specific language. A .pot file doesn’t contain any translation in itself.

Speaking of this, I recently tried Polylang as a replacement for WPML, and it works like a charm with this plugin! Just replace __() by pll__() and strings in Blade files will appear in the admin.


@nicooprat: Any success with installing the official sage translation files?
I tried different directories, but the translations for sage translation domain are not loaded.

Sorry, never tried, but I think it’s better to keep this issue in its separate thread “Install sage9 language files?”.

Unfortunately, this is still a big problem, and I feel so bad it’s not fully addressed yet :frowning:

In my case I cannot force it to work with wp-cli: wp i18n make-pot wp cli docs

I tried anything including --include flag pointing to theme folder manually. All strings in blade views are ignored.

Using <?php and ?> all the time makes no sense as avoiding such thing is one of the main reasons for using blade.

I saw this issue on GitHub Translation tools aren't picking up strings in templates · Issue #1875 · roots/sage · GitHub and I need to highly disagree with one of the comments:

I do not think this issue should be resolved on Sage level but rather on the translation tools themselves.

It’s silly to think that all tools, which are all working the same. will change because it’s not working in one product.

I use Loco Translate and scan the generated .php files in uploads/cache. This is achieved by configuring the Source file path to ../../../uploads/cache. This plugin will hold your hand and create the .pot file and .po and .mo files for each language you set up.

1 Like

Never thought about it. Sure, using compiled .php files in cache should work yeah!