App


Use Koi to Adjust to the Page CSS Framework

Learn how to use Connect.Koi to ensure your module/temlate has the right CSS frameworks, to either auto-include otherwise, show messages to the admin or generate different output. This uses Connect.Koi.

Some notes before we start

Koi works like magic behind the scenes, ensuring that your component knows what CSS-framework is already included, and can adapt its behavior.

For this to work, the theme must communicate what framework it's using, by including a koi.json file as explained in the docs. This is included in the default DNN themes since DNN 9.2, as well as in Bootstrap InstantnvQuickTheme and many other.

Some themes may not include that file, so your best bet is to always have something which either alerts the user, that this is missing, or automatically adds your framework, if it can't detect what's happening.

In this example, we'll assume your template needs Bootstrap5 as the preferred CSS framework. Note that this works for other frameworks as well, with minor modifications. But if it's used on any page, you may have one of the following situations:

  • Bootstrap5 could already be included - so you shouldn't do anything
  • A different CSS framework is included - so you should include Bootstrap5 automatically
  • The current CSS framework can't be detected, so to be safe, you should include Bootstrap 5 as well, until the theme is updated to broadcast what it's using

This page shows how to handle these problems with almost no code. Note that we've place the code in a separate file and use a helper to achieve this, as this allows us to re-use the code in multiple templates.
BTW: to see that this works, try switching the theme of this page to one without a koi.json or one with a different css-framework.

Result

The result is invisible; bootstrap5 is auto-added if not already present.
@inherits Custom.Hybrid.Razor14

@{  
  var bsCheck = CreateInstance("../../shared/Bootstrap5.cs");  
  bsCheck.EnsureBootstrap5();
}

Source Code of Bootstrap5.cs

using ToSic.Razor.Blade;

public class Bootstrap5 : Custom.Hybrid.Code14
{
  // if the theme framework is not BS4, just activate/load it from the WebResources
  // this solves both the cases where its unknown, or another framework
  public void EnsureBootstrap5()
  {
    if (Kit.Css.IsUnknown) {
      Kit.Page.Activate("Bootstrap5");
    }
  }

  // show warning for admin if koi.json is missing
  public IHtmlTag WarnAboutMissingOrUnknownBootstrap() {
    if (Kit.Css.IsUnknown && CmsContext.User.IsSiteAdmin) {
      return Tag.Div().Class("alert alert-warning").Wrap(
        Connect.Koi.Messages.CssInformationMissing,
        Tag.Br(),
        Connect.Koi.Messages.OnlyAdminsSeeThis
      );
    }
    return null;
  }
}

In this example, we'll assume your template needs Bootstrap5 as the preferred CSS framework. And we'll also assume, that you don't want to @Sys.TutLink("auto-include it", "koi110"), but instead want to warn the admin, to ensure he can correct the situation. This is what you want to do, when you believe the Admin should optimize the output, and prevent accidentally loading Bootstrap multiple times.

This page shows how to handle these problems with almost no code. We'll also show what you can do, so only admins see the message.
BTW: to see that this works, try switching the theme of this page to one without a koi.json or one with a different css-framework.

Result

The result is invisible; bootstrap5 is auto-added if not already present.
@inherits Custom.Hybrid.Razor14

@{  
  var bsCheck = CreateInstance("../../shared/Bootstrap5.cs");  
  bsCheck.EnsureBootstrap5();
}
@bsCheck.WarnAboutMissingOrUnknownBootstrap()

Source Code of Bootstrap5.cs

using ToSic.Razor.Blade;

public class Bootstrap5 : Custom.Hybrid.Code14
{
  // if the theme framework is not BS4, just activate/load it from the WebResources
  // this solves both the cases where its unknown, or another framework
  public void EnsureBootstrap5()
  {
    if (Kit.Css.IsUnknown) {
      Kit.Page.Activate("Bootstrap5");
    }
  }

  // show warning for admin if koi.json is missing
  public IHtmlTag WarnAboutMissingOrUnknownBootstrap() {
    if (Kit.Css.IsUnknown && CmsContext.User.IsSiteAdmin) {
      return Tag.Div().Class("alert alert-warning").Wrap(
        Connect.Koi.Messages.CssInformationMissing,
        Tag.Br(),
        Connect.Koi.Messages.OnlyAdminsSeeThis
      );
    }
    return null;
  }
}

In this example, we'll assume you have a Bootstrap3 and a Bootstrap4 template in the folders bs3/_Line.cshtml and the same in bs4/_Line.cshtml. We'll use Koi to load the right template file.

You can see in the source-codes that BS3 uses pull-left and another class on the blockquote tag than BS4.

Result

@inherits Custom.Hybrid.Razor14

@*
  This page is just an entry point for your code. It will do the following:
  1. Check if it can detect the CSS framework used by the theme
    - if yes, it will use that
    - otherwise it will fallback to assume it's bootstrap 4 = "bs4"
    - note that the BS4 edition has an additional check for unknown frameworks
  2. Then it will load the real cshtml-template from the matching edition-folder
*@
@{ 
  var folder = Kit.Css.Is("bs5") ? "bs5" : Kit.Css.Is("bs4") ? "bs4" : "bs3";
}
@Html.Partial("../" + folder + "/Alert.cshtml")

Source Code of Alert.cshtml

@inherits Custom.Hybrid.Razor14
<div class="alert alert-success pull-left" role="alert">
    <h3>You are seeing the Bootstrap3 Template</h3>
  <blockquote class="blockquote-reverse">
    "this is awesome!"
  </blockquote>
</div>

Source Code of Alert.cshtml

@inherits Custom.Hybrid.Razor14

<div class="alert alert-success float-left" role="alert">
  <h3>You are seeing the Bootstrap4 Template</h3>
  <blockquote class="text-right">
    "this is awesome!"
  </blockquote>
</div>

Source Code of Alert.cshtml

@inherits Custom.Hybrid.Razor14

<div class="alert alert-success float-left" role="alert">
  <h3>You are seeing the Bootstrap5 Template</h3>
  <blockquote class="text-right">
    "this is pretty awesome!"
  </blockquote>
</div>