Find a post...

DNN-Connect Blogs

Advanced Dynamic Data / Content - Ghost Content Types (300)

Doing Dynamic data can be very challenging - so when we developed the EAV (entity/attribute/value) system in 2sxc we created a system which has Ghost Content Types. Here's why, and how it works. This is a level 300 information - not for beginners.

A Standard EAV won't do

Dynamic Data always seems very simple, especially when looking at common implementation like Form-and-List which are basically just an over-normalized data schema (entity X has the attribute Y containing value Z). But this model is too simple - the entire system becomes a hybrid of sometimes-dynamic sometimes-SQL which leads to large problems and inconsistencies- and will quickly hit limits of what it can do.

Most developers will begin with such a model  - and often cannot get out of it any more. The inventor of List and Forms told me in 2012, that the best thing would have been to start all over. The problem is that the original concept seems simple and intuitive - so every developers first 5 generic data models work that way. A common indicator for such an implementation are the fact that configuration of the system itself - like how to define an input-field - is done in a SQL database instead of inside the dynamic data.

Learning from Magento, Umbraco and SharePoint

When we started work on 2sxc in 2012 we had already developed more than many generic data models for various other applications and had always hit a point where things started to hurt or got very confusing. And we wanted to do it much better. We knew that we can't be smarter than everybody else, we researched successful and failed implementations and tried to merge what had worked.

One of the concepts we ended up implementing were Ghost or Shadow Content Types to allow reuse of content-type definitions across isolated systems…

Show me some Ghosts

The quickest way to see some ghost content-types is by going into admin-mode, enable the advanced UI (Ctrl+Click) and then change the Scope to "System" which will show you some ghosted content-types of the current app. It's described in more detail in the blog Understanding Content Type Scopes.

Isolated Systems - Necessary for Encasulating Functionality

Here's the core problem: in a generic CMS like DNN any kind of functionality you create needs some kind of boundaries. These boundaries define what's part of this functionality and what is not. It's the only way to ensure that an export/import can work, and that certain actions don't have a side-effect. In 2sxc 1.0 this was not possible, everything was "in the same package". In 2sxc 3.0 we introduced Apps - which defined such limits and allowed this.

But it introduced the problem: how can the core system know that a content-type definition must be exported, and when not? How can a system be self-contained, but still refer to external stuff and do this in a reliable way? Here we looked at the data model in SharePoint and our solution works as follows:

  1. Each app is self contained - entities (content-items) can only be based on a content-type which exists in the app
  2. BUT: a content-type in the app can say that it's definition comes from somewhere else. So our content-types can say "I'm the content-type @String, and items in this app use my type. But if you want to know what fields I have, you must check out the definition of this other content-type…"

Implementation of Definition-Inheritance

Since the content-type definition is only important for certain parts of the application (loading from the DB, edit-UI, export/import) this was fairly easy to implement. Basically every Content-Type has a field "UsesConfigurationOf..." (see image). This causes all affected systems to use the other definition instead. The following example shows the @String being defined in the root app 1 and then the @String in the App #12 using the definition of this initial @String content-type: 

Automatically Create Ghosts In Every New App and Zone

In addition to that, there is a field called "AlwaysShareConfiguration". This tells the EAV-System that each newly generated App must receive a Ghost-entry for this content-type. This ensures that all apps have the same system types.

Creating your own Ghost/Shared Content-Types

There are some use cases where this is a good idea - but you need to know what you're doing. I'll explain it in a follow-up blog. 

Love from Japan,

Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see forge), an open source module for creating attractive content and DNN Apps.

Read more posts by Daniel Mettler
Daniel Mettler learned programming with the bible translation computer of his parents, deep in the jungles of Indonesia. Since he was only 12 years old at that time and the BIOS only had a version of BASICA, that's what got him started. With 16 he went back to Switzerland and learned German and basic city-survival skills. Equipped with this know-how he founded 2sic internet solutions in 1999 which was focused on web solutions on the Microsoft platform. After a few self-developed CMSs 2sic switched to DNN in 2003 and has been one of the largest partners (17 employees, 700+ projects) in Europe. Daniel is also the chief architect behind the open source 2sxc, a strong promoter of standardization (boostrap, patterns, AngularJS, checklists, etc.) and loves to eat anything - dead or alive. His motto: if the natives eat it, it game.

Hosting liberally provided by

Philipp Becker 6012 7
Geoff Barlow 547 4
DNN-Connect 431 6
Peter Donker 5059 30
Christopher Hammond 681 2
Olivier Jooris 419 1
Daniel Mettler 12009 88
Clint Patterson 1 1
Jos Richters 65 1
James Rosewell 327 2
Will Strohl 1546 27
Ernst Peter Tamminga 437 4
Barry Waluszko 2807 2
Declan Ward 453 1
Gifford Watkins 722 9
Torsten Weggen 2697 3