Support and Documentation

View models

In the model-view-view model pattern, the view model receives raw data from the model and transforms that data to produce a view. Brightspot's ViewModels accomplish this transformation in two steps. In the first step, the view model receives two categories of data:

  • Content, such as text, images, and videos available through methods in a received model object.

  • Web environment, such as HTTP header fields, query strings, and cookies available through annotations.

The view model implements methods specified in an underlying Java interface such that there is one method for each item appearing in the view. For example, if a view has three elements (headline, body, and date published), the view model includes three methods to return each element individually. If those elements require additional logic, such as instantiating a locale to properly format a date, the view model implements the corresponding methods and constructors accordingly.

In the second step, the view model transforms the extracted data into a form the view is expecting.

In the following example, the view model uses the getHeadline and getBody methods to access those model elements; it also uses the @HttpHeader annotation and getDatepublished method to access and format the publication date in a manner indicated by the client's locale.

import com.psddev.cms.view.ViewModel;
import com.psddev.cms.view.servlet.HttpHeader;

public class ArticleViewModel extends ViewModel<Article> {

    @Override
    public String getHeadline() { 1
        return model.getHeadline();
    }

    @Override
    public String getBody() { 2
        return model.getBody();
    }

    @HttpHeader("Accept-Language")
    public String acceptLanguage; 3

    @Override
    public String getDatepublished() { 4

        Date datePublished = model.getDatePublished(); 5

        String httpLocale = this.acceptLanguage.substring(0,5); 6

        Locale readerLocale = null; 7
        if (httpLocale.equals("en-US")) {
            readerLocale = new Locale("en","us");
        } else {
            readerLocale = new Locale("en","au");
       }

       DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, readerLocale); 8

       return "Date published: " + df.format(datePublished); 9

    }

}

1

Returns the article's headline.

2

Returns the article's body.

3

Extracts the Accept-Language field from the HTTP header. The first five characters of this field provide the locale, such as en-us.

4

Returns a date in a format as expected by the client's locale prepended with the string Date published: .

5

Retrieves the date published from the model.

6

Extracts the first five characters from the Accept-Language field to get the client's language and country.

7

Declares a standard Locale variable; set it to en-us or en-au depending on the characters extracted from the Accept-Language field.

8

Instantiates a DateFormat variable that formats the date based on the discovered locale.

9

Returns the formatted date prepended with the string Date published: .

The following image is an example of the previous snippet's output.

vm-output.png

You can modularize your code by implementing the interface PageEntryView—a marker interface you can use to determine the required view model based on the model's class or other criteria. See the following example.

public class ArticleViewModel extends ViewModel<Article> implements PageEntryView {

    if ((model instanceof DailySection) || (model instanceof WeeklySection)) {
        return createView(SectionViewModel.class, model); 1
    } else {
        return createView(ArticleViewModel.class, model);
    }
}

1

For information about the createView method, see createView.