diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 34a9d69ca74697d83bb5caf35001c9ad4b22859b..1e0d4406491a988cc51423a6c3e1e4dfd72245de 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -553,4 +553,5 @@ Views 3.x-7.x-dev
o #1000044 by pivica: Fix notice for element_type in some field handlers.
o #984390 by yhahn: Fix full pager variables.
o #972620 by dereine: Add an administrative title field for all handlers to make it more possible to distinguish similar fields from each other in the UI.
+ o #627378: Allow specifying that your module provides specialized views templates via hook_views_api.
diff --git a/tests/templates/views-view--frontpage.tpl.php b/tests/templates/views-view--frontpage.tpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a9410ff1bc5af41bec8aa8ef1fc312c16429eed
--- /dev/null
+++ b/tests/templates/views-view--frontpage.tpl.php
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/views_module.test b/tests/views_module.test
index 0a3c3b1e215eef72fb4a3bde6b25268d57825295..bec665f40ebd54051fc174bbe1c75d2f6d26f545 100644
--- a/tests/views_module.test
+++ b/tests/views_module.test
@@ -9,11 +9,11 @@ class viewsModuleTest extends ViewsSqlTest {
'group' => 'Views',
);
}
-
+
public function setUp() {
parent::setUp();
}
-
+
public function test_views_trim_text() {
// Test unicode, @see http://drupal.org/node/513396#comment-2839416
$text = array(
@@ -58,12 +58,22 @@ class viewsModuleTest extends ViewsSqlTest {
'сд асд',
'асд асд',
);
-
+
foreach ($text as $key => $line) {
$result_text = views_trim_text($alter, $line);
- debug($result_text);
- debug($expect[$key]);
$this->assertEqual($result_text, $expect[$key]);
}
}
+
+ /**
+ * Tests the dynamic includes of templates via module feature.
+ */
+ function testModuleTemplates() {
+ $views_status = variable_get('views_defaults', array());
+ $views_status['frontpage'] = FALSE; // false is enabled
+ variable_set('views_defaults', $views_status);
+
+ $registry = theme_get_registry();
+ $this->assertTrue(isset($registry['views_view__frontpage']));
+ }
}
diff --git a/tests/views_query.test b/tests/views_query.test
index 38efbc1e0479c8ba757749e3612ef4f0e6608baa..31d294927990fc7c3f1d3aec4870d9ea5a7472eb 100644
--- a/tests/views_query.test
+++ b/tests/views_query.test
@@ -312,6 +312,10 @@ abstract class ViewsSqlTest extends ViewsTestCase {
return $data;
}
+ protected function viewsPlugins() {
+ return array();
+ }
+
/**
* A very simple test dataset.
*/
diff --git a/tests/views_test.module b/tests/views_test.module
index 1820b3398f79b89e108686edb8ef73fe59fd8e89..0f7a3f9fa58db3f7979deaddd8b23bb859b45420 100644
--- a/tests/views_test.module
+++ b/tests/views_test.module
@@ -19,6 +19,7 @@ function views_test_permission() {
function views_test_views_api() {
return array(
'api' => '3.0-alpha1',
+ 'template path' => drupal_get_path('module', 'views_test') . '/templates',
);
}
diff --git a/views.info b/views.info
index db2ec7d8262ff59f850e354278bede68150acddb..c2265b4c79599ddc682a29cadb3743ecc39401cb 100644
--- a/views.info
+++ b/views.info
@@ -35,8 +35,7 @@ files[] = handlers/views_handler_filter_date.inc
files[] = handlers/views_handler_filter_equality.inc
files[] = handlers/views_handler_filter_in_operator.inc
files[] = handlers/views_handler_filter_many_to_one.inc
-files[] = handlers/views_handler_filter_numeric.inc
-files[] = handlers/views_handler_filter_string.inc
+files[] = handlers/views_handler_filter_numeric.inc files[] = handlers/views_handler_filter_string.inc
files[] = handlers/views_handler_relationship.inc
files[] = handlers/views_handler_sort.inc
files[] = handlers/views_handler_sort_group_by_numeric.inc
@@ -300,6 +299,7 @@ files[] = tests/views_exposed_form.test
files[] = tests/views_glossary.test
files[] = tests/views_groupby.test
files[] = tests/views_handlers.test
+files[] = tests/views_module.test
files[] = tests/views_pager.test
files[] = tests/views_plugin_localization_test.inc
files[] = tests/views_translatable.test
@@ -307,4 +307,4 @@ files[] = tests/views_query.test
files[] = tests/views_test.views_default.inc
files[] = tests/user/views_user_argument_default.test
files[] = tests/user/views_user_argument_validate.test
-files[] = tests/views_cache.test
\ No newline at end of file
+files[] = tests/views_cache.test
diff --git a/views.module b/views.module
index 754bd7f8e33dbcca32345017e7618006458072b0..f5e2fb6e5bd33b42cee36f23aefaccb5e126695a 100644
--- a/views.module
+++ b/views.module
@@ -33,7 +33,7 @@ function views_init() {
/**
* Implement hook_theme(). Register views theming functions.
*/
-function views_theme() {
+function views_theme($existing, $type, $theme, $path) {
$path = drupal_get_path('module', 'views');
include_once $path . '/theme/theme.inc';
@@ -116,9 +116,88 @@ function views_theme() {
'pattern' => 'views_more__',
'variables' => array('more_url' => NULL, 'link_text' => 'more'),
);
+
+ // Add theme suggestions which are part of modules.
+ foreach (views_get_module_apis() as $info) {
+ if (isset($info['template path'])) {
+ $hooks += _views_find_module_templates($hooks, $info['template path']);
+ }
+ }
return $hooks;
}
+/**
+ * Scans a directory of a module for template files.
+ *
+ * @param $cache
+ * The existing cache of theme hooks to test against.
+ * @param $path
+ * The path to search.
+ *
+ * @see drupal_find_theme_templates
+ */
+function _views_find_module_templates($cache, $path) {
+ $regex = '\.tpl\.php' . '$';
+
+ // Because drupal_system_listing works the way it does, we check for real
+ // templates separately from checking for patterns.
+ $files = drupal_system_listing($regex, $path, 'name', 0);
+ debug($files);
+ foreach ($files as $template => $file) {
+ // Chop off the remaining extensions if there are any. $template already
+ // has the rightmost extension removed, but there might still be more,
+ // such as with .tpl.php, which still has .tpl in $template at this point.
+ if (($pos = strpos($template, '.')) !== FALSE) {
+ $template = substr($template, 0, $pos);
+ }
+ // Transform - in filenames to _ to match function naming scheme
+ // for the purposes of searching.
+ $hook = strtr($template, '-', '_');
+ if (isset($cache[$hook])) {
+ $templates[$hook] = array(
+ 'template' => $template,
+ 'path' => dirname($file->filename),
+ 'include files' => $cache[$hook]['include files'],
+ );
+ }
+ // Ensure that the pattern is maintained from base themes to its sub-themes.
+ // Each sub-theme will have their templates scanned so the pattern must be
+ // held for subsequent runs.
+ if (isset($cache[$hook]['pattern'])) {
+ $templates[$hook]['pattern'] = $cache[$hook]['pattern'];
+ }
+ }
+
+ $patterns = array_keys($files);
+
+ debug($cache);
+ foreach ($cache as $hook => $info) {
+ if (!empty($info['pattern'])) {
+ // Transform _ in pattern to - to match file naming scheme
+ // for the purposes of searching.
+ $pattern = strtr($info['pattern'], '_', '-');
+
+ $matches = preg_grep('/^'. $pattern .'/', $patterns);
+ if ($matches) {
+ foreach ($matches as $match) {
+ $file = substr($match, 0, strpos($match, '.'));
+ // Put the underscores back in for the hook name and register this pattern.
+ debug($info);
+ $templates[strtr($file, '-', '_')] = array(
+ 'template' => $file,
+ 'path' => dirname($files[$match]->filename),
+ 'variables' => $info['arguments'],
+ 'original hook' => $hook,
+ 'include files' => $info['include files'],
+ );
+ }
+ }
+ }
+ }
+
+ return $templates;
+}
+
/**
* A theme preprocess function to automatically allow view-based node
* templates if called from a view.
@@ -640,6 +719,7 @@ function views_get_module_apis($reset = FALSE) {
}
}
+ debug($cache);
return $cache;
}