From f063348f5dcb0632c0b9746808370db1676a255f Mon Sep 17 00:00:00 2001 From: EngincanV Date: Tue, 26 Aug 2025 10:30:54 +0300 Subject: [PATCH 1/3] Add guide for integrating public and admin CMS Kit packages Added documentation on configuring global layout settings when using both admin and public CMS Kit packages in a unified application. Includes instructions for setting up a _ViewStart.cshtml file to ensure correct layout rendering. --- docs/en/modules/cms-kit/index.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/en/modules/cms-kit/index.md b/docs/en/modules/cms-kit/index.md index 5c30806028..498ad6419b 100644 --- a/docs/en/modules/cms-kit/index.md +++ b/docs/en/modules/cms-kit/index.md @@ -72,6 +72,23 @@ CMS kit packages are designed for various usage scenarios. If you check the [CMS - `Volo.CmsKit.Public.*` packages contain the functionalities used in public websites where users read blog posts or leave comments. - `Volo.CmsKit.*` (without Admin/Public suffix) packages are called as unified packages. Unified packages are shortcuts for adding Admin & Public packages (of the related layer) separately. If you have a single application for administration and public web site, you can use these packages. +## Integrating Public and Admin Packages in a Unified Application + +If you are using a single application for both admin and public web side, it's important to configure the global layout settings appropriately. By default, the layout is set for a **Public Website**, which is suitable for public-facing pages. However, when your application serves both admin and public pages, you should explicitly set the global layout for all CMS Kit pages. + +To do this, add a `_ViewStart.cshtml` file to your web project at `/Pages/Public/CmsKit/_ViewStart.cshtml` and configure the layout as shown below: + +```html +@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@inject IThemeManager ThemeManager +@{ + // default: GetPublicLayout() + Layout = ThemeManager.CurrentTheme.GetApplicationLayout(); +} +``` + +> The `_ViewStart.cshtml` file is used to set the layout for all pages in the `CmsKit` folder. + ## Internals ### Table / collection prefix & schema From 12381fc602e73b2fe94723425fc9f7a97030b8e3 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Tue, 26 Aug 2025 07:33:10 +0000 Subject: [PATCH 2/3] Update docs/en/modules/cms-kit/index.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/en/modules/cms-kit/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/modules/cms-kit/index.md b/docs/en/modules/cms-kit/index.md index 498ad6419b..3744ce3590 100644 --- a/docs/en/modules/cms-kit/index.md +++ b/docs/en/modules/cms-kit/index.md @@ -74,7 +74,7 @@ CMS kit packages are designed for various usage scenarios. If you check the [CMS ## Integrating Public and Admin Packages in a Unified Application -If you are using a single application for both admin and public web side, it's important to configure the global layout settings appropriately. By default, the layout is set for a **Public Website**, which is suitable for public-facing pages. However, when your application serves both admin and public pages, you should explicitly set the global layout for all CMS Kit pages. +If you are using a single application for both admin and public web site, it's important to configure the global layout settings appropriately. By default, the layout is set for a **Public Website**, which is suitable for public-facing pages. However, when your application serves both admin and public pages, you should explicitly set the global layout for all CMS Kit pages. To do this, add a `_ViewStart.cshtml` file to your web project at `/Pages/Public/CmsKit/_ViewStart.cshtml` and configure the layout as shown below: From c4372db9730da97893c4dd16dea4f03b9d703c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 26 Aug 2025 14:22:42 +0300 Subject: [PATCH 3/3] Refactor property conversion logic to TypeHelper Moved the primitive type conversion logic from HasExtraPropertiesExtensions.GetProperty to a new TypeHelper.ChangeTypePrimitiveExtended method. This centralizes and simplifies type conversion, improving code maintainability and reuse. --- .../Volo/Abp/Reflection/TypeHelper.cs | 31 +++++++++++++++++++ .../Abp/Data/HasExtraPropertiesExtensions.cs | 31 ++----------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs index 8a67d20b31..0118fd9874 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs @@ -80,6 +80,37 @@ public static class TypeHelper return false; } + public static TProperty? ChangeTypePrimitiveExtended(object? value) + { + if (value == null) + { + return default; + } + + if (IsPrimitiveExtended(typeof(TProperty), includeEnums: true)) + { + var conversionType = typeof(TProperty); + if (IsNullable(conversionType)) + { + conversionType = conversionType.GetFirstGenericArgumentIfNullable(); + } + + if (conversionType == typeof(Guid)) + { + return (TProperty)TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString()!)!; + } + + if (conversionType.IsEnum) + { + return (TProperty)Enum.Parse(conversionType, value.ToString()!); + } + + return (TProperty)Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture); + } + + throw new AbpException("ChangeTypePrimitiveExtended does not support non-primitive types. Use non-generic GetProperty method and handle type casting manually."); + } + public static bool IsNullable(Type type) { return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs index 75f5672a29..54cdc2bc94 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs @@ -26,34 +26,9 @@ public static class HasExtraPropertiesExtensions public static TProperty? GetProperty(this IHasExtraProperties source, string name, TProperty? defaultValue = default) { - var value = source.GetProperty(name); - if (value == null) - { - return defaultValue; - } - - if (TypeHelper.IsPrimitiveExtended(typeof(TProperty), includeEnums: true)) - { - var conversionType = typeof(TProperty); - if (TypeHelper.IsNullable(conversionType)) - { - conversionType = conversionType.GetFirstGenericArgumentIfNullable(); - } - - if (conversionType == typeof(Guid)) - { - return (TProperty)TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString()!)!; - } - - if (conversionType.IsEnum) - { - return (TProperty)Enum.Parse(conversionType, value.ToString()!); - } - - return (TProperty)Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture); - } - - throw new AbpException("GetProperty does not support non-primitive types. Use non-generic GetProperty method and handle type casting manually."); + return TypeHelper.ChangeTypePrimitiveExtended( + source.GetProperty(name, (object?) defaultValue) + ) ?? defaultValue; } public static TSource SetProperty(