diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php index a6cb957..50a2ff0 100644 --- a/core/lib/Drupal/Core/CoreServiceProvider.php +++ b/core/lib/Drupal/Core/CoreServiceProvider.php @@ -108,6 +108,11 @@ public static function registerTwig(ContainerBuilder $container) { ->addArgument(DRUPAL_ROOT); $container->setAlias('twig.loader', 'twig.loader.filesystem'); + $twig_extension = new Definition('Drupal\Core\Template\TwigExtension'); + // When in the installer these services are not yet available. + if (!drupal_installation_attempted()) { + $twig_extension->addMethodCall('setGenerators', array(new Reference('url_generator'), new Reference('link_generator'))); + } $container->register('twig', 'Drupal\Core\Template\TwigEnvironment') ->addArgument(new Reference('twig.loader')) ->addArgument(array( @@ -127,7 +132,7 @@ public static function registerTwig(ContainerBuilder $container) { 'debug' => settings()->get('twig_debug', FALSE), 'auto_reload' => settings()->get('twig_auto_reload', NULL), )) - ->addMethodCall('addExtension', array(new Definition('Drupal\Core\Template\TwigExtension'))) + ->addMethodCall('addExtension', array($twig_extension)) // @todo Figure out what to do about debugging functions. // @see http://drupal.org/node/1804998 ->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug'))); diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php index 53ac95d..eb3d5f7 100644 --- a/core/lib/Drupal/Core/Routing/UrlGenerator.php +++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php @@ -197,10 +197,17 @@ public function generateFromRoute($name, $parameters = array(), $options = array $scheme = $req; } $port = ''; - if ('http' === $scheme && 80 != $this->context->getHttpPort()) { - $port = ':' . $this->context->getHttpPort(); - } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { - $port = ':' . $this->context->getHttpsPort(); + if ('http' === $scheme) { + $http_port = $this->context->getHttpPort(); + if ($http_port && $http_port != 80) { + $port = ':' . $http_port; + } + } + elseif ('https' === $scheme) { + $https_port = $this->context->getHttpsPort(); + if ($https_port && $https_port != 443) { + $port = ':' . $https_port; + } } return $scheme . '://' . $host . $port . $base_url . $path . $fragment; } diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 9cd17b0..b26d169 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -10,6 +10,8 @@ */ namespace Drupal\Core\Template; +use Drupal\Core\Routing\UrlGeneratorInterface; +use Drupal\Core\Utility\LinkGeneratorInterface; /** * A class for providing Twig extensions (specific Twig_NodeVisitors, filters and functions). @@ -17,11 +19,41 @@ * @see \Drupal\Core\CoreServiceProvider */ class TwigExtension extends \Twig_Extension { + + /** + * The URL generator. + * + * @var \Drupal\Core\Routing\UrlGeneratorInterface + */ + protected $urlGenerator; + + /** + * The link generator. + * + * @var \Drupal\Core\Utility\LinkGeneratorInterface + */ + protected $linkGenerator; + + /** + * Constructs \Drupal\Core\Template\TwigExtension. + * + * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator + * The URL generator. + * @param \Drupal\Core\Utility\LinkGeneratorInterface $link_generator + * The link generator. + */ + public function setGenerators(UrlGeneratorInterface $url_generator, LinkGeneratorInterface $link_generator) { + $this->urlGenerator = $url_generator; + $this->linkGenerator = $link_generator; + } + public function getFunctions() { // @todo re-add unset => twig_unset if this is really needed return array( // @todo Remove URL function once http://drupal.org/node/1778610 is resolved. - 'url' => new \Twig_Function_Function('url'), + 'url_from_path' => new \Twig_SimpleFunction('url_from_path', array($this, 'generateFromPath')), + 'url' => new \Twig_SimpleFunction('url', array($this, 'generateUrl')), + 'link' => new \Twig_SimpleFunction('link', array($this, 'generateLink'), array('is_safe' => array('html'))), // These functions will receive a TwigReference object, if a render array is detected 'hide' => new TwigReferenceFunction('twig_hide'), 'render_var' => new TwigReferenceFunction('twig_render_var'), @@ -63,5 +95,32 @@ public function getName() { return 'drupal_core'; } + + /** + * Generates a URL using the route generator. + * + * @see \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute() + */ + public function generateUrl($route_name, $route_parameters = array(), $options = array()) { + return $this->urlGenerator->generateFromRoute($route_name, $route_parameters, $options); + } + + /** + * Generates a URL using the route generator and the method generateFromPath. + * + * @see \Drupal\Core\Routing\UrlGeneratorInterface::generateFromPath() + */ + public function generateFromPath($path, $options = array()) { + return $this->urlGenerator->generateFromPath($path, $options); + } + + /** + * Generates a link (A tag) using the link generator. + * + * @see \Drupal\Core\Utility\LinkGeneratorInterface::generate() + */ + public function generateLink($text, $route_name, $route_parameters = array(), $options = array()) { + return $this->linkGenerator->generate($text, $route_name, $route_parameters, $options); + } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTestTwig.php b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTestTwig.php index 2dce51f..61f9eac 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTestTwig.php +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTestTwig.php @@ -47,4 +47,30 @@ function testTwigVariableDataTypes() { } } + /** + * Tests the url and url_generate Twig function. + */ + public function testTwigUrlGenerator() { + $this->drupalGet('twig-theme-test/url-generator'); + // Find the absolute URL of the current site. + $url_generator = $this->container->get('url_generator'); + $link_generator = $this->container->get('link_generator'); + $expected = array( + 'url_from_path not absolute: ' . $url_generator->generateFromPath('user/register'), + 'url_from_path absolute: ' . $url_generator->generateFromPath('user/register', array('absolute' => TRUE)), + 'url not absolute: ' . $url_generator->generateFromRoute('user_register'), + 'url absolute: ' . $url_generator->generateFromRoute('user_register', array(), array('absolute' => TRUE)), + 'url absolute with fragment: ' . $url_generator->generateFromRoute('user_register', array(), array('absolute' => TRUE, 'fragment' => 'bottom')), + 'link not absolute: ' . $link_generator->generate('Register', 'user_register'), + 'link absolute: ' . $link_generator->generate('Register', 'user_register', array(), array('absolute' => TRUE)), + 'link absolute with fragment: ' . $link_generator->generate('Register', 'user_register', array(), array('absolute' => TRUE, 'fragment' => 'bottom')), + ); + // Make sure we got something. + $content = $this->drupalGetContent(); + $this->assertFalse(empty($content), 'Page content is not empty'); + foreach ($expected as $string) { + $this->assertRaw('