Support and Documentation

Creating updating content edit widgets

The content edit page includes an updating URLs widget that contains traditional HTML form tags such as <textarea> and <select>.You can create custom updating widgets that provide web forms in the content edit page by extending UpdatingContentEditWidget—an abstract class that includes the abstract method displayOrUpdate you must override in addition to the abstract methods described in Creating. These widgets respond to events and instantiate custom objects for data validation and posting content to the database.

In the following example you create a widget for attributing an article to a reporter—a typical task in a ghost-writing scenario.

Step 1: Create reporter model

In this step, you create a simple model to hold reporters' first and last names.

import com.psddev.cms.db.Content;

public class Reporter extends Content { 1

    private String firstName;
    private String lastName;

    /* Getters and setters */

    public String getFullName() { 2
        return getFirstName() + " " + getLastName();
    }
}

1

Declares the class Reporter that extends Content. In a more robust implementation, you might create the class Reporter that extends ToolUser, create the class ReporterRole that extends ToolRole, and then assign instances of Reporter to ReporterRole.

2

Returns a reporter's full name as a concatenation of the reporter's first and last name.

Step 2: Add field to model, hide from content edit form

By default, Brightspot places all of a model's fields in the content edit form. In this example, you are attributing an article to a reporter, so a reporterCredit field must be part of the article's model. Because reporterCredit appears in an updating content edit widget, you must use the @ToolUi.Hidden annotation in the model to remove the field from the content edit form.

public class Article extends Content implements Directory.Item {

    @ToolUi.Hidden
    private Reporter reporterCredit;

    public Reporter getReporterCredit() {
        return reporterCredit;
    }
}

Step 3: Declare a custom updating content edit widget

import com.psddev.cms.tool.UpdatingContentEditWidget;

public class ReporterCreditWidget extends UpdatingContentEditWidget {

}

Brightspot instantiates this class every time an event occurs in the content edit page, such as when loading an item or clicking Publish.

Step 4: Display the widget's header

You display the custom widget's header by implementing the method getHeading in the class from Step 3.

public String getHeading(ToolPageContext page, Object content) {
    /* Return string appearing in widget's title bar. */
}

Step 5: Display the widget's body

You display the custom widget's body, including form elements, by implementing the method displayOrUpdate in the class from Step 3.

public void displayOrUpdate(ToolPageContext page, Object content, ContentEditWidgetPlacement placement) throws IOException {
    /* Use page.write methods to display the widget's body,
       including form elements. */
}

Step 6: Catch the update event

The parameter placement in Step 5 is passed as null when the widget detects an update event. You test for null to process the widget's current state.

Warning

Writing HTML to the content edit page when (placement == null) may corrupt the content state. Do not write HTML in this code block.

if (placement == null) {
    /* Retrieve form values and update database. */
}

Step 7: Position the custom updating widget

You provide a position for the custom updating widget in the content edit page by implementing the method getPlacement in the class from Step 3.

public ContentEditWidgetPlacement getPlacement(ToolPageContext page, Object content) {
    /* Return one of the placement constants. */
}

See the table Placement constants for a list of possible placement values.

Step 8: Set Condition for displaying content edit widget

Custom updating content edit widgets often appear in the UI for certain types of content and are suppressed for other types. You override the method shouldDisplay with a condition that evaluates to true when you want the content edit widget to appear.

public boolean shouldDisplay(ToolPageContext page, Object content) {
     /* Condition for displaying custom updating widget. */
 }

Step 9: Display custom updating widget in content edit page

The following snippet shows an entire class for displaying the custom updating widget Reporter Credit in the content edit page. The widget lists the available reporters which can be assigned to the current article. When the user clicks Publish, Brightspot updates the article's record with the selected reporter. This example assumes you have a model that includes a field reporterCredit with the associated getter and setter as descried in Step 2.

import com.psddev.cms.tool.ContentEditWidgetPlacement;
import com.psddev.cms.tool.ToolPageContext;
import com.psddev.cms.tool.UpdatingContentEditWidget;
import com.psddev.dari.db.Query;
import content.article.*;

public class ReporterCreditWidget extends UpdatingContentEditWidget { 1

    @Override
    public void displayOrUpdate(ToolPageContext page, Object content, ContentEditWidgetPlacement placement) throws IOException {

        Article myArticle = (Article) content; 2

        if (placement == null) { 3
            UUID reporterID = page.param(UUID.class, "reporter.select"); 4
            Reporter creditedReporter = Query.from(Reporter.class).where("id = ?", reporterID).first(); 5
            myArticle.setReporterCredit(creditedReporter); 6
            return;
        }

        List<Reporter> reporters = Query.from(Reporter.class).selectAll(); 7
        Reporter currentReporter = myArticle.getReporterCredit(); 8

        page.writeStart("select", "name", "reporter.select"); 9
            page.writeStart("option", "value", "").writeEnd(); /* Initial blank option */
            for (Reporter reporter : reporters) { 
                page.writeStart("option", "selected", reporter.equals(currentReporter) ? "selected" : null, "value", reporter.getId()); 
                    page.writeHtml(reporter.getFullName()); 
                page.writeEnd(); /* option */ 
            }
        page.writeEnd(); /* select */
    }

    @Override
    public ContentEditWidgetPlacement getPlacement(ToolPageContext page, Object content) { 10
        return ContentEditWidgetPlacement.RIGHT;
    }

    @Override
    public String getHeading(ToolPageContext page, Object content) { 11
        return "Reporter Credit";
    }

    @Override
    public boolean shouldDisplay(ToolPageContext page, Object content) { 12
        return content instanceof Article;
    }
}

1

Declares the class ReporterCreditWidget.

2

Casts the incoming object as an Article.

3

Traps the widget's update event.

4

Retrieves the selected reporter's UUID.

5

Retrieves the Reporter record matching the selected reporter's UUID.

6

Assigns the retrieved reporter record to the article.

7

Retrieves all of the reporters.

8

Retrieves the current article's reporter credit.

9

Render the widget's body with an HTML <select> field. The field's options are a default blank entry and the list of retrieved reporters.

10

Positions the widget in the right rail.

11

Displays the widget's heading Reporter Credit.

12

Displays the widget if the current content type is an article.

Based on the previous snippet, the custom updating content widget Reporter Credit appears in the right rail of the content edit page.

updating-content-edit-widget.png