Code time document references

dantleech edited this page Oct 31, 2014 · 10 revisions
Clone this wiki locally

The purpose of this page is to explore solutions for referencing documents from code.


When developing a CMS implementation the developer should not be coding to data which may or may not be in the database.

Currently it is necessary to hard code paths to documents. The problem is that these paths may change during the lifetime of the application, causing the application to fail.

Use cases

Rendering a menu

Rendering a certain menu from a TWIG template

{{ knp_menu_render('main')

When the above TWIG function is called, the main node will be expected to exist at /<path-to-menu-base>/main. If the main node does not exist then the application will not display the menu - but this is not good behavior as this is surely not the developers intention.

Linking to a certain page

The site requires certain pages to exist and be linkable from a TWIG template:

<div class="footer">
    <a href="{{ path('/path/to/contents/privacy-terms') }}">Privacy</a>

Here we reference the content document containing the "Privacy terms". The problem is that the path to this document is mutable. If the user changes the path of this document the application will explode.


Structural nodes

Structural nodes are Documents which, after being created, are locked from being moved anywhere else. They are effectively static.

If a Structural Document is not found, then an Exception should be thrown.



 * @ODM\Document(structural=true)
class FooDocument

These documents could be created with Repository Initializers, at the PHPCR level such Nodes could have a phpcr:locked mixin or somesuch.


  • The internal document structure of the CMS is maintained throughout the lifetime of the application
  • Other components (CmfMenuBundle, RoutingBundle) are agnostic to this feature


  • Multi site / context (see below)


Roles would allow the developer to reference documents with a static name, e.g.:

{{ path('@privacy_policy') }}
{{ knp_menu('@main_menu') }}


  • The internal structure of the website can still be changed (or is that a feature?)
  • Multi site / context (see below)
  • Other components need to be aware of this feature (e.g. CmfMenuBundle, RoutingBundle)
  • How to assign the roles.

Role Assignation

Assigning roles could be achieved either by:

  1. Assigning a property to the node with the "role". (and searching for and removing the property from any previous node with that role) or...
  2. Having a central "configuration" document/node (f.e. /cms) which contains the roles, e.g.
    + roles/ [cmf:role]
        - privacy_policy: 1234-1234-1234-1234
        - footer: 1234-1234-1234-1235
        - menu: 1234-1234-1234-1236

The 2nd solution is the cleanest as it would be impossible to have duplicate roles.

Multisite problem

Both of the solutions above will not work in a multisite/context setup.

But I think this is a general problem which could be solved by introducing a scope which could, for example, automatically limit Document queries to a subtree.

So I don't think this is necessarily a problem