Summary

A complete solution for entering, storing and working with XML and Drupal. The versatility of this module spans from simply storing and displaying informational XML to your visitors, to using XML as a configuration mechanism and never displaying the actual XML to the end user.

The module provides API functions for working with XML, which extend PHP's own SimpleXML, and defines an XML field type, widget and formatters. Starting in version 1.6, the XML widget leverages CodeMirror for awesome data entry. You can format the XML to be hidden, display in color coded, escaped HTML, print directly as hidden XML, or show as a read-only text area for easy copy-and-paste. The formatter you choose will depend on your use case.

The module also adds theme_xml() for displaying XML in colorized, HTML entities, and adds a new form element: xmltext.

Highlights

Requirements

Installation

CodeMirror XML Widget (7.x-1.6+)

To use the XML widget (using CodeMirror), you must do the following:

  1. Download the CodeMirror package and unzip in to your libraries folder http://codemirror.net/codemirror.zip.
  2. Rename the folder to simply codemirror
  3. Enable the included module CodeMirror XML Widget (xml_field_codemirror). You do not need to install http://drupal.org/project/codemirror
  4. Make sure codemirror.js is located in the following location: libraries/codemirror/lib/codemirror.js.
  5. Check admin/reports/status and you should see the CodeMirror version number.
  6. Note that after setting an XML field's widget to CodeMirror XML, there are additional settings available under the Edit tab. This includes the CodeMirror color scheme (or theme).

CodeMirror Global Default Theme

Code mirror uses themes for colorizing the input widget. You can set a global theme and save yourself from lots of clicks by setting a $conf variable in your settings.php. To set a global default theme add the following line to your settings.php file:

$conf['xml_field_codemirror_default_theme'] = 'cobalt'

You do not have to do this in settings.php, rather you can do it in your own custom module using a hook. To do this using a custom module hook, implement the following in your custom module:

function my_module_xml_field_codemirror_defaults_alter(&$config) {
  $config['theme'] = 'cobalt';
}

Do either of these steps BEFORE creating fields and all your fields will default to this value.

API: CodeMirror Options

Check out xml_field_codemirror.api.php for API options.

Known Issues

  1. XML fields inside collapsed fieldsets may not show upon expansion; usually clicking the xml field brings it back.

Upgrade Path

to 7.x-1.6

To begin using the XML widget introduced in version 1.6:

  1. Upgrade XML Field to version 7.x-1.6
  2. Install the CodeMirror XML Widget (7.x-1.6+) as described above.
  3. Edit each XML field and change the widget to CodeMirror XML. Optionally, adjust the theme under the field's Edit tab.
  4. Edit a node to see the new widget in action.

Configuration

FAPI

xmltext

This module adds a new form element called xmltext which does xml validation on form submit.

Usage

There are essentially three use case modes for XML and this module.

  1. Output the XML so it can been seen in the browser window, by first converting it to html entities. For visual display of XML.
  2. Output the XML to the browser directly to influence the actual page load in some way. SECURITY WARNING, SEE BELOW!
  3. Hide the field (Manage Display) and use xml_field_xml() and xml_field() to extract the xml data, from within your custom module. This latter usage allows for very sophisticated layout and theming, while still allowing admins to modify content. (See Advanced Use Case)

Simple Use Case

You have a node type, which needs to display XML data below the body content and you just want an easy way to do it without having to write your own validation and sanitization code. How then? Install the module, create a field, and set the formatter to XML for display. You're done! You have instant XML validation and sanitized output. Viola.

Advanced Use Case

As a developer, you designate a page node to be the foundation of a page, as it provides a solid page callback, menu link, title and body text.

To this page node you add a single field called fieldxmlpagedata In hooknodeviewalter() you add extra content to $build, content that is generated dynamically based on any number of rules.

The problem is that you want to allow a title to this content and maybe a footer, text which needs to be accessible for modification by an content manager. How do you do it? You create an XML representation of the editable content, which is intuitive to a content manager with only a little knowledge of XML, something like this:

<page>
  <title>The Lone Ranger</title>
  <footer format="1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla at massa sed nulla consectetur malesuada.</description>
</page>

Now back in hooknodeview_alter() you will parse the xml and use the fields to insert the title and the description (after sanitizing as needed), like this:

$xml = $node->field_xml_page_data['und'][0]['xml'];
$title = xml_field($xml, 'title');
$format = xml_field($xml, 'description', 'format');
$description = xml_field($xml, 'description', NULL, array('check_markup', $format));

With this method you have a very robust way to allow disparate elements on the page to still be accessible to content managers, while maintaining absolute theme control at the PHP level. And, the beauty of XML is that you can make it as simple and descriptive as needed or as technical and nested as you desire since the tags are completely arbitrary (unlike trying to get content managers to understand HTML tags!)

Leveraging xml_field_xml()

This function is at the heart of the module and should be understood by developers. It will extract the xml from many different input sources and (used in conjunction with xml_field()) allows you to save code. As a brief example, the Advanced Case will be rewritten here, but there are assumptions to be made which allow this to happen. The first assumption is that there is only one XML field in the entity. The second assumption is that the entity is not translated into other languages. And the last assumption is that the field only allows one value. If all of these are true then we can simply pass the entity, in this case $node to our api funtions and save steps. Observe...

$title = xml_field($node, 'title');
$format = xml_field($node, 'description', 'format');
$description = xml_field($node, 'description', NULL, array('check_markup', $format));

Study the docblocks in the code for more info.

API

The main API Functions:

Additional API functions:

Security Warning!

This module contains a raw XML formatter that allows the output of unfiltered text directly to the browser, if malicious users are allowed to enter data into a field with this formatter, they could create a security problem. This is similiar to giving the PHP filter to untrusted users. The result could be the same.

This formatter can be used beneficially too, by trusted users, so it is included, however you must understand what you are doing if you employ it.

Similar Projects

Sponsored by

In the Loft Studios and Global Oneness Project

More Examples

Example A

This example shows how to iterate over multiple nodes and also to access properties.

<page>
  <button color="green">Order your free DVDs and host a screening</button>
  <button color="beige" class="more-link">Learn more about screenings</button>
</page>

<?php
// Add the buttons
$xml = xml_field_xml($node);
$build['buttons'] = $class = array();
foreach ($xml->button as $button) {
  $class[] = 'button-link';
  $class[] = xml_field($button, NULL, 'color');
  $class[] = xml_field($button, NULL, 'class');
  $build['buttons'][] = array('#markup' => l(xml_field($button), 'node/add/screening', array(
    'attributes' => array(
      'class' => $class
    ),
  )));
}
?>

Example B

This example shows how to populate two links' text using an XML field.

<page>
  <dvd_button>Order your free DVDs and host a screening</dvd_button>
  <learn_button>Learn more about screenings</learn_button>
</page>

<?php
$build['buttons'] = array()
if ($title = xml_field($node, 'dvd_button')) {
  $build['buttons'][] = array('#markup' => l($title, 'node/add/screening', array(
    'attributes' => array(
      'class' => array('button-link', 'green'),
    ),
  )));
}
if ($title = xml_field($node, 'learn_button')) {
  $build['buttons'][] = array('#markup' => l($title, 'node/2186', array(
    'attributes' => array(
      'class' => array('button-link', 'beige', 'more-link'),
    ),
  )));
}
?>

Contact

In the Loft Studios
Aaron Klump
PO Box 29294 Bellingham, WA 98228-1294
aim: theloft101
skype: intheloftstudios

http://www.InTheLoftStudios.com