diff --git a/Models/SiteSettings.cs b/Models/SiteSettings.cs index aea8a2f..1b23fcd 100644 --- a/Models/SiteSettings.cs +++ b/Models/SiteSettings.cs @@ -12,5 +12,6 @@ public class SiteSettings{ public string DisqusId { get; set; } public string ContactFormUrl { get; set; } public string? GoogleAnalytics { get; set; } + public bool OptimizeOutput { get; set; } = true; } } \ No newline at end of file diff --git a/Modules/HtmlOptimizer.cs b/Modules/HtmlOptimizer.cs index b279f1a..8f6c038 100644 --- a/Modules/HtmlOptimizer.cs +++ b/Modules/HtmlOptimizer.cs @@ -1,6 +1,5 @@ using NUglify; using NUglify.Html; -using NUglify.JavaScript; using Statiq.Common; using System; using System.Collections.Generic; @@ -8,24 +7,70 @@ namespace MemoirsTheme.Modules { + /// + /// Optimize HTML using NUglify. + /// public class OptimizeHtml : Module { + private readonly bool _enabled; + private readonly HtmlSettings _settings = new HtmlSettings(); + + /// + /// Optimize HTML in the content of the Document. + /// + public OptimizeHtml() : this(true) + { + + } + + /// + /// Optimize HTML in the content of the Document. + /// + /// Set to false to skip optimization. For example for debug builds. + public OptimizeHtml(bool enabled) + { + _enabled = enabled; + } + + /// + /// Configure the NUglify settings + /// + /// An action to tweak the settings. + /// + public OptimizeHtml WithSettings(Action settings) + { + settings?.Invoke(_settings); + return this; + } + protected override async Task> ExecuteInputAsync(IDocument input, IExecutionContext context) { - var settings = new HtmlSettings - { - MinifyJs = false - }; var original = await input.GetContentStringAsync(); - var minifiedContent = Uglify.Html(original, settings); + if (string.IsNullOrWhiteSpace(original)) + { + return (input).Yield(); // nothing to do, return original document + } + + var minifiedContent = Uglify.Html(original, _settings); if (minifiedContent.HasErrors) { - context.LogError(input, $"Minification failed"); foreach (var error in minifiedContent.Errors) { - context.LogError(input, $"{error.Message} {error.File} line ({error.StartLine},{error.StartColumn}) through ({error.EndLine},{error.EndColumn})"); + if (error.IsError) + { + context.LogError(input, error.ToString()); + } + else + { + context.LogWarning(input, error.ToString()); + } } + } + + if (string.IsNullOrWhiteSpace(minifiedContent.Code)) + { + context.LogWarning(input, $"Content minification skipped."); return (input).Yield(); // return original document } diff --git a/Pipelines/Posts.cs b/Pipelines/Posts.cs index 919be1b..0459733 100644 --- a/Pipelines/Posts.cs +++ b/Pipelines/Posts.cs @@ -44,7 +44,13 @@ public Posts(IDeliveryClient deliveryClient, SiteSettings site) .WithViewData("SiteMetadata", site ) .WithModel(KontentConfig.As()), new KontentImageProcessor(), - new OptimizeHtml() + new OptimizeHtml(site.OptimizeOutput) + .WithSettings(settings => + { + // conflicts with ratings + settings.RemoveScriptStyleTypeAttribute = false; + settings.MinifyJs = false; + }) }; OutputModules = new ModuleList { diff --git a/Pipelines/StyleSheets.cs b/Pipelines/StyleSheets.cs index ead9877..fae0d19 100644 --- a/Pipelines/StyleSheets.cs +++ b/Pipelines/StyleSheets.cs @@ -1,3 +1,4 @@ +using Kentico.Kontent.Statiq.Memoirs.Models; using Statiq.Common; using Statiq.Core; using Statiq.Sass; @@ -6,17 +7,22 @@ namespace Kentico.Kontent.Statiq.Lumen.Pipelines { public class StyleSheets : Pipeline { - public StyleSheets() + public StyleSheets(SiteSettings site) { InputModules = new ModuleList { new ReadFiles("_sass/**/{!_,}*.scss"), - new CompileSass() - .WithCompactOutputStyle(), + CompileSass(site.OptimizeOutput), new SetDestination(Config.FromDocument((doc, ctx) => new NormalizedPath($"assets/css/{doc.Source.FileNameWithoutExtension}.css"))), new WriteFiles() }; } + + private CompileSass CompileSass(bool optimize) + { + var module = new CompileSass(); + return optimize ? module.WithCompressedOutputStyle() : module.WithCompactOutputStyle(); + } } } \ No newline at end of file diff --git a/README.md b/README.md index ad4614d..dfce8ff 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,26 @@ # Memoirs Statiq Kontent Theme -This theme was adopted from the Memoirs Jekyl theme by [Wowthemes](https://www.wowthemes.net). Please [buy them coffee](https://www.wowthemes.net/donate/)! +This is a full featured theme for [Kontent](https://kontent.ai/) and [Statiq](https://statiq.dev/) using [Kontent.Statiq](https://github.com/alanta/Kontent.Statiq). -# TODO -- [Live Demo](https://wowthemesnet.github.io/jekyll-theme-memoirs/) | [Docs & Download](https://bootstrapstarter.com/bootstrap-templates/jekyll-theme-memoirs/) | [Buy me a coffee](https://www.wowthemes.net/donate/) +## Features + +* Posts & Pages with + * Quotes, Spoilers (blurring) + * GitHub Gists + * Code snippets with [Prism.js](https://prismjs.com/) + * Related pages, Tags and Categories + * Ratings + * Contact form using [Formspree](https://formspree.io/) + * Comments with [Disqus](https://disqus.com/) + * Table of contents generated from HTML _TODO_ +* SEO support _TODO_ +* Google Analytics +* Search with pre-compiled Lunr index +* HTML minification with [NUglify](https://github.com/trullock/NUglify) + +## Credits + +This theme was adopted from the Memoirs Jekyl theme by [Wowthemes](https://bootstrapstarter.com/bootstrap-templates/jekyll-theme-memoirs/). Please [buy them coffee](https://www.wowthemes.net/donate/)! ![memoirs](https://bootstrapstarter.com/assets/img/themes/memoirs-jekyll.jpg)