Monday, March 21, 2011

Spring Web MVC with Content

The idea that sparked me writing the Blossom Module for Magnolia CMS was to bring the CMS and especially the content into Spring Web MVC not the other way around. Controllers should be the building blocks when composing pages. The latest version 1.2.2 brings a small but significant piece to the puzzle. By adding a custom WebArgumentResolver you can add content objects to the argument list in annotated handler methods.

This is an example of a paragraph that displays a contact form where the author that created the page specified which office will be receiving the filled in form. The office is fetched from a database and passed to the view where details such as its address are displayed.

@RequestMapping("/contactForm")
public String contactForm(ModelMap model, Content page, Content paragraph) {
    model.put("office", officeDao.getOfficeById(paragraph.getNodeData("office").getString()));
    return "contactForm";
}

To enable it you need to add the BlossomWebArgumentResolver to your AnnotationMethodHandlerAdapter.

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="customArgumentResolver">
    <bean class="info.magnolia.module.blossom.web.BlossomWebArgumentResolver" />
  </property>
</bean>

BlossomWebArgumentResolver provides support for a few more arguments that is handy to have handed directly to your handler method. They are: AggregationState, WebContext, Context, User and MgnlUser.


6 comments:

  1. We are looking into using Magnolia CMS and one of the requirement is to integrate with an existing Spring MVC web application (with jsp and taglib). We are interested in using Blossom. Your statement "..bring the CMS and especially the content into Spring Web MVC not the other way around...." kind of worries me since we like to do the other way around. What's your recommendation of try to fit an existing web app into Magnolia? For example, when the user click a tab, it shows the the same UI inside the content area.. Thanks!

    ReplyDelete
  2. Alex, I've been doing exactly what you are describing. Bringing an existing webapp into magnolia. It fits very well. I guess it's just how you want to see it, which way that is the political correct way in each case. The site I was converting is http://www.kokaihop.se. Previously it was 100% pure Spring Web MVC. Now it's 100% Magnolia Blossom.

    ReplyDelete
  3. Hi Tobias,

    Now to try and post without errors ..

    We recently created an extra webArgumentResolver for use with Blossom, that resolves actual nodeData values from the local content node from the aggregation state.

    The resolver checks parameters annotated with @NodeData([value|name|defaultValue]) that try and resolve all general available PropertyTypes in Magnolia (Long, Double, Boolean, String, Date, and primitives as well).

    So basically:

    @RequestMapping("/contactForm")
    public String contactForm(ModelMap model, @NodeData(name="office") String officeId) {
    model.put("office", officeDao.getOfficeById(officeId));
    return "contactForm";
    }

    would get your office ID resolved in your method signature :)

    I am currenly writing a post about it on blog.orange11.nl, but this might be a nice add on to the current webresolver?

    Best regards,
    Erik Alphenaar
    Software architect @ Orange 11 (www.orange11.nl)

    ReplyDelete
    Replies
    1. That's very cool Erik, looking forward to see the blog post =)

      Delete
    2. Hi Tobias,

      Check out: http://blog.orange11.nl/2012/06/19/nodedata-blossom-spring-mvc/
      and let me know if this would be something for in the next release of Blossom ;)

      Delete
  4. My website is based on spring mvc , i want it to be completely in magnolia so that it can be managed through it and can i add other functionalities like blog in my website using magnolia ? Is there any such functionality provided us by magnolia?

    ReplyDelete