July 29, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Using Spring's Form Tag Library and Dialogs with the Magnolia CMS, Page 2

Using Spring's Form Tag Library with the Magnolia CMS

With the validation taken care of, there's one final step left. The JSP template must be updated to display error messages for fields that fail validation, so that users know what went wrong and can correct their input before re-submitting the form. When again, Spring comes to the rescue with its form tag library, which provides a set of tags to dynamically create Web forms. This tag library can also directly access controller properties, making it possible to easily inject data such as selection lists or error messages from the controller.

To see how this works, update your pizzaForm.jsp template to look like this:

<!--taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"-->
<!--taglib uri="cms-taglib" prefix="cms"-->
<!--taglib uri="blossom-taglib" prefix="blossom"-->
<!--taglib uri="http://www.springframework.org/tags/form" prefix="form"-->
<!--

.error {
color:red;
}

-->
<h2>Design a Pizza</h2>
Size:

Toppings:

Crust:
Thin and crisp
Thick and cheesy

Name:

Email address:

Notes:

<input name="submit" type="submit" value="Save" />

You can read all about the tag library here, but two important things to note about this template now are:

  1. The tag that dynamically produces a list of checkboxes from an array -- In this case, the availableToppings array defined earlier in the controller
  2. The tag that provides a way to display errors generated by the validator -- The path attribute serves as a key to look up the error message associated with that particular key.
Tip: If you prefer to display errors in a block at the top of the form, instead of under individual fields, use the '*' wildcard as your error path. Look here for more information.

Figure 1 shows what your project directory should now look like.

Spring Framework and Magnolia CMS
Figure 1:
Final Project Directory Structure

You should now recompile the module and then tell Magnolia to reinstall it. To do this, switch to the AdminCentral -> Configuration menu and, in the module list, find and delete the modules/example node (as shown in Figure 2).

Spring Framework and Magnolia CMS
Figure 2:
Magnolia CMS Module Deletion

Next, stop the server, copy the new module JAR file from the project's example-module/target directory to the WEB-INF/lib directory of the Magnolia authoring instance, and restart the server. Magnolia should offer to reinstall the module for you. Accept the offer, and then try revisiting the pizza form page and entering invalid data into the form. You should see a list of error messages as the validator detects and alerts you to the invalid items. Figure 3 shows what it looks like.

Spring Framework and Magnolia CMS
Figure 3: Validation of Invalid Form Input

The success page will now be displayed only after you enter valid data for all the fields. Try it yourself and see!

Creating Dialogs with the Spring Framework and Magnolia CMS

Magnolia templates also support user-level configuration through the use of dialogs. A dialog is essentially a configuration "menu" for a template, allowing authors to exert control over different aspects of the template, such as the title, orientation, or display attributes. Normally, dialogs need to be manually defined and associated with a template, as shown in the Magnolia templating tutorial. This can be tedious and time-consuming, especially with complex templates. Blossom and Spring however, make the entire exercise much simpler and easier to handle by allowing dialogs to be defined programmatically.

The main component here is Blossom's TabBuilder component, which provides a set of methods to create dialogs for paragraph templates. A key benefit of this is that it enables dialogs to become more dynamic, with dialog options specified at run-time rather than at design-time; an ancillary benefit is that since dialogs are now defined via code, changes to them can be tracked through regular source control systems.

Let's see how this works by enhancing the paragraph template to allow authors to define which pizza toppings are available for user selection. Update your paragraph definition as shown below:

package info.magnolia.module.example;
import info.magnolia.module.blossom.annotation.Paragraph;
import info.magnolia.module.blossom.annotation.ParagraphDescription;
import info.magnolia.module.blossom.annotation.TabFactory;
import info.magnolia.module.blossom.dialog.TabBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import java.util.List;
import java.util.ArrayList;
import info.magnolia.cms.core.Content;
import info.magnolia.context.WebContext;
import info.magnolia.context.MgnlContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* Displays a pizza order form and a confirmation page after the form is submitted.
*/
@Controller
@Paragraph(value="Pizza Form", name="pizzaForm")
@ParagraphDescription("A form for users to order a pizza")
public class PizzaFormParagraph {
private static final String[] toppings = new String[] {"Cheese", "Tomato", "Onion", "Ham", "Bacon", "Anchovies"};
@RequestMapping("/pizza/new")

public String handleRequest(ModelMap model, @ModelAttribute PizzaForm pizzaForm, BindingResult result, HttpServletRequest request) {
Content content = MgnlContext.getWebContext().getAggregationState().getCurrentContent();
List x = new ArrayList();

for (String t : toppings) {
if (content.getNodeData(t).getString().equals("true")) {
x.add(t);
model.addAttribute("availableToppings", x);
}
}
if ("POST".equals(request.getMethod())) {
new PizzaFormValidator().validate(pizzaForm, result);
if (result.hasErrors()) {
return "pizzaForm";
}
return "pizzaFormResult";
}
return "pizzaForm";
}

@TabFactory("Content")
public void contentTab(TabBuilder tab) {
for (String t : toppings) {
tab.addCheckbox(t, t, "Check this box to make " + t + " a selectable topping");
}
}
}

The most important change here is in the contentTab() method, which now iterates over the toppings array and creates a dialog containing a checkbox for each topping. This allows authors to define at run-time which toppings should actually appear in the output form. Within the handleRequest() method, a few additional lines of code implement a conditional test, adding only the selected toppings to the availableToppings attribute that is read by the JSP template script.

Now, compile and redeploy the module to Magnolia CMS. Preview the example page and add a new pizza form. This time, you should see a dialog that asks you to specify which toppings should appear in the output template, as shown in Figure 4.

Spring Framework and Magnolia CMS
Figure 4:
Template Configuration Dialog

The pizza form will now be configured with only the selected toppings, as shown in Figure 5.

Spring Framework and Magnolia CMS
Figure 5:
Form Template Configured as Per Dialog Input

Tip: It's also possible to validate dialog selections using Spring, just like you would validate regular form input. Look here for some sample code.

Conclusion

As these examples illustrate, Magnolia's Blossom module makes it easy to integrate advanced features of the Spring framework with Magnolia's existing templating architecture. This allows developers a great deal of creativity and flexibility when building complex Web sites with custom workflows and non-standard use cases. Try it out sometime and see how easy it is.

Code Download

  • Magnolia-Spring_src
  • For Further Reading

  • Spring Framework and Magnolia CMS: Creating Complex Java-based Websites (from Developer.com)
  • Set Up the Magnolia CMS for Web Content Creation in Just a Few Clicks (from WebReference)
  • Publish Web Content Efficiently with Magnolia CMS (from WebReference)
  • The Magnolia CMS templating tutorial (from documentation.magnolia-cms.com)
  • About the Author

    Vikram Vaswani is a consultant specializing in open-source tools and technologies. He has more than 11 years of experience deploying open-source tools in corporate intranets, high-traffic Web sites, and mission-critical applications. He is a frequent contributor of articles and tutorials to the open source community, and the author of six books on PHP, MySQL and XML technologies.


    Tags: CMS, Spring, Magnolia

    Originally published on http://www.developer.com.

    Page 2 of 2



    Comment and Contribute

     


    (Maximum characters: 1200). You have characters left.

     

     


    Sitemap | Contact Us

    Rocket Fuel