我想显示一个没有通常围绕它的页面模板的 Drupal 视图——我只想要视图节点的纯 HTML 内容。
此视图将包含在另一个非 Drupal 站点中。
我希望必须使用多个视图来执行此操作,因此让我快速轻松地设置这些视图的解决方案将是最好的 - 我不想每次都需要创建 .tpl.php 文件在某处包含一个视图。
我想显示一个没有通常围绕它的页面模板的 Drupal 视图——我只想要视图节点的纯 HTML 内容。
此视图将包含在另一个非 Drupal 站点中。
我希望必须使用多个视图来执行此操作,因此让我快速轻松地设置这些视图的解决方案将是最好的 - 我不想每次都需要创建 .tpl.php 文件在某处包含一个视图。
我正在寻找一种通过 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; ?>
根据 Ufonion Labs 的回答,我可以通过在我的主题 template.php 中实现这两者来完全删除 Drupal 7 中页面内容周围的所有 HTML 输出,如下所示hook_preprocess_page
:hook_preprocess_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>
页面内容,因此它可以嵌入到另一个页面中。
我知道这个问题已经得到解答,但我想添加我自己的解决方案,它使用费城网页设计 (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 路径时,它将使用我模块中的指定模板。
对于可能点击此页面的其他人,如果您只是使用标准回调(不一定是视图),这很容易。在您的回调函数中,不要返回要在页面内呈现的代码,而是使用“打印”函数。
例如:
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.
}
干杯!
另一种我觉得非常方便的方法是添加一个带有不返回字符串的页面回调函数的菜单项:
例子:
/**
* 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;
(见评论)会更好。
假设您在 Drupal 6 中,最简单的方法是phptemplate_views_view_unformatted_VIEWNAME
调用template.php
(假设您的视图未格式化 - 如果它是其他内容,列表说,使用适当的主题功能)。然后在此主题调用中为视图结果设置主题,而不是像往常一样返回结果,打印它们并返回NULL
。这将直接输出 HTML。
PS - 确保清除您的缓存(在 /admin/settings/performance)以查看这项工作。
嘿,这是另一种方法:
1) 下载并安装 Views Bonus Pack ( http://drupal.org/project/views_bonus ) 2) 创建 Views 显示“Feed”并使用样式“XML”(或您认为更适合您需要的东西)。3) 如果您对标准的 XML 输出不满意,可以通过调整视图的模板来更改它。检查“主题”设置以获取有关此特定视图的替代模板名称的建议(因此您仍将保留默认的 XML 输出以供将来使用)。
祝你好运!//Johan Falk,NodeOne,瑞典
根据费城网页设计的回答(谢谢)和一些谷歌搜索(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 引用。不知道如何输出完全没有主题的数据......
可能有很多方法可以解决这个问题,但是,“最简单的”可能只是设置您自己的自定义主题,并且让 page.tpl.php 为空,或者一些随机的 div
// page.tpl.php
<div id="page"><?php print $content ?></div>
这种方法基本上只允许 node.tpl.php 显示(或任何 drupal 的表单视图等),并且是避免修改核心或必须更改主题注册表以避免显示 page.tpl 的简单方法.php 放在首位。
编辑:见评论
好的,我玩了一下视图,看起来它接管并构建了自己的“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
总是可以检查,但如果我们正在查看视图,听起来应该设置它theme paths
如果您愿意,可以更改page
数组的 (更改 drupal 查找 page.tpl.php 的位置,而不是完全重命名它)template_preprocess_page()
可能是一个更好的主意。我喜欢 Drupal 模块。但是,这是另一种方式。
将主题文件夹中的 page.tpl.php 复制到名为 page-VIEWNAME.tpl.php 的新文件中,其中 VIEWNAME 是视图的机器可读名称。
然后编辑 page-VIEWNAME.tpl.php 以适应。
还有http://drupal.org/project/pagearray这是一个通用的解决方案......
此外,@Scott Evernden 的解决方案是跨站脚本 (XSS) 安全漏洞。不要那样做。阅读 drupal.org 上有关如何以安全方式处理文本的文档http://drupal.org/node/28984
一种显示您希望显示的特殊内容类型的内容的简单方法,而无需page.tpl.php
:
将以下代码段添加到您的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
在正文中显示的内容。
如果我理解您的问题,您希望拥有包含页面所有 HTML 的节点,从 DOCTYPE 到 </HTML>。我要做的是为这些节点创建一个内容类型——“fullhtml”作为它的机器可读名称——然后为它创建一个名为 node-fullhtml.tpl.php 的节点模板。您不能只转储节点的内容,因为它们已经过 HTML 过滤。node.fullhtml.tpl.php 实际上就是这样:
echo htmlspecialchars_decode($content);
然后,您需要一种方法来覆盖标准 page.tpl.php。我认为您可以做的是在 page.tpl.php 的顶部检查 $node 的内容类型,如果它是 fullhtml 则退出。或者,在 node-fullhtml.tpl.php 中设置 page.tpl.php 将检查的全局变量。
我不是 Drupal 专家,但我就是这样做的。我说的是即兴表演,所以要注意细节中的魔鬼。
我看到你已经把自己变成了一个模块,所以这可能不再有帮助,但是很容易获得公开 rss 提要的视图,这可能是获取内容的更简单方法,特别是如果你想要将其包含在不同的站点上。
在 D7 上,您可以使用menu_execute_active_handler
$build = menu_execute_active_handler('user', FALSE);
return render($build);
杰罗恩的回答是玩过它后对我有什么影响。我有一个 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
,所以我也必须更新它。如果您认为寻找它,这又是显而易见的。我的第一个答案只允许我在 Web 浏览器中调用它时显示该节点。然而,这样做的最终目标是使用 iframe 将 drupal 节点嵌入到第三方站点中。
由于 Drupal Core 7.50 iframe 的发布默认被阻止以防止 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');
}
}