开发者

Output Full Drupal Page in structured XML

Is there a way to output a drupal page (full node with any views, blocks etc) in pure XML format?

Thanks开发者_运维问答,

Shadi


You can use template files to override the default output and send XML instead of HTML.

I'm not sure which version of Drupal you're using, but the principle is the same in both (GrayB gives the link to the theme docs in another answer).

For Drupal 7, you have to override html.tpl.php, which is normally in /modules/system, as this sets the surrounding HTML (which you'll basically get rid of). You'll also probably want to override page.tpl.php and/or node.tpl.php, depending on your needs.

If your theme's directory already has a template.php, you can add the following. If there is no template.php file, you can create one and add these lines (changing yourtheme to the actual theme name).

<?php
function yourtheme_preprocess_html(&$vars) {
    /***
      * A bunch of other preprocess stuff you don't need to touch
      */

    // this works for a single page, check if node id = '3' 
    if (in_array('html__node__3', $vars['theme_hook_suggestions'])) {
        $vars['theme_hook_suggestions'][] = 'html__xml';
    }
}

function yourtheme_preprocess_page(&$vars) {
     /***
       * Same as above
       */
     $page_nids = $vars['node']->nid;
     if (!$vars['is_front'] && $page_nids == '3') {
         $vars['theme_hook_suggestions'][] = 'page__xml';
     }
}
function yourtheme_preprocess_node(&$vars) {
     /***
       * Same as above
       * You may not need this one, depending on how much control
       * you want over the XML output
       */
     $node_nid = $vars['nid'];
     if ($node_nid == 3) {
         $vars['theme_hook_suggestions'][] = 'node__xml';
     }
}

This tells Drupal to look for templates with the names html--xml.tpl.php etc. You could also use something like html--node--3.tpl.php if you know you just want to theme node 3, but giving it a generic name makes it more flexible.

You can now add the appropriate theme files into your theme folder: html--xml.tpl.php, page--xml.tpl.php (and node--xml.tpl.php if you included the node_preprocess function above). Note that underscores in the suggestion variables above become dashes in the theme file names.

If these files don't already exist in your theme, you can either copy the original tpl.php files and change the names (look at an existing core theme to get these - as mentioned above, you can get the html.tpl.php from the /modules/system folder), or create new ones. Copying is probably easier so you can see what you're starting with and can roll back changes.

In your html--xml.tpl.php, you can delete all that HTML stuff and strip it down to the core output, as well as the XML headers:

<?php header('Content-Type: text/xml'); ?>
<?php print '<?xml version="1.0"?>'; ?>
<document>
  <?php print $page; ?>
</document>

You can then do the same for the page.tpl.php according to your needs. This is what my stripped-down edition looked like:

  <?php if ($page['sidebar_first']): ?>
    <sidebar>
      <?php print render($page['sidebar_first']); 
      print render($page['sidebar_first']);
      ?>
    </sidebar>
  <?php endif; ?>

        <pagenode><?php print render($page['content']); ?></pagenode>

  <?php if ($page['sidebar_second']): ?>
      <?php print render($page['sidebar_second']); ?>
  <?php endif; ?>

Of course, yours will look quite different. After that, you can do whatever you like to place the blocks, menu items etc. that you want to render.


Following example will create "XML" tab next to "View" and "Edit" tabs on node page:

/**
 * Implementation of hook_menu().
 */
function example_menu() {
  return array(
    'node/%node/xml' => array(
      'title' => 'XML',
      'page callback' => '_example_xml',
      'page arguments' => array(1),
      'access callback' => 'node_access',
      'access arguments' => array('view', 1),
      'type' => MENU_LOCAL_TASK,
    ),
  );
}

function _example_xml($node) {
  node_feed(array($node->nid));
}

In sake of simplicity I reused node_feed, you can replace it with own header

drupal_add_http_header('Content-Type', 'text/xml');

And xml builder.


I posted a working example on Drupal Answers. Basically all you need is hook_menu() and customized versions of node_feed(), format_rss_channel() and format_rss_item().

Following blog post might be helpful as well. https://www.phase2technology.com/blog/creating-rss-feeds-with-a-light-hand/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜