From 4084b352de1a61f70d7d7ecf8a899e80be808571 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 15 Aug 2022 17:01:20 -0400 Subject: [PATCH] added ability to specify a site home page, updated default template content to include .NET MAUI --- .../Modules/Admin/Languages/Add.razor | 4 +++ .../Modules/Admin/ModuleDefinitions/Add.razor | 4 +++ Oqtane.Client/Modules/Admin/Site/Index.razor | 19 ++++++++++++ Oqtane.Client/Modules/Admin/Themes/Add.razor | 4 +++ .../Resources/Modules/Admin/Site/Index.resx | 6 ++++ Oqtane.Client/Resources/SharedResources.resx | 3 ++ Oqtane.Client/UI/SiteRouter.razor | 18 +++++++----- Oqtane.Maui/Main.razor | 2 +- .../SiteTemplates/DefaultSiteTemplate.cs | 4 +-- .../Tenant/03020001_AddSiteHomePage.cs | 29 +++++++++++++++++++ Oqtane.Server/Pages/_Host.cshtml.cs | 4 +++ Oqtane.Shared/Models/Site.cs | 5 ++++ 12 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 Oqtane.Server/Migrations/Tenant/03020001_AddSiteHomePage.cs diff --git a/Oqtane.Client/Modules/Admin/Languages/Add.razor b/Oqtane.Client/Modules/Admin/Languages/Add.razor index c72f21cd..0f371f29 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Add.razor @@ -110,6 +110,10 @@ else } @SharedLocalizer["Cancel"] + +
+
+ } diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor index 4428cabf..70723195 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor @@ -114,6 +114,10 @@ @SharedLocalizer["Cancel"] +
+
+ + @code { private List _packages; private string _price = "free"; diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index c741a252..008f287b 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -70,6 +70,18 @@ } + +
+ +
+ +
@@ -296,6 +308,7 @@ private string _themetype = "-"; private string _containertype = "-"; private string _admincontainertype = "-"; + private string _homepageid = "-"; private string _smtphost = string.Empty; private string _smtpport = string.Empty; private string _smtpssl = "False"; @@ -354,6 +367,11 @@ _containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer; _admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer; + if (site.HomePageId != null) + { + _homepageid = site.HomePageId.Value.ToString(); + } + _pwaisenabled = site.PwaIsEnabled.ToString(); if (site.PwaAppIconFileId != null) { @@ -480,6 +498,7 @@ refresh = true; // needs to be refreshed on client } site.AdminContainerType = _admincontainertype; + site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null); if (site.PwaIsEnabled.ToString() != _pwaisenabled) { diff --git a/Oqtane.Client/Modules/Admin/Themes/Add.razor b/Oqtane.Client/Modules/Admin/Themes/Add.razor index b8717647..f3ca2c98 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Add.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Add.razor @@ -114,6 +114,10 @@ @SharedLocalizer["Cancel"] +
+
+ + @code { private List _packages; private string _price = "free"; diff --git a/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx index 432a2089..4b204eab 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx @@ -333,4 +333,10 @@ Are You Sure You Wish To Delete {0}? + + Select the home page for the site (to be used if there is no page with a path of '/') + + + Home Page: + \ No newline at end of file diff --git a/Oqtane.Client/Resources/SharedResources.resx b/Oqtane.Client/Resources/SharedResources.resx index 1ad5ffb5..4ec3d693 100644 --- a/Oqtane.Client/Resources/SharedResources.resx +++ b/Oqtane.Client/Resources/SharedResources.resx @@ -339,4 +339,7 @@ Visitor Management + + Please note that the third party extensions displayed above have been registered in the <a href="https://www.oqtane.net" target="_new">Oqtane Marketplace</a> which enables them to be seamlessly downloaded and installed into the framework. + \ No newline at end of file diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index bcb90a35..7d0b26c0 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -135,7 +135,7 @@ { user = PageState.User; } - + // process any sync events var sync = await SyncService.GetSyncAsync(lastsyncdate); lastsyncdate = sync.SyncDate; @@ -171,25 +171,27 @@ if (site != null) { - if (PageState == null || refresh == UI.Refresh.Site) + if (PageState == null || refresh == UI.Refresh.Site || PageState.Page.Path != route.PagePath) { page = site.Pages.FirstOrDefault(item => item.Path.Equals(route.PagePath, StringComparison.OrdinalIgnoreCase)); + editmode = false; } else { page = PageState.Page; } - // get the new page if the path has changed - if (page == null || page.Path != route.PagePath) + if (page == null && route.PagePath == "") // naked path refers to site home page { - page = site.Pages.FirstOrDefault(item => item.Path.Equals(route.PagePath, StringComparison.OrdinalIgnoreCase)); - if (page == null && route.PagePath == "") + if (site.HomePageId != null) { - // if the home page path does not exist then use the first page in the collection + page = site.Pages.FirstOrDefault(item => item.PageId == site.HomePageId); + } + if (page == null) + { + // fallback to use the first page in the collection page = site.Pages.FirstOrDefault(); } - editmode = false; } if (page != null) diff --git a/Oqtane.Maui/Main.razor b/Oqtane.Maui/Main.razor index 2d6354bc..d139d631 100644 --- a/Oqtane.Maui/Main.razor +++ b/Oqtane.Maui/Main.razor @@ -9,7 +9,7 @@ Parameters = new Dictionary(); Parameters.Add(new KeyValuePair("AntiForgeryToken", "")); Parameters.Add(new KeyValuePair("Runtime", "Hybrid")); - Parameters.Add(new KeyValuePair("RenderMode", "")); + Parameters.Add(new KeyValuePair("RenderMode", "Hybrid")); Parameters.Add(new KeyValuePair("VisitorId", -1)); Parameters.Add(new KeyValuePair("RemoteIPAddress", "")); Parameters.Add(new KeyValuePair("AuthorizationToken", "")); diff --git a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs index c1a65d4a..b388e292 100644 --- a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs +++ b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs @@ -57,9 +57,9 @@ namespace Oqtane.SiteTemplates new Permission(PermissionNames.View, RoleNames.Admin, true), new Permission(PermissionNames.Edit, RoleNames.Admin, true) }.EncodePermissions(), - Content = "

Oqtane is an open source modular application framework that provides advanced functionality for developing web and mobile applications on .NET Core. It leverages the Blazor component model to compose a fully dynamic web development experience which can be hosted either client-side or server-side. Whether you are looking for a platform to accelerate your web development efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles.

" + + Content = "

Oqtane is an open source modular application framework that provides advanced functionality for developing web, mobile, and desktop applications on .NET Core. It leverages the Blazor component model to compose a fully dynamic web development experience which can be hosted either client-side or server-side. Whether you are looking for a platform to accelerate your web development efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles.

" + "

Join Our Community  Clone Our Repo

" + - "

Blazor is an open source and cross-platform web UI framework for building single-page apps using .NET and C# instead of JavaScript. Blazor WebAssembly relies on Wasm, an open web standard that does not require plugins or code transpilation in order to run natively in a web browser. Blazor Server uses SignalR to host your application on a web server and provide a responsive and robust development experience. Blazor applications work in all modern web browsers, including mobile browsers.

" + + "

Blazor is an open source and cross-platform web UI framework for building single-page applications using .NET and C#. Blazor applications can be hosted in a variety of ways. Blazor Server uses SignalR (WebSockets) to host your application on a web server and provide a responsive and robust development experience. Blazor WebAssembly relies on Wasm, an open web standard that does not require plugins in order for applications to run natively in a web browser. Blazor Hybrid is part of .NET MAUI and uses a Web View to render components natively on mobile and desktop devices. Razor components can be used with all of the hosting models without any modification.

" + "

Blazor is a feature of .NET Core, the popular cross platform web development framework from Microsoft that extends the .NET developer platform with tools and libraries for building web apps.

" }, new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "MIT License", Pane = PaneNames.Admin, diff --git a/Oqtane.Server/Migrations/Tenant/03020001_AddSiteHomePage.cs b/Oqtane.Server/Migrations/Tenant/03020001_AddSiteHomePage.cs new file mode 100644 index 00000000..5242fa89 --- /dev/null +++ b/Oqtane.Server/Migrations/Tenant/03020001_AddSiteHomePage.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Oqtane.Databases.Interfaces; +using Oqtane.Migrations.EntityBuilders; +using Oqtane.Repository; + +namespace Oqtane.Migrations.Tenant +{ + [DbContext(typeof(TenantDBContext))] + [Migration("Tenant.03.02.00.01")] + public class AddSiteHomePage : MultiDatabaseMigration + { + public AddSiteHomePage(IDatabase database) : base(database) + { + } + + protected override void Up(MigrationBuilder migrationBuilder) + { + var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase); + siteEntityBuilder.AddIntegerColumn("HomePageId", true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase); + siteEntityBuilder.DropColumn("HomePageId"); + } + } +} diff --git a/Oqtane.Server/Pages/_Host.cshtml.cs b/Oqtane.Server/Pages/_Host.cshtml.cs index da290b8e..77e215b5 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -152,6 +152,10 @@ namespace Oqtane.Pages } var page = _pages.GetPage(route.PagePath, site.SiteId); + if (page == null && route.PagePath == "" && site.HomePageId != null) + { + page = _pages.GetPage(site.HomePageId.Value); + } if (page != null && !page.IsDeleted) { // set page title diff --git a/Oqtane.Shared/Models/Site.cs b/Oqtane.Shared/Models/Site.cs index 9b04cac0..3918f2ca 100644 --- a/Oqtane.Shared/Models/Site.cs +++ b/Oqtane.Shared/Models/Site.cs @@ -83,6 +83,11 @@ namespace Oqtane.Models /// public string Version { get; set; } + /// + /// The home page of the site which will be used as a fallback if no page has a path of "/" + /// + public int? HomePageId { get; set; } + [NotMapped] public Dictionary Settings { get; set; }