Skip to content

Instantly share code, notes, and snippets.

@Antonytm
Forked from IvanLieckens/JssFieldsExtender.cs
Last active August 3, 2022 20:47
Show Gist options
  • Save Antonytm/b6c2a5106f00ddf9170dee04c7e75fc6 to your computer and use it in GitHub Desktop.
Save Antonytm/b6c2a5106f00ddf9170dee04c7e75fc6 to your computer and use it in GitHub Desktop.
Sitecore JSS GraphQL schema extension to output fields in JSS format
using GraphQL.Types;
using Newtonsoft.Json;
using Sitecore.Configuration;
using Sitecore.Data.Items;
using Sitecore.Data.Fields;
using Sitecore.Diagnostics;
using Sitecore.LayoutService.Serialization.FieldSerializers;
using Sitecore.LayoutService.Serialization.ItemSerializers;
using Sitecore.LayoutService.Serialization.Pipelines.GetFieldSerializer;
using Sitecore.Services.GraphQL.Content.GraphTypes;
using Sitecore.Services.GraphQL.GraphTypes;
using Sitecore.Services.GraphQL.Schemas;
using System.Globalization;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
public class JssFieldsExtender : SchemaExtender
{
private const string OwnFieldsAttributeName = "ownFields";
private const string FieldsAttributeName = "fields";
public JssFieldsExtender(IGetFieldSerializerPipeline fieldSerializerPipeline)
{
ExtendTypes<ItemGraphType>(
type => type.Field<JsonGraphType>(
"jssFields",
"Gets the item fields in JSS format",
new QueryArguments(
new QueryArgument<BooleanGraphType>
{
DefaultValue = false,
Name = OwnFieldsAttributeName,
Description = "Limits the fields to the fields on the template only or not"
},
new QueryArgument<ListGraphType<StringGraphType>>
{
DefaultValue = new List<string>(),
Name = FieldsAttributeName,
Description = "List of fields to display"
}),
context => Serialize(context, fieldSerializerPipeline),
null));
ExtendTypes<ItemInterfaceGraphType>(
type => type.Field<JsonGraphType>(
"jssFields",
"Gets the item fields in JSS format",
null,
null,
null));
}
protected virtual string Serialize(
ResolveFieldContext<Item> context,
IGetFieldSerializerPipeline getFieldSerializerPipeline)
{
Item item = context.Source;
bool ownFields = context.GetArgument(OwnFieldsAttributeName, false);
List<string> fieldNames = context.GetArgument(FieldsAttributeName, new List<string>());
StringBuilder result = new StringBuilder();
IEnumerable<Field> fields;
if (ownFields)
{
fields = item.Template.OwnFields.Select(f => item.Fields[f.ID]).ToList();
}
else
{
item.Fields.ReadAll();
fields = item.Fields;
}
var filteredFieldsByName = fieldNames.Any()
? fields.Where(x => fieldNames.Contains(x.Name))
: fields;
foreach (Field field in filteredFieldsByName)
{
result.Append($"{SerializeField(field, getFieldSerializerPipeline)},");
}
// Strip last , if needed
if (result.Length > 0)
{
result = result.Remove(result.Length - 1, 1);
}
return $"{{{result}}}";
}
protected virtual string SerializeField(
Field field,
IGetFieldSerializerPipeline getFieldSerializerPipeline)
{
using (new SettingsSwitcher("Media.AlwaysIncludeServerUrl", bool.TrueString))
{
GetFieldSerializerPipelineArgs args = new GetFieldSerializerPipelineArgs()
{
Field = field,
ItemSerializer = new DefaultItemSerializer(getFieldSerializerPipeline)
};
IFieldSerializer result = getFieldSerializerPipeline.GetResult(args);
Assert.IsNotNull(result, "fieldSerializer != null");
StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
using (JsonTextWriter writer = new JsonTextWriter(stringWriter))
{
writer.Formatting = Formatting.None;
result.EnableRenderedValues = Sitecore.Context.PageMode.IsExperienceEditorEditing;
result.Serialize(field, writer);
}
return stringWriter.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment