Skip to end of metadata
Go to start of metadata

Introduction to customizing pages

Remember that tapestry-model provides built-in support for CRUD (Create, Read, Update, Delete) operations, and techniques for customizing each differs. For customizing how the object gets displayed and what parts of it are editable and how, you commonly use annotations, and for customizing the UI, like layout etc. you'd commonly create a custom template for a particular domain model type and modify that template. For the latter type of customization, once you get the hang of customizing a tapestry-model page, you'll realize that you are simply using Tapestry rather than any Tynamo magic.

In other words:

Tynamo makes a lot of assumptions from your domain model in order to produce a working application. Of course, assumptions are wonderful when they are right - but sometimes they're wrong. Fortunately, Tynamo provides a great deal of flexibility in overriding the assumptions that it makes.

Annotating properties

For edit and display pages, Tynamo uses Tapestry's BeanEditForm and BeanDisplay components with custom property editors. The typical Tapestry and Hibernate annotations work as expected, as documented at Tapestry's BeanEditForm guide. The typical property annotations to use are @NonVisual, @Validate and @ReorderProperties (the last one's a class annotation). For now, refer to Tapestry's documentation regarding the annotations, we'll expand this section as needed.

Customized tapestry-model templates

If you don't customize anything, Tynamo uses default pages. In Tapestry, a component (a page is a component as well) is comprised of two parts: its template and a backing java class. There's a default page for each particular operation, such as: Add, Edit, List and Show. The archetype will put the Java page classes to src/main/java/<groupid>/pages and the corresponding templates to /src/main/webapp. The cool thing about this is that you can also customize the default look and feel of a page for an operation type. Most of the cases, however, you want to customize a page specific for a particular object.

Tynamo makes decisions about what page to display based on which kind of page is needed and the class of the object(s) involved. It will first look for a page using Add, Edit, Show or List depending on the kind of page needed, prefixed with the unqualified-type name of the object. If it can't find a specific page for a given type, it will instead use the default Add, Edit, Show or List page, respectively. The following table gives some examples of how Tynamo figures out which page to use:

Operation

Class

Look for page:

If not found, use page:

Edit

org.tynamo.recipe.entities.Recipe

org.tynamo.recipe.pages.edit.RecipeEdit

org.tynamo.recipe.pages.Edit

List

com.foo.entities.Product

com.foo.pages.list.ProductList

com.foo.pages.List

Add

org.wwf.entities.Gazelle

org.wwf.pages.add.GazzelleAdd

org.wwf.pages.Add

To start customizing a page, make a copy of the appropriate default page files and rename according the the table above. Most of the UI customization happens in the corresponding .tml template. Keep in mind that a Tapestry template is more or less just a html page with selected additional tags starting with <t:some-tapestry-element> that will be replaced by Tapestry components (which can be comprised of other templates and so forth). Read Tapestry's template guide for more comprehensive documentation.

The typical customization needed for edit forms is that you want to render something else for a specific field but you are fine with other defaults. Property Editor Overrides are exactly for that purpose, see the linked documentation for exact examples. If we wanted to, we could replace the Form component entirely and create a new form from scratch using standard Tapestry components.

Customizing the page class

You can also customize the pages java side. Just extend from ListPage or from EditPage according to your needs and rename it accordingly.

Icon

example needed here

Validation

Tapestry-model takes the approach that validation should be specified in your domain object, and makes it easy to do so. In keeping with the theme of not reinventing wheels, tapestry-model leverages the excellent Hibernate validation annotations. Tapestry-model integrates them into the error reporting system provided by Tapestry, with the net result being that adding validation to your domain object takes about as long as you've just spent reading this paragraph.

Let's see it in action by making the title property required.

That's all there is to it. The @NotNull annotation tells Tynamo (and Hibernate) to make this a required field. When we try to create a recipe with no title, we get a useful error message.

And if we don't like the default message, it's easy to change that, too. All of the Hibernate validation annotations allow a message attribute, so we can change our @NotNull annotation like so:

There are quite a few validation annotations provided by Hibernate. Writing your own is outside of the scope of this article, but not at all difficult to do.

Back to Working with databases or continue to Testing

  • No labels