Как использовать $this->_() в представлениях Zend Framework?
В моем приложении ZF 1.11 мой переводчик хранится в реестре следующим образом:
Zend_Registry::set('Zend_Translate', $translator);
Так что в моих скриптах просмотра я могу получить доступ к переводчику следующим образом:
$this->translate('abc');
Есть ли какой-нибудь умный способ использовать этот вызов вместо этого:
$this->_('abc');
Использование $this->translate запутывает представления, и многие люди все равно видят _().
2 ответа
В то время как я в целом согласен с понятием, что имена функций / методов должны быть осмысленными, я также согласен с тем, что _()
для переводов является широко используемым стандартом и, следовательно, приемлемым.
Вы можете сделать это, добавив оболочки к промежуточным слоям. Например, следующее сделает метод доступным для всех ваших контроллеров, полученных из MyProject_Controller_Action
:
class MyProject_Controller_Action extends Zend_Controller_Action
{
protected $translator;
public function init()
{
$this->translator = Zend_Registry::get('Zend_Translate');
}
/**
* Translator wrapper
*
* @param string $string The string to be translated
* @return string $translated The translated string
*/
protected function _($string)
{
$translated = $this->translator->translate($string);
return $translated;
}
}
Конечно, то же самое можно сделать с Zend_View
,
Отказ от ответственности: это не лучшая практика, чтобы загромождать ваш код с прямыми вызовами в реестр. На самом деле это анти-шаблон, который должен быть заменен на DI. Zend Framework 2
Нам будет намного проще избежать регистрации. Этот код может быть улучшен путем фактического внедрения объекта перевода в класс с помощью конструктора.
Нет, не то, что я знаю. В любом случае, есть несколько неявных вопросов, связанных с этим. Во-первых, вы всегда должны давать функциям (и в этом отношении переменным) осмысленные имена. Это сказало, __()
это не значимое имя вообще. Наоборот, на самом деле это не имеет смысла. Во-вторых, рекомендуется использовать только префиксprivate
а также protected
функции (и, опять же, переменные в этом отношении) с подчеркиванием.
Наконец, с тем, как работают помощники Zend View, вам бы пришлось "обмануть" систему, чтобы найти помощника View, если он был назван __(). Вы должны были бы назвать это как-то Zend_View_Helper___
и это не сработает. Не говоря уже о том, что это повлечет за собой необходимость назвать ваш файл __.php
,
Я полагаю, вы могли бы назвать свой помощник Zend_View_Helper_T
в этом случае вы могли бы перевести материал, используя $this->t($string);
(Я проверил это, и это работает), но опять же вы всегда должны использовать значимые имена.
редактировать
Не осознавая, что вы хотели позвонить из контроллера, я решил пересмотреть свой ответ и дать небольшой отзыв о комментарии, который получил от нижестоящего избирателя.
Трудно рекомендовать создать класс-оболочку для Zend_Controller_Action
в котором создать функцию _()
по следующей причине:
- Поскольку независимо от того, является ли это "принятым стандартом" или нет, я повторяю, что все методы и переменные должны иметь осмысленное имя. Я должен утверждать это, потому что я твердо верю в соблюдение явных стандартов кодирования (в отличие от тех "слуховых" или "недавно принятых" практик, которые непосредственно не соответствуют известной - и, следовательно, заслуживающей доверия - парадигме). Тем не менее, если PEAR или даже Zend решат принять такое радикальное изменение однажды, я уйду в отставку. ПРИМЕЧАНИЕ. Можно утверждать, что заслуживающие доверия компании, такие как Drupal, и их самопровозглашенные передовые практики могут рассматриваться как явные стандарты кодирования, но я не согласен. Зачем? Потому что груша... ну... это груша. А Zend - это "Компания PHP". Трудно получить больше доверия, чем это. Если кто-то не согласен с этим последним утверждением, пожалуйста, укажите причину или поправьте меня вместо того, чтобы голосовать. Несмотря на это, стандарты - это просто предложение, которое не требуется; следовательно, они должны рассматриваться как таковые. Так что, я думаю, если вы придерживаетесь какого-то стандарта, это хорошо! Это не правила в конце концов.
Тем не менее, решение Маркуса было хорошим, кроме имени функции (по причинам, указанным ранее). Единственное, что я хотел бы изменить, это вызов Zend_Registry::get()
в _()
функция. Если вы планируете вызывать эту функцию столько, сколько вы намекали, то что-то вроде этого может работать лучше:
class MyProject_Controller_Action extends Zend_Controller_Action
{
/**
* the translator object
* @var Zend_Translate
*/
protected $_translator;
public function init()
{
$this->_translator = Zend_Registry::get('Zend_Translate');
}
/**
* note my new method name, you don't have to use it but I still
* recommend it. the name is just a suggestion, if you prefer something
* like _translate() or _trnslte() then by all means (although I don't
* recommend abbreviations unless they're super obvious I guess).
*/
protected function _trans($string)
{
return $this->_translator->translate((string) $string);
}
}