我希望有一个文件或列表,我可以使用可能在整个应用程序中更改的值轻松更新。
我真的不想将文本值硬编码到模板中。我更喜欢将所有这些值放在一个地方并正确标记。
可能会更新的值的示例包括:
我考虑过两个选择:
还有其他选择还是其中一种更适合?
谢谢。
答案 0 :(得分:2)
您需要创建一个twig函数并使用它来返回所需的值。例如:
namespace AppBundle\Twig;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
class TwigExtension extends \Twig_Extension implements ContainerAwareInterface
{
use ContainerAwareTrait;
/**
* @var ContainerInterface
*/
protected $container;
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('parameter', function($name)
{
try {
return $this->container->getParameter($name);
} catch(\Exception $exception) {
return "";
}
})
);
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'app.twig.extension';
}
}
这将创建一个名为parameter
的函数,一旦你在twig {{ parameter('my.parameter') }}
中调用它,它将返回参数。您需要将其作为服务加载,您可以通过将以下内容添加到services.yml
文件来执行此操作:
app.twig.extension:
class: AppBundle\Twig\TwigExtension
calls:
- [setContainer, ["@service_container"]]
tags:
- { name: twig.extension }
从个人经验来看,人们通常希望能够改变一些参数。这就是为什么我通常更喜欢创建一个Setting
或Parameter
实体,它看起来像这样:
/**
* Setting
*
* @ORM\Table(name="my_parameters")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ParameterRepository")
*/
class Parameter
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="parameter_id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="value", type="text", nullable=true)
*/
private $value;
/**
* @param string|null $name
* @param string|null $value
*/
public function __construct($name = null, $value = null)
{
$this->setName($name);
$this->setValue($value);
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Parameter
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set value
*
* @param string $value
*
* @return Parameter
*/
public function setValue($value = null)
{
$this->value = serialize($value);
return $this;
}
/**
* Get value
*
* @return string
*/
public function getValue()
{
$data = @unserialize($this->value);
return $this->value === 'b:0;' || $data !== false ? $this->value = $data : null;
}
}
然后我会添加一个CompilerPass
,它将帮助从数据库中获取所有参数并缓存它们,以便您的应用程序不会对数据库进行不必要的SQL查询。这可能看起来类似于以下类:
// AppBundle/DependencyInjection/Compiler/ParamsCompilerPass.php
namespace AppBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ParamsCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$settings = $em->getRepository('AppBundle:Parameter')->findAll();
foreach($settings as $setting) {
// I like to prefix the parameters with "app."
// to avoid any collision with existing parameters.
$container->setParameter('app.'.strtolower($setting->getName()), $setting->getValue());
}
}
}
最后,在您的bundle类(即src/AppBundle/AppBundle.php
)中添加编译器传递:
namespace AppBundle;
use AppBundle\DependencyInjection\Compiler\ParamsCompilerPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $builder)
{
parent::build($builder);
$builder->addCompilerPass(new ParamsCompilerPass(), , PassConfig::TYPE_AFTER_REMOVING);
}
}
现在,您可以创建DoctrineFixture
模板来加载您一直使用的参数。使用TwigExtension
,您仍然可以从树枝模板调用参数,并且可以创建Web UI来更改某些参数/设置。