Merge pull request #6116 from oqtane/dev

10.1.1 Release
This commit is contained in:
Shaun Walker
2026-03-06 15:49:36 -05:00
committed by GitHub
36 changed files with 229 additions and 129 deletions

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<Configurations>Debug;Release</Configurations> <Configurations>Debug;Release</Configurations>
<Version>10.1.0</Version> <Version>10.1.1</Version>
<Product>Oqtane</Product> <Product>Oqtane</Product>
<Authors>Shaun Walker</Authors> <Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company> <Company>.NET Foundation</Company>
@@ -10,7 +10,7 @@
<Copyright>.NET Foundation</Copyright> <Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl> <PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl> <PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</PackageReleaseNotes> <PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl> <RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType> <RepositoryType>Git</RepositoryType>
</PropertyGroup> </PropertyGroup>

View File

@@ -23,7 +23,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Oqtane.Client" Version="10.1.0" /> <PackageReference Include="Oqtane.Client" Version="10.1.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata> <metadata>
<id>Oqtane.Application.Template</id> <id>Oqtane.Application.Template</id>
<version>10.1.0</version> <version>10.1.1</version>
<title>Oqtane Application Template For Blazor</title> <title>Oqtane Application Template For Blazor</title>
<authors>Shaun Walker</authors> <authors>Shaun Walker</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>

View File

@@ -33,7 +33,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Oqtane.Server" Version="10.1.0" /> <PackageReference Include="Oqtane.Server" Version="10.1.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -11,7 +11,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Oqtane.Shared" Version="10.1.0" /> <PackageReference Include="Oqtane.Shared" Version="10.1.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -28,7 +28,7 @@
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="site" HelpText="Specify if site properties should be updated (ie. name, headcontent, bodycontent)" ResourceKey="Site">Site Properties? </Label> <Label Class="col-sm-3" For="site" HelpText="Specify if site information should be updated (ie. name, head content, body content, settings)" ResourceKey="Site">Site Info? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="site" class="form-select" @bind="@_site"> <select id="site" class="form-select" @bind="@_site">
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
@@ -37,7 +37,7 @@
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="pages" HelpText="Specify if page properties should be updated (ie. name, title, headcontent, bodycontent)" ResourceKey="Pages">Page Properties? </Label> <Label Class="col-sm-3" For="pages" HelpText="Specify if page information should be updated (ie. name, title, head content, body content, settings)" ResourceKey="Pages">Page Info? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="pages" class="form-select" @bind="@_pages"> <select id="pages" class="form-select" @bind="@_pages">
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
@@ -46,7 +46,7 @@
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="modules" HelpText="Specify if module properties should be updated (ie. title, header, footer)" ResourceKey="Modules">Module Properties? </Label> <Label Class="col-sm-3" For="modules" HelpText="Specify if module information should be updated (ie. title, header, footer, settings)" ResourceKey="Modules">Module Info? </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<select id="modules" class="form-select" @bind="@_modules"> <select id="modules" class="form-select" @bind="@_modules">
<option value="True">@SharedLocalizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>

View File

@@ -130,7 +130,7 @@ else
private async Task LoadModuleDefinitions() private async Task LoadModuleDefinitions()
{ {
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList(); _moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries).Contains(_category)).ToList();
_packages = await PackageService.GetPackageUpdatesAsync("module"); _packages = await PackageService.GetPackageUpdatesAsync("module");
} }

View File

@@ -1413,10 +1413,13 @@
{ {
if (_siteGroupId != -1) if (_siteGroupId != -1)
{ {
var siteGroupMember = await SiteGroupMemberService.GetSiteGroupMemberAsync(PageState.Site.SiteId, _siteGroupId); if (_siteId != -1)
if (siteGroupMember != null)
{ {
await SiteGroupMemberService.DeleteSiteGroupMemberAsync(siteGroupMember.SiteGroupId); var siteGroupMember = await SiteGroupMemberService.GetSiteGroupMemberAsync(_siteId, _siteGroupId);
if (siteGroupMember != null)
{
await SiteGroupMemberService.DeleteSiteGroupMemberAsync(siteGroupMember.SiteGroupMemberId);
}
} }
var siteGroupMembers = await SiteGroupMemberService.GetSiteGroupMembersAsync(-1, _siteGroupId); var siteGroupMembers = await SiteGroupMemberService.GetSiteGroupMembersAsync(-1, _siteGroupId);

View File

@@ -12,7 +12,7 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.3" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="10.0.3" /> <PackageReference Include="Microsoft.Extensions.Localization" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.3" /> <PackageReference Include="Microsoft.Extensions.Http" Version="10.0.3" />
<PackageReference Include="Radzen.Blazor" Version="9.0.0" /> <PackageReference Include="Radzen.Blazor" Version="9.0.8" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -130,16 +130,16 @@
<value>Specify if module content should be updated</value> <value>Specify if module content should be updated</value>
</data> </data>
<data name="Pages.Text" xml:space="preserve"> <data name="Pages.Text" xml:space="preserve">
<value>Page Properties?</value> <value>Page Info?</value>
</data> </data>
<data name="Pages.HelpText" xml:space="preserve"> <data name="Pages.HelpText" xml:space="preserve">
<value>Specify if page properties should be updated (ie. name, title, headcontent, bodycontent)</value> <value>Specify if page information should be updated (ie. name, title, head content, body content settings)</value>
</data> </data>
<data name="Site.Text" xml:space="preserve"> <data name="Site.Text" xml:space="preserve">
<value>Site Properties?</value> <value>Site Info?</value>
</data> </data>
<data name="Site.HelpText" xml:space="preserve"> <data name="Site.HelpText" xml:space="preserve">
<value>Specify if site properties should be updated (ie. name, headcontent, bodycontent)</value> <value>Specify if site information should be updated (ie. name, head content, body content, settings)</value>
</data> </data>
<data name="Replace.Text" xml:space="preserve"> <data name="Replace.Text" xml:space="preserve">
<value>Replace With:</value> <value>Replace With:</value>
@@ -148,10 +148,10 @@
<value>Specify the replacement content</value> <value>Specify the replacement content</value>
</data> </data>
<data name="Modules.Text" xml:space="preserve"> <data name="Modules.Text" xml:space="preserve">
<value>Module Properties?</value> <value>Module Info?</value>
</data> </data>
<data name="Modules.HelpText" xml:space="preserve"> <data name="Modules.HelpText" xml:space="preserve">
<value>Specify if module properties should be updated (ie. title, header, footer)</value> <value>Specify if module information should be updated (ie. title, header, footer settings)</value>
</data> </data>
<data name="Success.Save" xml:space="preserve"> <data name="Success.Save" xml:space="preserve">
<value>Your Global Replace Request Has Been Submitted And Will Be Executed Shortly. Please Be Patient.</value> <value>Your Global Replace Request Has Been Submitted And Will Be Executed Shortly. Please Be Patient.</value>

View File

@@ -303,7 +303,7 @@
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType); _containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
_containerType = PageState.Site.DefaultContainerType; _containerType = PageState.Site.DefaultContainerType;
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Page.SiteId); _allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Page.SiteId);
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList(); _moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries).Contains(_category)).ToList();
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries)).Distinct().Where(item => item != "Headless").ToList(); _categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries)).Distinct().Where(item => item != "Headless").ToList();
_siteGroups = await SiteGroupService.GetSiteGroupsAsync(PageState.Site.SiteId); _siteGroups = await SiteGroupService.GetSiteGroupsAsync(PageState.Site.SiteId);
} }
@@ -312,7 +312,7 @@
private void CategoryChanged(ChangeEventArgs e) private void CategoryChanged(ChangeEventArgs e)
{ {
_category = (string)e.Value; _category = (string)e.Value;
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList(); _moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Split(',', StringSplitOptions.RemoveEmptyEntries).Contains(_category)).ToList();
_moduleDefinitionName = "-"; _moduleDefinitionName = "-";
_message = ""; _message = "";
} }
@@ -521,7 +521,7 @@
case "Edit": case "Edit":
// get page management moduleid // get page management moduleid
moduleId = int.Parse(PageState.Site.Settings[Constants.PageManagementModule]); moduleId = int.Parse(PageState.Site.Settings[Constants.PageManagementModule]);
NavigationManager.NavigateTo(Utilities.EditUrl(PageState.Alias.Path, "admin/pages", moduleId, "Edit", $"id={PageState.Page.PageId}&returnurl={WebUtility.UrlEncode(PageState.Route.PathAndQuery)}")); NavigationManager.NavigateTo(Utilities.EditUrl(PageState.Alias.Path, "admin/pages", moduleId, location, $"id={PageState.Page.PageId}&returnurl={WebUtility.UrlEncode(PageState.Route.PathAndQuery)}"));
break; break;
case "Copy": case "Copy":
// get page management moduleid // get page management moduleid

View File

@@ -18,7 +18,7 @@
<ApplicationId>com.oqtane.maui</ApplicationId> <ApplicationId>com.oqtane.maui</ApplicationId>
<!-- Versions --> <!-- Versions -->
<ApplicationDisplayVersion>10.1.0</ApplicationDisplayVersion> <ApplicationDisplayVersion>10.1.1</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion> <ApplicationVersion>1</ApplicationVersion>
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged --> <!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->

View File

@@ -2,7 +2,7 @@
<package> <package>
<metadata> <metadata>
<id>Oqtane.Client</id> <id>Oqtane.Client</id>
<version>10.1.0</version> <version>10.1.1</version>
<authors>Shaun Walker</authors> <authors>Shaun Walker</authors>
<owners>.NET Foundation</owners> <owners>.NET Foundation</owners>
<title>Oqtane Framework</title> <title>Oqtane Framework</title>
@@ -12,7 +12,7 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license> <license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl> <projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes> <releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
<readme>readme.md</readme> <readme>readme.md</readme>
<icon>icon.png</icon> <icon>icon.png</icon>
<tags>oqtane</tags> <tags>oqtane</tags>
@@ -23,7 +23,7 @@
<dependency id="Microsoft.AspNetCore.Components.WebAssembly.Authentication" version="10.0.3" exclude="Build,Analyzers" /> <dependency id="Microsoft.AspNetCore.Components.WebAssembly.Authentication" version="10.0.3" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Localization" version="10.0.3" exclude="Build,Analyzers" /> <dependency id="Microsoft.Extensions.Localization" version="10.0.3" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Http" version="10.0.3" exclude="Build,Analyzers" /> <dependency id="Microsoft.Extensions.Http" version="10.0.3" exclude="Build,Analyzers" />
<dependency id="Radzen.Blazor" version="9.0.0" exclude="Build,Analyzers" /> <dependency id="Radzen.Blazor" version="9.0.8" exclude="Build,Analyzers" />
</group> </group>
</dependencies> </dependencies>
</metadata> </metadata>

View File

@@ -2,7 +2,7 @@
<package> <package>
<metadata> <metadata>
<id>Oqtane.Framework</id> <id>Oqtane.Framework</id>
<version>10.1.0</version> <version>10.1.1</version>
<authors>Shaun Walker</authors> <authors>Shaun Walker</authors>
<owners>.NET Foundation</owners> <owners>.NET Foundation</owners>
<title>Oqtane Framework</title> <title>Oqtane Framework</title>
@@ -11,8 +11,8 @@
<copyright>.NET Foundation</copyright> <copyright>.NET Foundation</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license> <license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v10.1.0/Oqtane.Framework.10.1.0.Upgrade.zip</projectUrl> <projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v10.1.1/Oqtane.Framework.10.1.1.Upgrade.zip</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes> <releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
<readme>readme.md</readme> <readme>readme.md</readme>
<icon>icon.png</icon> <icon>icon.png</icon>
<tags>oqtane framework</tags> <tags>oqtane framework</tags>

View File

@@ -2,7 +2,7 @@
<package> <package>
<metadata> <metadata>
<id>Oqtane.Server</id> <id>Oqtane.Server</id>
<version>10.1.0</version> <version>10.1.1</version>
<authors>Shaun Walker</authors> <authors>Shaun Walker</authors>
<owners>.NET Foundation</owners> <owners>.NET Foundation</owners>
<title>Oqtane Framework</title> <title>Oqtane Framework</title>
@@ -12,7 +12,7 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license> <license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl> <projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes> <releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
<readme>readme.md</readme> <readme>readme.md</readme>
<icon>icon.png</icon> <icon>icon.png</icon>
<tags>oqtane</tags> <tags>oqtane</tags>
@@ -26,8 +26,8 @@
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="10.0.3" exclude="Build,Analyzers" /> <dependency id="Microsoft.EntityFrameworkCore.Relational" version="10.0.3" exclude="Build,Analyzers" />
<dependency id="SixLabors.ImageSharp" version="3.1.12" exclude="Build,Analyzers" /> <dependency id="SixLabors.ImageSharp" version="3.1.12" exclude="Build,Analyzers" />
<dependency id="HtmlAgilityPack" version="1.12.4" exclude="Build,Analyzers" /> <dependency id="HtmlAgilityPack" version="1.12.4" exclude="Build,Analyzers" />
<dependency id="Swashbuckle.AspNetCore" version="10.1.2" exclude="Build,Analyzers" /> <dependency id="Swashbuckle.AspNetCore" version="10.1.4" exclude="Build,Analyzers" />
<dependency id="MailKit" version="4.14.1" exclude="Build,Analyzers" /> <dependency id="MailKit" version="4.15.1" exclude="Build,Analyzers" />
<dependency id="MySql.Data" version="9.6.0" exclude="Build,Analyzers" /> <dependency id="MySql.Data" version="9.6.0" exclude="Build,Analyzers" />
<dependency id="MySql.EntityFrameworkCore" version="10.0.1" exclude="Build,Analyzers" /> <dependency id="MySql.EntityFrameworkCore" version="10.0.1" exclude="Build,Analyzers" />
<dependency id="EFCore.NamingConventions" version="10.0.1" exclude="Build,Analyzers" /> <dependency id="EFCore.NamingConventions" version="10.0.1" exclude="Build,Analyzers" />

View File

@@ -2,7 +2,7 @@
<package> <package>
<metadata> <metadata>
<id>Oqtane.Shared</id> <id>Oqtane.Shared</id>
<version>10.1.0</version> <version>10.1.1</version>
<authors>Shaun Walker</authors> <authors>Shaun Walker</authors>
<owners>.NET Foundation</owners> <owners>.NET Foundation</owners>
<title>Oqtane Framework</title> <title>Oqtane Framework</title>
@@ -12,7 +12,7 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license> <license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl> <projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes> <releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
<readme>readme.md</readme> <readme>readme.md</readme>
<icon>icon.png</icon> <icon>icon.png</icon>
<tags>oqtane</tags> <tags>oqtane</tags>
@@ -20,7 +20,7 @@
<group targetFramework="net10.0"> <group targetFramework="net10.0">
<dependency id="Microsoft.EntityFrameworkCore" version="10.0.3" exclude="Build,Analyzers" /> <dependency id="Microsoft.EntityFrameworkCore" version="10.0.3" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.DependencyInjection.Abstractions" version="10.0.3" exclude="Build,Analyzers" /> <dependency id="Microsoft.Extensions.DependencyInjection.Abstractions" version="10.0.3" exclude="Build,Analyzers" />
<dependency id="NodaTime" version="3.3.0" exclude="Build,Analyzers" /> <dependency id="NodaTime" version="3.3.1" exclude="Build,Analyzers" />
</group> </group>
</dependencies> </dependencies>
</metadata> </metadata>

View File

@@ -2,7 +2,7 @@
<package> <package>
<metadata> <metadata>
<id>Oqtane.Updater</id> <id>Oqtane.Updater</id>
<version>10.1.0</version> <version>10.1.1</version>
<authors>Shaun Walker</authors> <authors>Shaun Walker</authors>
<owners>.NET Foundation</owners> <owners>.NET Foundation</owners>
<title>Oqtane Framework</title> <title>Oqtane Framework</title>
@@ -12,7 +12,7 @@
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license> <license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl> <projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0</releaseNotes> <releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1</releaseNotes>
<readme>readme.md</readme> <readme>readme.md</readme>
<icon>icon.png</icon> <icon>icon.png</icon>
<tags>oqtane</tags> <tags>oqtane</tags>

View File

@@ -1 +1 @@
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.0.Install.zip" -Force Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.1.Install.zip" -Force

View File

@@ -1 +1 @@
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.0.Upgrade.zip" -Force Compress-Archive -Path "..\Oqtane.Server\bin\Release\net10.0\publish\*" -DestinationPath "Oqtane.Framework.10.1.1.Upgrade.zip" -Force

View File

@@ -266,6 +266,28 @@
private void HandlePageNotFound(Site site, Page page, Route route) private void HandlePageNotFound(Site site, Page page, Route route)
{ {
// filter
string useragent = (Context.Request.Headers[HeaderNames.UserAgent] != StringValues.Empty) ? Context.Request.Headers[HeaderNames.UserAgent] : "(none)";
var settings = Context.GetSiteSettings();
var filter = settings.GetValue("VisitorFilter", Constants.DefaultVisitorFilter);
foreach (string term in filter.ToLower().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray())
{
if (_remoteIPAddress.ToLower().Contains(term) || useragent.ToLower().Contains(term))
{
// handle not found request in static mode
if (_renderMode == RenderModes.Static)
{
NavigationManager.NotFound();
}
else
{
// redirect to 404 page
NavigationManager.NavigateTo(route.SiteUrl + "/404", true);
}
return;
}
}
// referrer will only be set if the link originated externally // referrer will only be set if the link originated externally
string referrer = (Context.Request.Headers[HeaderNames.Referer] != StringValues.Empty) ? Context.Request.Headers[HeaderNames.Referer] : ""; string referrer = (Context.Request.Headers[HeaderNames.Referer] != StringValues.Empty) ? Context.Request.Headers[HeaderNames.Referer] : "";
@@ -564,23 +586,6 @@
} }
} }
private void SetLocalizationCookie(string cookieValue)
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions
{
Expires = DateTimeOffset.UtcNow.AddYears(1),
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax, // Set SameSite attribute
Secure = true, // Ensure the cookie is only sent over HTTPS
HttpOnly = false // cookie is updated using JS Interop in Interactive render mode
};
Context.Response.Cookies.Append(
Shared.CookieRequestCultureProvider.DefaultCookieName,
cookieValue,
cookieOptions
);
}
private async Task<List<Resource>> GetPageResources(Alias alias, Site site, Page page, List<Module> modules, int moduleid, string action) private async Task<List<Resource>> GetPageResources(Alias alias, Site site, Page page, List<Module> modules, int moduleid, string action)
{ {
var resources = new List<Resource>(); var resources = new List<Resource>();
@@ -852,4 +857,21 @@
SetLocalizationCookie(cultureCookie); SetLocalizationCookie(cultureCookie);
} }
} }
private void SetLocalizationCookie(string cookieValue)
{
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions
{
Expires = DateTimeOffset.UtcNow.AddYears(1),
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax, // Set SameSite attribute
Secure = true, // Ensure the cookie is only sent over HTTPS
HttpOnly = false // cookie is updated using JS Interop in Interactive render mode
};
Context.Response.Cookies.Append(
Shared.CookieRequestCultureProvider.DefaultCookieName,
cookieValue,
cookieOptions
);
}
} }

View File

@@ -264,7 +264,7 @@ namespace Oqtane.Controllers
_userPermissions.IsAuthorized(User, module.SiteId, EntityNames.Folder, folderid, PermissionNames.Edit) && !string.IsNullOrEmpty(filename)) _userPermissions.IsAuthorized(User, module.SiteId, EntityNames.Folder, folderid, PermissionNames.Edit) && !string.IsNullOrEmpty(filename))
{ {
// get content // get content
var content = _modules.ExportModule(moduleid); var content = _modules.ExportModule(module, "Export Module");
// get folder // get folder
var folder = _folders.GetFolder(folderid, false); var folder = _folders.GetFolder(folderid, false);
@@ -317,7 +317,7 @@ namespace Oqtane.Controllers
var module = _modules.GetModule(moduleid); var module = _modules.GetModule(moduleid);
if (ModelState.IsValid && module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, module.SiteId, EntityNames.Page, pageid, PermissionNames.Edit)) if (ModelState.IsValid && module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, module.SiteId, EntityNames.Page, pageid, PermissionNames.Edit))
{ {
success = _modules.ImportModule(moduleid, content); success = _modules.ImportModule(module, content, "Import Module");
if (success) if (success)
{ {
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Module Content Imported {ModuleId}", moduleid); _logger.Log(LogLevel.Information, this, LogFunction.Update, "Module Content Imported {ModuleId}", moduleid);

View File

@@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Security;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Oqtane.Enums; using Oqtane.Enums;
@@ -239,10 +238,11 @@ namespace Oqtane.Controllers
}; };
module = _modules.AddModule(module); module = _modules.AddModule(module);
string content = _modules.ExportModule(pm.ModuleId); // deep copy module content (includes settings)
string content = _modules.ExportModule(pm.Module, "Copy Page");
if (content != "") if (content != "")
{ {
_modules.ImportModule(module.ModuleId, content); _modules.ImportModule(module, content, "Copy Page");
} }
PageModule pagemodule = new PageModule(); PageModule pagemodule = new PageModule();
@@ -509,6 +509,20 @@ namespace Oqtane.Controllers
var toPage = _pages.GetPage(toPageId); var toPage = _pages.GetPage(toPageId);
if (toPage != null && toPage.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, toPage.PermissionList)) if (toPage != null && toPage.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, toPage.PermissionList))
{ {
// copy page settings
var settings = _settings.GetSettings(EntityNames.Page, fromPage.PageId).ToList();
foreach (var setting in settings)
{
_settings.AddSetting(new Setting
{
EntityName = setting.EntityName,
EntityId = toPage.PageId,
SettingName = setting.SettingName,
SettingValue = setting.SettingValue,
IsPrivate = setting.IsPrivate
});
}
// copy modules // copy modules
List<PageModule> pageModules = _pageModules.GetPageModules(fromPage.SiteId).ToList(); List<PageModule> pageModules = _pageModules.GetPageModules(fromPage.SiteId).ToList();
foreach (PageModule pm in pageModules.Where(item => item.PageId == fromPage.PageId && !item.Module.AllPages && !item.IsDeleted)) foreach (PageModule pm in pageModules.Where(item => item.PageId == fromPage.PageId && !item.Module.AllPages && !item.IsDeleted))
@@ -544,10 +558,12 @@ namespace Oqtane.Controllers
}).ToList(); }).ToList();
module = _modules.AddModule(module); module = _modules.AddModule(module);
string content = _modules.ExportModule(pm.ModuleId);
// deep copy module content (includes settings)
string content = _modules.ExportModule(pm.Module, "Copy Page");
if (content != "") if (content != "")
{ {
_modules.ImportModule(module.ModuleId, content); _modules.ImportModule(module, content, "Copy Page");
} }
} }
else else

View File

@@ -617,7 +617,11 @@ namespace Oqtane.Infrastructure
private string SynchronizeModules(IServiceProvider provider, ISettingRepository settingRepository, IPageModuleRepository pageModuleRepository, IModuleRepository moduleRepository, SiteGroupMember siteGroupMember, List<PageModule> primaryPageModules, List<PageModule> secondaryPageModules, Page primaryPage, Page secondaryPage, int secondarySiteId) private string SynchronizeModules(IServiceProvider provider, ISettingRepository settingRepository, IPageModuleRepository pageModuleRepository, IModuleRepository moduleRepository, SiteGroupMember siteGroupMember, List<PageModule> primaryPageModules, List<PageModule> secondaryPageModules, Page primaryPage, Page secondaryPage, int secondarySiteId)
{ {
var log = ""; var log = "";
var removePageModules = secondaryPageModules.Where(item => item.PageId == secondaryPage.PageId).ToList(); var removePageModules = new List<PageModule>();
if (secondaryPage != null)
{
removePageModules = secondaryPageModules.Where(item => item.PageId == secondaryPage.PageId).ToList();
}
// iterate through primary modules on primary page // iterate through primary modules on primary page
foreach (var primaryPageModule in primaryPageModules.Where(item => item.PageId == primaryPage.PageId)) foreach (var primaryPageModule in primaryPageModules.Where(item => item.PageId == primaryPage.PageId))

View File

@@ -4,7 +4,6 @@ using System.Net;
using System.Text.Json; using System.Text.Json;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Modules;
using Oqtane.Repository; using Oqtane.Repository;
using Oqtane.Shared; using Oqtane.Shared;
@@ -20,7 +19,9 @@ namespace Oqtane.Infrastructure
var siteRepository = provider.GetRequiredService<ISiteRepository>(); var siteRepository = provider.GetRequiredService<ISiteRepository>();
var pageRepository = provider.GetRequiredService<IPageRepository>(); var pageRepository = provider.GetRequiredService<IPageRepository>();
var pageModuleRepository = provider.GetRequiredService<IPageModuleRepository>(); var pageModuleRepository = provider.GetRequiredService<IPageModuleRepository>();
var TenantManager = provider.GetRequiredService<ITenantManager>(); var moduleRepository = provider.GetRequiredService<IModuleRepository>();
var settingRepository = provider.GetRequiredService<ISettingRepository>();
var tenantManager = provider.GetRequiredService<ITenantManager>();
var syncManager = provider.GetRequiredService<ISyncManager>(); var syncManager = provider.GetRequiredService<ISyncManager>();
if (!string.IsNullOrEmpty(parameters)) if (!string.IsNullOrEmpty(parameters))
@@ -59,6 +60,14 @@ namespace Oqtane.Infrastructure
log += $"Site Updated<br />"; log += $"Site Updated<br />";
refresh = true; refresh = true;
} }
if (globalReplace.Site)
{
if (UpdateSettings(settingRepository, EntityNames.Site, site.SiteId, find, replace, comparisonType))
{
log += $"Site Settings Updated<br />";
refresh = true;
}
}
var pages = pageRepository.GetPages(site.SiteId).ToList(); var pages = pageRepository.GetPages(site.SiteId).ToList();
var pageModules = pageModuleRepository.GetPageModules(site.SiteId).ToList(); var pageModules = pageModuleRepository.GetPageModules(site.SiteId).ToList();
@@ -94,6 +103,14 @@ namespace Oqtane.Infrastructure
log += $"Page Updated: /{page.Path}<br />"; log += $"Page Updated: /{page.Path}<br />";
refresh = true; refresh = true;
} }
if (globalReplace.Pages)
{
if (UpdateSettings(settingRepository, EntityNames.Page, page.PageId, find, replace, comparisonType))
{
log += $"Page Settings Updated<br />";
refresh = true;
}
}
foreach (var pageModule in pageModules.Where(item => item.PageId == page.PageId)) foreach (var pageModule in pageModules.Where(item => item.PageId == page.PageId))
{ {
@@ -120,28 +137,24 @@ namespace Oqtane.Infrastructure
log += $"Module Updated: {pageModule.Title} Page: /{page.Path}<br />"; log += $"Module Updated: {pageModule.Title} Page: /{page.Path}<br />";
refresh = true; refresh = true;
} }
if (globalReplace.Modules)
{
if (UpdateSettings(settingRepository, EntityNames.Module, pageModule.ModuleId, find, replace, comparisonType))
{
log += $"Module Settings Updated<br />";
refresh = true;
}
}
// module content // module content
if (pageModule.Module.ModuleDefinition != null && pageModule.Module.ModuleDefinition.ServerManagerType != "") if (globalReplace.Content)
{ {
Type moduleType = Type.GetType(pageModule.Module.ModuleDefinition.ServerManagerType); var content = moduleRepository.ExportModule(pageModule.Module, "Global Replace");
if (moduleType != null && moduleType.GetInterface(nameof(IPortable)) != null) if (!string.IsNullOrEmpty(content) && content.Contains(WebUtility.HtmlEncode(find), comparisonType))
{ {
try content = content.Replace(WebUtility.HtmlEncode(find), WebUtility.HtmlEncode(replace), comparisonType);
{ moduleRepository.ImportModule(pageModule.Module, content, "Global Replace");
var moduleObject = ActivatorUtilities.CreateInstance(provider, moduleType); log += $"Module Content Updated: {pageModule.Title} Page: /{page.Path}<br />";
var moduleContent = ((IPortable)moduleObject).ExportModule(pageModule.Module);
if (!string.IsNullOrEmpty(moduleContent) && moduleContent.Contains(WebUtility.HtmlEncode(find), comparisonType) && globalReplace.Content)
{
moduleContent = moduleContent.Replace(WebUtility.HtmlEncode(find), WebUtility.HtmlEncode(replace), comparisonType);
((IPortable)moduleObject).ImportModule(pageModule.Module, moduleContent, pageModule.Module.ModuleDefinition.Version);
log += $"Module Content Updated: {pageModule.Title} Page: /{page.Path}<br />";
}
}
catch (Exception ex)
{
log += $"Error Processing Module {pageModule.Module.ModuleDefinition.Name} - {ex.Message}<br />";
}
} }
} }
} }
@@ -150,7 +163,7 @@ namespace Oqtane.Infrastructure
if (refresh) if (refresh)
{ {
// clear cache // clear cache
syncManager.AddSyncEvent(TenantManager.GetAlias(), EntityNames.Site, site.SiteId, SyncEventActions.Refresh); syncManager.AddSyncEvent(tenantManager.GetAlias(), EntityNames.Site, site.SiteId, SyncEventActions.Refresh);
} }
} }
else else
@@ -160,5 +173,21 @@ namespace Oqtane.Infrastructure
return log; return log;
} }
private bool UpdateSettings(ISettingRepository settingRepository, string entityName, int entityId, string find, string replace, StringComparison comparisonType)
{
var changed = false;
var settings = settingRepository.GetSettings(entityName, entityId).ToList();
foreach (var setting in settings)
{
if (setting.SettingValue != null && setting.SettingValue.Contains(find, comparisonType))
{
setting.SettingValue = setting.SettingValue.Replace(find, replace, comparisonType);
settingRepository.UpdateSetting(setting);
changed = true;
}
}
return changed;
}
} }
} }

View File

@@ -34,8 +34,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" /> <PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.2" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.4" />
<PackageReference Include="MailKit" Version="4.14.1" /> <PackageReference Include="MailKit" Version="4.15.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -48,7 +48,7 @@ namespace Oqtane.Pages
public IActionResult OnGet(string path) public IActionResult OnGet(string path)
{ {
if (string.IsNullOrWhiteSpace(path)) if (string.IsNullOrWhiteSpace(path) || _alias == null)
{ {
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return BrokenFile(); return BrokenFile();

View File

@@ -448,11 +448,20 @@ namespace Oqtane.Repository
var route = routeAttributes.First().Template; var route = routeAttributes.First().Template;
if (!string.IsNullOrEmpty(route)) if (!string.IsNullOrEmpty(route))
{ {
// @page "/route" (note that nested routes are not permitted) // @page "/path" or @page "alias/path" (note that nested paths are not permitted)
var pageTemplate = new PageTemplate(); var pageTemplate = new PageTemplate();
pageTemplate.AliasName = "*"; if (route.StartsWith("/"))
{
pageTemplate.AliasName = "*"; // all sites
pageTemplate.Path = route.Substring(1);
}
else // route contains an alias name
{
var lastSlash = route.LastIndexOf('/');
pageTemplate.AliasName = route.Substring(0, lastSlash);
pageTemplate.Path = route.Substring(lastSlash + 1);
}
pageTemplate.Version = "*"; pageTemplate.Version = "*";
pageTemplate.Path = route.Substring(1);
pageTemplate.Update = false; pageTemplate.Update = false;
pageTemplate.PageTemplateModules = new List<PageTemplateModule>(); pageTemplate.PageTemplateModules = new List<PageTemplateModule>();

View File

@@ -20,7 +20,9 @@ namespace Oqtane.Repository
Module GetModule(int moduleId, bool tracking); Module GetModule(int moduleId, bool tracking);
void DeleteModule(int moduleId); void DeleteModule(int moduleId);
string ExportModule(int moduleId); string ExportModule(int moduleId);
string ExportModule(Module module, string IPortableContext);
bool ImportModule(int moduleId, string content); bool ImportModule(int moduleId, string content);
bool ImportModule(Module module, string content, string IPortableContext);
} }
public class ModuleRepository : IModuleRepository public class ModuleRepository : IModuleRepository
@@ -99,18 +101,23 @@ namespace Oqtane.Repository
} }
public string ExportModule(int moduleId) public string ExportModule(int moduleId)
{
Module module = GetModule(moduleId);
return ExportModule(module, "Export Module");
}
public string ExportModule(Module module, string IPortableContext)
{ {
string content = ""; string content = "";
try try
{ {
Module module = GetModule(moduleId);
if (module != null) if (module != null)
{ {
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList(); List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
ModuleDefinition moduledefinition = moduledefinitions.FirstOrDefault(item => item.ModuleDefinitionName == module.ModuleDefinitionName); ModuleDefinition moduledefinition = moduledefinitions.FirstOrDefault(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
if (moduledefinition != null) if (moduledefinition != null)
{ {
var settings = _settings.GetSettings(EntityNames.Module, moduleId); var settings = _settings.GetSettings(EntityNames.Module, module.ModuleId);
ModuleContent modulecontent = new ModuleContent(); ModuleContent modulecontent = new ModuleContent();
modulecontent.ModuleDefinitionName = moduledefinition.ModuleDefinitionName; modulecontent.ModuleDefinitionName = moduledefinition.ModuleDefinitionName;
@@ -125,6 +132,7 @@ namespace Oqtane.Repository
{ {
try try
{ {
module.IPortableContext = IPortableContext;
module.Settings = settings.ToDictionary(x => x.SettingName, x => x.SettingValue); module.Settings = settings.ToDictionary(x => x.SettingName, x => x.SettingValue);
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype); var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
modulecontent.Content = ((IPortable)moduleobject).ExportModule(module); modulecontent.Content = ((IPortable)moduleobject).ExportModule(module);
@@ -149,30 +157,46 @@ namespace Oqtane.Repository
} }
public bool ImportModule(int moduleId, string content) public bool ImportModule(int moduleId, string content)
{
Module module = GetModule(moduleId);
return ImportModule(module, content, "Import Module");
}
public bool ImportModule(Module module, string content, string IPortableContext)
{ {
bool success = false; bool success = false;
try try
{ {
Module module = GetModule(moduleId);
if (module != null) if (module != null)
{ {
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList(); List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault(); ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault();
if (moduledefinition != null) if (moduledefinition != null)
{ {
ModuleContent modulecontent = JsonSerializer.Deserialize<ModuleContent>(content.Replace("\n", "")); var modulecontent = new ModuleContent();
if (content.StartsWith("{") && content.EndsWith("}"))
{
// content was exported as a serialized ModuleContent object
modulecontent = JsonSerializer.Deserialize<ModuleContent>(content.Replace("\n", ""));
}
else
{
// raw content
modulecontent.ModuleDefinitionName = moduledefinition.ModuleDefinitionName;
modulecontent.Version = moduledefinition.Version;
modulecontent.Content = content;
}
if (modulecontent.ModuleDefinitionName == moduledefinition.ModuleDefinitionName) if (modulecontent.ModuleDefinitionName == moduledefinition.ModuleDefinitionName)
{ {
var settings = _settings.GetSettings(EntityNames.Module, moduleId);
if (modulecontent.Settings != null) if (modulecontent.Settings != null)
{ {
var settings = _settings.GetSettings(EntityNames.Module, module.ModuleId);
foreach (var kvp in modulecontent.Settings) foreach (var kvp in modulecontent.Settings)
{ {
var setting = settings.FirstOrDefault(item => item.SettingName == kvp.Key); var setting = settings.FirstOrDefault(item => item.SettingName == kvp.Key);
if (setting == null) if (setting == null)
{ {
setting = new Setting { EntityName = EntityNames.Module, EntityId = moduleId, SettingName = kvp.Key, SettingValue = kvp.Value, IsPrivate = false }; setting = new Setting { EntityName = EntityNames.Module, EntityId = module.ModuleId, SettingName = kvp.Key, SettingValue = kvp.Value, IsPrivate = false };
_settings.AddSetting(setting); _settings.AddSetting(setting);
} }
else else
@@ -193,7 +217,8 @@ namespace Oqtane.Repository
{ {
try try
{ {
module.Settings = _settings.GetSettings(EntityNames.Module, moduleId).ToDictionary(x => x.SettingName, x => x.SettingValue); module.IPortableContext = IPortableContext;
module.Settings = _settings.GetSettings(EntityNames.Module, module.ModuleId).ToDictionary(x => x.SettingName, x => x.SettingValue);
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype); var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
((IPortable)moduleobject).ImportModule(module, modulecontent.Content, modulecontent.Version); ((IPortable)moduleobject).ImportModule(module, modulecontent.Content, modulecontent.Version);
success = true; success = true;

View File

@@ -1,14 +1,9 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Oqtane.Enums;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Modules.Admin.Users;
using Oqtane.Shared; using Oqtane.Shared;
namespace Oqtane.Repository namespace Oqtane.Repository

View File

@@ -51,6 +51,7 @@ namespace Oqtane.Repository
{ {
using var db = _dbContextFactory.CreateDbContext(); using var db = _dbContextFactory.CreateDbContext();
db.Entry(siteGroupMember).State = EntityState.Modified; db.Entry(siteGroupMember).State = EntityState.Modified;
db.Entry(siteGroupMember.SiteGroup).State = EntityState.Unchanged; // prevent update of linked entity
db.SaveChanges(); db.SaveChanges();
return siteGroupMember; return siteGroupMember;
} }

View File

@@ -532,27 +532,14 @@ namespace Oqtane.Repository
_logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Processing Page Module {PageModule}", pageModule); _logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Processing Page Module {PageModule}", pageModule);
} }
} }
if (!string.IsNullOrEmpty(pageTemplateModule.Content))
if (pageTemplateModule.Content != "" && moduleDefinition.ServerManagerType != "")
{ {
Type moduletype = Type.GetType(moduleDefinition.ServerManagerType); var module = _moduleRepository.GetModule(pageModule.ModuleId);
if (moduletype != null && moduletype.GetInterface(nameof(IPortable)) != null) if (!_moduleRepository.ImportModule(module, pageTemplateModule.Content, "Site Template"))
{ {
try if (alias != null)
{ {
var module = _moduleRepository.GetModule(pageModule.ModuleId); _logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, "Error Importing Content For {ModuleDefinitionName}", pageTemplateModule.ModuleDefinitionName);
if (module != null)
{
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
((IPortable)moduleobject).ImportModule(module, pageTemplateModule.Content, moduleDefinition.Version);
}
}
catch (Exception ex)
{
if (alias != null)
{
_logger.Log(LogLevel.Error, "Site Template", LogFunction.Other, ex, "Error Importing Content For {ModuleDefinitionName}", pageTemplateModule.ModuleDefinitionName);
}
} }
} }
} }

View File

@@ -39,6 +39,12 @@ namespace Oqtane.Models
[NotMapped] [NotMapped]
public bool IsShared { get; set; } public bool IsShared { get; set; }
/// <summary>
/// Specifies the scenario where the IPortable interface is being invoked
/// </summary>
[NotMapped]
public string IPortableContext { get; set; }
/// <summary> /// <summary>
/// Reference to the <see cref="ModuleDefinition"/> used for this module. /// Reference to the <see cref="ModuleDefinition"/> used for this module.
/// </summary> /// </summary>

View File

@@ -7,7 +7,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
<PackageReference Include="NodaTime" Version="3.3.0" /> <PackageReference Include="NodaTime" Version="3.3.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -4,8 +4,8 @@ namespace Oqtane.Shared
{ {
public class Constants public class Constants
{ {
public static readonly string Version = "10.1.0"; public static readonly string Version = "10.1.1";
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4,6.0.0,6.0.1,6.1.0,6.1.1,6.1.2,6.1.3,6.1.4,6.1.5,6.2.0,6.2.1,10.0.0,10.0.1,10.0.2,10.0.3,10.0.4,10.1.0"; public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4,6.0.0,6.0.1,6.1.0,6.1.1,6.1.2,6.1.3,6.1.4,6.1.5,6.2.0,6.2.1,10.0.0,10.0.1,10.0.2,10.0.3,10.0.4,10.1.0,10.1.1";
public const string PackageId = "Oqtane.Framework"; public const string PackageId = "Oqtane.Framework";
public const string ClientId = "Oqtane.Client"; public const string ClientId = "Oqtane.Client";
public const string UpdaterPackageId = "Oqtane.Updater"; public const string UpdaterPackageId = "Oqtane.Updater";

View File

@@ -12,7 +12,7 @@ Oqtane is being developed based on some fundamental principles which are outline
# Latest Release # Latest Release
[10.1.0](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0) was released on February 25, 2026 and is a maintenance release including 72 pull requests by 6 different contributors, pushing the total number of project commits all-time over 7600. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers. [10.1.1](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1) was released on March 6, 2026 and is a maintenance release including 21 pull requests by 2 different contributors, pushing the total number of project commits all-time over 7700. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
# Try It Now! # Try It Now!
@@ -111,6 +111,9 @@ Connect with other developers, get support, and share ideas by joining the Oqtan
# Roadmap # Roadmap
This project is open source, and therefore is a work in progress... This project is open source, and therefore is a work in progress...
[10.1.1](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.1) (Mar 6, 2026)
- [x] Stabilization improvements
[10.1.0](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0) (Feb 25, 2026) [10.1.0](https://github.com/oqtane/oqtane.framework/releases/tag/v10.1.0) (Feb 25, 2026)
- [x] Site Groups, Content Synchronization, Content Localization - [x] Site Groups, Content Synchronization, Content Localization
- [x] Global Replace - [x] Global Replace

View File

@@ -220,7 +220,7 @@
"apiVersion": "2024-04-01", "apiVersion": "2024-04-01",
"name": "[concat(parameters('BlazorWebsiteName'), '/ZipDeploy')]", "name": "[concat(parameters('BlazorWebsiteName'), '/ZipDeploy')]",
"properties": { "properties": {
"packageUri": "https://github.com/oqtane/oqtane.framework/releases/download/v10.1.0/Oqtane.Framework.10.1.0.Install.zip" "packageUri": "https://github.com/oqtane/oqtane.framework/releases/download/v10.1.1/Oqtane.Framework.10.1.1.Install.zip"
}, },
"dependsOn": [ "dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('BlazorWebsiteName'))]" "[resourceId('Microsoft.Web/sites', parameters('BlazorWebsiteName'))]"