Fork me on GitHub
2sxc 9.42 for DNN 7 to 9
Website Builder, Content Manager, App-System: open-source and amazing
You are here: Home  >  Blog

Auto-Include Missing Bootstrap - using Connect.Koi

If your DNN-Module, Component or App needs Bootstrap, but only wants to add it if the theme doesn't already include it, Connect.Koi will do this for you. 

Auto-Include Boostrap4 in Razor

All you need to do, is to add this code to your C# razor template:

Snippet to check if the theme has Bootstrap4 and otherwise adds it

@using Connect.Koi;
@if(!Koi.Is("bs4")) {
  <link rel="stylesheet" 
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 
    crossorigin="anonymous">
  }

How this works 

Connect.Koi reads the koi.json file from your theme folder (and it will cache it, so it's super fast) and from then on knows the themes CSS-Framework. It also knows if the theme didn't have a koi.json, so you could modify your behavior by checking Koi.IsUnknown. But in most cases, you can simply also inject Bootstrap4 if unknown.  
 
Your code then simply checks, if the theme is Bootstrap4 - with the code bs4, and if not (or unknown), will add Bootstrap from the CDN. You can adjust this any way you want - so you could also use a different CDN or a local copy. 

Reusing this Snippet as a Razor Helper

We often need such a snipped in many templates, so we tend to create a collection of Razor Helpers in a shared file. The shared file contains this:

Helpers in external, shared _bootstrap4.cshtml

@using Connect.Koi;
@helper EnsureBootstrap4() {
  // if the theme framework is not BS4, just include it
  // this solves both the cases where its unknown, or another framework
  if(!Koi.Is("bs4")) {
  <link rel="stylesheet" 
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 
    crossorigin="anonymous">
  }
}
Then to call it, we put this in the parent file:

Parent file calling shared snipped

@{
    // this example assumes that the shared file is in a subfolder  
    var bsCheck = CreateInstance("shared/_bootstrap4.cshtml");  
}
@bsCheck.EnsureBootstrap4()

Optionally Show Warning to Admin

In case you want to tell the admin that this happened - so he could also improve the situation, here's what the _bootstrap4.cshtml would look like, with the additional helper:

Advanced Shared _bootstrap4.cshtml with Admin-Warnings

@using Connect.Koi;
@helper EnsureBootstrap4() {
  // if the theme framework is not BS4, just include it
  // this solves both the cases where its unknown, or another framework
  if(!Koi.Is("bs4")) {
  <link rel="stylesheet" 
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 
    crossorigin="anonymous">
  }
}

@helper WarnAboutMissingOrUnknownBootstrap() {
  if(Dnn.User.IsInRole(Dnn.Portal.AdministratorRoleName)) {
    var message = Koi.IsUnknown
      ? "This template could not detect if bootstrap4 was already included in the page or not. " 
        + "Because of this, we auto-included it - but this may be unnecessary and slow down this page. " 
        + "Please fix, by supplying a koi.json file in the theme folder."
      : !Koi.Is("bs4")
        ? "Your theme seems to use a css framework different than bootstrap4, " 
            + "but these templates are optimized for it. Bootstrap4 was auto-included for your convenience. " 
            + "For performance reasons, we suggest you either switch to bootstrap4 " 
            + "or optimize these templates to work with the css-framework you prefer. "
        : "";

    if(message != "") {
      <div class="alert alert-warning" role="alert">
        <strong>Warning for page admins only:</strong>
        @message <br>
        You can also remove this message by commenting out the code calling 
        <code>WarnAboutMissingOrUnknownBootstrap()</code>
      </div>
    }
  }
}

Doing This in a WebControl

Note that this also works in asp.net web controls, though you'll need to make minor adjustments. For example, the using-statement varies depending on whether you put this in the ascx, or in the code-behind ascx.cs. But if you've been doing web-controls, I'm sure you'll figure it out. 
 
Love from Switzerland,
iJungleboy

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 github), an open source module for creating attractive content and DNN Apps.

Read more posts by Daniel Mettler