Posted by venkatd on November 9, 2009 at 7:07am
14 followers
| Project: | Views |
| Version: | 7.x-3.x-dev |
| Component: | Code |
| Category: | task |
| Priority: | normal |
| Assigned: | dawehner |
| Status: | closed (fixed) |
Issue Summary
I have overridden some views templates provided by the theme information link in the Views UI interface. Currently these templates are stored in the garland theme folder. I would like these templates to be moved (and if possible, renamed) to mymodule/templates. The reason is that I want my module to be self-contained and theme-independent. I don't want to make users copy these template files to each theme that they use.
I have tried editing the 'theme_paths' attribute of views_view_field in hook_theme_registry alter. I have tried manually implementing the override in hook theme as below:
<?php
/**
* Implementation of hook_theme()
*/
function loa_degree_theme() {
return array(
'views_view_field__degrees_edit__tid_1' => array(
'template' => 'views-view-field--degrees--edit--tid-1',
'path' => drupal_get_path('module', 'loa_degree') . '/templates',
'arguments' => array('view' => NULL, 'field' => NULL, 'row' => NULL),
'original hook' => 'views_view_field',
'type' => 'module',
'preprocess functions' => array('template_preprocess', 'template_preprocess_views_view_field'),
),
);
}
?>Any advice would be appreciated. Thanks!
Comments
#1
This is clearly documented in the advanced help. If you have specific questions about that documentation you may ask them.
#2
Got it working!
Sorry about that. I wasn't aware of advanced help. Wish it was part of core and more visible.
#3
I have the same problem as stated here. Can you please post the solution?
I would like to move my template files into my module folder. Views doesn't see them when I override them through hook_theme(). I looked through the advanced help (http://mysite.org/admin/advanced_help/views) but didn't find the solution.
#4
Hello,
I've read the documentation about views theming, and template suggestions, and I understood that the way the templates are searched is module -> base theme -> theme, so, I copied the views templates which are working on my current theme to a module with views embedded, but when i change to another theme the templates are not used.
I've cleared all caches including theme registry several times, rescanned the templates from views ui, but I can't get them to work.
Is there any document explaining how to use templates from a module directory which provides default views?
Thanks.
#5
Forget about my last comment, it's documented on http://yourdrupalsite.org/help/views/api-default-views
#6
Sorry for a late reply. I've been very distracted.
I wrote the following mini module that lets you put views template overrides in your module's directory (I named my module x, but obviously you can replace x_ with anything you want.) I hope something like this can be part of views because it's such a pain in the __ to do this every time I want to override a template.
<?php
/**
* Implementation of hook_theme()
**/
function x_theme() {
$theme = array();
foreach (module_implements('views_api') as $module) {
$theme += x_views_get_overrides($module);
}
return $theme;
}
function x_views_get_overrides($module) {
$theme = array();
$field_template_files = array();
$template_files = file_scan_directory(drupal_get_path('module', $module), '\.tpl\.php$');
foreach ($template_files as $file) {
$path = dirname($file->filename);
// view display override
if (preg_match('/^(?P<template>views-view--.+)\.tpl.php$/', $file->basename, $match)) {
$theme_hook = str_replace('-', '_', $match['template']);
$arguments = array('view' => NULL);
$theme[$theme_hook] = array(
'path' => $path,
'template' => $match['template'],
'arguments' => array('view' => NULL),
'original hook' => 'views_view',
);
}
//style override
elseif (preg_match('/^(?P<template>views-view-list--.+)\.tpl.php$/', $file->basename, $match)) {
$theme_hook = str_replace('-', '_', $match['template']);
$theme[$theme_hook] = array(
'path' => $path,
'template' => $match['template'],
'arguments' => array('view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL),
'original hook' => 'views_view_list',
);
}
// row style override
elseif (preg_match('/^(?P<template>views-view-fields--.+)\.tpl.php$/', $file->basename, $match)) {
$theme_hook = str_replace('-', '_', $match['template']);
$theme[$theme_hook] = array(
'path' => $path,
'template' => $match['template'],
'arguments' => array('view' => NULL, 'options' => NULL, 'row' => NULL),
'original hook' => 'views_view_fields',
);
}
// field override
elseif (preg_match('/^(?P<template>views-view-field--.+)\.tpl.php$/', $file->basename, $match)) {
$theme_hook = str_replace('-', '_', $match['template']);
$theme[$theme_hook] = array(
'path' => $path,
'template' => $match['template'],
'arguments' => array('view' => NULL, 'field' => NULL, 'row' => NULL),
'original hook' => 'views_view_field',
);
}
}
return $theme;
}
?>
#7
Let's reopen the issue.
I think we shouldn't use regexes here, we should check every existing theme type of views: style-theme/summary-theme etc.
This has to be written generalized.
#8
It would be better written as just a hook or something.
We cannot rely on the naming of templates because something like views_attach could create a template named views-attach--viewname.tpl.php etc. That's perfectly legit.
So what we should do is simply be able to provide a directory where we're doing theme overrides and try to scan it similarly to how core scans a directory and do what is needed.
#9
Would it be possible to add a feature to views so that it scans the /views_templates subdirectory (or something like that) within every module directory?
#10
Could use hook_views_api() to specify the directory easily enough, and then scan that for views-related templates. Actually it'd probably have to be any templates.
#11
http://api.drupal.org/api/function/drupal_find_theme_templates/6
Here is a similar function.
#12
subscribing
#13
Here is a patch, with a test.
One for d6-3 and one for d6-2
#14
Let's do this just for 6.x-3.x
I think the patch looks pretty good. Committed. Two things are needed:
1) Update the documentation so that developers know they can do this.
2) Port to D7.x
#15
Here is one.
Adding the info to docs/docs.php and help/api.html.
#16
Committed the documentation to both branches. I suppose that was premature on D7 since the initial patch actually may not have been ported?
#17
It's ported now.
#18
Automatically closed -- issue fixed for 2 weeks with no activity.
#19
The D7 port did not work for me, the new template path was not carried in the $templates structure from _views_find_module_templates. This seemed to be fixed by changing
'path' => dirname($files[$match]->filename)to'path' => dirname($files[$match]->uri)on line 179. This needs checking as I'm not that familiar with the code.#20
This sadly didn't fixed the simpletest, but this could be caused by something else.
Feel free to create a real patch file.
#21
subscribe
#22
#19 worked for me. Patch attached.
#23
@mstrelan
Does the simpletest run with your patch?
#24
Well for a start my patch was meant to only change one line, not two, so here is an updated one. Unfortunately the simpletest fails on viewsModuleTest->testModuleTemplates() but from what I can tell the views_module.test doesn't call
module_enable(array('views_test'));like views_query.test does. I'm new to simpletest so I'm not sure if the module gets enabled some other way.#25
That's fine. The enabling of the module happens because the test class in views_module.test inherits from the one on views_query.test
Can you try to find out whether the test is broken/why it's broken?
This would be really cool.
#26
I've given it a shot, but still no luck. Here is what I have found.
When I inspect the theme registry on my site with my custom module enabled I see views_view__MYVIEWNAME. When I debug the array keys of the registry from simpletest I don't see views_view__frontpage nor views_view__MYVIEWNAME.
In my custom module implementation of hook_views_api() I set the api version to 3. In views_test.module this is set to 3.0-alpha1. Assuming that this was way too specific, especially since I'm not using alpha1 I tried changing that to 3. No luck.
Finally I thought that when you add template files to your module / theme you have to flush the theme registry, and while I would have thought this was done automatically when views_test.module is enabled I thought I'd whack in a registry_rebuild() and maybe a cache_clear_all(). Still no luck, but I hope that this information will help someone else to find the problem. I probably won't get more time to look in to this for a while, but I am absolutely convinced that it is a broken test case rather than a broken patch.
#27
3.0-alpha1 is the right version, it's what views_api_version() returns.
You say that your patch works for you, and currently the feature doesn't work at all. So it's fine from my perspective to commit the patch, but fixing the test would be great
Commited to 7.x-3.x
please create a new issue for the test.
#28
#1176008: views_module.test fails testing for views template override in a module
#29
Maybe the wrong place for this, but in D7 can you still add a views template to your module using the
hook_theme()method? The issue I've run into is that I have a feature module (http://drupal.org/features) and as part of it I'd like to include a views template for the view I have in my feature. The issue is that Features module takes care of implementinghook_views_api()in the module_name.features.inc file, so I can't add thetemplate pathkey to the return array ofhook_views_api().Here is the
hook_theme()implementation I have in my module:/*** Implements hook_theme().
*/
function client_news_theme() {
return array(
'views_view__fields__news__page' => array(
'variables' => array('view' => NULL, 'options' => NULL, 'row' => NULL),
'template' => 'views-view--fields--news--page',
'base hook' => 'views_view_fields',
'path' => drupal_get_path('module', 'client_news'),
),
);
}
After adding the file views-view--fields--news--page.tpl.php and clearing the cache, I'm not seeing the override take effect. Any help is appreciated.
Matt
#30
Sigh...being a programmer is a b*tch. I figured it out. Turns out you can use the
hook_theme()method, exactly as I did above except for one suttle difference:/*** Implements hook_theme().
*/
function client_news_theme() {
return array(
'views_view_fields__news__page' => array(
'variables' => array('view' => NULL, 'options' => NULL, 'row' => NULL),
'template' => 'views-view-fields--news--page',
'base hook' => 'views_view_fields',
'path' => drupal_get_path('module', 'client_news'),
),
);
}
I had double '-' and '_' where I should have had single.
Matt
#31
Automatically closed -- issue fixed for 2 weeks with no activity.
#32
Does this work in drupal 7 as well ?
I am using this code:
'views_view_fields__article_images__block' => array('arguments' => array('view' => NULL, 'options' => NULL, 'row' => NULL),
'template' => 'views-view-fields--article-images--block',
'original hook' => 'views_view_fields',
'path' => drupal_get_path('module', 'article_js_and_css') . '/article_slider',
),
which works. but in the template file, the $fields variable is empty
#33
Doesn't work in D6 either.
We've noticed this behaviour when you clear your caches or you're running update.php. It's quite inconsistent when $fields is or isn't empty.
One way of fixing this is to press "rescan templates" in your view which rebuilds the theme registry including the reference to $fields argument in the themeing hook.
Any ideas on this?
#34
The $fields variable is empty due to the way hook theme was written. I have put a short tutorial here that shows how to get it working on Drupal 6 using views 3. http://pixelclever.com/how-declare-views-template-inside-module
Hope that helps.