This is what I came up with eventually:
I implemented by own generator base class that looks for 'object' parameter and tries to get required parameters from that object.
//src/Blogger/BlogBundle/Resources/config/services.yml
parameters:
router.options.generator_base_class: BloggerBlogBundleRoutingGeneratorUrlGenerator
//src/Blogger/BlogBundle/Routing/Generator/UrlGenerator.php
namespace BloggerBlogBundleRoutingGenerator;
use SymfonyComponentRoutingGeneratorUrlGenerator as BaseUrlGenerator;
use DoctrineCommonUtilInflector;
/**
* UrlGenerator generates URL based on a set of routes.
*
* @api
*/
class UrlGenerator extends BaseUrlGenerator
{
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute)
{
if (isset($parameters['object']) && is_object($parameters['object'])) {
$object = $parameters['object'];
$parameters = array_replace($this->context->getParameters(), $parameters);
$tparams = array_replace($defaults, $parameters);
$requiredParameters = array_diff_key(array_flip($variables), $tparams);
$parameters = $this->getParametersFromObject(array_flip($requiredParameters), $object);
}
return parent::doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute);
}
protected function getParametersFromObject($keys, $object)
{
$parameters = array();
foreach ($keys as $key) {
$method = 'get' . Inflector::classify($key);
if (method_exists($object, $method)) {
$parameters[$key] = $object->$method();
}
}
return $parameters;
}
}
Now I can write: {{ path('BBBundle_blog_show', {'object': blog}) }} and it will get required parameters (id, slug) from object.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…