Multi Domain Support

David Buchmann edited this page Nov 1, 2013 · 7 revisions
Clone this wiki locally

Right now we have different "base path" configuration options in various Bundles. For proper multi domain support we will need to allow configuration of multiple base paths for the different (sub)domains.

  • multi domain: same content in different looks. (the menu and navigation bundles are built with this in mind)
  • multi tenant: one instance with multiple separate sites. (phpcr workspaces should make this fairly easy, the menu and navigation bundles are built with this in mind, needs checks on security and acl)

Possible Implementation Approaches

1. Dynamic basepath parameters in bundle configuration

A possible solution for this could be to make the current "base path" parameters "dynamic". Right now Symfony2 DIC in 2.3 does not support such dynamic parameters explicitly however there is a new ExpressionLanguage component that will presumably be part of 2.4 which allows you to define service arguments that involve method calls on other services. For example you could define the content_basepath argument in xml as follows

<argument type="expression">service('basepath_resolver').getContentBasepath(request)</argument>

The is only available in the master branch (although being a standalone component perhaps we can simply provide instructions for users to require it directly or include it as part of the cmf). This seems like an ideal solution to this issue and would not involve refactoring any existing code. Providing a MultiDomainBasepathResolver and perhaps a BasepathResolver interface either as part of the cmf or in a cookbook/tutorial entry could provide users with a way to implement multi domain sites using cmf.

2. Refactor existing services accepting basepaths strings to accept resolver services

Refactor all of the services that rely on the basepaths to accept a basepath resolver service id as an alternatively to the string-based basepath configuration that is currently possible. The refactorings would be simple however there are many classes tied to the basepath concept.

3. Kernel event listener to configure basepaths

Provide a kernel event listener or tutorial on how to create one into which any services that rely on basepaths are injected. If enabled, this listener could then set the basepaths on all these services based on the domain required (based on a config).

An example of this type of implementation can be seen in the PrestaCms bundle. There is a WebsiteListener which uses a WebsiteManager to modify the basepaths in the MenuProvider, RouteProvider and RouteListener. The configuration of these websites (which in the Presta example are stored in the PHPCR) can be seen in the presta_cms_core.yml config file

The ExpressionLanguage component seems like the ideal solution although it would require dependency on this new component or Symfony 2.4. Some research needs to be into whether its plausible to enable this new component for the DIC in Symfony 2.3. Otherwise it would be a Symfony 2.4 only feature which may be a deal-breaker in terms of a solution for the CMF.

Multi-Domain Configuration

Any of these three solutions would involve the addition of some new configuration for multi-domain sites, formats for which is discussed at https://github.com/symfony-cmf/RoutingBundle/pull/156 It appears the current proposed config would be:

cmf_routing:
    dynamic:
        multidomain:
            enabled: true
            hosts:
                private:
                    pattern: private.mydomain.com
                    basepath: /cms/private # Optional, default if not set
                    menu_basepath: /cms/private-menu # Optional, default if not set
                    content_basepath: /cms/private-content # Optional, default if not set
                    locale: en # Optional, default if not set
                www:
                    pattern: *.mydomain.com # support wildcards for subdomains

The order of the hosts would be respected so that the private host pattern would match before the *.mydomain.com host. The basepath configuration could be optional and fall back to the defaults so in this case for the main website it would use cmf_core settings.

Additional Notes

Another general question is whether there could be some consolidation of the basepath parameters in existing services regardless. They are spread out over a number of bundles although they seem to be configurable all through the core bundle so perhaps this is a non-issue.

This looks to be a 1.1 feature although some kind of guide for how to implement this for CMF 1.0 seems like it would be very valuable as being a (potentially) centralized multi-site/domain cms platform without much configuration is a valuable feature of a content repository implementation.

The other bit we need for really good multi domain support would be some fallback rule system. For this we might in the end still need services to be aware of the multi domain configuration.

See also discussions on the mailinglist and https://github.com/symfony-cmf/RoutingBundle/issues/196#issuecomment-27386846