Friday, September 27, 2002

Getting into Dreamweaver for Studio users

I know a lot of Studio uses are unhappy with Dreamweaver and inclined to just stay put, but maybe you're being forced by licensing issues or organization policy to make the move. Or maybe you just realize that the writing is on the wall so you might as well suck it up and make the most of it. I want to offer a couple thoughts that might make things a little more palatable. Perhaps these won't be news to you, but maybe they'll be useful resources.

First, Macromedia has put together a couple of resources to help this very audience. Four particular articles at the Dreamweaver Development Center deserve your attention:



Beyond that, there are several other articles at that site which show how to apply DW to various tasks that CF developers may be interested in (developing, using components and web services, for instance). There are are also tutorial examples (like the Trio Motor Company app) where they include source code and steps to finish the projects. All these are great ways to become familiar with really leveraging DWMX, rather than simply opening it up and lamenting "where is this, why can't I do that". OK, some things from Studio are missing or hard to find, but there are also things that DWMX adds that Studio doesn't have.

And DW is much more than the WYSIWYG html editor that basic web page developers liked so much for years. If you don't like it "mucking with your code", don't go into design mode. You can still leverage the database tools, site management features, and so much more.

Still, I know it's not perfect. Some people have reported real problems using it. Some factors relate to using certain features, or working in certain environments, or problems with resources and speed (a faster machine with more memory seems to temper those concerns). Anyway, Macromedia is listening and future updates will surely address our most grievous complaints.

In the meantime, Macromedia really didn't really leave us high and dry. For died in the wool Studio fans (or when things just don't work as you need them to in DWMX), did you know that the DWMX CD comes with a separately installable "HomeSite +"? HomeSite Plus is really nearly entirely the same as Studio 5. Even the CFML debugger is included (for those that leveraged that). Just install it and use either one. Indeed, there are easy means to go back and forth between them.

I recommend you install both and just try to work more and more in DW as you grow comfortable with it. I know many people tried a "cold turkey" approach to force themselves into DWMX. Why suffer the hassle? Use each while you become more familiar and comfortable with DWMX. You may even find that you grow to find it perfectly acceptable, even preferable.

Sure, for some this has been like being forced to write with their other hand. But we humans are amazingly capable of adapting. And Macromedia really is working to make it a more effective transition. At least give these resources 15 minutes reading before you conclude it just won't work for you, and for the things that just flat don't work, drop back to HomeSite+.

Not a sermon. Just a thought. :-)

Monday, September 23, 2002

Building XML dynamically with CFXML

Some may know that they can create XML dynamically in CF, just like creating HTML, by outputting the elements such as within query loops, etc. Here's an example:
<CFQUERY NAME="getemps" DATASOURCE="cfsnippets">
   SELECT *
   FROM Employees
</CFQUERY>

<cfxml variable="employees">
<Employees>
<cfloop query="getemps">
   <Employee>
      <cfoutput>
      <Emp_ID>#getemps.emp_id#</Emp_ID>
      <FirstName>#getemps.firstname#</FirstName>
      </cfoutput>
   </Employee>
</cfloop>
</Employees>
</cfxml>

<cfdump var="#employees#">

While you could do the same sort of thing in CF5, I've added above something that's specific to CFMX. Note that the creation of the XML elements is done inside a CFXML tag. This causes CFMX to create the XML as an internal XML object, stored in the named variable ("employees", above). Doing this allows us to treat the XML as a first class XML object with a variety of internal variables and controls built-into CFMX. See the chapter on working with XML in the "Developing CFML Apps with CFMX" manual.

When building XML this way, however, it can be challenging if you make the slightest mistake. :-) I have a few generic tips:


  • make sure that matching opening and closing xml elements are the same case
  • when building XML dynamically, it's possible that the source of the data may provide values that are inappropriate for use within XML (special characters, or worse, possibly including brackets that are interpreted as elements themselves. You should wrap such dynamic data in an XMLFormat function.
  • when stumped, you might want to replace the CFXML tags with CFSAVECONTENT (no other changes needed) and try outputting that for debugging purposes. While it would seem that using tostring against the xml object would provide the same result, since the SAVECONTENT doesn't really invoke the underlying XML processing, you might see something in outputting that which would cause an error in CFXML processing. This may be especially valuable if you're building the actual XML element names dynamically
  • while minimizing whitespace has some value, it might also help to render the source code with normal indenting (as I have above) to help give visual cues as to whether things are coded as expected
  • try stripping out parts of the process to minimize it and make sure that outer portions of the XML generation process are indeed what you think it to be

    Finally, someone may wonder how to simply dump all the contents of a table into XML without needing to spell out the column names. The concepts are again similar to outputting HTML:

    <cfxml variable="employees">
    <Employees>
    <cfloop query="getemps">
       <Employee>
       <cfloop list="#getemps.ColumnList#" index="field">
          <cfoutput>
          <#field#>
             #xmlformat(getemps[field][currentrow])#
          </#field#>
          </cfoutput>
       </cfloop>
       </Employee>
    </cfloop>
    </Employees>
    </cfxml>

    <cfdump var="#employees#">