diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..4903ba5 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "cake.tool": { + "version": "1.3.0", + "commands": [ + "dotnet-cake" + ] + } + } +} \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..2720952 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# These owners will be the default owners for everything in the repo and +# will be requested for review when someone opens a pull request. +* @swissgrc/development \ No newline at end of file diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..e4637a6 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "github>cake-contrib/renovate-presets:cake-recipe" + ] +} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..c6d6428 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,68 @@ +name: Build + +on: + push: + branches: + - main + - develop + - "feature/**" + - "release/**" + - "hotfix/**" + tags: + - "*" + paths-ignore: + - "README.md" + pull_request: + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ windows-2022, ubuntu-22.04, macos-12 ] + + env: + GITHUB_PAT: ${{ secrets.GH_TOKEN }} + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + NUGET_SOURCE: "https://api.nuget.org/v3/index.json" + + steps: + - name: Checkout the repository + uses: actions/checkout@v4.1.1 + - name: Fetch all tags and branches + run: git fetch --prune --unshallow + - uses: actions/setup-dotnet@v4.0.0 + with: + # codecov needs 2.1, unittests needs 3.1, gitversion needs 5.0 + dotnet-version: | + 2.1 + 5.0 + 6.0 + 7.0 + 8.0 + - name: Cache Tools + uses: actions/cache@v3.3.2 + with: + path: tools + key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }} + - name: Build project + uses: cake-build/cake-action@v1.4.1 + with: + script-path: recipe.cake + target: CI + cake-version: 1.3.0 + - name: Upload Issues + uses: actions/upload-artifact@v3.1.3 + with: + if-no-files-found: warn + name: ${{ matrix.os }} Issues + path: | + BuildArtifacts/report.html + BuildArtifacts/**/coverlet/*.xml + - name: Upload Packages + uses: actions/upload-artifact@v3.1.3 + if: runner.os == 'Windows' + with: + if-no-files-found: warn + name: package + path: BuildArtifacts/Packages/**/* \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8a30d25..52acbe3 100644 --- a/.gitignore +++ b/.gitignore @@ -328,8 +328,8 @@ __pycache__/ *.pyc # Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config +tools/** +!tools/packages.config # Tabs Studio *.tss @@ -396,3 +396,7 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml + +# Project specific + +BuildArtifacts/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..be1cdd4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dotnet.defaultSolution": "src\\Statiq.Alerts.sln" +} \ No newline at end of file diff --git a/README.md b/README.md index 1b5982d..b66db33 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,61 @@ # Statiq.Alerts -📙 Extension for Statiq site generator to add annotations + + +[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/swissgrc/Statiq.Alerts/blob/main/LICENSE) [![Build](https://img.shields.io/github/actions/workflow/status/swissgrc/Statiq.Alerts/build.yml?branch=develop&style=flat-square)](https://github.com/swissgrc/Statiq.Alerts/actions/workflows/build.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=swissgrc_Statiq.Alerts&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=swissgrc_Statiq.Alerts) [![Downloads](https://img.shields.io/nuget/dt/Statiq.Alerts?style=flat-square)](https://www.nuget.org/packages/Statiq.Alerts) + + +Extension for [Statiq site generator] to add alerts. + +## Requirements + +The extensions require that [Bootstrap] and [FontAwesome] are loaded. + +## Using + +1. Add the `Statiq.Alerts` NuGet package to the Statiq project +2. Call `.AddAlertShortCodes()` on the bootstrapper + +## Available Shortcodes + +### Tip + +### Info + +### Note + +### Warning + +### Important + +## Custom Shortcuts + +Additional custom shortcuts can be implemented by inheriting from the `AlertShortcode` class and +define the `DefaultAlertClass`, `DefaultAlertIcon` and `DefaultAlertTitle` properties. +See [Parameters](#Parameters) for documentation about possible values. + +## Parameters + +The following parameters are available on all shortcuts and allow to override the default styling. + +### Class + +Allows to override the CSS class of the alert `div` element. +The `alert` class will always be set. + +### Icon + +Allows to override the icon of the alert. +Any [Fontawesome] icon can be used. +The `fa-solid` class will always be set. + +Can be an empty string to hide the icon. + +### Title + +Allow to override the title of the alert. + +Can be an empty string to not show any title. + +[Statiq site generator]: https://www.statiq.dev/ +[Bootstrap]: https://getbootstrap.com/ +[FontAwesome]: https://fontawesome.com/ diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..efa1885 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,13 @@ +$SCRIPT_NAME = "recipe.cake" + +Write-Host "Restoring .NET Core tools" +dotnet tool restore +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + +Write-Host "Bootstrapping Cake" +dotnet cake $SCRIPT_NAME --bootstrap +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + +Write-Host "Running Build" +dotnet cake $SCRIPT_NAME @args +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..ba5d0c9 --- /dev/null +++ b/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash +SCRIPT_NAME="recipe.cake" + +echo "Restoring .NET Core tools" +dotnet tool restore + +echo "Bootstrapping Cake" +dotnet cake $SCRIPT_NAME --bootstrap + +echo "Running Build" +dotnet cake $SCRIPT_NAME "$@" \ No newline at end of file diff --git a/global.json b/global.json new file mode 100644 index 0000000..3660ff8 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "allowPrerelease": true, + "version": "8.0.100", + "rollForward": "latestFeature" + } +} \ No newline at end of file diff --git a/recipe.cake b/recipe.cake new file mode 100644 index 0000000..fe2f6ef --- /dev/null +++ b/recipe.cake @@ -0,0 +1,22 @@ +#load nuget:?package=Cake.Recipe&version=3.1.1 + +Environment.SetVariableNames(); + +BuildParameters.SetParameters( + context: Context, + buildSystem: BuildSystem, + sourceDirectoryPath: "./src", + title: "Statiq.Alerts", + masterBranchName: "main", + repositoryOwner: "swissgrc", + repositoryName: "Statiq.Alerts", + shouldRunDotNetCorePack: true, + shouldUseDeterministicBuilds: true, + preferredBuildProviderType: BuildProviderType.GitHubActions, + preferredBuildAgentOperatingSystem: PlatformFamily.Linux); + +BuildParameters.PrintParameters(Context); + +ToolSettings.SetToolSettings(context: Context); + +Build.RunDotNetCore(); diff --git a/src/Statiq.Alerts.Tests/AlertShortcodeTests.cs b/src/Statiq.Alerts.Tests/AlertShortcodeTests.cs new file mode 100644 index 0000000..4543a10 --- /dev/null +++ b/src/Statiq.Alerts.Tests/AlertShortcodeTests.cs @@ -0,0 +1,175 @@ +namespace Statiq.Alerts.Tests +{ + using Shouldly; + using Statiq.Testing; + + public class AlertShortcodeTests + { + [Fact] + public void Should_Return_Correct_Result_When_Called_Without_Parameter() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = Array.Empty>(); + var shortcode = new FakeAlertShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 DefaultAlertTitle
Foo
", + StringCompareShould.IgnoreLineEndings); + } + + [Fact] + public void Should_Return_Correct_Result_When_Class_Parameter_Is_Passed() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = + new KeyValuePair[] + { + new("Class", "CustomClass") + }; + var shortcode = new FakeAlertShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 DefaultAlertTitle
Foo
", + StringCompareShould.IgnoreLineEndings); + } + + [Fact] + public void Should_Return_Correct_Result_When_Icon_Parameter_Is_Passed() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = + new KeyValuePair[] + { + new("Icon", "CustomIcon") + }; + var shortcode = new FakeAlertShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 DefaultAlertTitle
Foo
", + StringCompareShould.IgnoreLineEndings); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Should_Not_Render_Icon_If_Null_Empty_Or_Whitespace_Is_Passed(string value) + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = + new KeyValuePair[] + { + new("Icon", value) + }; + var shortcode = new FakeAlertShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
DefaultAlertTitle
Foo
", + StringCompareShould.IgnoreLineEndings); + } + + [Fact] + public void Should_Return_Correct_Result_When_Title_Parameter_Is_Passed() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = + new KeyValuePair[] + { + new("Title", "CustomTitle") + }; + var shortcode = new FakeAlertShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 CustomTitle
Foo
", + StringCompareShould.IgnoreLineEndings); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Should_Not_Render_Title_If_Null_Empty_Or_Whitespace_Is_Passed(string value) + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = + new KeyValuePair[] + { + new("Title", value) + }; + var shortcode = new FakeAlertShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "

Foo
", + StringCompareShould.IgnoreLineEndings); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Should_Not_Render_Title_If_Icon_And_Title_Are_Null_Empty_Or_Whitespace(string value) + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = + new KeyValuePair[] + { + new("Icon", value), + new("Title", value) + }; + var shortcode = new FakeAlertShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
Foo
", + StringCompareShould.IgnoreLineEndings); + } + } +} \ No newline at end of file diff --git a/src/Statiq.Alerts.Tests/FakeAlertShortcode.cs b/src/Statiq.Alerts.Tests/FakeAlertShortcode.cs new file mode 100644 index 0000000..d65bf46 --- /dev/null +++ b/src/Statiq.Alerts.Tests/FakeAlertShortcode.cs @@ -0,0 +1,11 @@ +namespace Statiq.Alerts.Tests +{ + internal class FakeAlertShortcode : AlertShortcode + { + protected override string DefaultAlertClass => "DefaultAlertClass"; + + protected override string DefaultAlertIcon => "DefaultAlertIcon"; + + protected override string DefaultAlertTitle => "DefaultAlertTitle"; + } +} diff --git a/src/Statiq.Alerts.Tests/GlobalUsings.cs b/src/Statiq.Alerts.Tests/GlobalUsings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/src/Statiq.Alerts.Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/src/Statiq.Alerts.Tests/ImportantShortcodeTests.cs b/src/Statiq.Alerts.Tests/ImportantShortcodeTests.cs new file mode 100644 index 0000000..7088494 --- /dev/null +++ b/src/Statiq.Alerts.Tests/ImportantShortcodeTests.cs @@ -0,0 +1,27 @@ +namespace Statiq.Alerts.Tests +{ + using Shouldly; + using Statiq.Testing; + + public class ImportantShortcodeTests + { + [Fact] + public void Should_Return_Correct_Default_Values() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = Array.Empty>(); + var shortcode = new ImportantShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 IMPORTANT
Foo
", + StringCompareShould.IgnoreLineEndings); + } + } +} \ No newline at end of file diff --git a/src/Statiq.Alerts.Tests/InfoShortcodeTests.cs b/src/Statiq.Alerts.Tests/InfoShortcodeTests.cs new file mode 100644 index 0000000..7d25795 --- /dev/null +++ b/src/Statiq.Alerts.Tests/InfoShortcodeTests.cs @@ -0,0 +1,27 @@ +namespace Statiq.Alerts.Tests +{ + using Shouldly; + using Statiq.Testing; + + public class InfoShortcodeTests + { + [Fact] + public void Should_Return_Correct_Default_Values() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = Array.Empty>(); + var shortcode = new InfoShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 INFO
Foo
", + StringCompareShould.IgnoreLineEndings); + } + } +} \ No newline at end of file diff --git a/src/Statiq.Alerts.Tests/NoteShortcodeTests.cs b/src/Statiq.Alerts.Tests/NoteShortcodeTests.cs new file mode 100644 index 0000000..fdd5e43 --- /dev/null +++ b/src/Statiq.Alerts.Tests/NoteShortcodeTests.cs @@ -0,0 +1,27 @@ +namespace Statiq.Alerts.Tests +{ + using Shouldly; + using Statiq.Testing; + + public class NoteShortcodeTests + { + [Fact] + public void Should_Return_Correct_Default_Values() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = Array.Empty>(); + var shortcode = new NoteShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 NOTE
Foo
", + StringCompareShould.IgnoreLineEndings); + } + } +} \ No newline at end of file diff --git a/src/Statiq.Alerts.Tests/Statiq.Alerts.Tests.csproj b/src/Statiq.Alerts.Tests/Statiq.Alerts.Tests.csproj new file mode 100644 index 0000000..31280fd --- /dev/null +++ b/src/Statiq.Alerts.Tests/Statiq.Alerts.Tests.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/src/Statiq.Alerts.Tests/TipShortcodeTests.cs b/src/Statiq.Alerts.Tests/TipShortcodeTests.cs new file mode 100644 index 0000000..bc7c56c --- /dev/null +++ b/src/Statiq.Alerts.Tests/TipShortcodeTests.cs @@ -0,0 +1,27 @@ +namespace Statiq.Alerts.Tests +{ + using Shouldly; + using Statiq.Testing; + + public class TipShortcodeTests + { + [Fact] + public void Should_Return_Correct_Default_Values() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = Array.Empty>(); + var shortcode = new TipShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 TIP
Foo
", + StringCompareShould.IgnoreLineEndings); + } + } +} \ No newline at end of file diff --git a/src/Statiq.Alerts.Tests/WarningShortcodeTests.cs b/src/Statiq.Alerts.Tests/WarningShortcodeTests.cs new file mode 100644 index 0000000..b4a92a0 --- /dev/null +++ b/src/Statiq.Alerts.Tests/WarningShortcodeTests.cs @@ -0,0 +1,27 @@ +namespace Statiq.Alerts.Tests +{ + using Shouldly; + using Statiq.Testing; + + public class WarningShortcodeTests + { + [Fact] + public void Should_Return_Correct_Default_Values() + { + // Given + var context = new TestExecutionContext(); + var document = new TestDocument(); + var content = @"Foo"; + var args = Array.Empty>(); + var shortcode = new WarningShortcode(); + + // When + var result = shortcode.Execute(args, content, document, context); + + // Then + result.ContentProvider.GetStream().ReadToEnd().ShouldBe( + "
 WARNING
Foo
", + StringCompareShould.IgnoreLineEndings); + } + } +} \ No newline at end of file diff --git a/src/Statiq.Alerts.sln b/src/Statiq.Alerts.sln new file mode 100644 index 0000000..6ffec6d --- /dev/null +++ b/src/Statiq.Alerts.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Statiq.Alerts", "Statiq.Alerts\Statiq.Alerts.csproj", "{6AD7112A-E5E3-4DFB-A604-542A06E373C9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Statiq.Alerts.Tests", "Statiq.Alerts.Tests\Statiq.Alerts.Tests.csproj", "{C7A5BDBA-8638-4A1C-9188-A01091A74B2C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6AD7112A-E5E3-4DFB-A604-542A06E373C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AD7112A-E5E3-4DFB-A604-542A06E373C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AD7112A-E5E3-4DFB-A604-542A06E373C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AD7112A-E5E3-4DFB-A604-542A06E373C9}.Release|Any CPU.Build.0 = Release|Any CPU + {C7A5BDBA-8638-4A1C-9188-A01091A74B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7A5BDBA-8638-4A1C-9188-A01091A74B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7A5BDBA-8638-4A1C-9188-A01091A74B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7A5BDBA-8638-4A1C-9188-A01091A74B2C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DB2D56A2-D3BC-4241-8152-D97A865BD077} + EndGlobalSection +EndGlobal diff --git a/src/Statiq.Alerts/AlertShortcode.cs b/src/Statiq.Alerts/AlertShortcode.cs new file mode 100644 index 0000000..47f106f --- /dev/null +++ b/src/Statiq.Alerts/AlertShortcode.cs @@ -0,0 +1,71 @@ +namespace Statiq.Alerts +{ + using Statiq.Common; + using System.Collections.Generic; + + public abstract class AlertShortcode : SyncShortcode + { + protected const string Class = nameof(Class); + protected const string Icon = nameof(Icon); + protected const string Title = nameof(Title); + + protected abstract string DefaultAlertClass { get; } + + protected abstract string DefaultAlertIcon { get; } + + protected abstract string DefaultAlertTitle { get; } + + public override ShortcodeResult Execute( + KeyValuePair[] args, + string content, + IDocument document, + IExecutionContext context) + { + var arguments = args.ToDictionary(Class, Icon, Title); + + var alertClass = DefaultAlertClass; + if (arguments.ContainsKey(Class)) + { + alertClass = arguments.GetString(Class); + } + + var alertIcon = DefaultAlertIcon; + if (arguments.ContainsKey(Icon)) + { + alertIcon = arguments.GetString(Icon); + } + + var alertTitle = DefaultAlertTitle; + if (arguments.ContainsKey(Title)) + { + alertTitle = arguments.GetString(Title); + } + + var result = $"
"; + + if (!string.IsNullOrWhiteSpace(alertIcon)) + { + result += $""; + } + + if (!string.IsNullOrWhiteSpace(alertTitle)) + { + if (!string.IsNullOrWhiteSpace(alertIcon)) + { + result += " "; + } + + result += $"{alertTitle}"; + } + + if (!string.IsNullOrWhiteSpace(alertIcon) || !string.IsNullOrWhiteSpace(alertTitle)) + { + result += "
"; + } + + result += $"{content}
"; + + return result; + } + } +} diff --git a/src/Statiq.Alerts/BootstrapperExtensions.cs b/src/Statiq.Alerts/BootstrapperExtensions.cs new file mode 100644 index 0000000..b161bd2 --- /dev/null +++ b/src/Statiq.Alerts/BootstrapperExtensions.cs @@ -0,0 +1,23 @@ +namespace Statiq.Alerts +{ + public static class BootstrapperExtensions + { + public static Bootstrapper AddAlertShortCodes( + this Bootstrapper bootstrapper, + string tipShortcode = "Tip", + string infoShortcode = "Info", + string noteShortcode = "Note", + string warningShortcode = "Warning", + string importantShortcode = "Important" + ) + { + bootstrapper.AddShortcode(tipShortcode); + bootstrapper.AddShortcode(infoShortcode); + bootstrapper.AddShortcode(noteShortcode); + bootstrapper.AddShortcode(warningShortcode); + bootstrapper.AddShortcode(importantShortcode); + + return bootstrapper; + } + } +} \ No newline at end of file diff --git a/src/Statiq.Alerts/ImportantShortcode.cs b/src/Statiq.Alerts/ImportantShortcode.cs new file mode 100644 index 0000000..29644e6 --- /dev/null +++ b/src/Statiq.Alerts/ImportantShortcode.cs @@ -0,0 +1,11 @@ +namespace Statiq.Alerts +{ + public class ImportantShortcode : AlertShortcode + { + protected override string DefaultAlertClass => "alert-danger"; + + protected override string DefaultAlertIcon => "fa-triangle-exclamation"; + + protected override string DefaultAlertTitle => "IMPORTANT"; + } +} diff --git a/src/Statiq.Alerts/InfoShortcode.cs b/src/Statiq.Alerts/InfoShortcode.cs new file mode 100644 index 0000000..cf62c52 --- /dev/null +++ b/src/Statiq.Alerts/InfoShortcode.cs @@ -0,0 +1,11 @@ +namespace Statiq.Alerts +{ + public class InfoShortcode : AlertShortcode + { + protected override string DefaultAlertClass => "alert-info"; + + protected override string DefaultAlertIcon => "fa-circle-info"; + + protected override string DefaultAlertTitle => "INFO"; + } +} diff --git a/src/Statiq.Alerts/NoteShortcode.cs b/src/Statiq.Alerts/NoteShortcode.cs new file mode 100644 index 0000000..2c80620 --- /dev/null +++ b/src/Statiq.Alerts/NoteShortcode.cs @@ -0,0 +1,11 @@ +namespace Statiq.Alerts +{ + public class NoteShortcode : AlertShortcode + { + protected override string DefaultAlertClass => "alert-primary"; + + protected override string DefaultAlertIcon => "fa-pen-to-square"; + + protected override string DefaultAlertTitle => "NOTE"; + } +} diff --git a/src/Statiq.Alerts/Statiq.Alerts.csproj b/src/Statiq.Alerts/Statiq.Alerts.csproj new file mode 100644 index 0000000..55693a3 --- /dev/null +++ b/src/Statiq.Alerts/Statiq.Alerts.csproj @@ -0,0 +1,13 @@ + + + + net6.0;net7.0;net8.0 + enable + enable + + + + + + + diff --git a/src/Statiq.Alerts/TipShortcode.cs b/src/Statiq.Alerts/TipShortcode.cs new file mode 100644 index 0000000..4cd1676 --- /dev/null +++ b/src/Statiq.Alerts/TipShortcode.cs @@ -0,0 +1,11 @@ +namespace Statiq.Alerts +{ + public class TipShortcode : AlertShortcode + { + protected override string DefaultAlertClass => "alert-success"; + + protected override string DefaultAlertIcon => "fa-lightbulb"; + + protected override string DefaultAlertTitle => "TIP"; + } +} diff --git a/src/Statiq.Alerts/WarningShortcode.cs b/src/Statiq.Alerts/WarningShortcode.cs new file mode 100644 index 0000000..a0eefa4 --- /dev/null +++ b/src/Statiq.Alerts/WarningShortcode.cs @@ -0,0 +1,11 @@ +namespace Statiq.Alerts +{ + public class WarningShortcode : AlertShortcode + { + protected override string DefaultAlertClass => "alert-warning"; + + protected override string DefaultAlertIcon => "fa-circle-exclamation"; + + protected override string DefaultAlertTitle => "WARNING"; + } +}