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..511c00b 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('
' . $string . '
'); + } + } + } diff --git a/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php index 9179de9..ced7226 100644 --- a/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php +++ b/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php @@ -38,4 +38,13 @@ public function transBlockRender() { ); } + /** + * Renders for testing url_generator functions in a Twig template. + */ + public function urlGeneratorRender() { + return array( + '#theme' => 'twig_theme_test_url_generator', + ); + } + } diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig new file mode 100644 index 0000000..70c2179 --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig @@ -0,0 +1,20 @@ +{# Test the url_from_path twig function #} +
url_from_path not absolute: {{ url_from_path('user/register') }}
+ +
url_from_path absolute: {{ url_from_path('user/register', {'absolute': 1 }) }}
+ +{# Test the url twig function #} + +
url not absolute: {{ url('user.register') }}
+ +
url absolute: {{ url('user.register', {}, {'absolute': '1' }) }}
+ +
url absolute with fragment: {{ url('user.register', {}, {'absolute': '1', 'fragment': 'bottom' }) }}
+ +{# Test the link twig function #} + +
link not absolute: {{ link('Register', 'user.register') }}
+ +
link absolute: {{ link('Register', 'user.register', {}, {'absolute': '1' }) }}
+ +
link absolute with fragment: {{ link('Register', 'user.register', {}, {'absolute': '1', 'fragment': 'bottom' }) }}
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module index 934d1b0..fc51628 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module @@ -11,6 +11,10 @@ function twig_theme_test_theme($existing, $type, $theme, $path) { 'variables' => array(), 'template' => 'twig_theme_test.trans', ); + $items['twig_theme_test_url_generator'] = array( + 'variables' => array(), + 'template' => 'twig_theme_test.url_generator', + ); return $items; } diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml index 07880fb..904e0ea 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml @@ -11,3 +11,9 @@ twig_theme_test.trans: _content: '\Drupal\twig_theme_test\TwigThemeTestController::transBlockRender' requirements: _permission: 'access content' +twig_theme_test_url_generator: + path: '/twig-theme-test/url-generator' + defaults: + _content: '\Drupal\twig_theme_test\TwigThemeTestController::urlGeneratorRender' + requirements: + _permission: 'access content' diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index 31ea371..e728abe 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -301,6 +301,7 @@ function simpletest_script_init($server_software) { } $_SERVER['HTTP_HOST'] = $host; + $_SERVER['SERVER_PORT'] = isset($parsed_url['port']) ? $parsed_url['port'] : 80; $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_SOFTWARE'] = $server_software;