Your starting base: play-cms-demo

To bootstrap your project, you should use the play-cms-demo as your starting point. Once it's up and running, continue with the steps below.

 

Setup and initialize the cms

To setup the cms programatically (wire up your own provider classes), you implement the ch.insign.cms.CMSApiLifecycle interface or override the ch.insign.cms.CMSApiLifecycleImpl class to change runtime settings, and implement the ch.insign.cms.models.Bootstrapper interface or override the ch.insign.cms.models.DefaultBootstrapper class to change the initial database content.

Main setup options 

Register your blocks
You should define your own block list, so the cms default page block (containing the default layout) does not appear. However, you can mix in any existing cms blocks, like the neutral CollectionBlock.


@Override
protected void registerCmsBlocks(CMSApi cmsApi) {
    // Either override or extend the list of cms blocks.
    // You can mix predefined and own blocks
    super.registerCmsBlocks(cmsApi); // optional
    cmsApi.getBlockManager().register(
        MyContentPage.class,
        MyContentBlock.class,
        MyCollectionBlock.class
    );
}

 

Create your own error pages
Error pages are treated as normal cms pages. Create and return them initially form code - the admins can then modify them using the cms.

Add example data
This helps greatly during development of your project: Create some demo pages and content using your own blocks and design, and matching the final project's desired content. During development, you can then easily reset the db (call yourdomain.ext/reset) and will find your example content again.

Add your own content filters
Content filters are a great tool to let the user add e.g. variables freely inside any content, e.g. [[currentUserCount]] which your filter resolves to the current value when displaying the page.

CMSApiLifecycle example

app/MyCMSApiLifecycle.java:

@Singleton
public class MyCMSApiLifecycle extends CMSApiLifecycleImpl {
    private final MyAuthenticationListener myAuthenticationListener;
    private final PlayAuthApi playAuthApi;

    @Inject
    public MyCMSApiLifecycle(
            JPAApi jpaApi,
            ActorSystem actorSystem,
            PlayAuthApi playAuthApi,
            MyAuthenticationListener myAuthenticationListener
    ) {
        super(jpaApi, actorSystem);
        this.myAuthenticationListener = myAuthenticationListener;
        this.playAuthApi = playAuthApi;
    }

    @Override
    public void onStart(CMSApi cmsApi) {
        super.onStart(cmsApi);

        // set your own authentication listener
        playAuthApi.getEventDispatcher().addSubscriber(loggingAuthenticationListener);

        // change other settings here...
    }

    @Override
    protected void registerCmsBlocks(CMSApi cmsApi) {
        // Either override or extend the list of cms blocks.
        // You can mix predefined and own blocks
        super.registerCmsBlocks(cmsApi); // optional
        cmsApi.getBlockManager().register(
            MyContentPage.class,
            MyContentBlock.class,
            MyCollectionBlock.class
        );
    }

    @Override
    protected void registerContentFilters(CMSApi cmsApi) {
        // Add your own content filters.
        super.registerContentFilters(cmsApi);
        cmsApi.getFilterManager().register(
            MyEmoticonContentFilter.class
        );
    }
}

 

Bootstrapper example

app/MyCMSBootstrapper.java:

@Singleton
public class MyCMSBootstrapper extends DefaultBootstrapper implements Bootstrapper {

    private PartyManager pm;
    private PartyRoleManager prm;
    private JPAApi jpaApi;

    @Inject
    public MyCMSBootstrapper(
            AccessControlManager accessControlManager,
             CMSApi cmsApi,
             PartyManager partyManager,
             PartyRoleManager partyRoleManager,
             JPAApi jpaApi
    ) {
        super(accessControlManager, cmsApi, partyRoleManager, jpaApi);
        this.pm = partyManager;
        this.prm = partyRoleManager;
        this.jpaApi = jpaApi;
    }

    /**
     * Load essential data which is required for all configured sites to function properly.
     *
     * Used to perform an initial project bootstrap or to reload it to the initial state.
     */
    @Override
    public synchronized void loadEssentialData() {
        super.loadEssentialData();
    }

    /**
     * Load example data for all configured sites.
     */
    @Override
    public synchronized void loadExampleData() {
        super.loadExampleData();
    }

    /* Override DefaultBootstrapper methods:
     *   The DefaultBootstrapper defines more fine grained methods
     *   which are called by DefaultBootstrapper.load*Data methods
     *   so it may be easier to override them if small changes required.
     */

    /**
     * Delete data created by loadEssentialData
     */
    @Override
    protected void deleteEssentialData() {
        super.deleteEssentialData();
    }

    /**
     * Delete data created by deleteExampleData
     */
    @Override
    protected void deleteExampleData() {
        super.deleteExampleData();
    }

    /**
     * Add navigation entries in the backend
     */
    @Override
    protected void createBackendNavigation() {
        super.createBackendNavigation();
    }

    @Override
    protected ErrorPage createErrorPageNotFound(Sites.Site site) {
        return super.createErrorPageNotFound(site);
    }

    @Override
    protected ErrorPage createErrorPageUnavailable(Sites.Site site) {
        return super.createErrorPageUnavailable(site);
    }

    @Override
    protected ErrorPage createErrorPageInternalServerError(Sites.Site site) {
        return super.createErrorPageInternalServerError(site);
    }

    @Override
    protected ErrorPage createErrorPageForbidden(Sites.Site site) {
        return super.createErrorPageForbidden(site);
    }

    @Override
    protected void createPartyRoles() {
        super.createPartyRoles();
        
        // add more user roles
    }

    @Override
    protected void createParties() {
        super.createParties();
        
        // add more users
    }
}

 

The CMSApiLifecycle and Bootstrapper implementations are configured as DI bindings in ch.insign.cms.inject.CmsApiModule and ch.insign.cms.inject.BootstrapperModule correspondingly, so they should also be overridden by implementing custom play.api.inject.Module, enabling them in the application.conf and also disabling the overridden modules, e.g.:

conf/application.conf

# Override CmsApiModule
play.modules.disabled += "ch.insign.cms.inject.CmsApiModule"
play.modules.enabled += "my.CmsApiModule"

# Override BootstrapperModule
play.modules.disabled += "ch.insign.cms.inject.BootstrapperModule"
play.modules.enabled += "my.BootstrapperModule"

 

Configuration


The cms uses configuration values defined in play-cms/conf/application.conf. You can override them in your global application.conf.

play-cms/conf/application.conf:
# play-cms default configuration
application.router=cms.Routes
 
# CMS config values.
# Always access these using Cms.getConfig().*
cms.deleteWithoutTrashBin = false
cms.enableResetRoute = false


From code, config values can be accessed using CMSApi#getConfig().*