Jump to content

Using translatable strings across template files


Webrocker
 Share

Recommended Posts

@tpr I must have missed your message but have came to the same result while inspecting the _init.php and _strings.php

I've added the php opening and the page looks OK.

Now I got another issue - when I try to browse another page (other than home) I get this error: 

 Call to undefined function _t(), did you mean _()?  

I tripple checked and yes, my _init.php contains:

// Shared functions
include_once("./_func.php");

// Translation strings
include_once("./_strings.php");

I checked my config.php file to make sure _init.php is prepended and it is:

$config->prependTemplateFile = '_init.php';

My _func.php contains:

<?php namespace ProcessWire;

//_strings.php function call
function _t($text, $context = 'General', $textdomain = '/site/templates/_strings.php') {
    return _x($text, $context, $textdomain);
}

And my _strings.php file contains;

<?php

/******************************************* 
Intentionally commented out

// Footer.php
_x('CONTACT INFO', 'General');
_x('COMPANY LINKS', 'General');
_x('ABOUT US', 'General');

// About.php
_x('OUR HISTORY & FACTS', 'General');
_x('LEADER IN THE REAL ESTATE MARKET SALES SINCE', 'General');
_x('GET A QOUTE', 'General');

//Services.php
_x('Our Services', 'General');

*******************************************/

The call of the function in the markup is like this:

<?php echo _t('ABOUT US');?>

The thing I don't understand is how come the same call in home template works fine for footer but not for other templates.. Something I am missing but what it is... That is the question :)

P.S. If I use __('blabla') - it works fine, but am trying to centralize the translation and avoid repetetive phrases etc.

 

Link to comment
Share on other sites

5 minutes ago, tpr said:

Has the footer php namespace ProcessWire in the first line?

Nope. As far as I am using direct output, footer.php is just some html markup with php code inserted where needed. Tried adding it, but still see the same error like _t function is not declared...

Link to comment
Share on other sites

@tpr Adding your code to _init.php fixed the error. The strange thing is that my _strings.php is located in the same folder as _init.php (/templates/) and I guess it must have had the correct path if the footer was working but strange thing happened and now everything seems to be fine.

I tried to change the include code to this: include_once("_strings.php"); and it also worked fine. Seems like the trailing slash was messing up the things. 

Thank you very-very-very much, again!

P.S. What is strange enough, after changing the code to your suggestion and then reverting it back to the standard include:

// Shared functions
include_once("./_func.php");

// Translation strings
include_once("./_strings.php");

made the site working just fine. As far as there is no cache enabled on templates, is it possible that I had to take some steps after changing the path to _strings.php from /templates/languages/ to just /templates/ ?

Link to comment
Share on other sites

Thanks to @tpr and @ryan I have played a bit with the translation and singular/pluriel and made them working with HTML code inside while using a single file holding all translations and the content of it being commented.

Here are the functions I am using that need to simply be added to _func.php (or other file used for calling the custom functions and included_once in _init.php):

<?php namespace ProcessWire;

/**
 * /site/templates/_func.php
 * 
 * This file is currently included by _init.php 
 * Which on the other side is prepended in config.php
 *
 */

// _strings.php function call
// Example: echo translate('text_string');
// Make sure to add the translation in Setup>Languages>LANGUAGE_NAME 
function translate($text, $context = 'General', $textdomain = '/site/templates/_strings.php') {
    return html_entity_decode(_x($text, $context, $textdomain));
}

// Singular/plural nouns iteration
// Example:  echo pluriel('<i> year</i>', '<b> years</b>', 2)
// Make sure to add the translation in Setup>Languages>LANGUAGE_NAME with the HTML in it (as needed)
function pluriel($singular, $plural, $count) {
    return html_entity_decode(translate(_n($singular, $plural, $count)));
}

Now I can have some complex language strings containing html code and would avoid splitting the translation lines to chunks etc.

<?php echo translate('Made with <i style="color: #FF0000;" class="fa fa-heart"></i> by <a href="http://processwire.com">ProcessWire</a>') . " - 11 " . pluriel('<i> year</i>', '<b> years</b> ago', 11) . "</a>"; ?>

by simply adding the following line to my _strings.php:

_x('Made with <i style="color: #FF0000;" class="fa fa-heart"></i> by <a href="http://processwire.com">ProcessWire</a>') . " - 11 " . pluriel('<i> year</i>', '<b> years</b> ago', 11) . "</a>"', 'General');

How cool is that ;)

Link to comment
Share on other sites

Hey guys, seems like my joy was not that long.. As soon as I started working the inner pages of my project I noticed that the function translate('smth' , 'General') is giving me the error I've seen previously: Call to undefined function translate()

Having reviewed my posts previously, I dully noted that I forgot to add the <?php namespace ProcessWire;  at the beginning of my inner pages templates. So if you happen to fall in my situation, make sure to have your namespace set to avoid my early morning big eyes ;)

Link to comment
Share on other sites

@MilenKo    For interfaces (buttons, short strings, etc)  this is what we do,  I am not saying either way is better just different way of doing this.

## _languages.php

$lang_strings = array(
	'home_button' => array(
		'en'=>'Home',
		'fr'=>'Acceuil',
	),
	'about_button' => array(
		'en'=>'About',
		'fr'=>'Apropos',
	),
	'links_button' => array(
		'en'=>'Links',
		'fr'=>'Liens',
	),
);

## _func.php

function userLang($lang){
	switch($lang){
		case 'fr':
			$lang = 'fr';
			break;
		default:
			$lang = 'en';
	}
	return $lang;
}

## _main.php

$lang = userLang($user->language->name);

<nav>
	<div><a href="#"><?= $lang_strings['home_button'][$lang]; ?></a></div>
	<div><a href="#"><?= $lang_strings['about_button'][$lang]; ?></a></div>
	<div><a href="#"><?= $lang_strings['links_button'][$lang]; ?></a></div>
</nav>

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

@tpr Thank you for that helpful info. I am still learning project after project.

@neosin Thank you for the alternative solution as well. For sure I could use it for some other projects, but in this one the idea was to provide an easy way to my friend to edit the translations without asking me to mess with the code once the project is finished.

This is what I love in ProcessWire - the elasticity of accomplishing the things in so many different ways - where the sky is the limit and it is up to the devs to decide which way to get the things done.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...