Pages

Overview

joist-web pages are objects that implement the Page interface.

Pages are responsible for initializing controls to render the page and handle any user interaction on form submissions.

Mapping

joist-web maps class names from URLs simply:

Although you can override this mapping in the PageResolver class.

Example

This is the code-behind Page class for foo.htm, a data-entry page for Foo objects:

    @Bindable
    public class FooPage extends AbstractProjectPage {

        // When hitting foo.htm?foo=1, Foo with id=1 is put into this field
        public Foo foo;
        public Form form = new Form("form");

        @Override
        public void onInitt() {
            if (this.foo == null) {
                // They hit the "new" button instead of the "edit" button
                this.foo = new Foo();
            }

            // Define the form using the bindgen-generated bindings
            FooPageBinding b = new FooPageBinding(this);
            this.form.add(new TextArea(b.foo().name()));
            this.form.add(new TextArea(b.foo().description()));
            this.form.add(new SubmitButton(b.save()));
        }

        // In AbstractProjectPage, DomainObjects are not allowed to be set into any public field
        // unless this method explicitly allows them--prevents users from screwing with URLs
        @Override
        public boolean isAllowedViaUrl(DomainObject instance) {
            return instance instanceof Foo && ((Foo) instance).getUser().equals(this.currentUser.get());
        }

        // Called when the user hit's submit
        public void save() {
            if (this.commit()) {
                this.messages.addInfo("Successfully saved {}", this.foo);
                redirect(EntriesPage.class);
            }
        }
    }

And now the foo.htm, which is a Velocity template:

    $form

Across lots of pages, the succinctness of the foo.htm page and the type-safety of the bindgen-based Form definition should be a boon to productivity.