diff --git a/Modules/AutoLayout/GenHTTP.Modules.AutoLayout.csproj b/Modules/AutoLayout/GenHTTP.Modules.AutoLayout.csproj index 06ddaeff..8e2e11b6 100644 --- a/Modules/AutoLayout/GenHTTP.Modules.AutoLayout.csproj +++ b/Modules/AutoLayout/GenHTTP.Modules.AutoLayout.csproj @@ -46,10 +46,11 @@ - + + - + diff --git a/Modules/AutoLayout/Provider/AutoLayoutHandler.cs b/Modules/AutoLayout/Provider/AutoLayoutHandler.cs index 48726e96..916907d5 100644 --- a/Modules/AutoLayout/Provider/AutoLayoutHandler.cs +++ b/Modules/AutoLayout/Provider/AutoLayoutHandler.cs @@ -24,24 +24,28 @@ public class AutoLayoutHandler : IHandler private IHandler Content { get; set; } + private HandlerRegistry HandlerRegistry { get; } + #endregion #region Initialization - public AutoLayoutHandler(IHandler parent, IResourceTree tree, string[] indexNames) + public AutoLayoutHandler(IHandler parent, IResourceTree tree, HandlerRegistry registry, string[] indexNames) { Parent = parent; Tree = tree; IndexNames = indexNames; + HandlerRegistry = registry; + Content = Layout.Create() .Build(this); } public async ValueTask ReloadAsync() { - Content = (await TreeScanner.ScanAsync(Tree, IndexNames)).Build(this); + Content = (await TreeScanner.ScanAsync(Tree, HandlerRegistry, IndexNames)).Build(this); } #endregion diff --git a/Modules/AutoLayout/Provider/AutoLayoutHandlerBuilder.cs b/Modules/AutoLayout/Provider/AutoLayoutHandlerBuilder.cs new file mode 100644 index 00000000..0bcc3530 --- /dev/null +++ b/Modules/AutoLayout/Provider/AutoLayoutHandlerBuilder.cs @@ -0,0 +1,61 @@ +using GenHTTP.Api.Content; +using GenHTTP.Api.Content.IO; +using GenHTTP.Api.Infrastructure; +using GenHTTP.Modules.AutoLayout.Scanning; +using System.Collections.Generic; + +namespace GenHTTP.Modules.AutoLayout.Provider +{ + + public class AutoLayoutHandlerBuilder : IHandlerBuilder + { + private readonly List _Concerns = new(); + + private IResourceTree? _Tree; + + private HandlerRegistryBuilder? _Registry; + + private string[]? _Index; + + #region Functionality + + public AutoLayoutHandlerBuilder Tree(IResourceTree tree) + { + _Tree = tree; + return this; + } + + public AutoLayoutHandlerBuilder Registry(HandlerRegistryBuilder registry) + { + _Registry = registry; + return this; + } + + public AutoLayoutHandlerBuilder Index(params string[] index) + { + _Index = index; + return this; + } + + public AutoLayoutHandlerBuilder Add(IConcernBuilder concern) + { + _Concerns.Add(concern); + return this; + } + + public IHandler Build(IHandler parent) + { + var tree = _Tree ?? throw new BuilderMissingPropertyException("tree"); + + var registry = _Registry ?? Resolvers.Default(); + + var index = _Index ?? new[] { "Index" }; + + return Concerns.Chain(parent, _Concerns, (p) => new AutoLayoutHandler(p, tree, registry.Build(), index)); + } + + #endregion + + } + +} diff --git a/Modules/AutoLayout/Provider/PlainProvider.cs b/Modules/AutoLayout/Provider/PlainProvider.cs new file mode 100644 index 00000000..783efe3d --- /dev/null +++ b/Modules/AutoLayout/Provider/PlainProvider.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; + +using GenHTTP.Api.Content; +using GenHTTP.Api.Content.IO; +using GenHTTP.Api.Protocol; + +using GenHTTP.Modules.Basics; +using GenHTTP.Modules.Placeholders; + +namespace GenHTTP.Modules.AutoLayout.Provider +{ + + public class PlainProvider : IResourceHandlerProvider + { + + public bool Supports(IResource resource) + { + var type = (resource.ContentType?.KnownType ?? resource.Name?.GuessContentType()); + + return (type == ContentType.TextPlain) || (type == ContentType.TextHtml); + } + + public ValueTask GetHandlerAsync(IResource resource) + { + return new(Page.From(resource)); + } + + } + +} diff --git a/Modules/AutoLayout/Resolvers.cs b/Modules/AutoLayout/Resolvers.cs index e3aceade..18d8e260 100644 --- a/Modules/AutoLayout/Resolvers.cs +++ b/Modules/AutoLayout/Resolvers.cs @@ -10,6 +10,7 @@ public static class Resolvers public static HandlerRegistryBuilder Default() { return new HandlerRegistryBuilder().Fallback(new DownloadProvider()) + .Add(new PlainProvider()) .Add(new MarkdownProvider()) .Add(new ScribanProvider()); } diff --git a/Modules/AutoLayout/Scanning/TreeScanner.cs b/Modules/AutoLayout/Scanning/TreeScanner.cs index b5e50200..1aa24952 100644 --- a/Modules/AutoLayout/Scanning/TreeScanner.cs +++ b/Modules/AutoLayout/Scanning/TreeScanner.cs @@ -12,18 +12,18 @@ namespace GenHTTP.Modules.AutoLayout.Scanning public static class TreeScanner { - public static ValueTask ScanAsync(IResourceTree tree, HandlerRegistry registry, params string[] indexNames) + public static ValueTask ScanAsync(IResourceTree tree, HandlerRegistry registry, string[] indexNames) { return ScanContainerAsync(tree, registry, indexNames); } - private static async ValueTask ScanContainerAsync(IResourceContainer container, HandlerRegistry registry, params string[] indexNames) + private static async ValueTask ScanContainerAsync(IResourceContainer container, HandlerRegistry registry, string[] indexNames) { var layout = Layout.Create(); await foreach (var node in container.GetNodes()) { - layout.Add(node.Name, await ScanContainerAsync(node, registry)); + layout.Add(node.Name.ToLowerInvariant(), await ScanContainerAsync(node, registry, indexNames)); } await foreach (var resource in container.GetResources()) @@ -34,7 +34,7 @@ private static async ValueTask ScanContainerAsync(IResourceContai var fileName = Path.GetFileNameWithoutExtension(resource.Name).ToLowerInvariant(); - var isIndex = indexNames.Any(n => n == fileName); + var isIndex = indexNames.Any(n => n.ToLowerInvariant() == fileName); if (isIndex) { @@ -42,7 +42,7 @@ private static async ValueTask ScanContainerAsync(IResourceContai } else { - layout.Add(resource.Name, handler); + layout.Add(fileName, handler); } } } diff --git a/Modules/AutoLayout/TreeLayout.cs b/Modules/AutoLayout/TreeLayout.cs new file mode 100644 index 00000000..63064c9b --- /dev/null +++ b/Modules/AutoLayout/TreeLayout.cs @@ -0,0 +1,16 @@ +using GenHTTP.Api.Content.IO; +using GenHTTP.Api.Infrastructure; +using GenHTTP.Modules.AutoLayout.Provider; + +namespace GenHTTP.Modules.AutoLayout +{ + public static class TreeLayout + { + + public static AutoLayoutHandlerBuilder From(IResourceTree tree) => new AutoLayoutHandlerBuilder().Tree(tree); + + public static AutoLayoutHandlerBuilder From(IBuilder tree) => new AutoLayoutHandlerBuilder().Tree(tree.Build()); + + } + +} diff --git a/Playground/GenHTTP.Playground.csproj b/Playground/GenHTTP.Playground.csproj index 3091ed9c..7d1d5744 100644 --- a/Playground/GenHTTP.Playground.csproj +++ b/Playground/GenHTTP.Playground.csproj @@ -11,6 +11,18 @@ + + + + + + + + + + + + @@ -47,6 +59,7 @@ + diff --git a/Playground/Header.jpg b/Playground/Header.jpg new file mode 100644 index 00000000..bfe82829 Binary files /dev/null and b/Playground/Header.jpg differ diff --git a/Playground/Program.cs b/Playground/Program.cs index 64ff2816..863ddd1f 100644 --- a/Playground/Program.cs +++ b/Playground/Program.cs @@ -1,10 +1,37 @@ using GenHTTP.Engine; - +using GenHTTP.Modules.AutoLayout; using GenHTTP.Modules.IO; using GenHTTP.Modules.Practices; +using GenHTTP.Modules.Websites; +using GenHTTP.Themes.Lorahost; +using System.Collections.Generic; + +var layout = TreeLayout.From(ResourceTree.FromDirectory(@"C:\Work\GenHTTP\GenHTTP.Website\Project\Pages")) + .Index("Home", "Index", "Intro"); + +var theme = Theme.Create() + .Header(Resource.FromAssembly("Header.jpg")) + .Title("GenHTTP Webserver") + .Subtitle("Simple and lightweight, embeddable HTTP webserver written in pure C# with few dependencies to 3rd-party libraries. Compatible with .NET 6/7/8.") + .Action("documentation/", "Get started"); + +var menu = Menu.Empty() + .Add("{website}", "Home") + .Add("features", "Features") + .Add("documentation/", "Documentation", new List<(string, string)> { ("content/", "Providing Content"), ("testing/", "Testing Apps"), ("server/", "Server Setup"), ("hosting/", "Hosting Apps"), ("asp-net-comparison", "Comparison with ASP.NET") }) + .Add("links", "Links") + .Add("https://discord.gg/GwtDyUpkpV", "Discord") + .Add("https://github.com/Kaliumhexacyanoferrat/GenHTTP", "GitHub") + .Add("legal", "Legal"); + + +var website = Website.Create() + .Content(layout) + .Theme(theme) + .Menu(menu); Host.Create() - .Handler(Content.From(Resource.FromString("Hello World"))) + .Handler(website) .Defaults() .Development() .Console()