Wolf X Machina

Back to blog

A Primer: Structured content in DNN using 2sxc

Posted in DNN on February 6, 2020

The people have spoken! A couple of weeks back, I created a poll on the DNN Connect Facebook group to determine what my next blog post will be about. Nineteen people voted for a post about creating really nice structured content in 2sxc so that’s what this post will be about.

For this post, I’m going to assume that you are relatively new to 2sxc and the idea of “structured content” so I hope this acts as a primer which helps you understand the very basics of setting up a simple module. Once you have these basics down, you should be able to create almost any type of content.

If you're asking, "why use something like 2sxc to make structured content?", here's the rundown:

  1. Simplified, standardized editing experience for your content editors and customers: your customers will need less support and will be happier
  2. Complete control over design of webpages: a true separation of content and design
  3. It's less expensive: when you can create custom content, you no longer need as many modules so you save on module licenses

Got it? Ok, let’s start by creating the most simple and common page component I can think of: the “Hero”. In modern web design, typically the hero component exists on every page and only has a few select components. I think it's good to learn using a simple but real and practical element.

Before we get into the specific steps, you should know about my setup. These are not prerequisites necessarily, but you should know that at the time of this posting I’m building on:

  • DNN 09.03.02
  • 2sxc 10.25.02 LTS
  • A custom (but plain) DNN skin built on Bootstrap 4.3.1

Also keep in mind that this is how I create modules. There might be a better way but this is what I’ve figured out over 5 years of building modules in 2sxc. Let’s get started.

Step 1: Decide on the design

As with all of my projects, I always try to take the design-first approach. I know this sounds obvious but not everyone does this. When you decide to design first, it narrows your focus on what you’re building. So, in our case, we’re creating a hero module. What goes in a hero? A heading 1 (h1), intro text, a background colour, and maybe a background image. What content will be optional? Will the hero flow full width of the screen or be contained to a specific width?

These are questions you should ask yourself because it will help determine how you will set things up. You might not need to necessarily design a PSD, but at least sketch it out or mark it up in simple HTML to determine what you’re creating.

Step 2: Add the Content module to the page

  1. Log in as a SuperUser
  2. Go into Edit Mode in DNN
  3. In the lower PersonaBar, click on “Add Module”
  4. Choose “Content” and drag and drop it to your pane
  5. Hit Refresh in your browser

Note: I've noticed some people use "App" but because we're just making content, just use the "Content" module.

Step 3: Set up the content type

Now that we have the module dropped on the page, we’re going to create our Hero content type. Think of the “Content type” as the actual fields that a content editor will fill in when creating a Hero.

  1. Hover over your new module’s edit pencil icon and click “Admin”
    Edit Admin 2sxc
  2. Click on the Data tab
  3. Click on the blue “+” icon to create our content type
  4. A modal for “Edit Content Type” will appear. Put a name and description for your new content type. I will put “Hero” and “Hero” for both fields
    Edit Content Type 2sxc
  5. Click the blue checkmark
  6. Once it’s created, we’ll need to add the fields to the content type. Find “Hero” in the list and click on the grey icon under the Fields column.
  7. A modal will appear that says “Content Type Fields” and it will be empty. Click on the blue “+”
  8. Another modal will appear to Add Fields. For our Hero, we want the following fields:
    Note: be sure to keep your field names simply named and don’t include spaces.
    Add Fields in 2SXC
    1. Title : Text/String : String / Text (basic)
      I like to keep the Title field as a simple string because it forces the content editor to keep the titles simple and leaves the formatting to the template.
    2. Text : Text / string : wysiwyg editor (tinymce)
      For Text, I make it a wysiwyg editor to let the content editor put anything they want in there.
    3. BackgroundImage : Link / file reference : default (link, page, file, …)
      The background image needs to be a link to allow the user to upload images.
  9. Once you’ve typed in your fields, click the blue checkmark. The modal will close. Now we want to add some settings onto the fields to make sure the Content Editor has a good experience editing content.
  10. Find the Title field and click on it. The settings modal will appear for that specific Title field.
    1. In this new modal, find the field “Required” and toggle it on. We always want the content editors to fill in this field so setting “Required” forces them to do that.
    2. Click the blue checkmark to save this setting.
  11. Now click on the BackgroundImage field.
    1. The field settings modal will appear. Update the label to be “Background Image” to give it space between words. You can do that now because it’s just the label and not the actual name of the field. Now go to the section called “Hyperlink / Link / File / Document” section and set these fields:
      1. Custom File Extensions: jpg,png
        It's good to set the file extensions so your content editors don't upload Word docs or PDFs when you want them to upload an image.
      2. Default Dialog: Automatic Data Asset Manager (ADAM)
      3. Toggle Show Adam but leave the rest untoggled
        Edit Field Settings in 2sxc
    2. Click the blue checkmark to save the field settings
  12. Close out of all the modals to get back to the main “Administration” modal

Congrats! You have created your first content type. Don’t celebrate yet because you’re only about halfway there.

Step 4: Create the template in C# razor

Now that you have a content type, you have to create a template for it. The template is what displays the content. I use C# Razor templates because I find that they have the most capability like conditional statements and the ability to manipulate content. Token based templates aren’t much simpler anyway so it's best to learn some simple C# Razor templates.

  1. Back on your page, go to the Administration Dashboard of the 2SXC module
  2. Click the “Views” tab. This is where we create and manage the templates
  3. Click the blue “+” icon to create a new template
  4. In the name field, give your template a name. “Hero” is probably perfect for what we’re doing.
  5. Under the “Template” section, find the “Template file” field and click the + icon on the right hand side.
    1. A modal will appear that says “enter a new file name” with a input text. Call your file “_hero.cshtml” and then click “OK”
      Create template
    2. After you clicked OK, the Template file will appear in the field.
  6. Go to the “Content Specs” section and under the “Content Type” dropdown, choose your content type called “Hero”
    Template settings
  7. Then under Content Demo Item, click the “+” sign to create a demo item. A modal will open up showing the Hero content type.
  8. Fill it out to create a demo item. I typically put in very obvious “Demo Title” text to make it super obvious. Once you’re done, click the blue checkmark
  9. Now that you’ve filled out the Template Name, Template File, and Content Type and Content Demo Item fields, you can save this template. Click the blue checkmark to save the template settings.
  10. Close the Administration Dashboard completely

By now, you’ve created both a Content Type and a Template. You’re doing great! The next thing we need to do is go back to our module we dropped on the page and set it as the Hero and then design the template.

Step 5: Set the hero

Back at the page, you should see just a simple, big, blue icon for choosing the content type. In the backend Administration Dashboard, all we’ve done is create the content type and template but we haven’t yet told the module that we want to display a Hero. So let’s do that now.

  1. Click on the big blue icon
  2. A panel will slide out at the bottom of the screen that says “Choose Content Type”
  3. Click on the “Hero” content type that we’ve created.
  4. Once you’ve clicked on it, the “Change View(1)” section will appear. This is the template that you created for the Hero. Because we only have 1 template, it will automatically choose it.
  5. Click on the blue checkmark to set the module.
  6. Refresh the page – this is important to do because once you’ve set the module, you will get more options under the edit pencil on the menu

Step 6: Design the template

Your module is set, but you still need to actually write the HTML for the template. This is the fun and creative part.

  1. Hover over the pencil and click “Edit Template”
  2. It will open a new tab with a fancy editor. I like to move this tab outside of the current window so that I can see both the page and the editor side by side as it makes for easier editing.
  3. In this template editor, write out or copy and paste your HTML. You can click “Ctrl + S” to save it on the fly and then refresh the other tab to see your changes immediately.
  4. Notice in the sidebar there’s a dropdown for “Content and Content-Presentation” > Choose that and then under “Fields” are all the fields available including your Hero fields: Title, Text, and BackgroundImage.
    Snippets in 2sxc template editor
  5. In the razor template, replace your static text with the content fields. It should look something like this: @Content.Title and @Html.Raw(Content.Text)

I’ve created this relatively simple template for our purposes. If you’ve followed along in the previous steps, feel free to copy and paste this template. There will be explanations below.

<section class="hero text-white">
    <div class="hero-tint py-5 d-flex align-items-center">
        <div class="container">
            <div class="row">
                <div class="col-12 col-lg-8" @Edit.TagToolbar(Content, actions: "edit")>
                    
                    <h1 class="mb-4 text-white">@Content.Title</h1>
                    
                    @if (Content.Text != "") {
                        <div class="mb-lc-0">
                            @Html.Raw(Content.Text)
                        </div>
                    }
                    
                </div>
            </div>
        </div>
    </div>    
</section>

@if (Content.BackgroundImage != "") {
    <style type="text/css">
        section.hero {
            background-image: url(@HttpUtility.UrlEncode(Content.BackgroundImage).Replace("+", "%20").Replace("%2f","/")?w=2000);
        }
    </style>
}

<style type="text/css">
    section.hero {
        background-repeat: no-repeat;
        background-position: 50% 0;
    }
    
    div.hero-tint {
        min-height: 500px;
        background-color: rgba(0,0,0,0.75);
    }
    
</style>

Here are some explanations of code inside a C# Razor template:

Edit Tag: @Edit.TagToolbar(Content, actions: "edit")

This part goes directly on a HTML tag and it is what gives you and your Content Editors the blue edit icon when you hover over the section. You can put this code onto any tag and it will make only that tag hoverable.

Conditional statements:

@if (Content.Text != "") {
 // your content goes here
}

This bit of code is a conditional statement. It means “If the user filled out the Text field, show this content”. Because my Text field is optional, I want to conditionally show the content only if it’s filled in.

Raw HTML@Html.Raw(Content.Text)

When you’re using a WYSIWYG (tinymce) field, you need to output the content as raw html, otherwise you will see the HTML tags in the content. So use @Html.Raw() to output your different fields.

Handling Images:

@HttpUtility.UrlEncode(Content.BackgroundImage).Replace("+", "%20").Replace("%2f","/")?w=2000

Ok, so there’s a few things going on here. If you wanted to simply output the background image, you could just put @Content.BackgroundImage and that would output the URL. That might be fine in most cases, but sometimes you need to use the power of the C# Razor template to manipulate the images that your Content Editors are uploading.

So, let’s break it down:

URL Encode

@HttpUtility.UrlEncode(Content.BackgroundImage) = Displays the URL but converts the spaces in the filename to +. We do this because if you are using inline CSS style to apply a background image, you can’t have spaces in the filename. Sometimes users don’t know any better so they’ll just upload the image named as-is. This makes sure the name is changed to something that works.

Replacements

@HttpUtility.UrlEncode(Content.BackgroundImage).Replace("+", "%20").Replace("%2f","/")

Stacking on top of the URL Encode utility, I also use a Replace utility to replace the + with %20, and the %2f to the forward slash. This makes sure the rewritten encoded URL is compatible.

You can learn more about why I made this here: https://stackoverflow.com/questions/57500986/how-can-i-rename-files-uploaded-through-adam-in-2sxc

Image Resizer

@HttpUtility.UrlEncode(Content.BackgroundImage).Replace("+", "%20").Replace("%2f","/")?w=2000

At the end of the image, I add a query string to invoke the image handler. This is to resize and crop the images to make sure they fit to what I need in the template. It’s useful for if the Content Editor uploads an image that is 8000 pixels wide for example, we want to limit the size of the background becuase what they uploaded is way too big. It’s super simple to use and you can learn more about it here: https://2sxc.org/learn-extensions/ImageResizer

Now that you have the template, your content module should be working. Save the template and refresh to see the module in action!

At this point, you should now know the very basics of creating structured content in 2sxc. With this, you should now have the fundamentals to build on. There are definitely a lot more things to learn but I hope this has shown you how easy it can be to build super solid websites that are easier for your Content Editors to maintain.

If you’re feeling adventurous, I have one more lesson to round this primer out. Now that you have a working Hero with a simple template, sometimes you want simple variations to the design. Instead of creating multiple templates, we can handle visual variations by using what is called “Presentation Settings” in 2sxc. Read on to learn how to do it.

Step 7: Create Presentation Content

Presentation Settings are really simple. They’re just like Content Types that you apply to a template and it gives your editor a second section to configure settings to display the content differently.

Step 7a: Create the Presentation Options

  1. Hover over the module edit pencil and click “Admin”
  2. Click Data
  3. Click the blue +
  4. For the Name and Description, type “Hero Presentation” and click the blue checkmark
  5. On your new Hero Presentation row, click the “Fields” icon and then click the blue Plus in the Content Type Fields modal that appears
  6. For our Hero, we want to give the Content Editors the ability to change the following things:
    1. the text colour of the header and text
    2. the tint that overlays the background image
    3. the display of the heading title
  7. So we create three fields:
    1. TextColor : Text / string : dropdown
    2. TintColor : Text/ string : dropdown
    3. ShowTitle : Boolean (yes/no) : default (yes/no slider)
  8. Click the blue checkmark
  9. Now click on your TextColor field to open the settings
    1. Rename TextColor to Text Color (with a space to make it readable)
    2. For “Default Value” type text-white
    3. Under the drop-down section, select all the Values and delete them. In their place, put the following on new lines:
      White:text-white
      Black:text-black
    4. Click the save button to save the settings and go back to the list
  10. Now click on your TintColor field to open the settings
    1. Rename TintColor to Tint Color (with a space to make it readable)
    2. For “Default Value” type rgba(0,0,0,0.75)
    3. Under the drop-down section, select all the Values and delete them. In their place, put the following on new lines:
      Black:rgba(0,0,0,0.75)
      White:rgba(255,255,255,0.75)
    4. Click the save button to save the settings and go back to the list
  11. Now click on your ShowTitle field to open the settings
    1. Rename ShowTitle to Show Title? (to make it readable)
    2. For “Default Value” type true
    3. Click the save button to save the settings and go back to the list
  12. Close the Hero Presentation Content Type Fields modal to go back to the main Admin Dashboard

Step 7b: Set the Presentation Options on the template

  1. Back at the Admin modal, now click “Views”
  2. Find your Hero template and click on it to edit it
  3. Expand the “Presentation Options” section
    Presentation settings in 2sxc template
  4. Choose the Content Type to be “Hero Presentation”
  5. Add a new Demo item by clicking the + icon on the right
  6. The default settings should already be set because you set the default values in the fields themselves: 
    1. Text Color: White
    2. Tint Color: Black
    3. Show Title? Toggled true. 
  7. Click the checkmark to save
  8. Then click the save checkmark on the template settings
  9. Close the Administration modal

Step 7c: Add the presentation fields to the C# Razor template

  1. Now go to the black and white edit pencil and click “Edit Template” to open the template editor again
  2. We now have to apply the Presentation Settings to the template just as we did the Content Type fields. See my updated template here:
<section class="hero @Content.Presentation.TextColor">
    <div class="hero-tint py-5 d-flex align-items-center">
        <div class="container">
            <div class="row">
                <div class="col-12 col-lg-8" @Edit.TagToolbar(Content, actions: "edit")>
                    
                    @if (@Content.Presentation.ShowTitle == true) {
                        <h1 class="mb-4 @Content.Presentation.TextColor">@Content.Title</h1>
                    }
                    
                    @if (Content.Text != "") {
                        <div class="mb-lc-0">
                            @Html.Raw(Content.Text)
                        </div>
                    }
                    
                </div>
            </div>
        </div>
    </div>    
</section>

@if (Content.BackgroundImage != "") {
    <style type="text/css">
        section.hero {
            background-image: url(@HttpUtility.UrlEncode(Content.BackgroundImage).Replace("+", "%20").Replace("%2f","/")?w=2000);
        }
    </style>
}

<style type="text/css">
    section.hero {
        background-repeat: no-repeat;
        background-position: 50% 0;
    }
    
    div.hero-tint {
        min-height: 500px;
        background-color: @Content.Presentation.TintColor;
    }
</style>

It’s really simple. Notice how I just replaced the original text-white CSS classes with @Content.Presentation.TextColor and the inline CSS for .hero-tint with @Content.Presentation.TintColor.

Then for the title, I use a simple conditional statement to detect if the Show Title toggle is equal to “true” and display the content if it is.

Back at the page, now when you edit the content, you will see a new section below the content called “Hero Presentation.” By default, the Presentation settings will fallback on the default settings always.

Edit presentation settings on a 2sxc item

But when you want to vary the design, you toggle the presentation settings on and then you can change the fields. It’s that easy! You can have lots of fields in the Presentation settings to vary layout, colours, sizes, types of headings, etc.

Wrapping Up

You did it! You created your content type, created a template for it, and even created presentation options for that template. There is so much more you could learn but I hope I've been able to show you how to start with 2sxc and structured content. You'll find that once you get a hang of the basics, it's so easy to set up other types of fancy content. Your customers are going to love what you build for them.

If you have any questions or comments, feel free to either comment on the Facebook post, comment below on the Facebook widget, or shoot me an email at aaron.lopez@wolfxmachina.com. I would love to hear from you.

I really hope this helps! This is just the tip of the iceberg. There are a lot more things that we can do in 2sxc like lists and multilingual. The real artistry comes in the design, CSS, and JS. If this is something that I could help you or your team learn, I would love to help. Check out my page on Expert DNN Development.

I even offer community rates to members of the DNN community. Get in touch to learn more!

Aaron Lopez

Aaron Lopez

Founder & Lead Developer at Wolf X Machina

Theme picker

Wolf X Machina

Next Level Interface Development for the DNN CMS

DNN themes, module design, and more from Wolf X Machina.

Learn More