添加不应从 Controller 缓存的翻译
Add translations that should not be cached from Controller
在我的应用程序中,我有两种翻译:
- 作为模板布局一部分的静态措辞(例如"Previous"、"Cancel"...)
- 从数据库中提取的动态措辞,可以针对每个请求进行更改(例如博客文章标题可能在数据库中有所不同)
我使用 Symfony 翻译服务在我的 twig 模板中使用静态措辞,使用 trans 过滤器。它适用于静态措辞,但对于动态措辞,事情变得越来越困难。
我在控制器操作中添加了我的 动态 措辞:
$trans = $this->get( 'translator' );
$trans->addLoader('array', new ArrayLoader());
$trans->addResource('array', array('BLOG_ARTICLE_TITLE'=>$article->getTitle('french')), 'fr', 'messages');
// ...
return new Response();
然后,我将它与我的模板中的 trans 一起使用,或者在我的前端应用程序中与 BazingaJsTranslationBundle 一起使用。
我想我的缓存有问题:对于动态措辞,我经常在页面上看到旧的措辞或翻译键——即使在返回响应之前在控制器上完成添加也是如此。
但是当我清除缓存 (app/console clear:cache) 并重新加载页面时,我得到了正确的措辞。
有没有办法告诉 Symfony 不要缓存动态添加的文字?
或者另一种更适合动态添加翻译的翻译器方法?
Symfony 文档:
Translating Database Content
The translation of database content should be handled by Doctrine through the Translatable Extension or the Translatable Behavior
(PHP 5.4+). For more information, see the documentation for these
libraries.
它是这样使用的:
use Gedmo\Translatable\Translatable;
// [...]
class Article implements Translatable
{
/** @ODM\Id */
private $id;
/**
* @Gedmo\Translatable
* @ODM\String
*/
private $title;
/**
* @Gedmo\Translatable
* @ODM\String
*/
private $content;
/**
* @Gedmo\Locale
* Used locale to override Translation listener`s locale
* this is not a mapped field of entity metadata, just a simple property
*/
private $locale;
针对您的具体问题:
您可以手动删除缓存文件
Lexik 翻译包使用这个系统。 see their Translator.php class below
public function removeLocalesCacheFiles(array $locales)
{
foreach ($locales as $locale) {
$this->removeCacheFile($locale);
}
// also remove database.resources.php cache file
$file = sprintf('%s/database.resources.php', $this->options['cache_dir']);
if (file_exists($file)) {
$this->invalidateSystemCacheForFile($file);
unlink($file);
}
$metadata = $file.'.meta';
if (file_exists($metadata)) {
$this->invalidateSystemCacheForFile($metadata);
unlink($metadata);
}
}
/**
* @param string $path
*
* @throws \RuntimeException
*/
protected function invalidateSystemCacheForFile($path)
{
if (ini_get('apc.enabled')) {
if (apc_exists($path) && !apc_delete_file($path)) {
throw new \RuntimeException(sprintf('Failed to clear APC Cache for file %s', $path));
}
} elseif ('cli' === php_sapi_name() ? ini_get('opcache.enable_cli') : ini_get('opcache.enable')) {
if (!opcache_invalidate($path, true)) {
throw new \RuntimeException(sprintf('Failed to clear OPCache for file %s', $path));
}
}
}
在我的应用程序中,我有两种翻译:
- 作为模板布局一部分的静态措辞(例如"Previous"、"Cancel"...)
- 从数据库中提取的动态措辞,可以针对每个请求进行更改(例如博客文章标题可能在数据库中有所不同)
我使用 Symfony 翻译服务在我的 twig 模板中使用静态措辞,使用 trans 过滤器。它适用于静态措辞,但对于动态措辞,事情变得越来越困难。
我在控制器操作中添加了我的 动态 措辞:
$trans = $this->get( 'translator' );
$trans->addLoader('array', new ArrayLoader());
$trans->addResource('array', array('BLOG_ARTICLE_TITLE'=>$article->getTitle('french')), 'fr', 'messages');
// ...
return new Response();
然后,我将它与我的模板中的 trans 一起使用,或者在我的前端应用程序中与 BazingaJsTranslationBundle 一起使用。
我想我的缓存有问题:对于动态措辞,我经常在页面上看到旧的措辞或翻译键——即使在返回响应之前在控制器上完成添加也是如此。
但是当我清除缓存 (app/console clear:cache) 并重新加载页面时,我得到了正确的措辞。
有没有办法告诉 Symfony 不要缓存动态添加的文字? 或者另一种更适合动态添加翻译的翻译器方法?
Symfony 文档:
Translating Database Content
The translation of database content should be handled by Doctrine through the Translatable Extension or the Translatable Behavior (PHP 5.4+). For more information, see the documentation for these libraries.
它是这样使用的:
use Gedmo\Translatable\Translatable;
// [...]
class Article implements Translatable
{
/** @ODM\Id */
private $id;
/**
* @Gedmo\Translatable
* @ODM\String
*/
private $title;
/**
* @Gedmo\Translatable
* @ODM\String
*/
private $content;
/**
* @Gedmo\Locale
* Used locale to override Translation listener`s locale
* this is not a mapped field of entity metadata, just a simple property
*/
private $locale;
针对您的具体问题:
您可以手动删除缓存文件 Lexik 翻译包使用这个系统。 see their Translator.php class below
public function removeLocalesCacheFiles(array $locales)
{
foreach ($locales as $locale) {
$this->removeCacheFile($locale);
}
// also remove database.resources.php cache file
$file = sprintf('%s/database.resources.php', $this->options['cache_dir']);
if (file_exists($file)) {
$this->invalidateSystemCacheForFile($file);
unlink($file);
}
$metadata = $file.'.meta';
if (file_exists($metadata)) {
$this->invalidateSystemCacheForFile($metadata);
unlink($metadata);
}
}
/**
* @param string $path
*
* @throws \RuntimeException
*/
protected function invalidateSystemCacheForFile($path)
{
if (ini_get('apc.enabled')) {
if (apc_exists($path) && !apc_delete_file($path)) {
throw new \RuntimeException(sprintf('Failed to clear APC Cache for file %s', $path));
}
} elseif ('cli' === php_sapi_name() ? ini_get('opcache.enable_cli') : ini_get('opcache.enable')) {
if (!opcache_invalidate($path, true)) {
throw new \RuntimeException(sprintf('Failed to clear OPCache for file %s', $path));
}
}
}