App


Crazy Tutorials

Tutorial HomeCrazy

Inspect a Content-Block

In this example, we'll see what content-blocks are in the system, and where they are in use.

You are on portal 13 - this sample has hard-wired IDs for portal 59 (our dev-environment) and 24 (the tutorials on 2sxc.org). If one of these is detected, it will show the stats for a portal we know on that system, otherwise from the current app - which won't show much, since this tutorial app doesn't have many content-blocks.
@inherits Custom.Hybrid.Razor14


@if (CmsContext.Platform.Name == "Oqtane") {
  @Html.Partial("../../shared/MessageOqtaneDisabled.cshtml")
} else {
  @Html.Partial("110-content-blocks.dnn.cshtml")
}

Source Code of 110-content-blocks.dnn.cshtml

@inherits Custom.Hybrid.Razor14
@using System.Collections;
@using System.Linq;
@using DotNetNuke.Entities.Modules;
@* 
  Tag: #DnnOnly - ATM can't work in Oqtane because it uses the Factory command and because it uses DNN objects
  2sxclint:disable:no-inline-script
  2sxclint:disable:no-dnn-namespaces
*@
@{
  // isDev should just tell us, if we're looking at the dev-portal (while creating this demo app) or if it's running on 2sxc.org
  // where we use other zoneId and appId;
  var isDev = CmsContext.Site.Id == 59;
  var is2sxcTutorial = CmsContext.Site.Id == 24;
  var portalId = isDev ? 10 : is2sxcTutorial ? 0 : CmsContext.Site.Id;

  // create array with all 2sxc modules in this portal
  var allMods = GetAllModulesOfPortal(portalId);

  // Get the app & views we're going to investigate the views of
  var app = isDev 
    ? ToSic.Sxc.Dnn.Factory.App(11, 35) // some app on our dev environment
    : is2sxcTutorial
      ? ToSic.Sxc.Dnn.Factory.App(2, 2) // the 2sxc.org Content-App
      : App; // fallback, use this app, but not very exciting
  
  // all views in this specific app, sorted by name
  var views = AsList(app.Data["2SexyContent-Template"]).OrderBy(t => t.Name);

  // get all content blocks which have templates - skip the ones without, as they have not been initialized yet
  var contentBlocks = AsList(app.Data["2SexyContent-ContentGroup"]);

  // create a map of all blocks to DNN modules
  var block2ModuleMap = contentBlocks.GroupJoin(allMods, 
    cb => cb.EntityGuid,
    m => Kit.Convert.ToGuid(m.ModuleSettings[SettingsCG]),
    (cb, m) => new { 
      Block = cb, 
      Modules = m 
    }
  );

  // now map all the template-IDs to the block-module map
  var template2BlockModuleMap = block2ModuleMap.GroupBy(b2m => {
    var templates = AsList(b2m.Block.Template as object);
    return templates.Any() ? templates.First().EntityGuid : null;
  });

  var viewsWithBlocks = views.GroupJoin(template2BlockModuleMap,
    v => v.EntityGuid,
    bwm => bwm.Key,
    (v, bwm) => {
      var blockWithMod = bwm.SingleOrDefault();
      return new { 
        View = v, 
        Blocks = blockWithMod,
        ModsCount = blockWithMod != null ? blockWithMod.SelectMany(bmlist => bmlist.Modules).Count() : 0,
      };
    }
  );
}

<h2>Statistics</h2>
<ol>
  <li>We're looking at portal @portalId, Zone @app.ZoneId, App: @app.AppId </li>
  <li>@views.Count() Views</li>
  <li>@contentBlocks.Count() Content Blocks </li>
  <li>@allMods.Count() DNN Modules in the primary language </li>
</ol>
<hr>

<h2>Views</h2>

@foreach (var set in viewsWithBlocks) {
  <h3>View @set.View.Name</h3>
  if (set.Blocks != null) {
    <div>
      Used in @set.Blocks.Count() blocks and @set.ModsCount modules
    </div>
      <ol>
      @foreach (var blockSet in set.Blocks) {
        <li>
          Block: @blockSet.Block.EntityGuid (@blockSet.Block.EntityId) 
          in @blockSet.Modules.Count() modules: @string.Join(",", blockSet.Modules.Select(m => m.ModuleID))
        </li>
      }
      </ol>
  } else {
    <text>not in use</text>
  }
}


@functions {
  // CONSTANTS
  // this key is used in module settings
  const string SettingsCG = "ToSIC_SexyContent_ContentGroupGuid";

  // create array with all 2sxc modules in this portal
  List<ModuleInfo> GetAllModulesOfPortal(int portalId) {
    var mc = ModuleController.Instance;
    var dnnMod2sxcContent = mc.GetModulesByDefinition(portalId, "2Sexy Content");
    var dnnMod2sxcApp = mc.GetModulesByDefinition(portalId, "2Sexy Content App");
    var mergedMods = new ModuleInfo[dnnMod2sxcContent.Count + dnnMod2sxcApp.Count];
    dnnMod2sxcContent.CopyTo(mergedMods);
    dnnMod2sxcApp.CopyTo(mergedMods, dnnMod2sxcContent.Count);
    var allMods = mergedMods
      .Where(m => m.DefaultLanguageModule == null)
      .Where(m => !m.IsDeleted)
      .Where(m => m.ModuleSettings.ContainsKey(SettingsCG));
    return allMods.ToList();
  }
}

Warning: This Sample uses Internal APIs

This sample uses some internal APIs, so if you use this, it may require some adjustments in future.