RFC: Fallback graph configuration

##Motivation
The current fallback configuration does not cover enough use cases for projects that require content dimensions. It is also rather misleading for both integrators and the service implementations that build up the fallback graphs. Both of this can be improved rather easily.

##Change Log
2017-09-13: Initial reference
2017-09-25: Adjusted naming convention from variant to specialization and extended example to one value having multiple specializations

##Status quo
Content Dimensions are configured like this:

Neos:
  ContentRepository:
    contentDimensions:
      market:
        default: row
        defaultPreset: row
        label: Market
        icon: icon-flag
        presets:
          row:
            label: 'Rest of the World'
            values:
              - row
            uriSegment: ROW
          eu:
            label: Europe
            values:
              - eu
              - row
            uriSegment: EU
          de:
            label: Deutschland
            values:
              - de
              - eu
              - row
            uriSegment: DE

There was some reason why both default and defaultPreset are necessary, although I’m pretty sure we can get rid of one of both.
Defining the fallbacks is something that people tend to get wrong the first time they see it (at least that is what the chat log in slack hints at). Take for example the definition of de with specifically defined fallbacks to eu and world. That one is actually quite treacherous, since in reality you don’t have any chance of changing the fallback from eu to row here anyway (this is defined in the eu preset and only there). People also tend to build recursive fallbacks by adding all values everywhere.
And last but not least, we’re currently restricted to path segments, which is fine for many use cases. But if you want to do it right, you’d rather have de.domain.ch instead of domain.com/de_CH/ for example.
##Suggestions
Here is an alternative way of configuration:

Neos:
  ContentRepository:
    contentDimensions:
      market:
        ui: (label, flag,...)
        detectionMode: 'uriPathSegment'
        defaultValue: row
        values:
          row:
            ui: (label,...)
            detectionValue: 'ROW'
            specializations:
              eu:
                ui: (label,...)
                detectionValue: 'EU'
                specializations:
                  de:
                    ui: (label,...)
                    detectionValue: 'DE'
              gb:
                ui: (label,...)
                detectionValue: 'GB'
                specializations:
                  en:
                    ui: (label,...)
                    detectionValue: 'EN'

As you can see, the fallback is configured as the tree it is in reality. There is almost nothing to be misconfigured here and it should be really easy (and fast) to parse the configuration into the respective graphs for fallback calculation.
Other detection modes would be subdomain, top-level domain, domain name, user group etc. At least the first three of these should be usable by default in addition to the path segment we use now.
Detection itself is another topic for another RFC.

Seems almost too simple to me, did I miss anything?

Yes that makes multiple “parents” impossible.

Lets say I have “ROW”, “DE”, EN" and currently have the following:

“ROW” -> no fallback
"EN" -> “ROW”
“DE” -> “ROW”

I can probably come up with other/better examples, but I think this nesting prohibits valid use cases.

Oh, I think there is just a misunderstanding here as my example might be too simple. ROW might of course have multiple direct “children” (specializations). I’ll adjust the above example accordingly.

Multiple parents for one value should imho be prohibited as it makes fallback calculation near impossible or at least extremely difficult (and difficult to understand, too)

I like the suggestion, but I struggle with ui and detectionValue

  • Why change “label”, isn’t that a good name for it?
  • Replacing uriSegment makes sense, what about id or designator or something along those lines?

I just grouped label and icon under ui because, well, it’s just UI stuff, the CR could very well do without it. It would probably be more feasible to use i18n on the identifiers instead of defining dedicated labels anyway. Additionally, this declaration would be in sync with NodeTypes. Constraints then could also be declared similarly as they are in NodeTypes. Would be nice to have common config options for this.

detectionValue is a reference to detectionMode in the dimension configuration. I could go with something like designator as well but would like to avoid id as this is already reserved for the association key. The keys ideally should be some kind of ISO stuff, while the designators must be allowed to vary from that (think of the top level domain de matching the ISO 3166 country code DE).