Learn More





DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

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


kurt wilby
Dear Mr. Mettler,

Because I think you are the most knowledgeable dnn-ng developer, I ask you to develop, if you already haven´t one, a dnn dev template incorporating all the ideas/technologies (grunt OR gulp, especially ANGULARJS, Formly OR AngularUI, ...). This would be a great boost for the community. Could you please give your ideas on this subject (start a new github project OR ...).

kurt wilby Wednesday, November 25, 2015 4:27 AM (link)
Benoit Sarton
Thanks Daniel, Ghosts are a great feature of 2sxc. I can imagine that the primary use case will be when an App contains many Content-types and/or is re-used in several portals of the same DNN instance. It can save thousands of records in the database (content-type definitions are shared rather than duplicated). It is also a huge benefit when you need to change the Content-type definition and apply the change for all portals. I encourage every 2sxc user to give them a try.

Starting with 2sxc v 08.00.08, Ghosts content-types can be exported / imported. Great!

Love from France
Benoit Sarton Friday, December 04, 2015 10:54 AM (link)

Comment Form

Only registered users may post comments.


2sic Daniel Mettler (124)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (21)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (6)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (269)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (163)
William Severance (5)
Try Evoq
For Free
Start Free Trial
a Demo
See Evoq Live
Need More Information?