-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Content Types: Introduce schema service to support future schema generation #21031
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
lauraneto
merged 7 commits into
main
from
v17/feature/introduce-content-type-schema-service
Dec 15, 2025
Merged
Changes from 2 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
f18182e
Introduce new content type schema service and models
lauraneto d951c2b
Merge branch 'main' into v17/feature/introduce-content-type-schema-se…
lauraneto 93dc897
Do not fail when content type is not in cache, simply ignore
lauraneto 66173f4
Added unit and integration tests
lauraneto 217487c
Fix failing unit tests
lauraneto b5d9ebd
Addressing comments from code review
lauraneto a73d41a
Merge branch 'main' into v17/feature/introduce-content-type-schema-se…
lauraneto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| namespace Umbraco.Cms.Core.Models; | ||
|
|
||
| /// <summary> | ||
| /// Represents the subset of content type property information that is needed for schema generation. | ||
| /// </summary> | ||
| public class ContentTypePropertySchemaInfo | ||
| { | ||
| /// <summary> | ||
| /// Gets the property alias. | ||
| /// </summary> | ||
| public required string Alias { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Gets the property editor alias. | ||
| /// </summary> | ||
| public required string EditorAlias { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Gets the CLR type used to represent this property in the Delivery API. | ||
| /// </summary> | ||
| public required Type DeliveryApiClrType { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Gets a value indicating whether this property is inherited from a composition. | ||
| /// </summary> | ||
| public bool Inherited { get; init; } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| namespace Umbraco.Cms.Core.Models; | ||
|
|
||
| /// <summary> | ||
| /// Represents the subset of content type information that is needed for schema generation. | ||
| /// </summary> | ||
| public class ContentTypeSchemaInfo | ||
| { | ||
| /// <summary> | ||
| /// Gets the content type alias. | ||
| /// </summary> | ||
| public required string Alias { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Gets the content type schema ID. | ||
| /// </summary> | ||
| public required string SchemaId { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Gets the schema IDs of the content type's compositions. | ||
| /// </summary> | ||
| public required IReadOnlyList<string> CompositionSchemaIds { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Gets the properties for this content type. | ||
| /// </summary> | ||
| public required IReadOnlyList<ContentTypePropertySchemaInfo> Properties { get; init; } | ||
|
|
||
| /// <summary> | ||
| /// Gets a value indicating whether the content type is an element type. | ||
| /// </summary> | ||
| public bool IsElement { get; init; } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| using Umbraco.Cms.Core.Models; | ||
| using Umbraco.Cms.Core.Models.PublishedContent; | ||
| using Umbraco.Cms.Core.PublishedCache; | ||
| using Umbraco.Cms.Core.Strings; | ||
| using Umbraco.Extensions; | ||
|
|
||
| namespace Umbraco.Cms.Core.Services; | ||
|
|
||
| /// <inheritdoc /> | ||
| internal sealed class ContentTypeSchemaService : IContentTypeSchemaService | ||
| { | ||
| private readonly IContentTypeService _contentTypeService; | ||
| private readonly IMediaTypeService _mediaTypeService; | ||
| private readonly IPublishedContentTypeCache _publishedContentTypeCache; | ||
| private readonly IShortStringHelper _shortStringHelper; | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="ContentTypeSchemaService"/> class. | ||
| /// </summary> | ||
| public ContentTypeSchemaService( | ||
| IContentTypeService contentTypeService, | ||
| IMediaTypeService mediaTypeService, | ||
| IPublishedContentTypeCache publishedContentTypeCache, | ||
| IShortStringHelper shortStringHelper) | ||
| { | ||
| _contentTypeService = contentTypeService; | ||
| _mediaTypeService = mediaTypeService; | ||
| _publishedContentTypeCache = publishedContentTypeCache; | ||
| _shortStringHelper = shortStringHelper; | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public IReadOnlyCollection<ContentTypeSchemaInfo> GetDocumentTypes() | ||
| => GetContentTypeSchemaInfos(PublishedItemType.Content, _contentTypeService.GetAll()); | ||
|
|
||
| /// <inheritdoc/> | ||
| public IReadOnlyCollection<ContentTypeSchemaInfo> GetMediaTypes() | ||
| => GetContentTypeSchemaInfos(PublishedItemType.Media, _mediaTypeService.GetAll()); | ||
|
lauraneto marked this conversation as resolved.
|
||
|
|
||
| private List<ContentTypeSchemaInfo> GetContentTypeSchemaInfos( | ||
| PublishedItemType itemType, | ||
| IEnumerable<IContentTypeComposition> contentTypes) | ||
| { | ||
| List<ContentTypeSchemaInfo> result = []; | ||
|
|
||
| foreach (IContentTypeComposition contentType in contentTypes) | ||
| { | ||
| IPublishedContentType publishedContentType = _publishedContentTypeCache.Get(itemType, contentType.Alias); | ||
|
lauraneto marked this conversation as resolved.
Outdated
|
||
| HashSet<string> ownPropertyAliases = [.. contentType.PropertyTypes.Select(p => p.Alias)]; | ||
|
|
||
| result.Add( | ||
| new ContentTypeSchemaInfo | ||
| { | ||
| Alias = contentType.Alias, | ||
| SchemaId = GetContentTypeSchemaId(contentType.Alias), | ||
| CompositionSchemaIds = [.. publishedContentType.CompositionAliases.Select(GetContentTypeSchemaId)], | ||
| Properties = | ||
| [ | ||
| .. publishedContentType.PropertyTypes.Select(p => new ContentTypePropertySchemaInfo | ||
| { | ||
| Alias = p.Alias, | ||
| EditorAlias = p.EditorAlias, | ||
| DeliveryApiClrType = p.DeliveryApiModelClrType, | ||
| Inherited = !ownPropertyAliases.Contains(p.Alias), | ||
|
lauraneto marked this conversation as resolved.
Outdated
|
||
| }) | ||
| ], | ||
| IsElement = publishedContentType.IsElement, | ||
| }); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| // Currently uses the same transformation as ModelsBuilder (UmbracoServices.GetClrName) | ||
| private string GetContentTypeSchemaId(string contentTypeAlias) => | ||
| contentTypeAlias.ToCleanString(_shortStringHelper, CleanStringType.ConvertCase | CleanStringType.PascalCase); | ||
| } | ||
|
lauraneto marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| using Umbraco.Cms.Core.Models; | ||
|
|
||
| namespace Umbraco.Cms.Core.Services; | ||
|
|
||
| /// <summary> | ||
| /// Service to get content type schema information for schema generation. | ||
| /// </summary> | ||
| public interface IContentTypeSchemaService | ||
| { | ||
| /// <summary> | ||
| /// Gets all available document types. | ||
| /// </summary> | ||
| /// <returns>A collection of document type schema information.</returns> | ||
| public IReadOnlyCollection<ContentTypeSchemaInfo> GetDocumentTypes(); | ||
|
|
||
| /// <summary> | ||
| /// Gets all available media types. | ||
| /// </summary> | ||
| /// <returns>A collection of media type schema information.</returns> | ||
| public IReadOnlyCollection<ContentTypeSchemaInfo> GetMediaTypes(); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.