I needed to serve up some xml content to provide to a piece of flash that was handling the display. I knew I could get all the information I needed with a view but had no idea how to get it into the format that I wanted. Searching on the site resulted in mostly stuff about rss so I wanted to post a "How To" for anyone else that needed it.

First thing create your view. Use a page view and specify the fields you want on the view like you would for any view.

Next, create a new template file, I called mine page-xml.tpl.php, and it should contain: (Borrowing from Creating a separate admin theme )

<?php
drupal_set_header('Content-Type: text/xml; charset=utf-8');
print "<?xml version=\"1.0\"?>";
print "<root>";
print $content;
print "</root>";

Now, inside template.php, we have to modify the template variable for phptemplate:

function _phptemplate_variables($hook, $variables)
{
   switch($hook) {
      case 'page':
            if(arg(0) == 'xml' && arg(1) == 'states') {
                $variables['template_file'] = 'page-xml';
                // skip everything else
                break;
            }
            if(arg(0) == 'admin' || arg(0) == 'control_panel') {
                $variables['template_file'] = 'page-admin';
            }
            blot_removetab('users', $variables);
            blot_removetab('content', $variables);
            break;
    }

    return $variables;
}


I used arg(0) and arg(1) since the url for my page view was "xml/states" but this could be done a few different ways. So whatever works for you.

You also need to theme the view form with template.php: (See Theming with Views)

function themeName_views_view_viewName($view, $type, $nodes, $level = NULL, $args = NULL) {
 ...
}

A limitation to this is that if you need more than one feed, it could get a little messy inside "_phptemplate_variables", but it could be done.

Enjoy! Hope it helps.
Eric.

Comments

emackn’s picture

simple create a new page template, page-xml.tpl.php:

drupal_set_header('Content-Type: text/xml; charset=utf-8');
print "<q xml version=\"1.0\"q>";
print "<root>";
print $content;
print "</root>";

* the q's should be ?,

Now just create a new View, and for that views url, use xml/whatever. The xml/ is key since that's how drupal will determine which page template to use. In this case, it will use page-xml.tpl.php. see http://drupal.org/node/104316 for more info.

Then just theme your view inside template.tpl.php and you are set. i.e.

function blot_views_view_xml_facts($view, $type, $nodes, $level = NULL, $args = NULL) {
  $output ="";

  foreach($nodes as $n) {
    $output .= "<fact>";
    $output .= "<source><![CDATA[".$n->node_data_field_source_field_source_value."]]></source>";
    $output .= "<title><![CDATA[".$n->node_title."]]></title>";
    $output .= "<value><![CDATA[".$n->node_data_field_fact_field_fact_value."]]></value>";
    $output .="</fact>";
  }
  return $output;
}
                    
greymoth’s picture

Hi. I wondered if you could clarify something for me.

When you say "use xml/whatever" for the view, how exactly does that correspond to the function in the template.tpl.php file?

would it be like this?:


themename_views_view_view_xml_whatever($view, $type, $nodes, $level = NULL, $args = NULL)

this seems obvious but it's not working for me yet.

In drupal 5 are the above two steps the only ones required?

Thanks.

emackn’s picture

My example is confusing a little. Instead of whatever, I should of put view-url. (remember the view-url is different from the view name)

So, The themeing function "themename_views_view_view_xml_whatever" would theme the view "xml_whatever".

For the xml part of the url, read this: http://drupal.org/node/104316

Basically, you are just theming a view like normal, mytheme_views_view_view_whatever, but calling the view with a different page template by adding xml to the path. xml/view-url

nofue’s picture

Servus!

I simply copied your code (great stuff, thanks) but it didn't work. I.e.:

$output .= "<title><![CDATA[".$n->node_title."]]></title>";

didn't show any data, all I got was blank items. I changed that (and everything else) to

$node = node_load($n->nid);
…
$output .= "<artist><![CDATA[". $node->title ."]]></artist>";

and it worked like a charm.

I just wonder if the code you posted ever worked for you, and if so, what's different here that your code didn't work for me… Oh, and that's with Drupal 5.5 / Views 5.x-1.6…

Norbert

-- form follows function

Norbert

-- form follows function

emackn’s picture

bluebee-1’s picture

well I tried that "view - page-xml.tpl.php - template.php hack" method and it worked. Now I have a fully drupal driven flash banner BUT, now I have a little problem. First of all I've realized that if I use for example,

$output .= "<title><![CDATA[".$node->path."]]></title>";

as an output string, the page source is parsed as:

<![CDATA[science-and-future]]>

As flash imports this value, the link becomes undifined. So I tried to ommit the cdata and used only:

$output .=<link>/". $node->path .";</link> and it worked.

Now the output is:

science-and-future

So far, so good. The last problem is Internet Explorer 7, FireFox 3 and Chrome parses different this code. While FF does his job IE shows nothing.

For IE 7: <link></link>
For FF 3: <link>/science-and-future</link>

What could be the problem?

texas-bronius’s picture

no seriously.

--
..happiness is point and click..

--
http://drupaltees.com
80s themed Drupal T-Shirts

bartezz’s picture

subscribing

________________
Live fast die young

Pav-2’s picture

You can use views bonus pack module, then in Views add feed display and in Style settings choose Style: XML.

mcfilms’s picture

I have had some degree of success with http://drupal.org/project/views_datasource. Worked out well for a Drupal back-end with Adobe Flash content display.

A list of some of the Drupal sites I have designed and/or developed can be viewed at motioncity.com