|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
drbenway Smarty n00b
Joined: 11 Jul 2010 Posts: 2
|
Posted: Sun Jul 11, 2010 10:51 am Post subject: Suggested small change to the smarty core |
|
|
I've been working on some translation tools. One problem we had was that we had many templates that were not actually being used. To remedy this problem I wrote a prefilter that, while a page is being loaded, grabs all the translatable text from a template and saves it along with a modified version of the template. But in order for this to work I needed to know the name of the template. I made a modified version of Smarty.class.php which adds this information as two class members: resource_name and (if the resource is a file) resource_file.
I implemented this in an older version of smarty: 2.6.25.
Last edited by drbenway on Sun Jul 11, 2010 10:57 am; edited 2 times in total |
|
Back to top |
|
drbenway Smarty n00b
Joined: 11 Jul 2010 Posts: 2
|
Posted: Sun Jul 11, 2010 10:55 am Post subject: Example usage: prefilter.extract.php |
|
|
This prefilter extracts translatable text from a template and creates two files: a frame with text replaced by placeholders and a texts file with the removed texts.
Look for the reference to $smarty->resource_file towards the bottom
Code: |
cat prefilter.extract.php
<?php
/**
* extract texts from a template and save to a file ending .texts
* replace with an array reference and save the modified
* smarty to another file ending .frame
*/
function smarty_prefilter_extract($source,&$smarty) {
Texts::reset($smarty->resource_name);
$filtered = $source;
$filtered = preg_replace_callback(
'#(<?notrans>.*?</notrans)|((?:<?[^>]*>|^)\s*)([^<]+?)(\s*(?:</script|<|$))#is',
'__html_extract',
$filtered
);
$filtered = preg_replace_callback(
'#((?:title|alt)\s*=\s*")([^"]*)#is',
'__alt_extract',
$filtered
);
$filtered = preg_replace('#({\s*)include#is', "$1".'showframe', $filtered);
__save_filtered($filtered, $smarty);
return $source;
}
class Texts {
public static $res = '';
public static $strings = array();
public static $count = -1;
public static $index = 0;
public static $seen = array();
public static function reset($resource_name) {
self::$strings = array();
self::$seen = array();
self::$count = -1;
self::$index = 0;
self::$res = preg_replace(
'#\W+#',
"_",
$resource_name
);
}
public static function addString($string) {
if (!isset(self::$seen[$string])) {
self::$strings[++self::$count] = $string;
self::$index = self::$count;
self::$seen[$string] = self::$index;
} else {
self::$index = self::$seen[$string];
}
}
}
function __html_extract($matches) {
# ignore some areas deliberately
if (preg_match('#^notrans>#i',$matches[1])) return $matches[0];
# ignore javascript blocks
if (preg_match('#script#i',$matches[4])) return $matches[0];
$strings = __strip_strings($matches[3]);
$replaced = implode('',$strings);
return $matches[2].$replaced.$matches[4];
}
function __alt_extract($matches) {
$strings = __strip_strings($matches[2]);
$replaced = implode('',$strings);
return $matches[1].$replaced;
}
function __strip_strings($match) {
$i = 0;
$strings = array();
// separate out {} tags from text
foreach (str_split($match) as $c) {
if ($c == '{') {
if (count($strings)) $i++;
$strings[$i] .= $c;
} else if ($c == '}') {
$strings[$i] .= $c;
$i++;
} else $strings[$i] .= $c;
}
for ($i = 0; $i < count($strings); $i++) {
if (
preg_match('#(?:^|\s)\w|\w(?:\s|$)#',$strings[$i])
and !preg_match('#{#',$strings[$i])
and !preg_match('#{php}#',$strings[$i-1])
) {
# trim the whitespace but preserve it in the template
preg_match('#^(\s*)(.*?)(\s*)$#s',$strings[$i],$m);
Texts::addString($m[2]);
$strings[$i] = $m[1].'{$texts.'.Texts::$res.'['.Texts::$index.']}'.$m[3];
}
}
return $strings;
}
function __save_filtered($filtered, &$smarty) {
global $textfiles;
umask(octdec('0000'));
$path = $smarty->resource_file;
$path = preg_replace('#/templates/#','/frames/',$path);
$dir = dirname($path);
# if not check for the directory
if (!is_dir($dir)) {
if (!mkdir($dir)) die("can't make $path");
}
# always save the frame
file_put_contents(
"$path.frame",
$filtered
);
# generate a string representation of the array
$newtexts = var_export(Texts::$strings,true);
# put a key in the statement so we can amalgamate
# translations when we have more than one template
$r = Texts::$res;
$newtextscode = "<?php\n\$texts['$r'] = $newtexts;\n";
$savetexts = true;
# see if we've already processed this page before
$tfile = "$path.texts";
$textfiles[$tfile]++;
if (is_file($tfile)) {
$oldtextscode = file_get_contents($tfile);
if ($oldtextscode == $newtextscode)
$savetexts = false;
}
# save the texts only if they have changed
if ($savetexts) {
file_put_contents( $tfile, $newtextscode );
}
}
|
|
|
Back to top |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|