Skip to main content
Home  › ... 2sxc Apps

2sxc Advanced Tutorials

Tutorial Home
#1 2sxc-Advanced - Query the Content Block

Query Content-Blocks

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

You are on portal 0 - 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.

2sxc Advanced Tutorials

Tutorial Home
#1 2sxc-Advanced - Query the Content Block

test

Statistics

  1. We're looking at portal 0, Zone 2, App: 34
  2. 152 Views
  3. 0 Content Blocks
  4. 26 DNN Modules in the primary language

Views

View 2sxc Advanced - Home

not in use

View 2sxc Advanced - Views and Content-Blocks

not in use

View B110 Variables

not in use

View B210 If Else Ternary

not in use

View B220 - For and Foreach

not in use

View B310 url params

not in use

View B311 url text param

not in use

View B320 Preserve Params

not in use

View B330 Switch Views

not in use

View B410 Url Encoding

not in use

View B-Basics

not in use

View C000 - Content

not in use

View C1 Code Basics

not in use

View C110 Platform

not in use

View C120 Culture

not in use

View C130 Site

not in use

View C140 Page

not in use

View C150 Module

not in use

View C160 User

not in use

View C170 View

not in use

View D000 Data

not in use

View D210 App.Data

not in use

View D220 App.Query

not in use

View D230 CSV from Query

not in use

View D231 CSV from Query - App Settings

not in use

View D310 SQL Query

not in use

View D330 SQL DataTable

not in use

View D331 SQL Datareader

not in use

View D510 DNN Pages/Tabs

not in use

View D610 list-details code

not in use

View D611 List Details Code 3 Files

not in use

View D620a list/details automatic switching

not in use

View D620b List/Details - Details

not in use

View D621a List for details with query

not in use

View D621b - Details with query

not in use

View D910 Content-Types

not in use

View Data 311 SQL Params

not in use

View Data 312 - sql reset

not in use

View E-Entity

not in use

View F100 - Formulas

not in use

View F110 Formulas Values

not in use

View F114 Formulas Dropdowns

not in use

View F115 Formulas Settings

not in use

View F116 Groups

not in use

View F120 Formulas using parameters

not in use

View F200 Formulas using WebAPIs and REST calls

not in use

View H000 - HTML

not in use

View H210 - Emojis

not in use

View Hybrid0-Hybrid

not in use

View Hybrid410 - Preprocessor Directives

not in use

View I000 - Images

not in use

View I100 - Image formats

not in use

View I105 - Images Basic Tags

not in use

View I106 - Images Picture Tag

not in use

View I107 - Images Picture Tag best practices

not in use

View I200 - Resize and Crop images

not in use

View I210 - Presets and Configurations

not in use

View I220 - Custom presets

not in use

View I230 - Merge settings

not in use

View JS 0 Home - temp, not used yet

not in use

View JS200 - Get Data

not in use

View JS220 - Get Queries

not in use

View JS230 - Query-Parameters

not in use

View JS300 - Edit

not in use

View JS310 - Create metadata

not in use

View Json home

not in use

View K000 - Koi

not in use

View K110 Auto Include BS4

not in use

View K120 Warn about missing bootstrap

not in use

View Koi 210 - switch between files

not in use

View L - Languages / i18n

not in use

View l1 Lists General

not in use

View P101 Page Properties

not in use

View P111 Page Base

not in use

View P121 Icons

not in use

View P201 Headers

not in use

View P302 Json LD

not in use

View P303 Open Graph

not in use

View P-Page

not in use

View Q1 - LINQ

not in use

View Q105 LINQ Where

not in use

View Q106 First/Last

not in use

View Q107 Take Skip

not in use

View Q108 Count

not in use

View Q120 Sorting

not in use

View Q210 List-In-List

not in use

View Q220 Grouping

not in use

View Q230 - List List List

not in use

View Q310 Parents

not in use

View R000 - Reuse code and templates

not in use

View R101 Template Delegates

not in use

View R110 Reuse Templates

not in use

View R210 Reuse Helpers

not in use

View R310 Reuse Functions

not in use

View R320 SharedCode

not in use

View R410 Reuse - Code-Behind

not in use

View Razor Tutorial Home

not in use

View RB000 - Razor Blade

not in use

View RB110 - Crop and Ellipsis

not in use

View RB120 - Text.Has

not in use

View RB130 - First

not in use

View RB140 Text.Zip

not in use

View RB150 Split Text

not in use

View RB210 Iscrub Tags

not in use

View RB220 Tags.Br2Nl and more

not in use

View RB221 IScrub attributes

not in use

View RB310 - Headers

not in use

View RB311 - AddBase

not in use

View RB320 - Json LD

not in use

View RB330 - Open Graph

not in use

View RB340 - Icons

not in use

View RB800 - Tags API Overview

not in use

View RB810 Tags Attribute

not in use

View RB811 - Attribute Json

not in use

View RB820 Fluid Intro

not in use

View RB822 - Attribute Concat

not in use

View RB825 - Img with Umlauts

not in use

View RB825 - Picture

not in use

View RB828 - Start End

not in use

View RB829 - Tag.Other

not in use

View S - Settings Home

not in use

View S100 - Read Settings

not in use

View S120 - Settings Stack

not in use

View S300 - Settings PageService.Activate

not in use

View Switch To View 1

not in use

View Switch To View 2

not in use

View T000 - turnOn

not in use

View T100 - turnOn

not in use

View T110 - turnOn parameters

not in use

View T111 - turnOn module parameters

not in use

View T120 - turnOn anonymous object

not in use

View T200 - turnOn multi-file

not in use

View T201 - turnOn await function

not in use

View T202 - turnOn await system scripts

not in use

View UI000 - Customize UX Home

not in use

View UI100 - Toolbar

not in use

View UI130 - Toolbar Workflow

not in use

View UI160 - Cms Run Commands

not in use

View UI201 - Custom Field - Empty - Hello World

not in use

View UI211 String Color Picker

not in use

View UI221 String - Color Picker Pro

not in use

View UI241 - String WYSIWYG Micro

not in use

View UI242 - String WYSIWYG Custom Button ML

not in use

View W000 - WebApi intro

not in use

View W110 - WebApi in root api

not in use

View W111 - Basic with CSRF protection

not in use

View W112 - WebApi methods

not in use

View W120 - Bare Metal

not in use

View W210 - Polymorph

not in use

View W800 - Hybrid

not in use

View WebApi 310 - app data

not in use

View WebApi 410 - authors query

not in use

@if(CmsContext.Platform.Name == "Oqtane") {
  @Html.Partial("../shared/_MessageOqtaneDisabled.cshtml")
} else {
  @Html.Partial("_110-content-blocks.dnn.cshtml")
}
#1 2sxc-Advanced - Query the Content Block

Source Code of this file

Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code

@inherits Custom.Hybrid.Razor14
@using System.Collections;
@using System.Linq;
<!-- unimportant stuff, hidden -->

Query Content-Blocks In this example, we... <!-- unimportant stuff, hidden -->


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




<!-- unimportant stuff, hidden -->

Source Code of /api/_110-content-blocks.dnn.cshtml

Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code

@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
*@
<!-- unimportant stuff, hidden -->

test
@{
  // 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();
  }
}