显示一个没有页面模板的Drupal视图

时间:2008-10-29 18:57:55

标签: php drupal drupal-views

我想显示一个没有通常围绕它的页面模板的Drupal视图 - 我只想要视图节点的纯HTML内容。

此视图将包含在另一个非Drupal站点中。

我希望必须通过一些视图来执行此操作,因此可以快速轻松地设置这些视图的解决方案将是最好的 - 我不希望每次都创建.tpl.php文件我需要在某处包含一个视图。

17 个答案:

答案 0 :(得分:49)

我一直在寻找一种通过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; ?>

答案 1 :(得分:19)

基于Ufonion Labs的答案,我能够通过在我的主题template.php中实现hook_preprocess_pagehook_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>,以便它可以嵌入到另一个页面中。

答案 2 :(得分:7)

我知道这个问题已经得到解答,但我想添加自己的解决方案,该解决方案使用费城网页设计(PWD)答案的元素,并使用了欧文建议的hook_theme_registry_alter。使用此解决方案,您可以直接从自定义模块加载模板。

首先,我将raw.tpl.php添加到模块中新创建的“templates”文件夹中。 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,将我模块的'templates'目录添加到主题注册表中(基于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');
}

现在,当我在视图的URL路径中添加?raw = 1时,它将使用我模块中指定的模板。

答案 3 :(得分:5)

对于可能会点击此页面的其他人,如果您只是使用标准回调(不一定是视图),这很容易。在回调函数中,不要返回要在页面内呈现的代码,而是使用'print'函数。

例如:

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.
}

干杯!

答案 4 :(得分:3)

我觉得非常方便的另一种方法是添加一个带有页面回调函数的菜单项,该函数不返回字符串:

示例:

/**
 * 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;会更好(请参阅评论)。

答案 5 :(得分:2)

假设您在Drupal 6中,最简单的方法是在phptemplate_views_view_unformatted_VIEWNAME中进行template.php调用(假设您的视图未格式化 - 如果是其他内容,则列表说,请使用适当的主题功能)。然后将视图结果主题化为此主题调用,而不是像往常一样返回结果,打印它们并返回NULL。这将直接输出HTML。

PS - 确保清除缓存(在/ admin / settings / performance)以查看此工作。

答案 6 :(得分:2)

嘿,这是另一种方法:

1)下载并安装Views Bonus Pack(http://drupal.org/project/views_bonus) 2)创建一个视图显示“Feed”并使用样式“XML”(或者您认为更符合您需求的东西)。 3)如果您对标准XML输出不满意,可以通过调整视图的模板来更改它。检查“主题”设置以获取此特定视图的替代模板名称的建议(因此您仍将保留默认的XML输出以供将来使用)。

祝你好运! // Johan Falk,NodeOne,瑞典

答案 7 :(得分:2)

基于费城网页设计的答案(谢谢)和一些谷歌搜索(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引用。不确定如何输出完全未经训练的数据...

答案 8 :(得分:1)

可能有很多方法,但是,“最简单”可能只是设置自己的自定义主题,并且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的位置,而不是完全重命名)
  • 此特定视图似乎没有任何标识符,因此此方法可能是“所有视图将被剥离”的方法。如果您只需要为特定视图剥离page.tpl.php,可能会挂钩template_preprocess_page()可能是个更好的主意。

答案 9 :(得分:1)

我喜欢Drupal模块。 BUt,这是另一种方式。

将主题文件夹中的page.tpl.php复制到名为page-VIEWNAME.tpl.php的新文件中,其中VIEWNAME是视图的机器可读名称。

然后编辑page-VIEWNAME.tpl.php以适应。

答案 10 :(得分:1)

还有http://drupal.org/project/pagearray这是一般解决方案......

此外,@ Scott Evernden的解决方案是跨站点脚本(XSS)安全漏洞。不要那样做。阅读drupal.org上关于如何以安全时尚处理文本的文档http://drupal.org/node/28984

答案 11 :(得分:1)

显示您想要显示的特殊内容类型内容的简单方法,而不需要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

答案 12 :(得分:0)

我的第一个回答只允许我在Web浏览器中调用该节点时显示该节点。但是,这样做的最终目标是使用iframe将drupal节点嵌入到第三方网站中。

自Drupal Core 7.50 iframe is by default blocked to prevent Clickjacking发行以来

要仅使节点成功嵌入到第三方站点中,您还需要覆盖X帧默认设置。在template.php中添加以下内容后,一切开始正常工作

function MY_THEME_page_alter($page) {

 if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
   header_remove('X-Frame-Options');
 } 
}

答案 13 :(得分:0)

jeroen的答案是玩了之后对我有什么帮助。我有一个Drupal 7网站。

  1. 首先,请确保将const lvalue替换为主题名称。是的,这很明显,但是大多数新手都错过了。

  2. 我实际上已经有一个MY_THEME。然后不要重新创建该函数,而应在函数末尾添加此代码,然后再使用function MY_THEME_preprocess_page(&$variables) {将其关闭。


}
  1. 我的函数使用if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') { $variables['theme_hook_suggestions'][] = 'page__embed'; } 而不是$vars,所以我也必须更新它。如果您认为需要的话,它再次显而易见。

答案 14 :(得分:0)

在D7上,您可以使用menu_execute_active_handler

$build = menu_execute_active_handler('user', FALSE);
return render($build);

答案 15 :(得分:0)

我看到你已经离开并自己制作了一个模块,所以这可能不再有用,但是很容易获得一个暴露rss feed的视图,这可能是获取内容的一种更简单的方法,尤其是如果您想将其包含在其他网站上。

答案 16 :(得分:0)

如果我理解您的问题,您希望拥有包含网页所有HTML的节点,从DOCTYPE到&lt; / HTML&gt;。我要做的是为这些节点创建一个内容类型 - “fullhtml”作为其机器可读的名称 - 然后为它创建一个名为node-fullhtml.tpl.php的节点模板。您不能只是转储节点的内容,因为它们已经过HTML清理。 node.fullhtml.tpl.php就是这样:

echo htmlspecialchars_decode($content);

然后你需要一种方法来覆盖标准的page.tpl.php。我认为你可以做的是在你的page.tpl.php的顶部检查$ node的内容类型,如果它是fullhtml则挽救。或者,在page.tpl.php中检查的node-fullhtml.tpl.php中设置一个全局变量。

我不是Drupal专家,但我就是这样做的。我正在谈论袖口,所以请注意细节中的恶魔。