From 6fbfb60478058e574c11c77b78169bf3d4df1a4f Mon Sep 17 00:00:00 2001 From: Mark Carver Date: Thu, 5 Jun 2014 10:59:46 -0500 Subject: [PATCH] Issue #2226207 by mgbellaire, lauriii, Mark Carver, Cottser, euphoric_mv: Make 'template' the default output option for hook_theme(). --- core/includes/theme.inc | 21 ++++++++++- core/lib/Drupal/Core/Template/TwigEnvironment.php | 18 +++++---- core/lib/Drupal/Core/Theme/Registry.php | 41 +++++++++++++------- core/modules/aggregator/aggregator.module | 2 + core/modules/book/book.module | 2 + core/modules/field_ui/field_ui.module | 1 + core/modules/file/file.module | 7 ++++ core/modules/forum/forum.module | 1 + core/modules/image/image.module | 10 +++++ core/modules/language/language.module | 3 ++ core/modules/locale/locale.module | 1 + core/modules/menu_ui/menu_ui.module | 1 + core/modules/node/node.module | 1 + .../responsive_image/responsive_image.module | 3 ++ core/modules/simpletest/simpletest.module | 1 + core/modules/system/system.module | 4 ++ .../tests/modules/common_test/common_test.module | 1 + .../theme_suggestions_test.module | 1 + .../tests/modules/theme_test/theme_test.module | 6 +++ core/modules/toolbar/toolbar.module | 3 +- core/modules/update/update.module | 5 +++ core/modules/user/user.module | 3 ++ core/modules/views/views.module | 44 ++++++++++++---------- core/modules/views_ui/views_ui.module | 3 ++ core/themes/engines/twig/twig.engine | 23 ++++++----- 25 files changed, 153 insertions(+), 53 deletions(-) diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 7e92f95..7919094 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -2575,6 +2575,7 @@ function drupal_common_theme() { ), 'mark' => array( 'variables' => array('status' => MARK_NEW), + 'function' => 'theme_mark', ), 'item_list' => array( 'variables' => array('items' => array(), 'title' => '', 'list_type' => 'ul', 'attributes' => array(), 'empty' => NULL), @@ -2585,7 +2586,8 @@ function drupal_common_theme() { 'template' => 'feed-icon', ), 'more_link' => array( - 'variables' => array('url' => NULL, 'title' => NULL) + 'variables' => array('url' => NULL, 'title' => NULL), + 'function' => 'theme_more_link', ), 'progress_bar' => array( 'variables' => array('label' => NULL, 'percent' => NULL, 'message' => NULL), @@ -2593,6 +2595,7 @@ function drupal_common_theme() { ), 'indentation' => array( 'variables' => array('size' => 1), + 'function' => 'theme_indentation', ), // From theme.maintenance.inc. 'maintenance_page' => array( @@ -2605,12 +2608,17 @@ function drupal_common_theme() { ), 'task_list' => array( 'variables' => array('items' => NULL, 'active' => NULL, 'variant' => NULL), + 'function' => 'theme_task_list', + 'path' => 'core/includes', + 'file' => 'theme.maintenance.inc', ), 'authorize_message' => array( 'variables' => array('message' => NULL, 'success' => TRUE), + 'function' => 'theme_authorize_message', ), 'authorize_report' => array( 'variables' => array('messages' => array()), + 'function' => 'theme_authorize_report', ), // From pager.inc. 'pager' => array( @@ -2620,22 +2628,30 @@ function drupal_common_theme() { // From menu.inc. 'menu_link' => array( 'render element' => 'element', + 'function' => 'theme_menu_link', + 'path' => 'core/includes', + 'file' => 'menu.inc', ), 'menu_tree' => array( 'render element' => 'tree', + 'function' => 'theme_menu_tree', ), 'menu_local_task' => array( 'render element' => 'element', + 'function' => 'theme_menu_local_task', ), 'menu_local_action' => array( 'render element' => 'element', + 'function' => 'theme_menu_local_action', ), 'menu_local_tasks' => array( 'variables' => array('primary' => array(), 'secondary' => array()), + 'function' => 'theme_menu_local_tasks', ), // From form.inc. 'input' => array( 'render element' => 'element', + 'function' => 'theme_input', ), 'select' => array( 'render element' => 'element', @@ -2655,6 +2671,7 @@ function drupal_common_theme() { ), 'date' => array( 'render element' => 'element', + 'function' => 'theme_date', ), 'checkboxes' => array( 'render element' => 'element', @@ -2670,6 +2687,7 @@ function drupal_common_theme() { ), 'tableselect' => array( 'render element' => 'element', + 'function' => 'theme_tableselect', ), 'form_element' => array( 'render element' => 'element', @@ -2677,6 +2695,7 @@ function drupal_common_theme() { ), 'form_element_label' => array( 'render element' => 'element', + 'function' => 'theme_form_element_label', ), 'vertical_tabs' => array( 'render element' => 'element', diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php index c671899..ae7179a 100644 --- a/core/lib/Drupal/Core/Template/TwigEnvironment.php +++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php @@ -40,17 +40,19 @@ public function __construct(\Twig_LoaderInterface $loader = NULL, $options = arr // Set twig path namespace for themes and modules. $namespaces = array(); - foreach ($module_handler->getModuleList() as $name => $extension) { - $namespaces[$name] = $extension->getPath(); + foreach ($module_handler->getModuleList() as $extension) { + $namespaces[] = $extension->getPath(); } - foreach ($theme_handler->listInfo() as $name => $extension) { - $namespaces[$name] = $extension->getPath(); + foreach ($theme_handler->listInfo() as $extension) { + $namespaces[] = $extension->getPath(); } - foreach ($namespaces as $name => $path) { - $templatesDirectory = $path . '/templates'; - if (file_exists($templatesDirectory)) { - $loader->addPath($templatesDirectory, $name); + foreach ($namespaces as $path) { + $templates_dir = DRUPAL_ROOT . '/' . $path . '/templates'; + if (file_exists($templates_dir)) { + // We currently do not use namespaces in Twig. We must add all possible + // template directory paths to the __main__ namespace. + $loader->addPath($templates_dir); } } diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php index 402c9f7..abaad13 100644 --- a/core/lib/Drupal/Core/Theme/Registry.php +++ b/core/lib/Drupal/Core/Theme/Registry.php @@ -389,6 +389,9 @@ protected function build() { * @see _theme() * @see hook_theme() * @see list_themes() + * @see twig_render_template() + * + * @throws \BadFunctionCallException */ protected function processExtension(&$cache, $name, $type, $theme, $path) { $result = array(); @@ -418,12 +421,6 @@ protected function processExtension(&$cache, $name, $type, $theme, $path) { $result[$hook]['type'] = $type; $result[$hook]['theme path'] = $path; - // If function and file are omitted, default to standard naming - // conventions. - if (!isset($info['template']) && !isset($info['function'])) { - $result[$hook]['function'] = ($type == 'module' ? 'theme_' : $name . '_') . $hook; - } - if (isset($cache[$hook]['includes'])) { $result[$hook]['includes'] = $cache[$hook]['includes']; } @@ -439,20 +436,36 @@ protected function processExtension(&$cache, $name, $type, $theme, $path) { $result[$hook]['includes'][] = $include_file; } + // Templates are the default implementation for a theme hook. If a + // theme hook provides a theme function callback, it should only + // override existing template implementations. + if (isset($info['function'])) { + // Ensure theming function exists and remove any provided template. + if (function_exists($info['function'])) { + unset($result[$hook]['template']); + } + else { + throw new \BadFunctionCallException(sprintf( + 'Theme hook "%s" refers to a theme function callback that does not exist: "%s"', + $hook, + $info['function'] + )); + } + } + // Provide a default naming convention for 'template' based on the + // hook used. If the template does not exist, the template engine used + // (Twig) will throw throw an exception at runtime when attempting to + // include the template file (\Twig_Error_Loader). + elseif (!isset($info['template'])) { + $result[$hook]['template'] = strtr($hook, '_', '-'); + } + // If the default keys are not set, use the default values registered // by the module. if (isset($cache[$hook])) { $result[$hook] += array_intersect_key($cache[$hook], $hook_defaults); } - // The following apply only to theming hooks implemented as templates. - if (isset($info['template'])) { - // Prepend the current theming path when none is set. - if (!isset($info['path'])) { - $result[$hook]['template'] = $path . '/templates/' . $info['template']; - } - } - // Preprocess variables for all theming hooks, whether the hook is // implemented as a template or as a function. Ensure they are arrays. if (!isset($info['preprocess functions']) || !is_array($info['preprocess functions'])) { diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module index 1fb5027..126fa10 100644 --- a/core/modules/aggregator/aggregator.module +++ b/core/modules/aggregator/aggregator.module @@ -84,10 +84,12 @@ function aggregator_theme() { 'aggregator_page_opml' => array( 'variables' => array('feeds' => NULL), 'file' => 'aggregator.theme.inc', + 'function' => 'theme_aggregator_page_opml', ), 'aggregator_page_rss' => array( 'variables' => array('feeds' => NULL), 'file' => 'aggregator.theme.inc', + 'function' => 'theme_aggregator_page_rss', ), ); } diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 9cc4835..23de3f5 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -60,6 +60,7 @@ function book_theme() { ), 'book_link' => array( 'render element' => 'element', + 'function' => 'theme_book_link', ), 'book_export_html' => array( 'variables' => array('title' => NULL, 'contents' => NULL, 'depth' => NULL), @@ -68,6 +69,7 @@ function book_theme() { 'book_admin_table' => array( 'render element' => 'form', 'file' => 'book.admin.inc', + 'function' => 'theme_book_admin_table', ), 'book_all_books_block' => array( 'render element' => 'book_menus', diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index 84078a2..e152755 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -87,6 +87,7 @@ function field_ui_theme() { return array( 'field_ui_table' => array( 'render element' => 'elements', + 'function' => 'theme_field_ui_table', ), ); } diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 47b72ef..340a70a 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -589,26 +589,33 @@ function file_theme() { // file.module. 'file_link' => array( 'variables' => array('file' => NULL, 'icon_directory' => NULL, 'description' => NULL, 'attributes' => array()), + 'function' => 'theme_file_link', ), 'file_icon' => array( 'variables' => array('file' => NULL, 'icon_directory' => NULL), + 'function' => 'theme_file_icon', ), 'file_managed_file' => array( 'render element' => 'element', + 'function' => 'theme_file_managed_file', ), // file.field.inc. 'file_widget' => array( 'render element' => 'element', + 'function' => 'theme_file_widget', ), 'file_widget_multiple' => array( 'render element' => 'element', + 'function' => 'theme_file_widget_multiple', ), 'file_formatter_table' => array( 'variables' => array('items' => NULL), + 'function' => 'theme_file_formatter_table', ), 'file_upload_help' => array( 'variables' => array('description' => NULL, 'upload_validators' => NULL, 'cardinality' => NULL), + 'function' => 'theme_file_upload_help', ), ); } diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 1b9b8f8..af44304 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -97,6 +97,7 @@ function forum_theme() { ), 'forum_form' => array( 'render element' => 'form', + 'function' => 'theme_forum_form', ), ); } diff --git a/core/modules/image/image.module b/core/modules/image/image.module index fc6f319..409bc58 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -108,46 +108,56 @@ function image_theme() { 'title' => NULL, 'attributes' => array(), ), + 'function' => 'theme_image_style', ), // Theme functions in image.admin.inc. 'image_style_effects' => array( 'render element' => 'form', 'file' => 'image.admin.inc', + 'function' => 'theme_image_style_effects', ), 'image_style_preview' => array( 'variables' => array('style' => NULL), 'file' => 'image.admin.inc', + 'function' => 'theme_image_style_preview', ), 'image_anchor' => array( 'render element' => 'element', 'file' => 'image.admin.inc', + 'function' => 'theme_image_anchor', ), 'image_resize_summary' => array( 'variables' => array('data' => NULL), 'file' => 'image.admin.inc', + 'function' => 'theme_image_resize_summary', ), 'image_scale_summary' => array( 'variables' => array('data' => NULL), 'file' => 'image.admin.inc', + 'function' => 'theme_image_scale_summary', ), 'image_crop_summary' => array( 'variables' => array('data' => NULL), 'file' => 'image.admin.inc', + 'function' => 'theme_image_crop_summary', ), 'image_rotate_summary' => array( 'variables' => array('data' => NULL), 'file' => 'image.admin.inc', + 'function' => 'theme_image_rotate_summary', ), // Theme functions in image.field.inc. 'image_widget' => array( 'render element' => 'element', 'file' => 'image.field.inc', + 'function' => 'theme_image_widget', ), 'image_formatter' => array( 'variables' => array('item' => NULL, 'item_attributes' => NULL, 'path' => NULL, 'image_style' => NULL), 'file' => 'image.field.inc', + 'function' => 'theme_image_formatter', ), ); } diff --git a/core/modules/language/language.module b/core/modules/language/language.module index 3e7a04f..1a25dc9 100644 --- a/core/modules/language/language.module +++ b/core/modules/language/language.module @@ -118,14 +118,17 @@ function language_theme() { 'language_negotiation_configure_form' => array( 'render element' => 'form', 'file' => 'language.admin.inc', + 'function' => 'theme_language_negotiation_configure_form', ), 'language_negotiation_configure_browser_form_table' => array( 'render element' => 'form', 'file' => 'language.admin.inc', + 'function' => 'theme_language_negotiation_configure_browser_form_table', ), 'language_content_settings_table' => array( 'render element' => 'element', 'file' => 'language.admin.inc', + 'function' => 'theme_language_content_settings_table', ), ); } diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index d3e05dc..4c74d2c 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -190,6 +190,7 @@ function locale_theme() { 'locale_translate_edit_form_strings' => array( 'render element' => 'form', 'file' => 'locale.pages.inc', + 'function' => 'theme_locale_translate_edit_form_strings', ), 'locale_translation_last_check' => array( 'variables' => array('last' => NULL), diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module index 3639d26..57ecc30 100644 --- a/core/modules/menu_ui/menu_ui.module +++ b/core/modules/menu_ui/menu_ui.module @@ -109,6 +109,7 @@ function menu_ui_theme() { 'menu_overview_form' => array( 'file' => 'menu_ui.admin.inc', 'render element' => 'form', + 'function' => 'theme_menu_overview_form', ), ); } diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 38e047b..43b7ebf 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -164,6 +164,7 @@ function node_theme() { ), 'node_search_admin' => array( 'render element' => 'form', + 'function' => 'theme_node_search_admin', ), 'node_add_list' => array( 'variables' => array('content' => NULL), diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module index 53c182c..dbb818c 100644 --- a/core/modules/responsive_image/responsive_image.module +++ b/core/modules/responsive_image/responsive_image.module @@ -86,6 +86,7 @@ function responsive_image_theme() { 'attributes' => array(), 'breakpoints' => array(), ), + 'function' => 'theme_responsive_image', ), 'responsive_image_formatter' => array( 'variables' => array( @@ -94,6 +95,7 @@ function responsive_image_theme() { 'image_style' => NULL, 'breakpoints' => array(), ), + 'function' => 'theme_responsive_image_formatter', ), 'responsive_image_source' => array( 'variables' => array( @@ -102,6 +104,7 @@ function responsive_image_theme() { 'dimensions' => NULL, 'media' => NULL, ), + 'function' => 'theme_responsive_image_source', ), ); } diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index bec96c4..c65782f 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -56,6 +56,7 @@ function simpletest_theme() { 'simpletest_result_summary' => array( 'render element' => 'form', 'file' => 'simpletest.theme.inc', + 'function' => 'theme_simpletest_result_summary', ), ); } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 6bd8dd4..145bc95 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -176,6 +176,7 @@ function system_theme() { ), 'system_config_form' => array( 'render element' => 'form', + 'function' => 'theme_system_config_form', ), 'confirm_form' => array( 'render element' => 'form', @@ -184,10 +185,12 @@ function system_theme() { 'system_modules_details' => array( 'render element' => 'form', 'file' => 'system.admin.inc', + 'function' => 'theme_system_modules_details', ), 'system_modules_uninstall' => array( 'render element' => 'form', 'file' => 'system.admin.inc', + 'function' => 'theme_system_modules_uninstall', ), 'status_report' => array( 'variables' => array('requirements' => NULL), @@ -216,6 +219,7 @@ function system_theme() { ), 'system_compact_link' => array( 'variables' => array(), + 'function' => 'theme_system_compact_link', ), )); } 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 31ad453..32b5b26 100644 --- a/core/modules/system/tests/modules/common_test/common_test.module +++ b/core/modules/system/tests/modules/common_test/common_test.module @@ -119,6 +119,7 @@ function common_test_theme() { ), 'common_test_empty' => array( 'variables' => array('foo' => 'foo'), + 'function' => 'theme_common_test_empty', ), ); } diff --git a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module index e963c2f..974856a 100644 --- a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module +++ b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module @@ -12,6 +12,7 @@ function theme_suggestions_test_theme() { $items['theme_suggestions_test_include'] = array( 'file' => 'theme_suggestions_test.inc', 'variables' => array(), + 'function' => 'theme_theme_suggestions_test_include', ); return $items; } diff --git a/core/modules/system/tests/modules/theme_test/theme_test.module b/core/modules/system/tests/modules/theme_test/theme_test.module index b6f13c8..27a0136 100644 --- a/core/modules/system/tests/modules/theme_test/theme_test.module +++ b/core/modules/system/tests/modules/theme_test/theme_test.module @@ -7,6 +7,7 @@ function theme_test_theme($existing, $type, $theme, $path) { $items['theme_test'] = array( 'file' => 'theme_test.inc', 'variables' => array('foo' => ''), + 'function' => 'theme_theme_test', ); $items['theme_test_template_test'] = array( 'template' => 'theme_test.template_test', @@ -32,12 +33,15 @@ function theme_test_theme($existing, $type, $theme, $path) { ); $items['theme_test_function_suggestions'] = array( 'variables' => array(), + 'function' => 'theme_theme_test_function_suggestions', ); $items['theme_test_suggestions_include'] = array( 'variables' => array(), + 'function' => 'theme_theme_test_suggestions_include', ); $items['theme_test_foo'] = array( 'variables' => array('foo' => NULL), + 'function' => 'theme_theme_test_foo', ); $items['theme_test_render_element'] = array( 'render element' => 'elements', @@ -45,9 +49,11 @@ function theme_test_theme($existing, $type, $theme, $path) { ); $items['theme_test_render_element_children'] = array( 'render element' => 'element', + 'function' => 'theme_theme_test_render_element_children', ); $items['theme_test_function_template_override'] = array( 'variables' => array(), + 'function' => 'theme_theme_test_function_template_override', ); $info['test_theme_not_existing_function'] = array( 'function' => 'test_theme_not_existing_function', diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module index f46770a..402abc1 100644 --- a/core/modules/toolbar/toolbar.module +++ b/core/modules/toolbar/toolbar.module @@ -50,7 +50,6 @@ function toolbar_permission() { function toolbar_theme($existing, $type, $theme, $path) { $items['toolbar'] = array( 'render element' => 'element', - 'template' => 'toolbar', ); $items['toolbar_item'] = array( 'render element' => 'element', @@ -95,7 +94,7 @@ function toolbar_element_info() { // property contains a renderable array. $elements['toolbar_item'] = array( '#pre_render' => array('toolbar_pre_render_item'), - '#theme' => 'toolbar_item', + '#theme' => 'theme_toolbar_item', 'tab' => array( '#type' => 'link', '#title' => NULL, diff --git a/core/modules/update/update.module b/core/modules/update/update.module index eb77313..93af25d 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -175,21 +175,26 @@ function update_theme() { 'update_manager_update_form' => array( 'render element' => 'form', 'file' => 'update.manager.inc', + 'function' => 'theme_update_manager_update_form', ), 'update_last_check' => array( 'variables' => array('last' => NULL), + 'function' => 'theme_update_last_check', ), 'update_report' => array( 'variables' => array('data' => NULL), 'file' => 'update.report.inc', + 'function' => 'theme_update_report', ), 'update_version' => array( 'variables' => array('version' => NULL, 'tag' => NULL, 'class' => array()), 'file' => 'update.report.inc', + 'function' => 'theme_update_version', ), 'update_status_label' => array( 'variables' => array('status' => NULL), 'file' => 'update.report.inc', + 'function' => 'theme_update_status_label', ), ); } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 4b28c81..9dea4f2 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -109,12 +109,15 @@ function user_theme() { 'user_permission_description' => array( 'variables' => array('permission_item' => NULL, 'hide' => NULL), 'file' => 'user.admin.inc', + 'function' => 'theme_user_permission_description', ), 'user_signature' => array( 'variables' => array('signature' => NULL), + 'function' => 'theme_user_signature', ), 'username' => array( 'variables' => array('account' => NULL, 'attributes' => array()), + 'function' => 'theme_username', ), ); } diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 216bc93..8fe8ebb 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -121,7 +121,6 @@ function views_theme($existing, $type, $theme, $path) { // Our extra version of pager from pager.inc $hooks['views_mini_pager'] = $base + array( 'variables' => array('tags' => array(), 'quantity' => 10, 'element' => 0, 'parameters' => array()), - 'template' => 'views-mini-pager', ); $variables = array( @@ -141,10 +140,10 @@ function views_theme($existing, $type, $theme, $path) { // Default view themes $hooks['views_view_field'] = $base + array( 'variables' => array('view' => NULL, 'field' => NULL, 'row' => NULL), + 'function' => 'theme_views_view_field', ); $hooks['views_view_grouping'] = $base + array( 'variables' => array('view' => NULL, 'grouping' => NULL, 'grouping_level' => NULL, 'rows' => NULL, 'title' => NULL), - 'template' => 'views-view-grouping', ); $plugins = Views::getPluginDefinitions(); @@ -173,35 +172,44 @@ function views_theme($existing, $type, $theme, $path) { 'variables' => $variables[$type], ); - // For the views module we ensure views.theme.inc is included. - if ($def['provider'] == 'views') { - $def['theme_file'] = 'views.theme.inc'; - } // We always use the module directory as base dir. $module_dir = drupal_get_path('module', $def['provider']); + $hooks[$def['theme']]['path'] = $module_dir; + // For the views module we ensure views.theme.inc is included. + if ($def['provider'] == 'views') { + if (!isset($hooks[$def['theme']]['includes'])) { + $hooks[$def['theme']]['includes'] = array(); + } + if (!in_array('views.theme.inc', $hooks[$def['theme']]['includes'])) { + $hooks[$def['theme']]['includes'][] = $module_dir . '/views.theme.inc'; + } + } // The theme_file definition is always relative to the modules directory. - if (isset($def['theme_file'])) { - $hooks[$def['theme']]['path'] = $module_dir; + elseif (!empty($def['theme_file'])) { $hooks[$def['theme']]['file'] = $def['theme_file']; } + // Whenever we got a theme file, we include it directly so we can // auto-detect the theme function. if (isset($def['theme_file'])) { - $include = DRUPAL_ROOT . '/' . $module_dir. '/' . $def['theme_file']; + $include = DRUPAL_ROOT . '/' . $module_dir . '/' . $def['theme_file']; if (is_file($include)) { require_once $include; } } - // If there is no theme function for the given theme definition, we assume - // a template file shall be used. By default this file is located in the - // /templates directory of the module's folder. - // If a module wants to define its own location it has to set - // register_theme of the plugin to FALSE and implement hook_theme() by - // itself. + + // If there is no theme function for the given theme definition, it must + // be a template file. By default this file is located in the /templates + // directory of the module's folder. If a module wants to define its own + // location it has to set register_theme of the plugin to FALSE and + // implement hook_theme() by itself. if (!function_exists('theme_' . $def['theme'])) { - $hooks[$def['theme']]['path'] = $module_dir; - $hooks[$def['theme']]['template'] = 'templates/' . drupal_clean_css_identifier($def['theme']); + $hooks[$def['theme']]['path'] .= '/templates'; + $hooks[$def['theme']]['template'] = drupal_clean_css_identifier($def['theme']); + } + else { + $hooks[$def['theme']]['function'] = 'theme_' . $def['theme']; } } } @@ -211,13 +219,11 @@ function views_theme($existing, $type, $theme, $path) { ); $hooks['views_exposed_form'] = $base + array( - 'template' => 'views-exposed-form', 'render element' => 'form', ); $hooks['views_more'] = $base + array( 'variables' => array('more_url' => NULL, 'link_text' => 'more', 'view' => NULL), - 'template' => 'views-more', ); return $hooks; diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module index ba5e342..dc5e7cc 100644 --- a/core/modules/views_ui/views_ui.module +++ b/core/modules/views_ui/views_ui.module @@ -80,10 +80,12 @@ function views_ui_theme() { 'views_ui_rearrange_filter_form' => array( 'render element' => 'form', 'file' => 'views_ui.theme.inc', + 'function' => 'theme_views_ui_rearrange_filter_form', ), 'views_ui_expose_filter_form' => array( 'render element' => 'form', 'file' => 'views_ui.theme.inc', + 'function' => 'theme_views_ui_expose_filter_form', ), // list views @@ -97,6 +99,7 @@ function views_ui_theme() { 'views_ui_build_group_filter_form' => array( 'render element' => 'form', 'file' => 'views_ui.theme.inc', + 'function' => 'theme_views_ui_build_group_filter_form', ), // On behalf of a plugin diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine index 1595bf8..b6d8fdb 100644 --- a/core/themes/engines/twig/twig.engine +++ b/core/themes/engines/twig/twig.engine @@ -36,22 +36,27 @@ function twig_init(Extension $theme) { * If the Twig debug setting is enabled, HTML comments including _theme() call * and template file name suggestions will surround the template markup. * - * @param $template_file + * @param string $template_file * The file name of the template to render. - * @param $variables + * @param array $variables * A keyed array of variables that will appear in the output. * - * @return + * @return string * The output generated by the template, plus any debug information. */ function twig_render_template($template_file, $variables) { $twig_service = \Drupal::service('twig'); - $output = array( - 'debug_prefix' => '', - 'debug_info' => '', - 'rendered_markup' => $twig_service->loadTemplate($template_file)->render($variables), - 'debug_suffix' => '', - ); + try { + $output = array( + 'debug_prefix' => '', + 'debug_info' => '', + 'rendered_markup' => $twig_service->loadTemplate($template_file)->render($variables), + 'debug_suffix' => '', + ); + } + catch (\Twig_Error_Loader $e) { + drupal_set_message($e->getMessage(), 'error'); + } if ($twig_service->isDebug()) { $output['debug_prefix'] .= "\n\n"; $output['debug_prefix'] .= "\n"; -- 1.9.1