StaticWebEpiserverPlugin 3.0.1

dotnet add package StaticWebEpiserverPlugin --version 3.0.1                
NuGet\Install-Package StaticWebEpiserverPlugin -Version 3.0.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="StaticWebEpiserverPlugin" Version="3.0.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add StaticWebEpiserverPlugin --version 3.0.1                
#r "nuget: StaticWebEpiserverPlugin, 3.0.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install StaticWebEpiserverPlugin as a Cake Addin
#addin nuget:?package=StaticWebEpiserverPlugin&version=3.0.1

// Install StaticWebEpiserverPlugin as a Cake Tool
#tool nuget:?package=StaticWebEpiserverPlugin&version=3.0.1                

StaticWebEpiserverPlugin

Generate static website but still use EpiServer as your CMS for your editors

Introduction

Do you need a crisis web or handling peek load of users on your site? I have started develop a add-on for sites using EpiServer that will take everything you publish and make a static version of it. This way you get the instant publishing of a dynamic website and the performance and scalability of static websites in one go. It should (havn't yet test it) be possible to create the pages directory in your EpiServer site making it fully dynamic for things like search and filtering but static for general information.

Pro

  • Reliable serverside response time
  • Very easy to scale up
  • No database dependency for visitor
  • No serverside code requried
  • Very secure (hard to hack static pages)
  • Supports having some pages dynamic and others generated static (see UseRouting below)
  • Supports custom resource types (You can extend default or start from scratch using <allowedResourceTypes>)
  • Event driven page generation, always latest changes on your website (created when editor publish page or block)
  • Static content can easily be synced with cloud solutions like Azure (Example using events: AfterIOWrite and AfterIODelete

Con/limitations

  • Only pages inheriting from PageData will trigger page write
  • Only block inheriting from BlockBata will trigger page write
  • Resource limitations:
    • css (only support dependencies declared in url())
    • javascript (no dependencies)

What functionality is provided in Plugin?

Below you can read more what StaticWebEpiserverPlugin can do today. If you are missing something or something is not working as expected, please let me know 😃

Generate static pages on publishing of Pages and Blocks

StaticWebEpiserverPlugin uses the PublishedContent event on IContentEvents to listen for changes that are published on your site. This way it will make sure your site is always up to date with what you have published in EpiServer. No need for busting caches or having your website running without cache do always show the lastest information. As long as your pages are inheriting from PageData and your blocks are inheriting from BlockData, StaticWebEpiserver will keep track of your changes.

Generate static pages on running scheduled job

StaticWebEpiserverPlugin are also providing a scheduled job for you to run that will generate alla pages below the home of your website. Pages that are not a child (or a child of a child, and so on) of your startpage it will not be included in the pages generated. To start the job, run the job called "Generate StaticWeb".

Having different views for StaticWeb and normal users

Using DisplayChannel

StaticWeb is registering a displaychannel called "StaticWeb" (See Header.cshtml and Header.staticweb.cshtml for examples on how to use it, can be found in EpiServerStaticWebExample repository). It is perfect for removing functionality that can't be used in a static website (like filitering or search). It also makes it possible for you to view how the page will look and work on the static version.

Using VisitorGroup

StaticWeb is registering a criteria called "StaticWeb user" under "Technical" category so that you can create your own vistor groups. Making it possible to show different content for page generation and other users. If you for example is using StaticWebEpiServerPlugin for create a static emergency/reserve website to use if everything else fails.

How to ignore page or block type?

By inherit from IStaticWebIgnoreGenerate iterface on a page or block type you will tell StaticWeb NOT to generate a static version of this type when publishing or running the scheduled job.

How to ignore page at runtime?

By inherit from IStaticWebIgnoreGenerateDynamically iterface on a page type you will tell StaticWebEpiServerPlugin that it MAY or MAY NOT generate a static version of this page when publishing or running the scheduled job. StaticWebEpiServerPlugin will call method ShouldGenerate for the page and if it returns true, it will generate a static version of the page when publishing or running the scheduled job. BUT if it returns false, it will not generate page AND also check (by calling ShouldDeleteGenerated) if it should remove any previously generated version of this page. See StandardPage.cs for example on how it can be used.

You can customize it using Events

We want people to be able to modify the use after their own liking. There for we support the use of events on the IStaticWebService. They will be called in the order specified below. You can read more on what is available at Issue #2

Example: Using RequiredCssOnly extension

Showing how to extract only the required CSS need for rendering the page and injecting rulesets as inline CSS. To decrease dependencies and make your webpage have a faster initial load time by using AfterEnsurePageResources event in this example: StaticWebRequiredCssDemoInitialization

Example: Inject HTML before saving

Showing how AfterGetPageContent event can be consumed in this example: StaticWebMessageInjectionDemoInitialization

Find, download and generate resources

When generating a page, StaticWebEpiserverPlugin will find all client side resources required for the page to work, download them and store them in the output folder along with the pages.

Following markup will searched for resources

  • script element (src attribute)
  • link element (href attribute)
  • a element (href attribute)
  • img element (src attribute)
  • source element (srcset attribute)

Following resource types will be stored by default

  • css (and resources declared in url())
  • javascript (no dependencies)
  • Web fonts (woff and woff2)
  • Images (png, jpg, jpeg, jpe, gif, webp, svg)
  • documents (pdf)
  • Icons (ico)
  • Assembly Resources (WebResource.axd and ScriptResource.axd as long as resulting content type are allowed)

The rest will be ignored.

(Note: You can add or change supported resource types using <allowedResourceTypes>)

Requirements

  • EpiServer 7.5+
  • .Net 4.7.2+
  • All pages need to inherit from PageData
  • All blocks needs to inherit from BlockData
  • Website has to return pages, javascript and css as UTF-8
  • Must allow visits with user-agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36 StaticWebPlugin/0.1

Installation

NuGet

  • Add nuget package https://www.nuget.org/packages/StaticWebEpiserverPlugin/ to your solution.

  • Add below into: <configSections> element of web.config <section name="staticweb" type="StaticWebEpiserverPlugin.Configuration.StaticWebConfigurationSection" />

  • Add below to the same level as appSettings element (for example right below the end tag)

  • <staticweb>

    • <sites>
      • <add name="Test Website" url="http://localhost:49822/" outputPath="C:\websites\website1\wwwroot" resourceFolder="cache\v1" />
  • Change url and outputPath after your needs and you are ready to go 😃

  • You are ready to go 😃

GitHub Source download

  • Copy StaticWebEpiserverPlugin folder and add StaticWebEpiserverPlugin.csproj into your solution.

  • Add below into: <configSections> element of web.config <section name="staticweb" type="StaticWebEpiserverPlugin.Configuration.StaticWebConfigurationSection" />

  • Add below to the same level as appSettings element (for example right below the end tag)

  • <staticweb>

    • <sites>
      • <add name="Test Website" url="http://localhost:49822/" outputPath="C:\websites\website1\wwwroot" resourceFolder="cache\v1" />
  • Change url and outputPath after your needs and you are ready to go 😃

Site Configuration

With the <sites> configuration you can define multiple websites and also have different settings between them.

  • <staticweb>
    • <sites>
      • <add name="" enabled="true/false" (default: true) url="" outputPath="" resourceFolder="" useRouting="true/false" (default: false) useHash="true/false" (default: true) useResourceUrl="true/false" (default: false) removeObsoleteResources="true/false" (default: false) removeObsoletePages="true/false" (default: false) />

Below you can see the different attributes that can be used for a site.

Name="Example Site 1" (default: ``)

Specifies a name for your website. If specified it will be used in Scheduled job status information. By default this is will use EpiServer site name if used.

Enabled="true/false" (default: true)

Allows you to disable plugin by just changing configuration. Good if you temporarly want to disable plugin or if you on one server want to disable functionality (for example on editor only servers).

Url="http://localhost:49822/" (required)

Specifies url to use as base url for this website. Make sure it matches one specified in EpiServer under Config → `Manage Websites.

OutputPath="C:\websites\website1\wwwroot" (required)

Folder to write your static website to. This can be any folder you have read, write and change access to. For example a GitHub repository folder, folder used directly by IIS or directly into your EpiServer website (look more at: userRouting).

ResourceFolder="cache\v1" (default: ``)

Sub folder of outputPath to write resources to. Above tells StaticWebEpiServerPlugin to use a subfolder cache\v1 for all resources. You should also look at: useHash and useResourceUrl.

UseRouting="true/false" (default: false)

By setting this to "true" you allow StaticWebEpiServerPlugin to write pages and resources inside a EpiServer instance and taking over the routing for pages it has generated static html pages, returning them instead of calling the page controllers. Relative resource path needs to be set also to use this (read more on useResourceUrl).

UseHash="true/false" (default: true)

Tells StaticWebEpiServerPlugin to generate content hash and use for resource name. ( This value has to be true to support .axd resources and make them static)

UseResourceUrl="true/false" (default: false)

Tells StaticWebEpiServerPlugin to use orginal resource url for resource name. (If you also set useHash to true it will combine the two)

removeObsoletePages="true/false" (default: false)

Specifies if scheduled job should remove generated resources not being used by any generated pages anymore. (Please note that enabling this can be dangerous as other files might be deleted if not setup correctly, backup everyhing before use)

RemoveObsoleteResources="true/false" (default: false)

Specifies if scheduled job should remove generated pages not represented in EpiServer anymore. (Please note that enabling this can be dangerous as other files might be deleted if not setup correctly, backup everyhing before use)

useTemporaryAttribute="true/false" (default: null)

Specifies that pages and resources writen because of publish event should have Temporary file attribute set. If this is set to false it will set Normal file attribute. If this is not set (read: default) it will not set any file attributes when writen to disk. This attribute may be used for identify high priority changes when you have a custom application to transfer files to multiple servers. (It is better to use rsync or similar instead of this if possible).

AllowedResourceTypes Configuration

With the <allowedResourceTypes> you can add, remove or change support for resource types. This is usefull if you for example want to extend support for more file extensions.

The <allowedResourceTypes> should be a direct child element to the <staticweb> element in your web.config. Below you will find how it can be used.

Add/extend support for resource type

Below illustrate how to extend the default resource types that are being supported by adding support for the .mp4 file extension and bind it to the video/mp4 mime type.

`<allowedResourceTypes>
	<add fileExtension=".mp4" mimeType="video/mp4" />
</allowedResourceTypes>`

Define your own list of allowed resource types

Below illustrate how to remove the default resource types and start from scratch. Allowing you to finetune exactly what resource types you support. In below example we only support resources with the following file extensions (and resources using mime type related to that): .css, .js and .jpg

`<allowedResourceTypes>
	<clear />
	<add fileExtension=".css" mimeType="text/css" />
	<add fileExtension=".js" mimeType="text/javascript" />
	<add fileExtension=".jpg" mimeType="image/jpg" />
</allowedResourceTypes>`
Product Compatible and additional computed target framework versions.
.NET Framework net472 is compatible.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.1 341 12/4/2021
3.0.0 294 12/4/2021
2.0.0 437 5/27/2020
1.1.0 424 4/15/2020
1.0.1 417 3/30/2020
1.0.0 450 3/30/2020

New features:
- Added support for content changing access righs
- Added support for removal of old content
- Added support for adding redirect pages when renaming/moving pages
- Added support for simple address
- Added support page references in ContentAreas
- Added support for not write to disk when not needed (if file hash matches existing content)
- Added support for PageControllers returning different mimeType then HTML
- Added support for file change events using (AfterIOWrite and AfterIODelete event)
- Added support to sync content to Azure Blob Storage (Thanks for suggestion maer0216-star, see issue-49 for more info)

Bug fixes:
- Source tags only allowed image references, not image candidates (Thanks for bug report themaf)
- Removed reference to file outside of project (Thanks bug report GrumpyMeow)
- Child pages where not added if current page was ignored
- No longer writing empty resource to disk
- Items property on Events are now initiated and not null

Additional:
- Added extension StaticWebEpiserverPlugin.RequiredCssOnly to allow for extraction of required CSS Only (for example to use as inline on every page)
- We now use regression tests to ensure quality