This is just an idea, I don't know if it's really useful:
Currently if you are rendering a template from a controller you have to
specify the bundle and controller name in the template identifier
('DominateTheWorldBundle:Default:index.html.twig'). This makes renaming the
bundle or controller very hard (since there is no IDE refactoring support
for values within strings) and the whole thing is also error prone (you have
to type the same stuff over and over again).
One way to solve this is to use the @extra:Template annotation from the
FrameworkExtraBundle.
What I'd like to be able to do would be defining the template using a
identifier like '@self:@self:index.html.twig' where the different
@self-elements expand to the current bundle and controller name (the same
way you say self::$var and not MyClass::$var in a class). However
implementing this seems to be quite hard (at least for me) since there is no
way for the TemplateNameParser to know about the current bundle and
controller.
Another approach would be using a syntax like
__CLASS__.':'.__FUNCTION__.'.html.twig' when defining the template.
Transforming this into the template name is quite easy (see patch attached
below, getBundleNameForClass is obviously influenced by the
AnnotationTemplateListener) - it seems to be useful, but it looks kind of
ugly ... - so I don't want to sent a pull request right now :)
Sven
--- TemplateNameParser.php.orig 2011-03-05 12:06:35.070807641 +0100
+++ TemplateNameParser.php 2011-03-05 12:01:00.025689000 +0100
@@ -57,7 +57,12 @@
}
$parts = explode(':', $name);
- if (3 !== count($parts)) {
+ // allow bundle and controller class to be given using __CLASS__
+ if (2 == count($parts) &&
preg_match('#Controller/(.*)Controller$#', $parts[0], $match)) {
+ $parts[2] = $parts[1];
+ $parts[1] = $match[1];
+ $parts[0] = $this->getBundleNameForClass($parts[0]);
+ } else if (3 !== count($parts)) {
throw new \InvalidArgumentException(sprintf('Template name "%s"
is not valid (format is "bundle:section:template.format.engine").', $name));
}
@@ -65,6 +70,8 @@
if (3 !== count($elements)) {
throw new \InvalidArgumentException(sprintf('Template name "%s"
is not valid (format is "bundle:section:template.format.engine").', $name));
}
+ // allow template name to be given using __FUNCTION__
+ $elements[0] = preg_replace('/Action$/', '', $elements[0]);
$template = new TemplateReference($parts[0], $parts[1],
$elements[0], $elements[1], $elements[2]);
@@ -98,4 +105,26 @@
return new TemplateReference('', implode('/', $parts),
$elements[0], $elements[1], $elements[2]);
}
+ /**
+ * Returns the name of the bundle containing the given class.
+ *
+ * @param string $class the name of the class including namespace
+ *
+ * @return string the name of the bundle
+ *
+ * @throws \InvalidArgumentException if bundle isn't found
+ */
+ protected function getBundleNameForClass($class)
+ {
+ $namespace = strtr(dirname(strtr($class, '\\', '/')), '/', '\\');
+ foreach ($this->kernel->getBundles() as $bundle) {
+ if (0 === strpos($namespace, $bundle->getNamespace())) {
+ return $bundle->getName();
+ }
+ }
+
+ throw new \InvalidArgumentException(sprintf('The "%s" class does
not belong to a registered bundle.', $class));
+ }
+
+
}
--
If you want to report a vulnerability issue on symfony, please send it to
security at symfony-project.com
You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en