Skip to content

Commit 4570f44

Browse files
committed
Moved Dictionary functionality out of PagesGQLHandler into dedicated DictionaryService
1 parent d380f8e commit 4570f44

14 files changed

Lines changed: 608 additions & 422 deletions

File tree

src/Sitecore.AspNetCore.SDK.Pages/Configuration/PagesOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,9 @@ public class PagesOptions
3434
/// Gets or sets the Editing Secret.
3535
/// </summary>
3636
public string? EditingSecret { get; set; } = string.Empty;
37+
38+
/// <summary>
39+
/// Gets or sets the number of entries per page in a dictionary. The default value is set to 1000.
40+
/// </summary>
41+
public int DictionaryPageSize { get; set; } = 1000;
3742
}

src/Sitecore.AspNetCore.SDK.Pages/Extensions/PagesAppConfigurationExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Sitecore.AspNetCore.SDK.Pages.GraphQL;
1111
using Sitecore.AspNetCore.SDK.Pages.Middleware;
1212
using Sitecore.AspNetCore.SDK.Pages.Request.Handlers.GraphQL;
13+
using Sitecore.AspNetCore.SDK.Pages.Services;
1314
using Sitecore.AspNetCore.SDK.RenderingEngine.Configuration;
1415
using Sitecore.AspNetCore.SDK.RenderingEngine.Extensions;
1516
using Sitecore.AspNetCore.SDK.RenderingEngine.Interfaces;
@@ -75,6 +76,7 @@ public static ISitecoreRenderingEngineBuilder WithSitecorePages(this ISitecoreRe
7576

7677
services.AddSingleton<PagesMarkerService>();
7778
services.AddSingleton<IGraphQLClientFactory>(new GraphQLClientFactory(contextId));
79+
services.AddSingleton<IDictionaryService, DictionaryService>();
7880

7981
if (options != null)
8082
{

src/Sitecore.AspNetCore.SDK.Pages/Properties/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Sitecore.AspNetCore.SDK.Pages/Properties/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,7 @@
147147
<data name="Exception_EditingScriptsTagHelperSitecoreRenderingContextNull" xml:space="preserve">
148148
<value>EditingScriptsTagHelper: Sitecore RenderingContext is Null</value>
149149
</data>
150+
<data name="Exception_UableToProcessEditingResponse" xml:space="preserve">
151+
<value>GraphQLEditingServiceHandler.HandleEditingLayoutRequest: Response is null, unable to process EditingResponse</value>
152+
</data>
150153
</root>

src/Sitecore.AspNetCore.SDK.Pages/Request/Handlers/GraphQL/EditingLayoutQueryResponse.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.AspNetCore.Mvc.Formatters;
1+
using System.Text.Json.Serialization;
22
using Sitecore.AspNetCore.SDK.LayoutService.Client.Request.Handlers.GraphQL;
33

44
namespace Sitecore.AspNetCore.SDK.Pages.Request.Handlers.GraphQL;
@@ -16,5 +16,5 @@ public class EditingLayoutQueryResponse
1616
/// <summary>
1717
/// Gets or sets the Site for the Editing Layout Response.
1818
/// </summary>
19-
public Site? Site { get; set; }
19+
public Site Site { get; set; } = new();
2020
}

src/Sitecore.AspNetCore.SDK.Pages/Request/Handlers/GraphQL/GraphQLEditingServiceHandler.cs

Lines changed: 19 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Sitecore.AspNetCore.SDK.LayoutService.Client.Serialization.Fields;
1313
using Sitecore.AspNetCore.SDK.Pages.GraphQL;
1414
using Sitecore.AspNetCore.SDK.Pages.Properties;
15+
using Sitecore.AspNetCore.SDK.Pages.Services;
1516

1617
namespace Sitecore.AspNetCore.SDK.Pages.Request.Handlers.GraphQL;
1718

@@ -20,16 +21,19 @@ namespace Sitecore.AspNetCore.SDK.Pages.Request.Handlers.GraphQL;
2021
/// Initializes a new instance of the <see cref="GraphQLEditingServiceHandler"/> class.
2122
/// </summary>
2223
/// <param name="logger">The <see cref="ILogger"/> to use for logging.</param>
24+
/// <param name="dictionaryService">DictionaryService used to return all dictionary items for a Sitecore site.</param>
2325
/// <param name="clientFactory">The GraphQlClientFactory used to generate instances of the GraphQl client.</param>
2426
/// <param name="serializer">The serializer to handle response data.</param>
2527
public partial class GraphQLEditingServiceHandler(IGraphQLClientFactory clientFactory,
2628
ISitecoreLayoutSerializer serializer,
27-
ILogger<GraphQLEditingServiceHandler> logger)
29+
ILogger<GraphQLEditingServiceHandler> logger,
30+
IDictionaryService dictionaryService)
2831
: ILayoutRequestHandler
2932
{
3033
private readonly IGraphQLClientFactory clientFactory = clientFactory ?? throw new ArgumentNullException(nameof(clientFactory));
3134
private readonly ISitecoreLayoutSerializer serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
3235
private readonly ILogger<GraphQLEditingServiceHandler> logger = logger ?? throw new ArgumentNullException(nameof(logger));
36+
private readonly IDictionaryService dictionaryService = dictionaryService ?? throw new ArgumentNullException(nameof(dictionaryService));
3337

3438
/// <inheritdoc />
3539
public async Task<SitecoreLayoutResponse> Request(SitecoreLayoutRequest request, string handlerName)
@@ -263,101 +267,27 @@ private static string GetRequestArgValue(SitecoreLayoutRequest request, string a
263267
return headers[argName].FirstOrDefault() ?? string.Empty;
264268
}
265269

266-
private static async Task GetFullDictionaryInformation(SitecoreLayoutRequest request, string requestLanguage, IGraphQLClient client, GraphQLResponse<EditingLayoutQueryResponse> response)
267-
{
268-
var hasNext = response.Data?.Site?.SiteInfo?.Dictionary?.PageInfo?.HasNext ?? false;
269-
var endCursor = response.Data?.Site?.SiteInfo?.Dictionary?.PageInfo?.EndCursor ?? string.Empty;
270-
while (hasNext && endCursor != string.Empty)
271-
{
272-
GraphQLRequest dictionaryRequest = BuildEditingDictionaryRequest(request, requestLanguage, endCursor);
273-
274-
GraphQLResponse<EditingDictionaryResponse> dictionaryResponse = await client.SendQueryAsync<EditingDictionaryResponse>(dictionaryRequest).ConfigureAwait(false);
275-
response.Data?.Site?.SiteInfo?.Dictionary?.Results.AddRange(dictionaryResponse.Data?.Site?.SiteInfo?.Dictionary?.Results ?? []);
276-
277-
hasNext = dictionaryResponse.Data?.Site?.SiteInfo?.Dictionary?.PageInfo?.HasNext ?? false;
278-
endCursor = dictionaryResponse.Data?.Site?.SiteInfo?.Dictionary?.PageInfo?.EndCursor ?? string.Empty;
279-
}
280-
}
281-
282-
private static GraphQLRequest BuildEditingDictionaryRequest(SitecoreLayoutRequest request, string requestLanguage, string endCursor)
283-
{
284-
return new()
285-
{
286-
Query = @"
287-
query EditingDictionaryQuery(
288-
$siteName: String!
289-
$language: String!
290-
$after: String
291-
$pageSize: Int
292-
) {
293-
site {
294-
siteInfo(site: $siteName) {
295-
dictionary(language: $language, first: $pageSize, after: $after) {
296-
results {
297-
key
298-
value
299-
}
300-
pageInfo {
301-
endCursor
302-
hasNext
303-
}
304-
}
305-
}
306-
}
307-
}
308-
",
309-
OperationName = "EditingDictionaryQuery",
310-
Variables = new
311-
{
312-
language = requestLanguage,
313-
siteName = request.SiteName(),
314-
pageSize = 10,
315-
after = endCursor
316-
}
317-
};
318-
}
319-
320270
private static GraphQLRequest BuildEditingLayoutRequest(SitecoreLayoutRequest request, string requestLanguage)
321271
{
322272
return new()
323273
{
324274
Query = @"
325275
query EditingQuery(
326-
$siteName: String!,
327-
$itemId: String!,
328-
$language: String!,
329-
$version: String,
330-
$after: String,
331-
$pageSize: Int
332-
) {
333-
item(path: $itemId, language: $language, version: $version) {
334-
rendered
335-
}
336-
site {
337-
siteInfo(site: $siteName) {
338-
dictionary(language: $language, first: $pageSize, after: $after) {
339-
results {
340-
key
341-
value
342-
}
343-
pageInfo {
344-
endCursor
345-
hasNext
346-
}
347-
}
348-
}
349-
}
350-
}
276+
$itemId: String!,
277+
$language: String!,
278+
$version: String
279+
) {
280+
item(path: $itemId, language: $language, version: $version) {
281+
rendered
282+
}
283+
}
351284
",
352285
OperationName = "EditingQuery",
353286
Variables = new
354287
{
355288
itemId = GetRequestArgValue(request, "sc_itemid"),
356289
language = requestLanguage,
357-
siteName = request.SiteName(),
358-
version = GetRequestArgValue(request, "sc_version"),
359-
pageSize = 10,
360-
after = string.Empty
290+
version = GetRequestArgValue(request, "sc_version")
361291
}
362292
};
363293
}
@@ -366,8 +296,12 @@ query EditingQuery(
366296
{
367297
IGraphQLClient client = clientFactory.GenerateClient(GetRequestArgValue(request, "sc_layoutKind"), GetRequestArgValue(request, "mode") == "edit");
368298
GraphQLResponse<EditingLayoutQueryResponse> response = await client.SendQueryAsync<EditingLayoutQueryResponse>(BuildEditingLayoutRequest(request, requestLanguage)).ConfigureAwait(false);
299+
if (response?.Data == null)
300+
{
301+
throw new Exception(Resources.Exception_UableToProcessEditingResponse);
302+
}
369303

370-
await GetFullDictionaryInformation(request, requestLanguage, client, response).ConfigureAwait(false);
304+
response.Data.Site.SiteInfo.Dictionary.Results = await dictionaryService.GetSiteDictionary(request.SiteName() ?? string.Empty, requestLanguage, client);
371305

372306
if (logger.IsEnabled(LogLevel.Debug))
373307
{

src/Sitecore.AspNetCore.SDK.Pages/Request/Handlers/GraphQL/Site.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ public class Site
88
/// <summary>
99
/// Gets or sets the site info.
1010
/// </summary>
11-
public SiteInfo? SiteInfo { get; set; }
11+
public SiteInfo SiteInfo { get; set; } = new();
1212
}

src/Sitecore.AspNetCore.SDK.Pages/Request/Handlers/GraphQL/SiteInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ public class SiteInfo
88
/// <summary>
99
/// Gets or sets the dictionary for a Sitecore Site.
1010
/// </summary>
11-
public SiteInfoDictionary? Dictionary { get; set; }
11+
public SiteInfoDictionary Dictionary { get; set; } = new();
1212
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using GraphQL;
2+
using GraphQL.Client.Abstractions;
3+
using Microsoft.Extensions.Options;
4+
using Sitecore.AspNetCore.SDK.Pages.Configuration;
5+
using Sitecore.AspNetCore.SDK.Pages.Request.Handlers.GraphQL;
6+
7+
namespace Sitecore.AspNetCore.SDK.Pages.Services;
8+
9+
/// <summary>
10+
/// DictionaryService used retrieve dictionary items for a Sitecore site.
11+
/// </summary>
12+
public class DictionaryService(IOptions<PagesOptions> options) : IDictionaryService
13+
{
14+
private readonly PagesOptions options = options != null ? options.Value : throw new ArgumentNullException(nameof(options));
15+
16+
/// <summary>
17+
/// Retrieves a list of site information dictionary items based on the specified site and language.
18+
/// </summary>
19+
/// <param name="siteName">Specifies the name of the site for which the dictionary items are being retrieved.</param>
20+
/// <param name="requestLanguage">Indicates the language in which the dictionary items should be returned.</param>
21+
/// <param name="client">Represents the GraphQL client used to send requests and receive responses.</param>
22+
/// <returns>Returns a list of site information dictionary items.</returns>
23+
public async Task<List<SiteInfoDictionaryItem>> GetSiteDictionary(string siteName, string requestLanguage, IGraphQLClient client)
24+
{
25+
if (string.IsNullOrWhiteSpace(siteName) || string.IsNullOrWhiteSpace(requestLanguage) || client == null)
26+
{
27+
throw new ArgumentNullException(nameof(siteName));
28+
}
29+
30+
List<SiteInfoDictionaryItem> dictionary = new();
31+
GraphQLResponse<EditingDictionaryResponse> dictionaryPageResponse = await GetSinglePageOfDictionaryItems(siteName, requestLanguage, client, dictionary, string.Empty).ConfigureAwait(false);
32+
33+
while (dictionaryPageResponse.Data?.Site?.SiteInfo?.Dictionary?.PageInfo?.HasNext ?? false
34+
&& (dictionaryPageResponse.Data?.Site?.SiteInfo?.Dictionary?.PageInfo?.EndCursor ?? string.Empty) != string.Empty)
35+
{
36+
dictionaryPageResponse = await GetSinglePageOfDictionaryItems(siteName, requestLanguage, client, dictionary, dictionaryPageResponse.Data?.Site?.SiteInfo?.Dictionary?.PageInfo?.EndCursor ?? string.Empty).ConfigureAwait(false);
37+
}
38+
39+
return dictionary;
40+
}
41+
42+
private async Task<GraphQLResponse<EditingDictionaryResponse>> GetSinglePageOfDictionaryItems(string siteName, string requestLanguage, IGraphQLClient client, List<SiteInfoDictionaryItem> dictionary, string endCursor)
43+
{
44+
GraphQLRequest dictionaryPageRequest = BuildEditingDictionaryRequest(siteName, requestLanguage, endCursor);
45+
GraphQLResponse<EditingDictionaryResponse> dictionaryPageResponse = await client.SendQueryAsync<EditingDictionaryResponse>(dictionaryPageRequest).ConfigureAwait(false);
46+
dictionary.AddRange(dictionaryPageResponse.Data?.Site?.SiteInfo?.Dictionary?.Results ?? []);
47+
return dictionaryPageResponse;
48+
}
49+
50+
private GraphQLRequest BuildEditingDictionaryRequest(string siteName, string requestLanguage, string endCursor)
51+
{
52+
return new()
53+
{
54+
Query = @"
55+
query DictionaryQuery(
56+
$siteName: String!
57+
$language: String!
58+
$after: String
59+
$pageSize: Int
60+
) {
61+
site {
62+
siteInfo(site: $siteName) {
63+
dictionary(language: $language, first: $pageSize, after: $after) {
64+
results {
65+
key
66+
value
67+
}
68+
pageInfo {
69+
endCursor
70+
hasNext
71+
}
72+
}
73+
}
74+
}
75+
}
76+
",
77+
OperationName = "DictionaryQuery",
78+
Variables = new
79+
{
80+
language = requestLanguage,
81+
siteName = siteName,
82+
pageSize = options.DictionaryPageSize,
83+
after = endCursor
84+
}
85+
};
86+
}
87+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using GraphQL.Client.Abstractions;
2+
using Sitecore.AspNetCore.SDK.Pages.Request.Handlers.GraphQL;
3+
4+
namespace Sitecore.AspNetCore.SDK.Pages.Services
5+
{
6+
/// <summary>
7+
/// DictionaryService used retrieve dictionary items for a Sitecore site.
8+
/// </summary>
9+
public interface IDictionaryService
10+
{
11+
/// <summary>
12+
/// Retrieves a list of site information based on the specified site and language.
13+
/// </summary>
14+
/// <param name="siteName">Specifies the name of the site for which information is being requested.</param>
15+
/// <param name="requestLanguage">Indicates the language in which the site information should be returned.</param>
16+
/// <param name="client">Represents the GraphQL client used to make the request for site information.</param>
17+
/// <returns>Returns a task that resolves to a list of site information dictionary items.</returns>
18+
Task<List<SiteInfoDictionaryItem>> GetSiteDictionary(string siteName, string requestLanguage, IGraphQLClient client);
19+
}
20+
}

0 commit comments

Comments
 (0)