✨ Render self-managed site
This commit is contained in:
3
DysonNetwork.Zone/.gitignore
vendored
3
DysonNetwork.Zone/.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
# dependencies (bun install)
|
||||
node_modules
|
||||
wwwroot/css/site.dist.css
|
||||
wwwroot/SiteData
|
||||
|
||||
# output
|
||||
out
|
||||
@@ -33,5 +34,3 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
|
||||
SiteData
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
haven't configure anything that match this route.
|
||||
</p>
|
||||
<div class="text-xs opacity-70 mt-1">
|
||||
<p>Path: <b>@Model.CurrentPath</b> Site ID: <b>@(Model.Site?.Id.ToString() ?? "none")</b></p>
|
||||
<p>Path: <b>@Model.CurrentPath</b></p>
|
||||
<p>Site ID: <b>@(Model.Site?.Id.ToString() ?? "none")</b></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Zone.Publication;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DysonNetwork.Zone.Pages;
|
||||
|
||||
public class IndexModel(AppDatabase db) : PageModel
|
||||
public class IndexModel(AppDatabase db, PublicationSiteManager psm) : PageModel
|
||||
{
|
||||
public SnPublicationSite? Site { get; set; }
|
||||
public string? SiteName { get; set; }
|
||||
@@ -21,25 +22,46 @@ public class IndexModel(AppDatabase db) : PageModel
|
||||
if (string.IsNullOrEmpty(siteNameValue))
|
||||
{
|
||||
SiteName = null;
|
||||
return Page();
|
||||
}
|
||||
else
|
||||
{
|
||||
var capturedName = siteNameValue;
|
||||
Site = await db.PublicationSites.FirstOrDefaultAsync(s => s.Slug == capturedName);
|
||||
if (Site == null) return Page();
|
||||
var pagePath = CurrentPath;
|
||||
|
||||
var page = await db.PublicationPages.FirstOrDefaultAsync(p => p.SiteId == Site.Id && p.Path == pagePath);
|
||||
if (page == null) return Page();
|
||||
var capturedName = siteNameValue;
|
||||
Site = await db.PublicationSites.FirstOrDefaultAsync(s => s.Slug == capturedName);
|
||||
if (Site == null) return Page();
|
||||
var pagePath = CurrentPath;
|
||||
|
||||
var page = await db.PublicationPages.FirstOrDefaultAsync(p => p.SiteId == Site.Id && p.Path == pagePath);
|
||||
if (page != null)
|
||||
{
|
||||
switch (page.Type)
|
||||
{
|
||||
case PublicationPageType.HtmlPage when page.Config.TryGetValue("html", out var html) && html is JsonElement content:
|
||||
case PublicationPageType.HtmlPage
|
||||
when page.Config.TryGetValue("html", out var html) && html is JsonElement content:
|
||||
return Content(content.ToString(), "text/html");
|
||||
case PublicationPageType.Redirect when page.Config.TryGetValue("url", out var url) && url is JsonElement redirectUrl:
|
||||
case PublicationPageType.Redirect
|
||||
when page.Config.TryGetValue("url", out var url) && url is JsonElement redirectUrl:
|
||||
return Redirect(redirectUrl.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// If the site is enabled the self-managed mode, try lookup the files then
|
||||
if (Site.Mode == PublicationSiteMode.SelfManaged)
|
||||
{
|
||||
// TODO: Fix the path contains a wwwroot
|
||||
var provider = new FileExtensionContentTypeProvider();
|
||||
var hostedFilePath = psm.GetValidatedFullPath(Site.Id, CurrentPath);
|
||||
if (System.IO.File.Exists(hostedFilePath))
|
||||
{
|
||||
if (!provider.TryGetContentType(hostedFilePath, out var mimeType))
|
||||
mimeType = "text/html";
|
||||
return File(hostedFilePath, mimeType);
|
||||
}
|
||||
|
||||
var hostedNotFoundPath = psm.GetValidatedFullPath(Site.Id, "404.html");
|
||||
if (System.IO.File.Exists(hostedNotFoundPath))
|
||||
return File(hostedNotFoundPath, "text/html");
|
||||
}
|
||||
|
||||
return Page();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,10 @@ public class PublicationSiteManager(
|
||||
{
|
||||
// Treat paths starting with separator as relative to site root
|
||||
relativePath = relativePath.TrimStart('/', '\\');
|
||||
string fullPath = Path.Combine(_basePath, siteId.ToString(), relativePath);
|
||||
string normalizedPath = Path.GetFullPath(fullPath);
|
||||
string siteDirFull = Path.Combine(_basePath, siteId.ToString());
|
||||
string normalizedSiteDir = Path.GetFullPath(siteDirFull);
|
||||
var fullPath = Path.Combine(_basePath, siteId.ToString(), relativePath);
|
||||
var normalizedPath = Path.GetFullPath(fullPath);
|
||||
var siteDirFull = Path.Combine(_basePath, siteId.ToString());
|
||||
var normalizedSiteDir = Path.GetFullPath(siteDirFull);
|
||||
if (!normalizedPath.StartsWith(normalizedSiteDir + Path.DirectorySeparatorChar) &&
|
||||
!normalizedPath.Equals(normalizedSiteDir))
|
||||
{
|
||||
|
||||
@@ -15,6 +15,6 @@
|
||||
"PublicBasePath": "/zone"
|
||||
},
|
||||
"Sites": {
|
||||
"BasePath": "/SiteData"
|
||||
"BasePath": "SiteData"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user