views:

12666

answers:

13

I would like to display a Drupal view without the page template that normally surrounds it - I want just the plain HTML content of the view's nodes.

This view would be included in another, non-Drupal site.

I expect to have to do this with a number of views, so a solution that lets me set these up rapidly and easily would be the best - I'd prefer not to have to create a .tpl.php file every time I need to include a view somewhere.

+1  A: 

there are probably a number of ways around this, however, the "easiest" may be just setting your own custom theme, and having the page.tpl.php just be empty, or some random divs

// page.tpl.php
<div id="page"><?php print $content ?></div>

this method would basically just allow node.tpl.php to show (or any of drupal's form views, etc...) and would be an easy way to avoid modifying core, or having to alter the theme registry to avoid displaying page.tpl.php in the first place.

edit: see comments

ok i played around with views a bit, it looks like it takes over and constructs it's own "node.tpl.php" (in a sense) for display within "page.tpl.php". on first glance, my gut feeling would be to hook into theme_registry_alter().

when you're looking at a views page, you have access to piles of information here, as well as the page.tpl.php paths/files. as such i would do something like:

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';        
  }
}

this should allow you to use a "override_page.tpl.php" template in your current theme in which you can remove anything you want (as my first answer above).

a few things:

  • as i said, not sure if views_ui_list_views is always available to check against, but it sounds like it should be set if we're looking at a view
  • you can alter the theme paths of the page array if you prefer (to change the location of where drupal will look for page.tpl.php, instead of renaming it altogether)
  • there doesn't appear to be any identifiers for this specific view, so this method might be an "all views will be stripped" approach. if you need to strip the page.tpl.php for a specific view only, perhaps hooking into template_preprocess_page() might be a better idea.
Owen
That would work if I were only using this site for embedding elsewhere, but I need normal nodes to display with their normal page templates.
ceejayoz
hmm, do you have only specific node types that would be "external view"? or can you clarify that a bit more? ie i think there's a different answer for "page nodes are external" vs "nodes of any type i select are external"
Owen
It's not nodes, it's views. All of the nodes need to display within page templates at some times. It's the views (with page displays) that need to be unthemed. Sort of like how the feed displays work, but with the node HTML instead of a RSS format.
ceejayoz
ah hmm, i haven't played around with views much, but i'll take a look this afternoon and see if i can offer some better advice, i'm not sure how views specifically pieces together it's elements, but i have a feeling the answer is in altering the theme registry. this is drupal 6 yes?
Owen
Yeah, D6. I suspect you're right that a small module that tweaks the theme registry might be the best way. I'm surprised no one has needed something like this enough to make a module yet...
ceejayoz
A: 

If I understand your question, you want to have nodes which contain all the HTML for a page, from DOCTYPE to </HTML>. What I would do is create a content type for those nodes -- "fullhtml" as its machine-readable name -- and then create a node template for it called node-fullhtml.tpl.php. You can't just dump the node's contents, as they've been HTML-sanitized. node.fullhtml.tpl.php would literally be just this:

echo htmlspecialchars_decode($content);

Then you'll need a way to override the standard page.tpl.php. I think what you could do is at the top of your page.tpl.php check the $node's content type, and bail out if it's fullhtml. Or, set a global variable in node-fullhtml.tpl.php that page.tpl.php would check for.

I'm no Drupal expert, but that's how I'd do it. I'm talking off the cuff, so watch for devils in the details.

Jim Nelson
You misunderstand my question. I don't want the DOCTYPE and HTML, as the page the view will be included in already has all that. I want just the actual, unstyled content of the node.Creating a new content type won't work, as I depend on content types for organisation within the site.
ceejayoz
Maybe you should rephrase or expand the question.
Jim Nelson
I feel I was clear enough in my original question, seeing as how it explicitly states that I don't want the page template surrounding the node contents.
ceejayoz
I think if you look at my solution, that's what it's doing. Maybe it's not what you're looking for, but the whole point of what I'm presenting here is to prevent the page template from activating.
Jim Nelson
FYI - Jim's solution is good and has the benefit of being implementable on both drupal 5 and 6.
Mike Heinz
+2  A: 

Assuming you're in Drupal 6, the easiest way to do this is to put a phptemplate_views_view_unformatted_VIEWNAME call in template.php (assumes your view is unformatted - if it's something else, a list say, use the appropriate theme function). Theme the view results in this theme call then, instead of returning the results as you normally would, print them and return NULL. This will output the HTML directly.

PS - make sure to clear your cache (at /admin/settings/performance) to see this work.

Chris
A: 

I like the Drupal module. BUt, here's another way.

copy page.tpl.php in your theme folder to a new file called page-VIEWNAME.tpl.php, where VIEWNAME is the machine-readible name of the view.

Then edit page-VIEWNAME.tpl.php to suit.

A: 

I see you have already gone and made yourself a module, so this may no longer help, but it is fairly easy to get a view to expose an rss feed, which might be an easier way of getting at the content, especially if you want to include it on a different site.

Andrew
+11  A: 

I was looking for a way to pull node data via ajax and came up with the following solution for Drupal 6. After implementing the changes below, if you add ajax=1 in the URL (e.g. mysite.com/node/1?ajax=1), you'll get just the content and no page layout.

in the template.php file for your theme:

function phptemplate_preprocess_page(&$vars) {

  if ( isset($_GET['ajax']) && $_GET['ajax'] == 1 ) {
        $vars['template_file'] = 'page-ajax';
  }

}

then create page-ajax.tpl.php in your theme directory with this content:

<?php print $content; ?>
That's a nice simple and effective way of doing it! Wow! Welcome to StackOverflow, and thank you!
ceejayoz
This seems like the right answer, but it doesn't work for me. I put a print statement inside function phptemplate_preprocess_page( } and nothing happens. I don't even think this function is getting called.
Brian T Hannan
Are there any situations where this might not get called?
Brian T Hannan
A: 

There is also http://drupal.org/project/pagearray which is a general solution...

Also, @Scott Evernden's solution is a cross site scripting (XSS) security hole. Don't do that. Read the documentation on drupal.org about how to Handle Text in a Secure Fashion http://drupal.org/node/28984

greggles
A: 

For others who may hit this page, if you're just working with standard callbacks (not necessarily views), this is easy. In your callback function, instead of returning the code to render within the page, use the 'print' function.

For example:

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

Cheers!

A: 

use node.php can be VERY dangerous, this won't check permission!!!

This probably was meant to be a comment on @Scott Evernden's answer?
ceejayoz
A: 

@Scott Evernden Thanks for the great solution. I came back to this page 5x and the original solution doesnt work. That function never fires. I even set it to 1 to force a fire. It may be HTACCESS filtering. I gave up.

But then your elegant solution came along. Saved the day. I named my file 'light.php' and call it when I need to LIGHTBOX something. It's almost perfect. However, I use paths and URL naming so getting the NODE ID is a little lame. BUt it works great.

Please don't use answers as comments.
ceejayoz
Also, @Scott Evernden's answer has major security holes.
ceejayoz
A: 

a simple way to display content of a special content-type you wish to display without all the stuff of the page.tpl.php: add the following snippet to your template.php file:

function mytheme_preprocess_page(&$vars) { if ($vars['node'] && arg(2) != 'edit') { $vars['template_files'][] = 'page-nodetype-'. $vars['node']->type; } }

add a page-nodetype-examplecontenttype.tpl.php to your theme,like your page.tpl.php but without the stuff you don't want to display and with print $content in the body

nerdbabe
+1  A: 

Hey, here's yet another way of doing it:

1) Download and install Views Bonus Pack (http://drupal.org/project/views_bonus) 2) Create a Views display "Feed" and use style "XML" (or something you think fits your needs better). 3) If you're not satisfied with the standard XML output, you can change it by adjusting the template for the view. Check the "theme" settings to get suggestions for alternative template names for this specific view (so you'll still have the default XML output left for future use).

Good luck! //Johan Falk, NodeOne, Sweden

A: 

@xyzzy thanks for your solution. However, having got this to work I think you mean that VIEWNAME is the url path of the view, not its machine readable name.