Библиотека для cis, online, cms1

This commit is contained in:
Фёдор Подлеснов 2016-06-29 18:51:32 +03:00
commit 3c2e614d87
269 changed files with 39854 additions and 0 deletions

View file

@ -0,0 +1,107 @@
<?php
require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php';
// i18n:attributes
//
// This attribute will allow us to translate attributes of HTML tags, such
// as the alt attribute in the img tag. The i18n:attributes attribute
// specifies a list of attributes to be translated with optional message
// IDs? for each; if multiple attribute names are given, they must be
// separated by semi-colons. Message IDs? used in this context must not
// include whitespace.
//
// Note that the value of the particular attributes come either from the
// HTML attribute value itself or from the data inserted by tal:attributes.
//
// If an attibute is to be both computed using tal:attributes and translated,
// the translation service is passed the result of the TALES expression for
// that attribute.
//
// An example:
//
// <img src="http://foo.com/logo" alt="Visit us"
// tal:attributes="alt here/greeting"
// i18n:attributes="alt"
// />
//
//
// In this example, let tal:attributes set the value of the alt attribute to
// the text "Stop by for a visit!". This text will be passed to the
// translation service, which uses the result of language negotiation to
// translate "Stop by for a visit!" into the requested language. The example
// text in the template, "Visit us", will simply be discarded.
//
// Another example, with explicit message IDs:
//
// <img src="../icons/uparrow.png" alt="Up"
// i18n:attributes="src up-arrow-icon; alt up-arrow-alttext"
// >
//
// Here, the message ID up-arrow-icon will be used to generate the link to
// an icon image file, and the message ID up-arrow-alttext will be used for
// the "alt" text.
//
/**
* @package phptal.php.attribute
*/
class PHPTAL_Php_Attribute_I18N_Attributes extends PHPTAL_Php_Attribute
{
public function start()
{
// split attributes to translate
$expressions = $this->tag->generator->splitExpression($this->expression);
// foreach attribute
foreach ($expressions as $exp){
list($attribute, $key) = $this->parseSetExpression($exp);
// if the translation key is specified
if ($key != null){
// we use it and replace the tag attribute with the result of
// the translation
$key = str_replace('\'', '\\\'', $key);
$this->tag->attributes[$attribute] = $this->_getTranslationCode("'$key'");
}
else if ($this->tag->isOverwrittenAttribute($attribute)){
$varn = $this->tag->getOverwrittenAttributeVarName($attribute);
$this->tag->attributes[$attribute] = $this->_getTranslationCode($varn);
}
// else if the attribute has a default value
else if ($this->tag->hasAttribute($attribute)){
// we use this default value as the translation key
$key = $this->tag->getAttribute($attribute);
$key = str_replace('\'', '\\\'', $key);
$this->tag->attributes[$attribute] = $this->_getTranslationCode("'$key'");
}
else {
// unable to translate the attribute
throw new PHPTAL_Exception("Unable to translate attribute $attribute");
}
}
}
public function end()
{
}
private function _getTranslationCode($key)
{
$code = '<?php ';
if (preg_match_all('/\$\{(.*?)\}/', $key, $m)){
array_shift($m);
$m = array_shift($m);
foreach ($m as $name){
$code .= "\n".'$_translator->setVar(\''.$name.'\','.phptal_tale($name).');'; // allow more complex TAL expressions
}
$code .= "\n";
}
// notice the false boolean which indicate that the html is escaped
// elsewhere looks like an hack doesn't it ? :)
$result = $this->tag->generator->escapeCode(sprintf('$_translator->translate(%s, false)', $key));
$code .= 'echo '.$result.'?>';
return $code;
}
}
?>

View file

@ -0,0 +1,24 @@
<?php
require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php';
// i18n:data
//
// Since TAL always returns strings, we need a way in ZPT to translate
// objects, the most obvious case being DateTime objects. The data attribute
// will allow us to specify such an object, and i18n:translate will provide
// us with a legal format string for that object. If data is used,
// i18n:translate must be used to give an explicit message ID, rather than
// relying on a message ID computed from the content.
//
/**
* @package phptal.php.attribute.i18n
*/
class PHPTAL_Php_Attribute_I18N_Data extends PHPTAL_Php_Attribute
{
public function start(){}
public function end(){}
}
?>

View file

@ -0,0 +1,41 @@
<?php
require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php';
// i18n:domain
//
// The i18n:domain attribute is used to specify the domain to be used to get
// the translation. If not specified, the translation services will use a
// default domain. The value of the attribute is used directly; it is not
// a TALES expression.
//
/**
* @package phptal.php.attribute.i18n
*/
class PHPTAL_Php_Attribute_I18N_Domain extends PHPTAL_Php_Attribute
{
public function start()
{
// ensure a domain stack exists or create it
$this->tag->generator->doIf('!isset($__i18n_domains)');
$this->tag->generator->pushCode('$__i18n_domains = array()');
$this->tag->generator->doEnd();
//\''.str_replace(array('\\',"'"),array('\\\\',"\\'"),$expression).'\'
$expression = $this->tag->generator->interpolateTalesVarsInString($this->expression);
// push current domain and use new domain
$code = '$__i18n_domains[] = $_translator->useDomain('.$expression.')';
$this->tag->generator->pushCode($code);
}
public function end()
{
// restore domain
$code = '$_translator->useDomain(array_pop($__i18n_domains))';
$this->tag->generator->pushCode($code);
}
}
?>

View file

@ -0,0 +1,40 @@
<?php
require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php';
// i18n:name
//
// Name the content of the current element for use in interpolation within
// translated content. This allows a replaceable component in content to be
// re-ordered by translation. For example:
//
// <span i18n:translate=''>
// <span tal:replace='here/name' i18n:name='name' /> was born in
// <span tal:replace='here/country_of_birth' i18n:name='country' />.
// </span>
//
// would cause this text to be passed to the translation service:
//
// "${name} was born in ${country}."
//
/**
* @package phptal.php.attribute.i18n
*/
class PHPTAL_Php_Attribute_I18N_Name extends PHPTAL_Php_Attribute
{
public function start()
{
$this->tag->generator->pushCode('ob_start()');
}
public function end()
{
$code = '$_translator->setVar(\'%s\', ob_get_contents())';
$code = sprintf($code, $this->expression);
$this->tag->generator->pushCode($code);
$this->tag->generator->pushCode('ob_end_clean()');
}
}
?>

View file

@ -0,0 +1,38 @@
<?php
require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php';
// i18n:source
//
// The i18n:source attribute specifies the language of the text to be
// translated. The default is "nothing", which means we don't provide
// this information to the translation services.
//
/**
* @package phptal.php.attribute.i18n
*/
class PHPTAL_Php_Attribute_I18N_Source extends PHPTAL_Php_Attribute
{
public function start()
{
// ensure that a sources stack exists or create it
$this->tag->generator->doIf('!isset($__i18n_sources)');
$this->tag->generator->pushCode('$__i18n_sources = array()');
$this->tag->generator->end();
// push current source and use new one
$code = '$__i18n_sources[] = $_translator->setSource(\'%s\')';
$code = sprintf($code, $this->expression);
$this->tag->generator->pushCode($code);
}
public function end()
{
// restore source
$code = '$_translator->setSource(array_pop($__i18n_sources))';
$this->tag->generator->pushCode($code);
}
}
?>

View file

@ -0,0 +1,32 @@
<?php
require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php';
// i18n:target
//
// The i18n:target attribute specifies the language of the translation we
// want to get. If the value is "default", the language negotiation services
// will be used to choose the destination language. If the value is
// "nothing", no translation will be performed; this can be used to suppress
// translation within a larger translated unit. Any other value must be a
// language code.
//
// The attribute value is a TALES expression; the result of evaluating the
// expression is the language code or one of the reserved values.
//
// Note that i18n:target is primarily used for hints to text extraction
// tools and translation teams. If you had some text that should only be
// translated to e.g. German, then it probably shouldn't be wrapped in an
// i18n:translate span.
//
/**
* @package phptal.php.attribute.i18n
*/
class PHPTAL_Php_Attribute_I18N_Target extends PHPTAL_Php_Attribute
{
public function start(){}
public function end(){}
}
?>

View file

@ -0,0 +1,97 @@
<?php
require_once PHPTAL_DIR.'PHPTAL/Php/Attribute.php';
// ZPTInternationalizationSupport
//
// i18n:translate
//
// This attribute is used to mark units of text for translation. If this
// attribute is specified with an empty string as the value, the message ID
// is computed from the content of the element bearing this attribute.
// Otherwise, the value of the element gives the message ID.
//
/**
* @package phptal.php.attribute.i18n
*/
class PHPTAL_Php_Attribute_I18N_Translate extends PHPTAL_Php_Attribute
{
public function start()
{
$escape = true;
if (preg_match('/^(text|structure)(?:\s+(.*)|\s*$)/',$this->expression,$m))
{
if ($m[1]=='structure') $escape=false;
$this->expression = isset($m[2])?$m[2]:'';
}
// if no expression is given, the content of the node is used as
// a translation key
if (strlen(trim($this->expression)) == 0){
$key = $this->_getTranslationKey($this->tag, !$escape);
$key = trim(preg_replace('/\s+/sm'.($this->tag->generator->getEncoding()=='UTF-8'?'u':''), ' ', $key));
$code = '\'' . str_replace('\'', '\\\'', $key) . '\'';
}
else {
$code = $this->tag->generator->evaluateExpression($this->expression);
}
$this->_prepareNames($this->tag);
$php = sprintf('echo $_translator->translate(%s,%s);', $code, $escape ? 'true':'false');
$this->tag->generator->pushCode($php);
}
public function end()
{
}
private function _getTranslationKey($tag, $preserve_tags)
{
$result = '';
foreach ($tag->children as $child){
if ($child instanceOf PHPTAL_Php_Text){
$result .= $child->node->getValue();
}
else if ($child instanceOf PHPTAL_Php_Element){
if ($child->hasAttribute('i18n:name')){
$value = $child->getAttribute('i18n:name');
$result .= '${' . $value . '}';
}
else {
if ($preserve_tags)
{
$result .= '<'.$child->name;
foreach($child->attributes as $k => $v)
{
$result .= ' '.$k.'="'.$v.'"';
}
$result .= '>'.$this->_getTranslationKey($child, $preserve_tags).'</'.$child->name.'>';
}
else
{
$result .= $this->_getTranslationKey($child, $preserve_tags);
}
}
}
}
return $result;
}
private function _prepareNames($tag)
{
foreach ($tag->children as $child){
if ($child instanceOf PHPTAL_Php_Element){
if ($child->hasAttribute('i18n:name')){
$child->generate();
}
else {
$this->_prepareNames($child);
}
}
}
}
}
?>