Is there any way I can translate dynamic content in wordpress using .po files and e or _ functions?
I have all the static content translated but I would like to have dynamic content translated as well, wp_nav_menu, site header text etc.
I'm using poedit and that doesn't let me add any extra strings into the resource file so if you know how to get around that it would be nice as well.
Recently I have been using Polylang Plugin for WordPress. It gives you plain control over the website translation, from content to menus and strings translations. Best of all: most of your work will be done through WP Admin interface instead of php code.
You will can without plugin if you know the exactly word, like that
$translate = '';
$result = 'dynamical string need to be translate';
if ( $result == 'dynamical string need to be translate' ) {
$translate = __('dynamical string need to be translate', 'plugin');
}
if ( $result == 'other dynamical string' ) {
$translate = __('other dynamical string', 'plugin');
}
echo $translate;
Related
If I want to link to a cms page from a template with smarty, I currently use something like this:
{$link->getPageLink('cms',null,null,'id_cms=4')}
But that is going to generate a regular url (with query string), so if I activate pretty urls (url rewrite), it won't work. I analized the Link class but I can't find a way to generate a proper rewritten url. In fact, THERE IS a simple way:
{$link->getCMSLink(4)}
BUT, taking a look into Link::getCMSLink notes, I read that using an ID instead of a CMS object is deprecated. But from a template I don't have the cms object available.
Anyone had the same problem?
I found it really by "let's try if this one works".....
In PS1.6 you can get CMS object like:
$myCMS = new CMS( YOUR_CMS_ID );
If you want to use it in tpl, you have to define it in your controller e.g.:
$this->context->smarty->assign( "myCMS", $myCMS );
This is my solution. I recently tested it for Prestashop v1.6 and v1.7
This code utilizes the method getCMSLink of the Link class. It is necessary to know the id_cms of the CMS Page, to create the object model.
$link = new Link();
$cmsPageObject = new CMS(
$id_cms,
$id_lang
);
// $cmsLink has the URL string.
$cmsLink = $link->getCMSLink(
$cmsPageObject,
null,
Configuration::get("PS_SSL_ENABLED") === "1",
$id_lang,
null,
null
);
I'm wrapping up a project using Cakes internationalization features to allow our application to be translated into different languages. That's worked great.
A problem I've noticed though is there are a few places where text is added via JavaScript and this text does not currently come from the server at all. It's for things like dialogue boxes and a few pieces of text that change based on a users selection.
How have you handled this in your own applications? How would you handle this? Is there a library or component that handles this. What about any jQuery libraries?
You can also do it using JavaScript translation files with this format:
lang = {
no: "No",
yes: "Ja",
agreed: "Akkoord"
}
One file per language, for example: lang.nl.js, lang.es.js, lang.en.js...
Then, you can check the current language and, depending on it, load one or another file:
if($this->Session->read('Config.language') == 'es'){
$this->Html->script('lang.es', array('inline' => false));
}else{
$this->Html->script('lang.en', array('inline' => false));
}
And inside your javascripts, instead of using something like this:
alert("Yes");
You should use this:
alert(lang.yes);
And that's it :)
CakePHP does not have a built-in / standard way of localizing JavaScript. It does offer various ways to localize strings 'in general'. See Internationalization & Localization
To localize strings that are output by JavaScript, consider;
For 'static' strings (i.e. strings that are not depending on the content of your website), create localization files for your scripts.
Many plugins use this approach
For example, see this page on localizing the JQuery-UI date picker UI/Datepicker/Localization
If you're already localizing strings in your website via .po files, and want to use the same translations in your JavaScript, you may consider to dynamically create the translation-files as mentioned in 1.), for example;
In your app/Config/routes.php, enable parsextensions, see File Extensions
Router::parseExtensions('json');
Create a controller that will output strings localized as JavaScript/JSON
http://example.com/localized/strings/eng.json
class LocalizedController extends AppController {
public function strings($lang)
{
if('json' !== $this->request->ext) {
throw new NotFoundException();
}
// Switch to the requested language
Configure::write('Config.language', $lang);
$strings = array(
'hello',
'world',
);
//translated the strings
$translations = array();
foreach ($strings as $string) {
$translations[$string] = __($string);
}
// build and send a JSON response
$this->autoRender = false;
$this->response->type('json');
$this->response->body(json_encode($translations));
return $this->response;
}
}
This json file should now be accessible via http://example.com/localized/strings/eng.json and can be loaded from within your javascripts at runtime
note
Just to clarify; the example is untested and just to illustrate the idea of dynamically creating JSON (or JavaScript) files containing localized strings. The code is far from efficient and (at least part of) the code should not be inside the controller, but (for example) inside a model.
For translating JavaScript inside my CakePHP applications, I use this library : https://github.com/wikimedia/jquery.i18n , it's the one used in Wikipedia.
You have all the necessary files inside the src folder. It's quite easy to set up and use. Of course it works with any kind of application, not only CakePHP !
Here's a solution i'm using for cakePHP 3 :
in your layout file ( mine is default.ctp ) :
if( isset( $translated_js ) && !empty( $translated_js ) ){
$this->Html->scriptStart($block_render);
echo "var translated_js = " . json_encode( $translated_js ) . ";";
$this->Html->scriptEnd();
}
Now in any controller add a beforeRender method :
public function beforeRender(Event $event){
parent::beforeRender( $event );
$translated_js = [
'reinit_map' => __('Reinit map to default'),
];
$this->set( 'translated_js' , $translated_js );
}
This way you can use the gettext instructions.
In your JS files you can now use the translated eelements this way :
translated_js.reinit_map
Hope it helps someone searching a way to translate texts and pass to JS
I had the same problem like you and i found this link very helpful: http://jamnite.blogspot.de/2009/05/cakephp-form-validation-with-ajax-using.html
It's not up to date, but the main principle should be clear.
Checkout this CakePHP plugin: https://github.com/wvdongen/CakePHP-I18nJs
It uses the functionality of Drupal 8 JavaScript translations. It has CakePHP console functions to generate .po file(s) (exactly as you're used with Cake), and to generate your translated .po files to JavaScript.
I use a more straightforward method. ( I do not know if it is the best, but it works ).
Inside the template file I define a series of hidden fields with the messages that js might need.
echo( $this->Form->hidden( 'msg-select-promotion-items', [ 'value' => __( 'Select promotion items' ) ] ) );
Here we take advantage of cake's own localization system.
And then in the js file :
alert( $('input[name=msg-select-promotion-items]').val() );
Hope this helps.
Regards.
Facundo.
I took the easier path:
alert( "<?php echo __('This is my translated string'); ?>" )
This way you can keep all translations in a single place: the .po file
I have been using zend translate to translate the site content but what about the urls? How could I translate it?
Ex.:
localhost/app/contact (English)
localhost/app/contato (Portuguese)
If you are indeed using Zend Translate you should be able to use translations in your router like:
routes.someroute.route = "/:langparam/#translateme"
routes.someroute.defaults.module = public
routes.someroute.defaults.controller = page
routes.someroute.defaults.action = show
If your translation source contains 'translateme' it wil be translated, if not the router will use 'translateme' as value.
Is is possible to display (via php) the main menu of a Drupal 6.20 site in a WordPress theme template file located in a subdirectory on the same domain?
Right now, I'm displaying the menu by copying the static html from the Drupal site and adding it to header.php in the WordPress template in the site located in mydomain.com/blog/. But of course that's not going to work when another menu item is added to the Drupal site, or the Drupal menu is changed in any way.
So is there a Drupal php function that will pull the menu into the WP file?
Failing that, is there a way with php to parse a Drupal page for the html of the menu (yes, this would be ugly) and display it in WP?
The first part of the challenge is to output only the menu, with as little (or none) of the surrounding HTML as possible, so you have as little work to do in parsing the HTML as possible.
The second part is to take that output from Drupal and actually display it on your WordPress site.
You could add the Drupal database as a secondary database in WordPress using the a new instance of the $wpdb object, write the query to get the right content from the tables, and format the results. That could work, but might be overkill.
An alternative workable option may be to use JSON to format the output of the primary links, using the drupal_json function in Drupal, then consume the JSON feed in Wordpress.
I'm assuming:
you have admin access to login to the Drupal site, which you'll need to create nodes, and clear the theme cache
you want to output the Primary Links menu, which 90%+ of Drupal sites use. This is probably true, but it is possible your site uses custom menus. If so, this is still possible, you'd just write slightly different code in step 3.
The steps would be:
Create a Drupal node (you can call it anything, it's just a placeholder)
Get the node id of your dummy page (ie., node/234). From the node id, create a one-off page template in your Drupal site's themes folder. It should be called page-node-xxxx.tpl.php, with xxxx being your node id
Add this code to page-node-xxxx.tpl.php:
<?php
drupal_json(menu_navigation_links(variable_get('menu_primary_links_source', 'primary-links')));
?>
This will create a JSON feed of your menu items.
Clear the theme cache of your Drupal site by visiting http://yoursite.com/admin/build/themes and visit http://yoursite.com/node/xxxx to see the raw JSON feed.
You should now be able to use a jQuery method like $.getJSON or $.ajax in your Wordpress theme to consume and display the JSON feed, or possibly use json_decode and curl to output your array as HTML.
A good thing about Drupal's drupal_json function is that it already sends the correct JSON headers, so now all you have to do is write the jQuery or PHP that does what you need.
I'm assumed you are more of a Wordpress specialist and have a working knowledge of Drupal but maybe not a lot of familiarity with its inner workings. So, sorry if it seemed too basic (or not basic enough :).
The Drupal theming engine is very modular - you may be able to make an appropriate PHP call into Drupal to get just the menu rendered, then emit that HTML as a part of your WordPress page.
g_thom's answer is very good and if you wish to create a very simple module to output the main navigation you can write something like this:
<?php
function getmenus_help($path, $arg) {
// implementing the help hook ... well, not doing anything with it just now actually
}
function getmenus_all() {
$page_content = '';
$page_content = json_encode(menu_navigation_links(variable_get('menu_primary_links_source', 'primary-links')));
// fill $page_content with the menu html
print $page_content;
return NULL;
}
function getmenus_menu() {
$items = array();
$items['getmenus'] = array(
'title' => 'Get Menus',
'page callback' => 'getmenus_all',
'access arguments' => array('access getmenus'),
'type' => MENU_CALLBACK,
);
return $items;
}
// permissions
function getmenus_perm() {
return array('access getmenus');
}
In your PHP code you can then write something like:
function primary_links() {
$primary_links = file_get_contents(SITE_URL . '/getmenus');
$primary_links = json_decode($primary_links);
$primary_links = (array)$primary_links;
$i = 0;
$last = count($primary_links);
$output = '';
foreach ($primary_links as $pm) {
$href = $pm->href;
if (strpos($pm->href, 'http://') === FALSE) {
if ($pm->href == '<front>') {
$href = SITE_URL . '/';
} else {
$href = SITE_URL . '/' . $pm->href;
}
}
$output .= '
<li>
'.$pm->title.'</li>';
$i++;
}
return $output;
}
I hope this helps!
PS: Make sure you update the module's permissions to allow anonymous users to have access to the path you set in your module - otherwise you will get a 403 Permission Denied.
Ok for sure this has been asked and answered already but i somehow can't find a proper tutorial.
I want to keep the text displayed to users somewhere else and to prevent my code from becoming too large and unreadable.
My site won't be internationalized. I just want to have some kind of file with key-value structure and get the text from there. I want to keep the text in files, not in the database as some tutorials suggest.
I found a solution which will work but i am not sure whether this is a good approach.
I am thinking of using parse_ini_file and to keep my texts in .ini file. Is there something wrong with this approach? Could you suggest something better?
I put all language data in arrays. Its easy and also we can add multi-language support
lang/en.php
<?php
return array(
'index' => 'Homepage',
'feedback' => 'Feedback'
'logout' => 'Logout from profile',
)
?>
lang/ru.php
<?php
return array(
'logout' => 'Выйти из профиля',
)
?>
Then we can load languages:
$lang = include('lang/en.php');
if(isset($_GET['lang']))
{
$lang = array_merge($lang, include('lang/ru.php'));
}
After all it $lang will look like:
Array
(
[index] => Homepage
[feedback] => Feedback
[logout] => Выйти из профиля
)
And we can very simple use it:
function __($name) {
global $lang;
return $lang[$name];
}
Somewhere in the site template:
...
<title><?=__('index')?></title>
</head>
<body>
<?=__('feedback')?>
why not use a plain text file with commas or some uncommon character to hold this data? you can read it and parse it into an array with
$file = file_get_contents("/path/to/file");
$lines = explode('\r', $file);
foreach($lines as $line) $message[substr($line, 0, strpos($line, ','))] = substr($line, strpos($line, ','));
then you should have an array like $messages[3] = "No soup for you!";
the file might look like:
1,The site is down.
2,Try again.
3,No soup for you!
4,Signs point to yes.
(I probably have some of the arguments misplaced in those functions - i always forget which is the needle and which the haystack.)
You can process your data in a script. In this script, you call a certain source (e.g. the ini file you suggest). Then you use a template engine. For this engine, you point towards a template file and give the template all the variables.
The template generates the html and inserts the variables at the right place. This way, you keep you php (business logic) code clean, away from the presentation (the template). Also you can manage the variables in one file (ini/xml but this can be something completely different).
For template engines, Smarty is the most known of all. There are also pure php-based template systems, just Google for them to find one that suits your needs.
I do like this:
$defaultLang = array('Home','Logout',etc)
$otherLang=array( 'ru' => array('Home_in_ru','logout_in_ru',etc);
you translate like this:
echo translate('Home');
function is:
function translate($msg) {
if ($_GET['lang']=='en')
return $msg;
return $otherLang[$_GET['lang']][array_search($msg,$defaultLang)];
}
// Note the function is simplified up there
As you can see the default case deosnt' need to load anything or do any operation, the function just returns back the argument passed
i like the answer with the lang/en.php file. but instead of a file for each language, i use a file for each web page (or class, etc). this keeps file sizes lower and i create a 3D array:
`return array( "EN" => array( "title" => "Welcome - Good Morning", ...),
"TG" => array( "title" => "Mabuhay - Magandang Umaga Po", ...)
);'
Real easy to add new language strings too...
This makes it real easy for language translation contractors since they can see the native language in close proximity to the foreign in 1 editor,,,