The cms contains an administrator backend which can be accessed by the /admin url. The navigation menu in the backend is managed by the cms, just like on frontend pages. This means admins can order the navigation, handle access rights or add links or even (frontend) pages.

Add navigation entries

The cms adds the backend navigation entries for the core modules when /reset is called. To add your own entries, override the Setup.addAdminBackendNavigation() method. Example:

MySetup.java:

    @Override
    public void addAdminBackendNavigation() {
        super.addAdminBackendNavigation(); // Make sure to call super first!
        PageBlock root = PageBlock.find.byKey(PageBlock.KEY_BACKEND);
        String key;
        String lang = Language.getCurrentLanguage();
 
        key = "_backend_rngr_products";
        if (BackendLinkBlock.find.byKey(key) == null) {
            BackendLinkBlock page = new BackendLinkBlock();
            root.getSubPages().add(page);
            page.setParentBlock(root);
            page.setKey(key);
            page.getLinkTarget().set(lang, "/admin/products");
            page.getNavTitle().set("de", "Produkte");
            page.setLinkIcon("book");
            page.save();
        }
    }

Notes:

  • Set the link target at least for the default (fallback) language. Or use per-language links.
  • Check if the entry already exists. This will later allow incrementally adding links (by using addAdminBackendNavigation() without /reset)
  • You can and should set a css class for icon (Font awesome icons are used).


Mark the active element

Since your backend page has its own route(s), the cms controller is not called. The LinkPage tries to match the called to the configured url.

However, this will fail where multiple urls exist for the active backend navigation element. Example: /admin/products/1, /admin/products/2, /admin/products/3 etc. should all mark the "Products" entry as active.

Solution: Manually mark the link active in your controller:

ProductController.java:

public class ProductController extends Controller {
 
    public static Result list(int page) {
 
        // Since this URL changes (/1, /2 etc), we need to tell the cms which nav entry is active
        BackendLinkBlock.find.byKey("_backend_rngr_products").setActive(true);

 

Access management

Since the backend navigation acts like another cms navigation, admins can manage the navigation entries just like in the frontend.

 Keep in mind that this only manages the navigation entries! Unlike cms pages, the direct url to your controller action is still accessible and it is your responsibility to protect it in your controller.

TODO: Add example