Annotations
There are two groups of annotations specific to the View system: type and field.
Type annotations
Type annotations are class-level annotations. They typically appear with view-model classes, but may be used with other classes or interface implementations.
@HandlebarsTemplate
Identifies the view model as a producer of Handlebars output, and specifies the Handlebars template's location. This annotation is included in the Brightspot Handlebars plugin.
This annotation requires the @ViewInterface annotation.
import com.psddev.cms.view.PageEntryView; import com.psddev.cms.view.ViewInterface; import com.psddev.cms.view.ViewModel; import com.psddev.handlebars.HandlebarsTemplate; @HandlebarsTemplate("Article") @ViewInterface public class ArticleViewModel extends ViewModel<Article> implements PageEntryView { public String getBody() { return model.getBody(); } public String getHeadline() { return model.getHeadline(); } }
The above example specifies that for the class ArticleViewModel
, the associated Handlebars file is <webroot>/Article.hbs
.
For detailed information about Handlebars, see Handlebars.
@JsonView
Declares the view model as a producer of JSON output.
This annotation requires the @ViewInterface annotation.
import com.psddev.cms.view.JsonView; import com.psddev.cms.view.PageEntryView; import com.psddev.cms.view.ViewInterface; import com.psddev.cms.view.ViewModel; @JsonView @ViewInterface public class ArticleViewModel extends ViewModel<Article> implements PageEntryView { public String getBody() { return model.getBody(); } public String getHeadline() { return model.getHeadline(); } }
The JSON output is an object with keys corresponding to the model's fields and associated values, as in the following example.
{ "body" : "A platoon of aliens who traveled four light years in suspended animation landed in Times Square Wednesday evening...", "headline" : "Squashed by Earth's Gravity, Aliens Demand Submission" }
@ViewInterface
Invokes a process to transform a Model's data into the form specified by another annotation, usually @HandlebarsTemplate (for Handlebars output), @JsonView (for JSON output), or @ViewRendererClass (for customized output). See those annotations for examples of how to use @ViewInterface
.
@ViewRendererClass
Specifies a class implementing ViewRenderer
to render the model's data.
This annotation requires the @ViewInterface annotation.
The following example comes from Brightspot's implementation for RawView
:
package com.psddev.cms.view; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @ViewInterface @ViewRendererClass(RawViewRenderer.class) public interface RawView { List<?> getItems(); /* static methods... */ }
Field annotations
The following field-level annotations appear before the declaration of individual fields within a ViewModel
.
@CurrentSite
Retrieves the current Site
object based on the Request URL. This annotation is available only if your Brightspot project is configured as a multi-site instance.
@HttpCookie
Retrieves the value for a specified cookie. If the specified cookie does not exist in the request, the annotation returns a null value.
@HttpHeader
Retrieves the value for a specified field in the HTTP request header. If the specified field does not exist in the request header, the annotation returns a null value.
@HttpMethod
Retrieves the HTTP request method. Typical values for the request method are GET and POST. For a listing of possible HTTP request methods, see HTTP request methods.
@HttpParameter
Retrieves the value of a requested parameter passed in a URL's query string or in a posted form. For example, if the URL is http://www.example.com/index.html?userid=5
, you can use this annotation to retrieve the value for userid
. If the parameter does not exist in the query string or form, this annotation returns a null value.
@HttpRequestAttribute
Retrieves the object or string representing a requested servlet attribute. If the attribute does not exist, this annotation returns a null value.
@HttpServletPath
Returns the servlet path, typically the path appearing after the domain in a URL. For example, in the URL http://www.example.com/solar-system-implodes
, the servlet path is /solar-system-implodes
.
@HttpSignedCookie
Retrieves the value for a specified signed cookie. If the specified cookie does not exist in the request, the annotation returns a null value.
@HttpStorageItemParameter
Transforms a submitted file into a StorageItem
, and associates the value for name
with the StorageItem
. The files can be uploaded files or JSON representations of files.
For example, the following HTML snippet submits two images to the server, one as a file and another in JSON format.
<html> <input type="file" name="image" /> <input type="hidden" value="{JSON structure here}" name="imageJson" /> </html>
The following view model snippet transforms the uploaded files into StorageItem
s.
@MainObject
Retrieves the object associated with a published permalink. For example, if the permalink associated with an article is http://localhost/gravity-canceled-today
, this annotation returns the object associated with /gravity-canceled-today
.
Custom field annotations
Custom field annotations are a mechanism for populating fields on a view model before any of your view-model logic executes. Currently, ServletViewRequestAnnotationProcessor is the only interface which allows you to populate fields on your view model. If you need to access the HttpServletRequest on your view model, then as a best practice you should create a custom annotation.
The simplest pattern for creating custom view-model annotations is to implement the annotation in a class and then apply the annotation to a view model's property or method. For many examples of advanced implementations of view-model annotations, including standalone annotation processors, see the Brightspot repository's servlet directory.
In the following sample, you develop a custom view-model annotation that checks if the current user is logged in before displaying an article's body. If the user is not logged in, the view model displays an appropriate message.
Step 1: Define annotation
In a file CurrentUser.java
, enter the following text:
import com.psddev.cms.view.servlet.ServletViewRequestAnnotationProcessor; import com.psddev.cms.view.servlet.ServletViewRequestAnnotationProcessorClass; import yourpackage.User; /* User-defined class */ import java.lang.annotation.*; @ServletViewRequestAnnotationProcessorClass(CurrentUserProcessor.class) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) 1 public @interface CurrentUser { } class CurrentUserProcessor implements ServletViewRequestAnnotationProcessor<CurrentUser> { 2 @Override public Object getValue(HttpServletRequest request, String fieldName, CurrentUser annotation) { Cookie[] cookies = request.getCookies(); 3 for (Cookie cookie : cookies ) { 4 if (cookie.getName().equals("authenticationCookieName")) { 5 if (passesAuthenticatonTest(cookie.getValue())) { 6 User currentUser = lookupUserByToken(cookie); 7 return currentUser; } else { return null; } } } return null; } }
Declares the | |
Implements the annotation's processor as an implementation of ServletViewRequestAnnotationProcessor: | |
Retrieves the cookies provided by an HTTP request. | |
Loops over all the cookies. | |
Processes the cookie | |
Checks if the authentication cookie is valid. | |
Retrieves the user record associated with the authentication cookie. |
Step 2: Apply annotation to view model
In the view model, enter the following text:
import annotations.CurrentUser; import yourpackage.User; /* User-defined class */ import com.psddev.cms.view.ViewModel; import com.psddev.cms.view.PageEntryView; import styleguide.content.article.ArticleView; public class ArticleViewModel extends ViewModel<Article> implements ArticleView, PageEntryView { @CurrentUser 1 private User currentUser; @Override public String getBody() { 2 if (currentUser == null) { return "Please log in or register to read this story."; } else { return model.getBody(); } } }
Applies the customized annotation
| |
Implements the
|