显示一个没有页面模板的 Drupal 视图
Posted
技术标签:
【中文标题】显示一个没有页面模板的 Drupal 视图【英文标题】:displaying a Drupal view without a page template around it 【发布时间】:2010-09-19 20:46:02 【问题描述】:我想显示一个没有通常围绕它的页面模板的 Drupal 视图 - 我只想要视图节点的纯 html 内容。
此视图将包含在另一个非 Drupal 站点中。
我希望必须使用多个视图来执行此操作,因此让我快速轻松地设置这些视图的解决方案将是最好的 - 我不想每次都创建一个 .tpl.php 文件我需要在某处包含一个视图。
【问题讨论】:
【参考方案1】:我正在寻找一种通过 ajax 提取节点数据的方法,并为 Drupal 6 提出了以下解决方案。在实施以下更改后,如果您在 URL 中添加 ajax=1(例如 mysite.com/node/1 ?ajax=1),您将只得到内容而没有页面布局。
在您的主题的 template.php 文件中:
function phptemplate_preprocess_page(&$vars)
if ( isset($_GET['ajax']) && $_GET['ajax'] == 1 )
$vars['template_file'] = 'page-ajax';
然后使用以下内容在您的主题目录中创建 page-ajax.tpl.php:
<?php print $content; ?>
【讨论】:
这是一种简单而有效的方法!哇!欢迎使用 ***,谢谢! 这似乎是正确的答案,但它对我不起作用。我在 function phptemplate_preprocess_page(&$vars) print "It gets here";并且什么也没有发生。我什至不认为这个函数被调用了。 有没有什么情况可能不会被调用? Brian:名称“phptemplate”表示您的主题名称。我的主题名称是“carshop”,所以函数名称是 carshop_preprocess_page(&$vars)。 这既简单又优雅……但您仍然必须处理所有那些乱七八糟的格式和垃圾。当然,有一个不错的模块:drupal.org/project/views_datasource【参考方案2】:根据 Ufonion Labs 的回答,通过在我的主题 template.php 中实现 hook_preprocess_page
和 hook_preprocess_html
,我能够完全删除 Drupal 7 中页面内容周围的所有 HTML 输出,如下所示:
function MY_THEME_preprocess_page(&$variables)
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed')
$variables['theme_hook_suggestions'][] = 'page__embed';
function MY_THEME_preprocess_html(&$variables)
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed')
$variables['theme_hook_suggestions'][] = 'html__embed';
然后我在我的主题中添加了两个模板:html--embed.tpl.php
:
<?php print $page; ?>
和page--embed.tpl.php
:
<?php print render($page['content']); ?>
现在当我打开一个节点页面时,例如http://example.com/node/3,我照常看到完整的页面,但是当我添加 response_type 参数时,例如http://example.com/node/3?response_type=embed,我只得到<div>
带有页面内容,因此可以嵌入到另一个页面中。
【讨论】:
谢谢,我花了几个小时测试其他不起作用的方法。【参考方案3】:我知道这个问题已经得到解答,但我想添加我自己的解决方案,该解决方案使用费城网页设计 (PWD) 答案的元素并使用 Hook_theme_registry_alter,正如 Owen 所建议的那样。使用此解决方案,您可以直接从自定义模块加载模板。
首先,我将 raw.tpl.php 添加到模块内新创建的“模板”文件夹中。 raw.tpl.php的内容和PWD的page-ajax.tpl.php是一样的:
<?php print $content; ?>
接下来,我以与 PWD 相同的方式在我的模块中实现了 hook_preprocess_page(除了我修改了 $_GET 参数并更新了模板文件引用:
function MY_MODULE_NAME_preprocess_page(&$vars)
if ( isset($_GET['raw']) && $_GET['raw'] == 1 )
$vars['template_file'] = 'raw';
最后,我实现了 hook_theme_registry_alter 将我的模块的“模板”目录添加到主题注册表中(基于http://drupal.org/node/1105922#comment-4265700):
function MY_MODULE_NAME_theme_registry_alter(&$theme_registry)
$modulepath = drupal_get_path('module','MY_MODULE_NAME');
array_unshift($theme_registry['page']['theme paths'], $modulepath.'/templates');
现在,当我将 ?raw=1 添加到视图的 URL 路径时,它将使用我模块中的指定模板。
【讨论】:
【参考方案4】:对于可能点击此页面的其他人,如果您只是使用标准回调(不一定是视图),这很容易。在您的回调函数中,不要返回要在页面中呈现的代码,而是使用“打印”函数。
例如:
function mymodule_do_ajax($node)
$rval = <<<RVAL
<table>
<th>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</th>
<tr>
<td>Cool</td>
<td>Cool</td>
<td>Cool</td>
</tr>
</table>
RVAL;
//return $rval; Nope! Will render via the templating engine.
print $rval; //Much better. No wrapper.
干杯!
【讨论】:
这是迄今为止最简单的解决方案。谢谢。【参考方案5】:另一种我觉得非常方便的方法是添加一个带有不返回字符串的页面回调函数的菜单项:
例子:
/**
* Implementation of hook_menu.
*/
function test_menu()
$items['test'] = array (
/* [...] */
'page callback' => 'test_callback',
/* [...] */
);
return $items;
function test_callback()
// echo or print whatever you want
// embed views if you want
// DO NOT RETURN A STRING
return TRUE;
-- 更新
最好使用exit();
而不是return TRUE;
(见评论)。
【讨论】:
如果您使用 ctools,这将导致一堆警告(ctools_page_alter
将假定它是一个数组)。【参考方案6】:
嘿,这是另一种方法:
1) 下载并安装 Views Bonus Pack (http://drupal.org/project/views_bonus) 2)创建一个视图显示“Feed”并使用样式“XML”(或您认为更适合您需要的东西)。 3) 如果您对标准的 XML 输出不满意,可以通过调整视图的模板来更改它。检查“主题”设置以获取有关此特定视图的替代模板名称的建议(因此您仍将保留默认的 XML 输出以供将来使用)。
祝你好运! //Johan Falk,NodeOne,瑞典
【讨论】:
【参考方案7】:根据Philadelphia Web Design 的回答(谢谢)和一些谷歌搜索(http://drupal.org/node/957250),这对我来说在 Drupal 7 中可以在没有模板的情况下显示所选页面:
function pixture_reloaded_preprocess_page(&$vars)
if ( isset($_GET['vlozeno']) && $_GET['vlozeno'] == 1 )
$vars['theme_hook_suggestions'][] = 'page__vlozeno';
代替 phptemplate,在 D7 中,函数名称中必须有 name_of_your_theme。另外,我必须在文件名的 php 变量中加上两个下划线 __,但实际的模板文件名需要两个破折号 --
页面内容--vlozeno.tpl.php:
<?php print render($page['content']); ?>
然而,输出仍然有很多包装和主题的 CSS 引用。不知道如何输出完全没有主题的数据...
【讨论】:
如果你想完全去除所有的包装html,包括,假设您在 Drupal 6 中,最简单的方法是在 template.php
中调用 phptemplate_views_view_unformatted_VIEWNAME
(假设您的视图未格式化 - 如果是其他内容,列表说,请使用适当的主题功能)。然后,在此主题调用中为视图结果设置主题,而不是像往常一样返回结果,而是打印它们并返回 NULL
。这将直接输出 HTML。
PS - 确保清除缓存(在 /admin/settings/performance)以查看这项工作。
【讨论】:
【参考方案9】:可能有很多方法可以解决这个问题,但是,“最简单的”可能只是设置您自己的自定义主题,并且让 page.tpl.php 为空,或者一些随机的 div
// page.tpl.php
<div id="page"><?php print $content ?></div>
这个方法基本上只允许 node.tpl.php 显示(或任何 drupal 的表单视图等......),并且是避免修改核心或必须更改主题注册表以避免显示的简单方法page.tpl.php 放在首位。
编辑:见 cmets
好吧,我玩了一下视图,看起来它接管并构建了它自己的“node.tpl.php”(在某种意义上)以在“page.tpl.php”中显示。乍一看,我的直觉是喜欢theme_registry_alter()
。
当您查看视图页面时,您可以访问此处的大量信息以及 page.tpl.php 路径/文件。因此我会做类似的事情:
function modulejustforalteration_theme_registry_alter(&$variables)
if (isset($variables['views_ui_list_views']) )
// not sure if that's the best index to test for "views" but i imagine it'll work
// as well as others
$variables['page']['template'] = 'override_page';
这应该允许您在当前主题中使用“override_page.tpl.php”模板,您可以在其中删除您想要的任何内容(如我上面的第一个答案)。
一些事情:
正如我所说,不确定views_ui_list_views
是否始终可以检查,但听起来如果我们正在查看视图,应该设置它
如果您愿意,可以更改 page
数组的 theme paths
(更改 drupal 查找 page.tpl.php 的位置,而不是完全重命名)
此特定视图似乎没有任何标识符,因此此方法可能是“所有视图都将被剥离”的方法。如果您只需要为特定视图剥离 page.tpl.php,也许挂钩到 template_preprocess_page()
可能是一个更好的主意。
【讨论】:
如果我只使用这个站点来嵌入其他地方,那会起作用,但我需要普通节点与它们的普通页面模板一起显示。 嗯,您是否只有特定的节点类型,即“外部视图”?或者你能再澄清一点吗?即我认为“页面节点是外部的”与“我选择的任何类型的节点都是外部的”有不同的答案 不是节点,而是视图。有时,所有节点都需要在页面模板中显示。需要取消主题的是视图(带有页面显示)。有点像提要显示的工作方式,但使用节点 HTML 而不是 RSS 格式。 啊嗯,我没怎么玩视图,但是我今天下午会看看,看看我是否可以提供一些更好的建议,我不确定视图具体是如何组合在一起的它是元素,但我感觉答案是改变主题注册表。这是 drupal 6 是吗? 是的,D6。我怀疑你是对的,一个调整主题注册表的小模块可能是最好的方法。我很惊讶没有人需要这样的东西来制作模块......【参考方案10】:我喜欢 Drupal 模块。但是,这是另一种方式。
将主题文件夹中的 page.tpl.php 复制到名为 page-VIEWNAME.tpl.php 的新文件中,其中 VIEWNAME 是视图的机器可读名称。
然后编辑 page-VIEWNAME.tpl.php 以适应。
【讨论】:
【参考方案11】:还有http://drupal.org/project/pagearray,这是一个通用的解决方案……
另外,@Scott Evernden 的解决方案是跨站脚本 (XSS) 安全漏洞。不要那样做。阅读 drupal.org 上的文档,了解如何以安全的方式处理文本http://drupal.org/node/28984
【讨论】:
【参考方案12】:一种显示您希望显示的特殊内容类型的简单方法,无需 page.tpl.php
的所有内容:
将以下 sn-p 添加到您的 template.php
文件中:
function mytheme_preprocess_page(&$vars)
if ($vars['node'] && arg(2) != 'edit')
$vars['template_files'][] = 'page-nodetype-'. $vars['node']->type;
将page-nodetype-examplecontenttype.tpl.php
添加到您的主题中,例如您的page.tpl.php
,但不要显示您不想显示的内容,并且在正文中添加print $content
。
【讨论】:
【参考方案13】:如果我理解您的问题,您希望节点包含页面的所有 HTML,从 DOCTYPE 到
【参考方案14】:我看到你已经把自己变成了一个模块,所以这可能不再有帮助,但是获得一个视图来公开一个 rss 提要相当容易,这可能是获取内容的一种更简单的方法,尤其是如果您想将其包含在其他站点上。
【讨论】:
【参考方案15】:在 D7 上,您可以使用 menu_execute_active_handler
$build = menu_execute_active_handler('user', FALSE);
return render($build);
【讨论】:
【参考方案16】:jeroen 的回答是玩过它后对我的影响。我有一个 Drupal 7 站点。
首先确保将MY_THEME
替换为您的主题名称。是的,这很明显,但大多数新手都错过了这一点。
我实际上已经有一个function MY_THEME_preprocess_page(&$variables)
。然后不要重新创建函数,而是在函数末尾添加这段代码,然后用 关闭它。
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed')
$variables['theme_hook_suggestions'][] = 'page__embed';
-
我的函数使用了
$vars
而不是$variables
,所以我也必须更新它。如果您想寻找它,这又是显而易见的。
【讨论】:
【参考方案17】:我的第一个回答只允许我在网络浏览器中调用它时显示该节点。然而,这样做的最终目标是使用 iframe 将 drupal 节点嵌入到第三方站点中。
自 Drupal 发布以来Core 7.50 iframe is by default blocked to prevent Clickjacking
要仅让节点成功嵌入第 3 方站点,您还需要覆盖 x-frame 默认设置。在 template.php 中添加以下内容后,一切都开始工作了
function MY_THEME_page_alter($page)
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed')
header_remove('X-Frame-Options');
【讨论】:
以上是关于显示一个没有页面模板的 Drupal 视图的主要内容,如果未能解决你的问题,请参考以下文章