diff --git a/core/includes/common.inc b/core/includes/common.inc index 8a8ea0e85bb540e0a421332f5d96efeae489be8b..711d8d3a898eae540bf8a1d49fb56c789be7711a 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -4683,32 +4683,25 @@ function drupal_render(&$elements) { // element have to be rendered there. If the internal #render_children // property is set, do not call the #theme function to prevent infinite // recursion. - $theme_is_implemented = FALSE; if (isset($elements['#theme']) && !isset($elements['#render_children'])) { $elements['#children'] = theme($elements['#theme'], $elements); - // If theme() returns FALSE this means that the hook in #theme was not found - // in the registry. This is common for theme suggestions. - $theme_is_implemented = ($elements['#children'] !== FALSE); - } - // #theme is either not set or does not exist in the registry. - if (!$theme_is_implemented) { - // If #theme is not implemented and the element has children, render them - // now. This is the same process as drupal_render_children() but is inlined - // for speed. + } + // If #theme was not set and the element has children, render them now. + // This is the same process as drupal_render_children() but is inlined + // for speed. + if ($elements['#children'] === '') { foreach ($children as $key) { $elements['#children'] .= drupal_render($elements[$key]); } - - // If #theme is not implemented and the element has raw #markup as a - // fallback, prepend the content in #markup to #children. In this case - // #children will contain whatever is provided by #pre_render prepended to - // what is rendered recursively above. If #theme is implemented then it is - // the responsibility of that theme implementation to render #markup if - // required. Eventually #theme_wrappers will expect both #markup and - // #children to be a single string as #children. - if (isset($elements['#markup'])) { - $elements['#children'] = $elements['#markup'] . $elements['#children']; - } + } + // If #theme was not set, but the element has raw #markup, prepend the content + // in #markup to #children. #children may contain the rendered content + // supplied by #theme, or the rendered child elements, as processed above. If + // both #theme and #markup are set, then #theme is responsible for rendering + // the element. Eventually assigned #theme_wrappers will expect both the + // element's #markup and the rendered content of child elements in #children. + if (!isset($elements['#theme']) && isset($elements['#markup'])) { + $elements['#children'] = $elements['#markup'] . $elements['#children']; } // Add any JavaScript state information associated with the element. diff --git a/core/includes/theme.inc b/core/includes/theme.inc index df03ad669af54afb9a8abffb3fadefbe7a451f3c..45737c5ccbc69900e90d7eab80e4bc0f44528b8f 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -932,9 +932,8 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) { * properties are mapped to variables expected by the theme hook * implementations. * - * @return string|false - * An HTML string representing the themed output or FALSE if the passed $hook - * is not implemented. + * @return + * An HTML string representing the themed output. * * @see themeable * @see hook_theme() @@ -983,10 +982,7 @@ function theme($hook, $variables = array()) { if (!isset($candidate)) { watchdog('theme', 'Theme hook %hook not found.', array('%hook' => $hook), WATCHDOG_WARNING); } - // There is no theme implementation for the hook passed. Return FALSE so - // the function calling theme() can differentiate between a hook that - // exists and renders an empty string and a hook that is not implemented. - return FALSE; + return ''; } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php index fac11fa5e26d9a458112a8918d421663657adcc2..31e4f340325c731c11cfefc0e15447b7495e1111 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php @@ -83,59 +83,6 @@ function testDrupalRenderBasics() { } } - /** - * Tests fallback rendering behaviour when #theme is not implemented. - * - * If #theme is set and is an implemented theme hook then theme() is 100% - * responsible for rendering the array including children and #markup. - * - * If #theme is not set or is not found in the registry then drupal_render() - * should recursively render child attributes of the array and #markup. - * - * This dual rendering behaviour is only relevant to the internal processing - * of drupal_render() before #theme_wrappers are called, so not #prefix and - * #suffix for example. - */ - function testDrupalRenderFallbackRender() { - // Theme suggestion is not implemented, #markup should be rendered. - $theme_suggestion_not_implemented_has_markup = array( - '#theme' => array('suggestionnotimplemented'), - '#markup' => 'foo', - ); - $rendered = drupal_render($theme_suggestion_not_implemented_has_markup); - $this->assertIdentical($rendered, 'foo'); - - // Theme suggestion is not implemented, children should be rendered. - $theme_suggestion_not_implemented_has_children = array( - '#theme' => array('suggestionnotimplemented'), - 'child' => array( - '#markup' => 'foo', - ), - ); - $rendered = drupal_render($theme_suggestion_not_implemented_has_children); - $this->assertIdentical($rendered, 'foo'); - - // Theme suggestion is implemented but returns empty string, #markup should - // not be rendered. - $theme_implemented_is_empty_has_markup = array( - '#theme' => array('common_test_empty'), - '#markup' => 'foo', - ); - $rendered = drupal_render($theme_implemented_is_empty_has_markup); - $this->assertIdentical($rendered, ''); - - // Theme suggestion is implemented but returns empty string, children should - // not be rendered. - $theme_implemented_is_empty_has_children = array( - '#theme' => array('common_test_empty'), - 'child' => array( - '#markup' => 'foo', - ), - ); - $rendered = drupal_render($theme_implemented_is_empty_has_children); - $this->assertIdentical($rendered, ''); - } - /** * Tests sorting by weight. */ diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php index 072bfb0ea0e0dfe2baffb8b0f4215a4590ab97ce..32f9321c255cea3d461174c91849c7095cccba49 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php @@ -204,7 +204,7 @@ function testRegistryRebuild() { // throws an exception. $this->rebuildContainer(); $this->container->get('module_handler')->loadAll(); - $this->assertIdentical(theme('theme_test_foo', array('foo' => 'b')), FALSE, 'The theme registry does not contain theme_test_foo, because the module is disabled.'); + $this->assertIdentical(theme('theme_test_foo', array('foo' => 'b')), '', 'The theme registry does not contain theme_test_foo, because the module is disabled.'); module_enable(array('theme_test'), FALSE); // After enabling/disabling a module during a test, we need to rebuild the diff --git a/core/modules/system/tests/modules/common_test/common_test.module b/core/modules/system/tests/modules/common_test/common_test.module index 175cd5ac0c3528ef0f32f978238713bff37757f7..83d19e0309a92bbe7dbb627c6b2c474498ac7434 100644 --- a/core/modules/system/tests/modules/common_test/common_test.module +++ b/core/modules/system/tests/modules/common_test/common_test.module @@ -164,26 +164,9 @@ function common_test_theme() { 'variables' => array('foo' => 'foo', 'bar' => 'bar'), 'template' => 'common-test-foo', ), - 'common_test_empty' => array( - 'variables' => array('foo' => 'foo'), - ), ); } -/** - * Provides a theme function for drupal_render(). - */ -function theme_common_test_foo($variables) { - return $variables['foo'] . $variables['bar']; -} - -/** - * Always returns an empty string. - */ -function theme_common_test_empty($variables) { - return ''; -} - /** * Implements hook_library_info_alter(). */