Quantcast

Chaining MarkupBuilders in Controller render

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Chaining MarkupBuilders in Controller render

Mike Cantrell-2
I'd like to let each of my domain objects contain a closure
representing it's XML (or JSON) format. This works well until I need
to render some sort of relationship. Ideally, I'd like to "chain"
these closures together and let the controller render it.

class Book {
        static belongsTo = [author:Author]
        String title
       
        def xml = {
                book(id:id) {
                        title(title)
                        author.xml  // or author.xml() or some sort of yieldUnescaped invocation
                }
        }
       
        def json = {
          ....
        }
}

class Author {
        static hasMany = [books:Book]
        String firstName
        String lastName
       
        def xml = {
                author(id:id) {
                        firstName(firstName)
                        lastName(lastName)
                }
        }
        def json = {
         ....
        }
}

class BookController {
        def restGet = {
                def book = Book.get(id)
                withFormat {
                      xml {
                        render(contentType: "text/xml", book.xml)
                      }
                      json {
                        render(contentType: "text/json", book.json)
                      }
                    }
                }
        }
}

The idea here is that I can lookup a Book and render it and it's
parent object in XML or JSON. I know the default XML and JSON
converters can handle these sorts of relationships but I'd really like
to decouple my domain model from it's external service representations
(although not evident in the crappy example). I know I can also just
create the complete closure with both Book and Author inside the
BookController but I need a re-usable solution that I can apply via a
custom plugin.

Is it possible to "chain" these sort of closures with MarkupBuilder?
Maybe there's a better way to accomplish the same end?

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Chaining MarkupBuilders in Controller render

btilford
Pass in a writer to each builder.

Also you'll probably wan't to begin the builder with xml.someclass { ...}  instead of xml = { someclass {...}}
class Book {
       static belongsTo = [author:Author]
       String title

       def xml = {writer->
               def xml = new MarkupBuilder(writer)
               xml.book(id:id) {
                       title(title)
                       author.xml(writer)
               }
       }

class Author {
      def xml = {writer->
      def xml = new MarkupBuilder(writer)
      xml.author(id:id) {...}

}


On Mon, Oct 5, 2009 at 11:02 PM, Mike Cantrell <[hidden email]> wrote:
I'd like to let each of my domain objects contain a closure
representing it's XML (or JSON) format. This works well until I need
to render some sort of relationship. Ideally, I'd like to "chain"
these closures together and let the controller render it.

class Book {
       static belongsTo = [author:Author]
       String title

       def xml = {
               book(id:id) {
                       title(title)
                       author.xml  // or author.xml() or some sort of yieldUnescaped invocation
               }
       }

       def json = {
         ....
       }
}

class Author {
       static hasMany = [books:Book]
       String firstName
       String lastName

       def xml = {
               author(id:id) {
                       firstName(firstName)
                       lastName(lastName)
               }
       }
       def json = {
        ....
       }
}

class BookController {
       def restGet = {
               def book = Book.get(id)
               withFormat {
                     xml {
                       render(contentType: "text/xml", book.xml)
                     }
                     json {
                       render(contentType: "text/json", book.json)
                     }
                   }
               }
       }
}

The idea here is that I can lookup a Book and render it and it's
parent object in XML or JSON. I know the default XML and JSON
converters can handle these sorts of relationships but I'd really like
to decouple my domain model from it's external service representations
(although not evident in the crappy example). I know I can also just
create the complete closure with both Book and Author inside the
BookController but I need a re-usable solution that I can apply via a
custom plugin.

Is it possible to "chain" these sort of closures with MarkupBuilder?
Maybe there's a better way to accomplish the same end?

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Chaining MarkupBuilders in Controller render

Mike Cantrell-2
Ahh.. yes. I guess that would work just fine. Thanks! I'll give it a
shot in the morning.

On Mon, Oct 5, 2009 at 10:31 PM, Ben Tilford <[hidden email]> wrote:

> Pass in a writer to each builder.
>
> Also you'll probably wan't to begin the builder with xml.someclass { ...}
> instead of xml = { someclass {...}}
> class Book {
>        static belongsTo = [author:Author]
>        String title
>
>        def xml = {writer->
>                def xml = new MarkupBuilder(writer)
>                xml.book(id:id) {
>                        title(title)
>                        author.xml(writer)
>                }
>        }
>
> class Author {
>       def xml = {writer->
>       def xml = new MarkupBuilder(writer)
>       xml.author(id:id) {...}
>
> }
>
>
> On Mon, Oct 5, 2009 at 11:02 PM, Mike Cantrell <[hidden email]> wrote:
>>
>> I'd like to let each of my domain objects contain a closure
>> representing it's XML (or JSON) format. This works well until I need
>> to render some sort of relationship. Ideally, I'd like to "chain"
>> these closures together and let the controller render it.
>>
>> class Book {
>>        static belongsTo = [author:Author]
>>        String title
>>
>>        def xml = {
>>                book(id:id) {
>>                        title(title)
>>                        author.xml  // or author.xml() or some sort of
>> yieldUnescaped invocation
>>                }
>>        }
>>
>>        def json = {
>>          ....
>>        }
>> }
>>
>> class Author {
>>        static hasMany = [books:Book]
>>        String firstName
>>        String lastName
>>
>>        def xml = {
>>                author(id:id) {
>>                        firstName(firstName)
>>                        lastName(lastName)
>>                }
>>        }
>>        def json = {
>>         ....
>>        }
>> }
>>
>> class BookController {
>>        def restGet = {
>>                def book = Book.get(id)
>>                withFormat {
>>                      xml {
>>                        render(contentType: "text/xml", book.xml)
>>                      }
>>                      json {
>>                        render(contentType: "text/json", book.json)
>>                      }
>>                    }
>>                }
>>        }
>> }
>>
>> The idea here is that I can lookup a Book and render it and it's
>> parent object in XML or JSON. I know the default XML and JSON
>> converters can handle these sorts of relationships but I'd really like
>> to decouple my domain model from it's external service representations
>> (although not evident in the crappy example). I know I can also just
>> create the complete closure with both Book and Author inside the
>> BookController but I need a re-usable solution that I can apply via a
>> custom plugin.
>>
>> Is it possible to "chain" these sort of closures with MarkupBuilder?
>> Maybe there's a better way to accomplish the same end?
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>    http://xircles.codehaus.org/manage_email
>>
>>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Chaining MarkupBuilders in Controller render

Ian Roberts
In reply to this post by Mike Cantrell-2
Mike Cantrell wrote:

> I'd like to let each of my domain objects contain a closure
> representing it's XML (or JSON) format. This works well until I need
> to render some sort of relationship. Ideally, I'd like to "chain"
> these closures together and let the controller render it.
>
> class Book {
> static belongsTo = [author:Author]
> String title
>
> def xml = {
> book(id:id) {
> title(title)
> author.xml  // or author.xml() or some sort of yieldUnescaped invocation
> }
> }

This ought to work provided you connect up the delegates properly, and
bear in mind that if you want to create an XML element with the same
name as one of your domain object's properties, you'll need to prefix it
with 'delegate.' - title(title) would cause groovy to try and .call()
the title property of the Book instance, which won't work, but
delegate.title(title) will create a title element in the XML:

book(id:id) {
  delegate.title(title)
  author.xml.delegate = delegate
  author.xml.call()
}

Ian

--
Ian Roberts               | Department of Computer Science
[hidden email]  | University of Sheffield, UK

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Chaining MarkupBuilders in Controller render

Mike Cantrell-2
Assigning the delegate works great. Thanks for the feedback guys.

On Tue, Oct 6, 2009 at 5:40 AM, Ian Roberts <[hidden email]> wrote:

> Mike Cantrell wrote:
>> I'd like to let each of my domain objects contain a closure
>> representing it's XML (or JSON) format. This works well until I need
>> to render some sort of relationship. Ideally, I'd like to "chain"
>> these closures together and let the controller render it.
>>
>> class Book {
>>       static belongsTo = [author:Author]
>>       String title
>>
>>       def xml = {
>>               book(id:id) {
>>                       title(title)
>>                       author.xml  // or author.xml() or some sort of yieldUnescaped invocation
>>               }
>>       }
>
> This ought to work provided you connect up the delegates properly, and
> bear in mind that if you want to create an XML element with the same
> name as one of your domain object's properties, you'll need to prefix it
> with 'delegate.' - title(title) would cause groovy to try and .call()
> the title property of the Book instance, which won't work, but
> delegate.title(title) will create a title element in the XML:
>
> book(id:id) {
>  delegate.title(title)
>  author.xml.delegate = delegate
>  author.xml.call()
> }
>
> Ian
>
> --
> Ian Roberts               | Department of Computer Science
> [hidden email]  | University of Sheffield, UK
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Loading...