Documentation / Concepts / View Dispatching
The CoreMedia Content Type Model is a rich and powerful concept to work with
different kinds of content and structures. It consists of simple content
types like CMArticle
but also super types and more complex structures/containers like
CMCollection
or PageGrid
. These more complex structures can be composed by
the editors themselves and - in some cases - the presentation can even easily
be manipulated via layout variants in CoreMedia Studio.
So a web app has to be able to handle these challenges. It needs a way to automatically match a content type to the best fitting (rendering) component to render the desired content in a web browser.
A naive approach could be to use a big switch statement
that checks for the
content type and forwards to a corresponding (rendering) component.
This could look like this:
switch(contentType) {
case "CMArticle":
// render CMArticle component
break;
case "CMCollection":
// render CMCollection component
break;
...
}
But this would need to be updated manually and quickly becomes bloated. So a more intelligent and automated approach, similar to the View Dispatching of CoreMedia’s CAE is the preferred way.
A View Dispatcher in React needs two essential information. A list of all
available views and the type hierarchy, to know the order in which to compare
the given type and view to the available templates. Therefore, these templates
must follow the naming scheme like in the CAE: Type.ViewName.tsx
. So for
example: CMArticle.asHeroBanner.tsx
. All templates for view dispatching should
be in folders called views
. They will be used to redirect to the component or
container you wish to render a specific content with.
The second important information is the type hierarchy. The CoreMedia Headless
Server offers a list of all types for an interface, from most to least specific,
via GraphQL. It is downloaded and stored in
interfaces.json by the script
pnpm download:interfaces
.
The resulting list looks like this:
{
"CMArticleImpl": [
"CMArticle",
"CMTeasable",
"CMLinkable",
"CMLocalized",
"CMObject",
"Content_"
],
"CMTeaserImpl": [
"CMTeaser",
"CMTeasable",
"CMLinkable",
"CMLocalized",
"CMObject",
"Content_"
],
...
}
The View Dispatcher itself is used via a React component, that receives as
properties the content item as self
and the desired view or view type:
<Include key={key} self={content} view="{view}" />
Inside this component the view dispatcher is utilised and identifies the content
type from the __typename
property of self
. Then it gets the first entry in
the type hierarchy for this type and looks into the list of available views if
a specific entry for this type and given view is available. If yes, the name of
the corresponding view component is returned and rendered. If not, the look up
process iterates over both lists, until a match is found.
So if the content is a CMTeaser
and the view asCarouselBanner
, but there is
no CMTeaser.asCarouselBanner.tsx
file available, it tries again for a template
with the same type, but without the view. If this template is not available, the
parent type is taken for CMTeaserImpl
and rendered, if
a CMTeasable.asCarouselBanner.tsx
view is available.
App
Page
PageGrid
with header
and footer