- A Brief Introduction to XML
- Exporting Template Content to XML
- Manually Importing from XML
- Automated Import to Template
Exporting Template Content to XML
Most of Dreamweaver's XML focus is dedicated to working with templates and template-derived documents. Dreamweaver regards the locked areas of a template as the presentation layer of a document and the content within the editable and repeating regions as well as some other template markup as the data. Dreamweaver can only pull XML data from an instance of a template and, similarly, import XML data into a template instance.
Exporting a Single Document
As noted earlier, Dreamweaver provides a direct menu command for extracting the XML content from templates: File, Export, Template Data as XML. When invoking this commandwhich becomes active only when the current document is template derivedthe Export Template Data as XML dialog box is displayed (see Figure 4.1). For basic templatesones that use only editable regionsDreamweaver can format the XML output in one of two ways. The standard Dreamweaver XML approach lists every region as an <item> tag, identified separately by the name attribute. For example, if a template had three editable regionssuch as bookTitle, authorName, and bookDescriptionthen selecting the Use Standard Dreamweaver XML Tags option would output the following:
<item name="bookTitle"><![CDATA[Critical Space]]></item> <item name="authorName"><![CDATA[Greg Rucka]]></item> <item name="bookDescription>><![CDATA[Bodyguard Atticus Kodiak is hired by
someone who attempted to once kill him.]]></item>
NOTE
You might find it helpful to examine output from Dreamweaver's Export Template Data as XML command; you'll find examples in Listing 4-1 (standard items sample) and Listing 4-2 (editable regions sample) at the end of this section.
In contrast, the Use Editable Region Names as XML Tags option formats the data like this:
<bookTitle>![CDATA[Critical Space]]></bookTitle> <authorName><![CDATA[Greg Rucka]]></authorName> <bookDescription><![CDATA[Bodyguard Atticus Kodiak is hired by someone who
attempted to once kill him.]]></bookDescription>
Figure 4.1 The Export Template Data as XML dialog box offers two export stylesas long as the only template markup tags in the document are editable regions.
There are other differences as well. For instance, the syntax for the master template under the standard Dreamweaver XML tags is this:
<templateItems template="/Templates/BasicBookList.dwt" codeOutsideHTMLIsLocked="false"> ... </templateItems> as opposed to this: <BasicBookList template="/Templates/BasicBookList.dwt" codeOutsideHTMLIsLocked="false"> ... </BasicBookList>
As noted, complex template documentsthose that have repeating regions or template parameters as well as editable regionscan only be output in the standard Dreamweaver format. Several additional tags are used to note the enhanced template markup. A template parameterthe only evidence of a conditional regionlooks like this:
<parameter name="dbOnSale" type="boolean" passthrough="false"><![CDATA[true]]></parameter>
NOTE
Don't get the idea that template data can only be exported from static pages. Dynamic pages, which often include code outside of the <html> tag pair, can also be exported. Dreamweaver uses a special syntax for code that appears before the opening <html> tag: <item name="(code before HTML tag)">
or
<pre_html>
Similar tags are used for code that appears after the closing </html> tag.
A repeating region is coded this way:
<repeat name="RepeatRegion1"> <repeatEntry> <item name="BookTitle"><![CDATA[Critical Space]]></item> <item name="AuthorName"><![CDATA[Greg Rucka]]></item> <item name="MainCharacter"><![CDATA[Atticus Kodiak]]></item> </repeatEntry> <repeatEntry> <item name="BookTitle"><![CDATA[Blackwater Sound]]></item> <item name="AuthorName"><![CDATA[James W. Hall]]></item> <item name="MainCharacter"><![CDATA[Thorn]]></item> </repeatEntry> </repeat>
That's it. The following listings show the completed code.
NOTE
If your template region names include special charactersincluding spaces or underscoresthen Dreamweaver only lets you export using the standard Dreamweaver method.
Listing 4-1 Standard Items Sample (04_standarditems.xml)
<?xml version="1.0"?> <templateItems template="/Templates/Basic Admin.dwt" codeOutsideHTMLIsLocked="false"> <item name="(code after HTML tag)"><![CDATA[ ]]></item> <item name="(code before HTML tag)"><![CDATA[<%@LANGUAGE="VBSCRIPT"%> ]]></item> <item name="doctitle"><![CDATA[ <title>Untitled Document</title> ]]></item> <item name="Content"><![CDATA[ <p>The content goes here.</p> <p> </p> ]]></item> </templateItems>
Listing 4-2 Editable Regions Sample (04_editableregions.xml)
<?xml version="1.0"?> <Basic_Admin template="/Templates/Basic Admin.dwt" codeOutsideHTMLIsLocked="false"> <post_html><![CDATA[]]></post_html> <pre_html><![CDATA[<%@LANGUAGE="VBSCRIPT"%> </pre_html> <doctitle><![CDATA[ <title>Untitled Document</title> ]]></doctitle> <Content><![CDATA[ <p>The content goes here.</p> <p> </p> ]]></Content> </Basic_Admin>
Exporting an Entire Site
Undoubtedly, the Export, Template Data as XML command is quite useful at extracting the content from a templated page; unfortunately, it's also somewhat tedious. If you are responsible for exporting the content from an entire site, you have quite a repetitive task ahead of you when you're using just this feature. Luckily, Dreamweaver includes an equally powerful command for extracting all the data from all the template-derived pages in a site.
Although the command for exporting a single page is front and center, you really have to dig to find the equivalent site-wide command. In fact, you have to perform an entirely differentsomewhat antitheticaloperation to get the XML output. Dreamweaver MX includes the ability to export a site, completely stripping out all the template markup from template-derived documents. When you choose Modify, Templates, Export Without Markup, the dialog box shown in Figure 4.2 is displayed.
Figure 4.2 To extract all the data as XML from a site, you first must choose Templates > Export Without Markup.
To enable the XML operation, make sure that the Keep Template Data Files option is selected. This is the signal to Dreamweaver to make two copies of template-derived documents: one without template markup and another in XML data format. Dreamweaver stores both files in the same folder. If you've previously exported the site and want to update the data files, select Extract Only Changed Files.
NOTE
To avoid having to ask for individual names for each file exported, Dreamweaver automatically appends the .xml extension to whatever the original filename isincluding the extension. For example, marchbooklist.htm becomes marchbooklist.htm.xml.
Exporting Selected Files in a Site
So far, we've seen how Dreamweaver can export XML data from a single page or from an entire site. However, what if you need something in between? What if you need to export the five files you're working on or only a couple of folders of files? What if you don't want to make a template-less copy of the site to get the exported files?
Although Dreamweaver makes exporting template data as XML programmatically appear straightforward, there's an aptly named function, dw.exportTemplateDataAsXML(). It's not as easy as it seems. Every time the exportTemplateDataAsXML() function is called, the Export Template Data as XML dialog box opens, disrupting the automatic nature of the operation. Luckily, Dreamweaver makes it fairly easy to get an array of all the editable regions in a document with another API function, dom.getEditableRegionList(). That function serves as the basis for the Export XML extension.
The Export XML extension (see Figure 4.3) allows the user to select the scope of the operation (Current Document, All Open Documents, Selected Files in Site Panel or Entire Site), which template to declare in the XML file, and where to store the files.
Figure 4.3 Export XML uses Massimo Foti's site-wide library to work with a wide range of file selections.
Another real challenge is developing a system to supply the file URLs as needed, whether it's just from the current document, from the selected files, or from the entire site. Although Macromedia hasn't seen fit to provide this functionality, a robust solution has emerged from Dreamweaver's premier third-party developer, Massimo Foti. Fairly early on in the development of his extensions, Massimo came across this very problem: How do you process a single command across a site?
Over the years, Massimo has refined his library numerous times, and it is quite full featured and extremely useful. Although the code is too lengthy to reproduce and analyze in this chapter, I have included it as Bonus Listing 4-A (Massimo Foti's Site-Wide Library [04_siteutils.js]) on the book's web site, with Massimo's permission, as well as a small extension to demonstrate its use, shown here in listing 4-3.
TIP
To see the full range of Massimo Foti's work, visit http://www.massimocorner.com.
Listing 4-3 Export XML (04_exportxml.mxp)
<html> <head> <title>Export XML</title> <script language="javascript" src="../Shared/Beyond/Scripts/Beyond_Site.js"></script> <script language="JavaScript" src="../Shared/MM/Scripts/CMN/UI.js" type="text/JavaScript">
</script> <script language='javascript'> //init globals *************************************************** var theSelect = findObject('fileList'); var theWildText = findObject('wildText'); var theTemplateList = findObject("template_list"); var theXML = ""; //******************* Primary Functions ************************** function commandButtons(){ -return new Array( 'OK', 'doCommand()', 'Cancel', 'window.close()',
'Help', 'getHelp(theHelpFile)') } function exportXML(theURL) { var theDOM = dw.getDocumentDOM(); -if(theDOM.documentElement.innerHTML.indexOf("InstanceBegin template=") != -1) { var theERs = theDOM.getEditableRegionList(); var theName, theData theXML = ""; for (i = 0; i < theERs.length; ++i) { theName = theERs[i].getAttribute("name"); theData = theERs[i].innerHTML; -theXML += '<item name="' + theName + '"><![CDATA[' + theData + ']]></item>' + '\n'; } var theXMLHeader = ""; -theTemplate = theTemplateList.options [theTemplateList.selectedIndex].text; -var theTemplateFile = dw.getSiteRoot() + "Templates/" + theTemplate; theXMLHeader += '<?xml version="1.0"?>' + '\n'; -theXMLHeader += '<templateItems template="/Templates/' + theTemplate + '"
codeOutsideHTMLIsLocked="false">' + '\n'; -theXML = theXMLHeader + theXML + '\n' + '</templateItems>' + '\n'; -var fileURL = findObject("folder_text").value + theURL.substr(theURL.lastIndexOf("/")
+ 1) + ".xml"; r = DWfile.write(fileURL, theXML); } dw.releaseDocument(theDOM); } function doCommand() { -var selectArray = new Array("currentDoc","openedDocs", "siteSelected","wholeSite"); var theRes = 1 -var theWildCards = ".htm;.html;.shtm;.shtml;.asp;.cfm;.cfml; .php;.php3" for (var i=0; i<theSelect.options.length; i++){ if (theSelect.options[i].selected){ whichFiles = selectArray[i]; } } switch (whichFiles){ case "currentDoc": urlArray = getCurrentDoc(); if(urlArray){ exportXML(urlArray); } break; case "openedDocs": -agree = confirm("This command cannot be undone. Proceed?"); //If it's ok, go if (agree){ openFilesArray = new Array(); //Get the currently opened files openFilesArray = getOpenedDocs(); //Filter them to get just the ones matching extensions urlArray = filterFiles(theWildCards,openFilesArray); for (var i=0; i<openFilesArray.length; i++){ exportXML(urlArray[i]); } } else { return; } break; case "siteSelected": var siteFocus,agree; siteSelectedArray = new Array(); writeSiteSelectedArray = new Array(); siteFocus = site.getFocus(); if(siteFocus == "local" || "site map"){ //Ask the user -agree = confirm("This command cannot be undone. Proceed?"); //If it's ok, go if (agree){ -//Get the urls of the files selected inside //the site window siteSelectedArray = site.getSelection(); -if (siteSelectedArray.length == 0 || siteSelectedArray[0].indexOf(".") == -1) { -alert("No files in Site window selected. \nChoose another Generate From option.") return; } //Filter them to get just the matching extensions -urlArray = filterFiles(theWildCards, siteSelectedArray); for (var i=0; i<urlArray.length; i++){ exportXML(urlArray[i]); } } else { return; } } else{ alert("This command can affect only local files"); } break; case "wholeSite": var agree; wholeSiteArray = new Array(); writeFilesArray = new Array(); //Ask the user -agree = confirm("This command cannot be undone. Proceed?"); //If it's ok, go if (agree){ -//Get all the urls of files in the site with //matching extensions wholeSiteArray = getWholeSite(); //Filter them to get just the matching extensions urlArray = filterFiles(theWildCards,wholeSiteArray); for (var i=0; i<urlArray.length; i++){ exportXML(urlArray[i]); } } else { return; } break; } window.close(); return; } function findFolder() { findObject("folder_text").value = dw.browseForFolderURL(); } function getTemplateList() { //returns a list of templates in site var theTemplateDir = dw.getSiteRoot() + "Templates/"; var theTemplates = new Array(); -theTemplates = DWfile.listFolder(theTemplateDir + "*.dwt", "files"); if (theTemplates){ loadSelectList(theTemplateList,theTemplates); } } function initUI() { getTemplateList(); } </script> </head> <body onLoad="initUI()"> <form name="theForm"> <table border="0"> <tr> <td nowrap> <div align="right">Export XML from</div></td> <td nowrap> <select name="fileList" style="width:220px"> <option selected>Current Document</option> <option>All Open Documents</option> <option>Selected Files in Site Window </option> <option>Entire Site</option> </select> </td> </tr> <tr> <td nowrap><div align="right">Template</div></td> -<td nowrap><select name="template_list" id="template_list" style="width:220"> <option selected>Loading templates.............</option> </select></td> </tr> <tr> <td><div align="right">Save In</div></td> -<td><input name="folder_text" type="text" id="folder_text" style="width:155"> -<input type="button" name="Button" value="Browse" onClick="findFolder()"></td> </tr> </table> </form></body> </html>
After Massimo's function does the heavy lifting of finding all the required file URLs, that information is passed to the exportXML() function in the extension. As is often the case, the Document Object Model (DOM) for the document is first appropriated and put into a variable. Then the function tests to make sure that the document is derived from a template and that it's possible to export XML from it. Again, there is a Macromedia API function intended for this purposeand again, we can't use it because it requires the document to be open before it will work. Because I don't want to open and close every document, I found another way to determine whether the file is template derived:
if(theDOM.documentElement.innerHTML.indexOf("InstanceBegin template=") != -1)
This code walks down the DOM a bit and looks for the key words that indicate the document is a template instance. If so, we're ready for the process to begin by getting all the editable regions in the file:
var theERs = theDOM.getEditableRegionList();
The next significant action takes place in a loop where the editable region name and innerHTML are extracted and inserted into an XML format:
for (i = 0; i < theERs.length; ++i) { theName = theERs[i].getAttribute("name"); theData = theERs[i].innerHTML; theXML += '<item name="' + theName + '"><![CDATA[' + theData + ']]></item>' + '\n'; }
Next, we're ready to set up the template name variable, which we'll soon insert into the XML file:
theTemplate = theTemplateList.options[theTemplateList. selectedIndex].text;
The header for the XML file is constructed next, integrating the template name:
theXMLHeader += '<?xml version="1.0"?>' + '\n'; theXMLHeader += '<templateItems template="/Templates/' + theTemplate + '"
codeOutsideHTMLIsLocked="false">' + '\n';
Now the entire XML file is concatenated into one string:
theXML = theXMLHeader + theXML + '\n' + '</templateItems>' + '\n';
After building the file URL to store the XML file, the DWfile API is used to write it out:
var fileURL = findObject("folder_text").value + theURL.substr(theURL.lastIndexOf("/")
+ 1) + ".xml"; r = DWfile.write(fileURL, theXML);
The final instruction in the code is used to release the memory used to work with the DOMa necessary step when possibly processing an entire site:
dw.releaseDocument(theDOM);