使用Symfony和CMF包处理项目。我按照documentation创建了自己的块。
但是,在渲染块时,Symfony抛出一个异常,告诉我指定的选项不存在。
An exception has been thrown during the rendering of a template ("The options "title", "url" do not exist. Known options are: "attr", "extra_cache_keys", "template", "ttl", "use_cache"") in FooMainBundle::Page/Standard.html.twig at line 15.
这是我的模板(Standard.html.twig):
{% extends "FooMainBundle::layout.html.twig" %}
{% block content %}
{{ sonata_block_render({'name': 'rssBlock'}, {
'title': 'Symfony CMF news',
'url': 'http://cmf.symfony.com/news.rss'
}) }}
{% endblock %}
这是我的文件:
<?php
namespace Foo\BarContentBundle\Document;
use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCR;
use Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\AbstractBlock;
/**
* @PHPCR\Document(referenceable=true)
*/
class RssBlock extends AbstractBlock
{
/**
* @PHPCR\String(nullable=true)
*/
private $feedUrl;
/**
* @PHPCR\String()
*/
private $title;
public function getType()
{
return 'foo_barcontent.block.rss';
}
public function getOptions()
{
$options = array(
'title' => $this->title,
);
if ($this->feedUrl) {
$options['url'] = $this->feedUrl;
}
return $options;
}
public function getTitle() {
return $this->title;
}
public function setTitle($title) {
$this->title = $title;
}
public function getFeedUrl() {
return $this->feedUrl;
}
public function setFeedUrl($feedUrl) {
$this->feedUrl = $feedUrl;
}
}
这是我的服务:
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\BlockBundle\Model\BlockInterface;
use Sonata\BlockBundle\Block\BlockContextInterface;
use Sonata\BlockBundle\Block\BaseBlockService;
class RssBlockService extends BaseBlockService
{
public function getName()
{
return 'Rss Reader';
}
/**
* Define valid options for a block of this type.
*/
public function setDefaultSettings(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'url' => false,
'title' => 'Feed items',
'template' => 'FooBarContentBundle:Block:block_rss.html.twig',
));
}
/**
* The block context knows the default settings, but they can be
* overwritten in the call to render the block.
*/
public function execute(BlockContextInterface $blockContext, Response $response = null)
{
$block = $blockContext->getBlock();
if (!$block->getEnabled()) {
return new Response();
}
// merge settings with those of the concrete block being rendered
$settings = $blockContext->getSettings();
$resolver = new OptionsResolver();
$resolver->setDefaults($settings);
$settings = $resolver->resolve($block->getOptions());
$feeds = false;
if ($settings['url']) {
$options = array(
'http' => array(
'user_agent' => 'Sonata/RSS Reader',
'timeout' => 2,
)
);
// retrieve contents with a specific stream context to avoid php errors
$content = @file_get_contents($settings['url'], false, stream_context_create($options));
if ($content) {
// generate a simple xml element
try {
$feeds = new \SimpleXMLElement($content);
$feeds = $feeds->channel->item;
} catch (\Exception $e) {
// silently fail error
}
}
}
return $this->renderResponse($blockContext->getTemplate(), array(
'feeds' => $feeds,
'block' => $blockContext->getBlock(),
'settings' => $settings
), $response);
}
// These methods are required by the sonata block service interface.
// They are not used in the CMF. To edit, create a symfony form or
// a sonata admin.
public function buildEditForm(FormMapper $formMapper, BlockInterface $block)
{
throw new \Exception();
}
public function validateBlock(ErrorElement $errorElement, BlockInterface $block)
{
throw new \Exception();
}
}
我把它放在我的services.xml中:
<service id="foo_barcontent.block.rss" class="Foo\BarBundle\Block\RssBlockService">
<tag name="sonata.block" />
<argument>foo_barcontent.block.rss</argument>
<argument type="service" id="templating" />
</service>