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.

Understanding Content-Binding to Modules and Pages (300)

Content Management has some unique challenges which are very different from working with data. One of these is how a module knows which content to show. 2sxc has various features, here I'll provide you a deeper understanding to help you create advanced solutions.

This is a level 300 (fairly advanced) topic, and important if you have advanced projects.

Content is NOT Data

Basically we must start with explaining that content is NOT data. As a developer, you may think that it is so, but content is different from data. Usually when designing information systems, this is how such things related:

  1. Data (facts, signals, records, etc.)
  2. Information (meaningful, useful, organized)
  3. Knowledge (contextual, learning)
  4. Wisdom (application of knowledge)

Content is usually in the league of contextual knowledge (#3). The fact that it's information in a context is important and puts it two steps away from data. This data "Langäulistrasse 64" means very little, but in put in context on the contact page of, and with more information like "Switzerland", it becomes useful content.

Content in Multiple Different Contexts

The very same content can appear in different contexts. For example the same content can appear in multiple languages. In such a case it is the same information, but because of the language change it is shown differently. Or a product information can appear in a teaser-context (small, pic+title) or in a list-context (larger pic, more details) or even a again in a "these products are part of our SEO services" - again a different context with different requirements. The following example shows multiple uses / contexts of the same content in 1 language (profile, map, vCard, contact-me):

To keep this kind of flexibility simple is fairly complex - let me show you how it's done.

Basics: How a Module is Linked to a DNN Page

This is how a module is linked to a DNN page

  1. Tab which is the page, with a TabId
  2. TabModule which binds a module to a page, with a TabModuleId
  3. Module which is kind of the box for any module, with a ModuleId

In the DB this looks like this:


If you've never looked at the DNN database this may surprise you. It's linked this way to allow 1 page to have many module instances (an intro text, a contact form, a footer-text), and that many module instances could point to the same module. You need the middle connection to share a module across pages like a footer text repeated on the main topic pages.

The Module then defines what ModuleDef it uses (for example that it's a 2sxc-module), and from that point on the inner component takes over. It is told that it is module 7532 and that it should now do its thing.

Common Module-To-Content/Data Linking

99% of all modules use one of the following mechanisms to determine what to show in their module:

  1. Some modules will simply show something that only exists once in the system - such modules don't care what module number they are on, because they would always show the same thing. A common example is a tag-cloud module, which would show a tag-cloud no matter how it's used. Such modules don't need any configuration. 
  2. Trivial content modules will show 1 piece of content - like the Text-HTML which shows a specific piece of text bound to this module ID. These modules will actually use the module-ID in their tables to link their own data to the module ID. Here you can see this on the text-html table: 
  3. Some modules will have a few options (which are saved in Module-Settings) to then decide what to do. For example, a Blog-Extract module will let you select a tag, which it would then use to filter the blog posts. Simple settings are usually stored in the ModuleSettings table. Notice that these settings are shared across all copies of the same module.

  4. More complex modules - for example a custom forms module or a real-estate module - will place the configuration in an own table and remember the module ID, the same way that the text/Html does it.

Advanced Data-Context-Linking used in 2sxc

All the mechanisms above only scale up to a certain point. A common point where they break down is when content exported/imported, when it is multi-lingual or if parts of the content is re-used again. This is very common in content - think of a list of employees, where other lists of employees re-use some, but not all, of the main list. If employees were data, we would simply categorize them and filter, but if we are using them as content, then it needs better mechanisms. Here's how:

  1. The module has various settings in in the ModuleSettings table, the most important of which is an ID of a Content Group - this is called the ContentGroupGuid
  2. The ContentGroupGuid is an EntityGuid of a Content Group (surprise!). A Content Group contains a reference to the template used and references to various Content Items (aka entities) + presentation settings and more.
  3. The Content Items are the items themselves, like a text+image combination or a person profile. A content-item itself can be multi-lingual
  4. Because the Content Group (which points to the Content Item) defines what template is used and optional presentation settings, the same Content Item can be shown in many different ways as needed.
  5. Since the Content Item itself is multi-lingual, it will automatically show the best possible translation every time it's used.


The Benefits of this Setup

What you just read is something most people are not even aware of - and that's a good thing. The simple user interface in 2sxc hides all this complexity, but it is necessary to allow many advanced scenarios. With this setup, it's possible to

  1. Do very simple things like just add content to the page (what most people do)
  2. But it's also possible to re-use content items (like a person profile) in many different ways
  3. …and the re-used instances can look different (different template) or be presented different (different presentation settings)
  4. It's also possible to re-use collections of content-items, like a person-list which is needed in identical form in multiple languages
  5. Thanks to this setup, it's also possible to export a site, and reliably duplicate it in a new DNN portal. Without this complexity, many aspects would break down on export/import.

Side-Effects of this Setup

There is one common side effect which people don't expect because of this setup. If you export/import a module which already has content in it, then the imported module will reference the existing Content Group. This is necessary to enable export/import of entire sites. But sometimes users will do this expecting that the content itself would be duplicated, so they will edit the content and be surprised that they also edited the original. There are simple ways to work around this, but I'll write about that in a separate blog post.

Love from Switzerland,

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


There are currently no comments, be the first to post one.

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 (22)
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 (270)
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?