diff --git a/src/OrchardCore.Modules/OrchardCore.Media/GraphQL/MediaFieldQueryObjectType.cs b/src/OrchardCore.Modules/OrchardCore.Media/GraphQL/MediaFieldQueryObjectType.cs index 93981a76b7c..a09243a3c66 100644 --- a/src/OrchardCore.Modules/OrchardCore.Media/GraphQL/MediaFieldQueryObjectType.cs +++ b/src/OrchardCore.Modules/OrchardCore.Media/GraphQL/MediaFieldQueryObjectType.cs @@ -14,46 +14,61 @@ public MediaFieldQueryObjectType() { Name = nameof(MediaField); - Field, IEnumerable>("paths") - .Description("the media paths") - .PagingArguments() - .Resolve(x => - { - if (x.Source?.Paths is null) + if (MediaAppContextSwitches.EnableLegacyMediaFields) + { + Field, IEnumerable>("paths") + .Description("the media paths") + .PagingArguments() + .Resolve(x => { - return Array.Empty(); - } + if (x.Source?.Paths is null) + { + return Array.Empty(); + } - return x.Page(x.Source.Paths); - }); + return x.Page(x.Source.Paths); + }); - Field, IEnumerable>("fileNames") - .Description("the media file names") - .PagingArguments() - .Resolve(x => - { - var fileNames = x.Page(x.Source.GetAttachedFileNames()); - if (fileNames is null) + Field, IEnumerable>("fileNames") + .Description("the media file names") + .PagingArguments() + .Resolve(x => { - return Array.Empty(); - } - return fileNames; - }); + var fileNames = x.Page(x.Source.GetAttachedFileNames()); + if (fileNames is null) + { + return Array.Empty(); + } + return fileNames; + }); + + Field, IEnumerable>("urls") + .Description("the absolute urls of the media items") + .PagingArguments() + .Resolve(x => + { + if (x.Source?.Paths is null) + { + return Array.Empty(); + } + var paths = x.Page(x.Source.Paths); + var mediaFileStore = x.RequestServices.GetService(); - Field, IEnumerable>("urls") - .Description("the absolute urls of the media items") + return paths.Select(p => mediaFileStore.MapPathToPublicUrl(p)); + }); + + Field, IEnumerable>("mediatexts") + .Description("the media texts") .PagingArguments() .Resolve(x => { - if (x.Source?.Paths is null) + if (x.Source?.MediaTexts is null) { return Array.Empty(); } - var paths = x.Page(x.Source.Paths); - var mediaFileStore = x.RequestServices.GetService(); - - return paths.Select(p => mediaFileStore.MapPathToPublicUrl(p)); + return x.Page(x.Source.MediaTexts); }); + } Field, IEnumerable>("files") .Description("the files of the media items") @@ -84,18 +99,6 @@ public MediaFieldQueryObjectType() return items; }); - - Field, IEnumerable>("mediatexts") - .Description("the media texts") - .PagingArguments() - .Resolve(x => - { - if (x.Source?.MediaTexts is null) - { - return Array.Empty(); - } - return x.Page(x.Source.MediaTexts); - }); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Media/MediaAppContextSwitches.cs b/src/OrchardCore.Modules/OrchardCore.Media/MediaAppContextSwitches.cs new file mode 100644 index 00000000000..946537588a5 --- /dev/null +++ b/src/OrchardCore.Modules/OrchardCore.Media/MediaAppContextSwitches.cs @@ -0,0 +1,10 @@ +using System; + +namespace OrchardCore.Media; + +internal static class MediaAppContextSwitches +{ + private const string EnableLegacyMediaFieldGraphQLFieldsKey = "OrchardCore.Media.EnableLegacyMediaFieldGraphQLFields"; + + internal static bool EnableLegacyMediaFields => AppContext.TryGetSwitch(EnableLegacyMediaFieldGraphQLFieldsKey, out var enabled) && enabled; +} diff --git a/src/docs/releases/2.0.0.md b/src/docs/releases/2.0.0.md index 6d9aa8ef531..0f6450aeed3 100644 --- a/src/docs/releases/2.0.0.md +++ b/src/docs/releases/2.0.0.md @@ -342,6 +342,48 @@ You may have to adjust your GraphQL queries in that case. Additionally, the `GetAliases` method in the `IIndexAliasProvider` interface is now asynchronous and has been renamed to `GetAliasesAsync`. Implementations of this interface should be modified by updating the method signature and ensure they handle asynchronous operations correctly. +#### Media fields + +The schema for media fields has been updated. Instead of separate lists for `fileNames`, `urls`, `paths`, and `mediatexts`, these fields are now grouped under a single `files` type to simplify data binding on the front end. + +Please update your existing queries as shown in the following example: + +Before: + +```json +{ + article { + contentItemId + image { + mediatexts(first: 10) + urls(first: 10) + } + } +} +``` + +After: + +```json +{ + article { + contentItemId + image { + files(first: 10) { + mediaText + url + } + } + } +} +``` + +A compatibility switch has been introduced to allow continued use of the old `fileNames`, `urls`, `paths`, and `mediatexts` fields. To restore the legacy fields, add the following AppContext switch to your startup class: + +```csharp +AppContext.SetSwitch("OrchardCore.Media.EnableLegacyMediaFieldGraphQLFields", true); +``` + ### Resource Management Previously the `` Razor tag helper and the `{% resources type: "..." %}` Liquid tag were only capable of handling a hard-coded set of resource definition types (`script`, `stylesheet`, etc). Now both can be extended with `IResourcesTagHelperProcessor` to run custom rendering logic. To make this possible, the `OrchardCore.ResourceManagement.TagHelpers.ResourceType` and `OrchardCore.Resources.Liquid.ResourcesTag.ResourceType` enums have been replaced with a common `OrchardCore.ResourceManagement.ResourceTagType`. It was renamed to avoid confusion with `ResourceDefinition.Type`. This change does not affect the uses of the Razor tag helper or the Liquid tag in templates of user projects, but it affects published releases such as NuGet packages. Any themes and modules that contain `` in a Razor file (e.g. _Layout.cshtml_) must be re-released to generate the updated `.cshtml.cs` files, because the old pre-compiled templates would throw `MissingMethodException`.