Content with Style

Web Technique

Quick helper script for ZF view translations

by Pascal Opitz on October 29 2009, 10:34

Manual copy and paste jobs are a pain. Faced with the prospect of internationalizing 30+ big view files, I thought there had to be a better way. When I started to use the reg exp search facility in Textmate, the penny dropped. A helper script is what was needed.

PHP cli script 'internationalize.php'


<?php
// check for CLI
if (php_sapi_name() != "cli") {
  print "This script is written to run under the command line ('cli') version of\n";
  print "the PHP interpreter, but you're using the '".php_sapi_name()."' version\n";
  exit(1);
}

// check for valid syntax
if(empty($argv[1])) {
  die('syntax: php internationalize.php <file> <optional token prefix>');
}


function get_key($str, $prefix) {
  $key = str_replace(' ', '_', strtolower($str));
  $key = preg_replace('/[\:\.\,\!\?]{0,}/', '', $key);
  $prefix = $GLOBALS['prefix'];
  return $prefix.$key;
}

function key_replace($matches) {
  if(trim($matches[2]) != "") {
    $key = get_key($matches[2]);
    return '<'.$matches[1].'><?php echo $this->translate->_("'.$key.'"); ?></'.$matches[3].'>';
  } else {
    return $matches[0];
  }
}


// get a prefix for the tokens
$prefix = (!empty($argv[2])) ? $argv[2] . '_' : '';

// identify and load file
$file = realpath($argv[1]);
$contents = file_get_contents($file);

// create backup file
copy($file, $file.'.bak');

// reg exp to find all text in between tags
$pattern = '/<([\w \=\%\"\(\)\'\:]+)>([\w\s\:\.\,\!\?_-]+)<\/([\w]+)>/';

// replace with translation calls
$translated = preg_replace_callback($pattern, 'key_replace', $contents);
file_put_contents($file, $translated);


// start generate ini file
$rows = array();
$matches = array();
preg_match_all($pattern, $contents, $matches);

for($i=0; $i<count($matches[1]); $i++) {
  if(trim($matches[2][$i]) != "") {
    $key = get_key($matches[2][$i]);
    $rows[] = $key.'="'.addslashes($matches[2][$i]).'"';
  }
}

$ini_string = implode("\n", $rows);
file_put_contents($file.'.translation.ini', $ini_string);

Example view file 'test.phtml'


<p>Fooo</p>

<blockquote style="test">Ich teste gerade</blockquote>

<ul>
  <li>Test list</li>
  <li>Test list  2</li>
</ul>

Translate it!

Now we're set. We just need to call:


php internationalize.php test.phtml

We end up with a this in test.phtml:


<p><?php echo $this->translate->_("fooo"); ?></p>

<blockquote style="test"><?php echo $this->translate->_("ich_teste_gerade"); ?></blockquote>

<ul>
  <li><?php echo $this->translate->_("test_list"); ?></li>
  <li><?php echo $this->translate->_("test_list__2"); ?></li>
</ul>

and this in test.phtml.translation.ini:


fooo="Fooo"
ich_teste_gerade="Ich teste gerade"
test_list="Test list"
test_list__2="Test list  2"

In progress

This is not meant as THE solution. It's merely a quick script I put together in a couple of minutes. There are a couple of things that it can't do, like translating attributes and all that.

I'm no reg exp guru, and if you can improve please feel free to comment. Otherwise, have fun.