From: Marc P. <ma...@an...> - 2003-04-21 12:56:00
|
On Sun, 20 Apr 2003 13:03:48 -0700, Brian Goetz <br...@qu...> wrote: >> For what it's worth, relatively simple cases (with shallow depth and >> simple structure) can be implemented using #macro and without recursion >> (#foreach on all the child nodes you are interested in, and examine each >> only for the 1 or 2 deep children you are interested in). > > And these are probably the cases we care about anyway, aren't they? I know what you're saying, but I think it would be foolish to limit the usefulness of WM for these tasks to the simple examples we can think of now (i.e. RSS). What about 3 or 4 deep? It's not much more, but it increases the complexity of the WM code enormously - a new nested #foreach for each level, at the very least. >> However the simplest way to deal with these things is usually to have a >> single loop "macro" and a long #if list checking tag type and >> calling/including the bit of WMScript to render a node of that tag type. > > And the long #if _can_ be a macro since it doesn't call back to the > looper. Yes, but the loops can't (as far as I can see). >> I have used the "hard coded" method so far with my RSS display code for >> WM, but I am using the recursion method on the wmwebapp docs because it >> is a less rigid structure, were <code> can appear inside a <para> or a >> <title> for example. > > How about an XPath tool? I suspect that would go a long way towards > making the sorts of problems you want to solve more tractable without > building DOM support into the template language. We are going to build XPath or an XPath-like tool into our XML helper. Our XML helper class presents a simple WM-friendly wrapper around nodes, without requiring the template writer to fully understand DOM. Perhaps this is where some confusion is arising. I am not proposing that we manipulate DOM objects directly in WM script - only simplified wrappers of DOM Nodes. Here's the basic node wrapper API: boolean getIsCDATA(); boolean getIsComment(); boolean getIsDocumentFragment(); boolean getIsDocumentType(); boolean getIsElement(); boolean getIsEntity(); boolean getIsEntityReference(); boolean getIsNotation(); boolean getIsProcessingInstruction(); boolean getIsText(); String getName(); XMLParentNode getParent(); XMLNode getNextSibling(); XMLNode getPreviousSibling(); String getValue(); String getText(); XMLNode[] getChildren(); XMLNode getFirstChild(); XMLNode getLastChild(); XMLNode[] getAll( String name ); XMLNode getById( String id ); XMLNode[] getChildren( String name ); XMLNode getFirstChild( String name ); String getAttribute( String name ); String[] getAttributeNames(); These can all be used very simply and nicely from a WM template. Yes we cache the wrappers on a per-doc basic. These methods work very nicely in templates - and the XMLNode implementations implement toString and return getValue/getText (all child text nodes to any depth) depending on the current node type. i.e. #foreach $node in $xmlHelper.Children( "item") <h1>$node.FirstChild.title</h1> <p>$node.FirstChild.description</p> #end We will add an XPath-like find method.. i.e. $node.find( "channel/item"). Do you know of a good free XPath lib we can pull in to use for this? I haven't found one yet. There's one in Apache Xalan 2 but I am pretty sure it depends on a lot of Xalan code so it would be serious overkill. >> By community do you mean webmacro-devel or webmacro-users? > > Either! But since this conversation is on -devel, that's the one that > has a bigger chance of responding. Hehe, but I meant we could post a question to the wm-users list asking "Do you think it would be good to be able to easily display pages containing data taken from XML documents?". Or "Do you think we should deliberately not make it easy for you to use XML data in your templates?" :-) >> Have you looked at Google's web services, or Amazon's web services? I >> will be building demo templates that retrieve XML information about a >> product search on Amazon and dump out the product image thumbnails, >> prices, descriptions etc. - this is KILLER stuff, and WM needs to be >> there doing it. > > Yes, I've even written an article about it. Very slick. Took me less > than an hour to build an Amazon search web-app with Glue+IDEA+WM. > Since it came back as Java objects, no need to even touch the XML. > Glue rocks. Yes I've heard good things about it - but you're taking the SOAP approach :) (it would seem) It's easy (though it should be VERY easy) to do this in WM script alone, without any Java code apart from an XML helper to give you nodes. >> Remember, the solution can be as simple as supporting an inline template >> directive - and whether "crazies" like me use it for the "right" reasons >> or not is not really an issue. > > The issue is when some "crazy" uses it for the "wrong" reason and then > posts to the list something like "#include is broken -- proof!" :) OK OK... but it also depends on the docs clearly showing what is/isn't possible. I made incorrect assumptions, unfortunately :-) >> Inline template sections would be very useful for many things I think, >> although I agree it does move one step closer to WMScript becoming a >> little more like a "functional" language. > > The only reason inline templates never made it was that we didn't have > a syntax for the substitution. If we had inline templates without > context substitution, it would take no more than five minutes for > peopel to say "How about some way of calling this template with this > parameter list..." > > Now that the parser has been upgraded to do argument lists, this would > be pretty simple to write: > > #template t(arg-list) { block } > #expand t(arg-list) > > Hnm, that was what you were asking for, right? Something like that yes - where the net effect is EXACTLY the same as: #set $myglobalVar1 = "something" #set $myglobalVar2 = "something else" #include as template "subtemplate.wmt" ...but without putting the vars into the "global" context. >> Thanks for your discussion on this so far Brian. Have you dealt with >> any XML / tree-based data in apps using WM yet? If so, what were >> your solutions? If not... then perhaps you should try it. Get >> yourself a free developer token from Amazon and start writing code >> that puts this data into a WM template. > > This is a great example. I used the Glue wsdl2java tool (which is > nicely integrated with IDEA), and it generated Java classes for all > the types used in the WSDL. They are bean types, so you can justput > an array of them right in your context, done! Look Ma, no XML! Ah yes, but this is using SOAP. This is completely different. You can use Amazon just as "XML RPC" with a straight forward request URI and get an XML doc back. This is far more efficient and is possible without any Java code, just WM script. Glue looks very nice though for more serious apps. Remember, I'm thinking web designers here, not java developers. The forthcoming webapp is a tool as much for web designers as it is for WM developers. As a result I want to make sure we have features and capabilities in there to address most if not all of the common problems facing web designers making complex web sites - which are not necessarily the high grade bespoke Java web applications people like you and I write. > Working Amazon WS example: > > KeywordRequest request = new KeywordRequest(); > request.keyword = httpServletRequest.getParameter("query_string"); > request.devtag = MY_AMAZON_TOKEN; > request.type = "heavy"; > request.page = "1"; > request.mode = "books"; > ProductInfo pi = amazon.KeywordSearchRequest(request); > context.put("search_results", pi.Details); > > where Details is an array of ProductInfo objects, which are generated > by GLUE directly from the WSDL. Yes, nice. Although here is something controversial. I was thinking about SOAP... calling a method on a helper in a template is conceptually not any different to calling a method on another server. So, I think we should seriously consider writing a #soapcall directive that does just what you think. I'm still a SOAP noobie but I can't see why it shouldn't be possible. Of course I don't mean this should be a core directive, but if we have #bean why not have something that is vaguely equivalent that can call across the net to any machine running any language? It could be a killer feature for people working on WM sites that must integrate with other platforms/languages such as Delphi. If this is of interest I think we should start a new thread - "WM and SOAP/XML-RPC support". Again, I don't see why we should force web designers to get some java code written by somebody (and also increase their runtime code overhead and deployment complexities) when we can make it possible to do this straight from WMScript. Marc -- Marc Palmer (Wangjammer5) http://www.wangjammers.org Java Consultants |