diff --git a/MfGames.Nitride.sln b/MfGames.Nitride.sln
index 82ad9dd..1e0b9d5 100644
--- a/MfGames.Nitride.sln
+++ b/MfGames.Nitride.sln
@@ -47,6 +47,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Nitride.Temporal.Te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Nitride.Markdown.Tests", "tests\MfGames.Nitride.Markdown.Tests\MfGames.Nitride.Markdown.Tests.csproj", "{2AAE2B69-A93D-4045-B7E6-A32ED08D0D65}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Nitride.Json", "src\MfGames.Nitride.Json\MfGames.Nitride.Json.csproj", "{9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Nitride.Json.Tests", "tests\MfGames.Nitride.Json.Tests\MfGames.Nitride.Json.Tests.csproj", "{7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -288,6 +292,30 @@ Global
{2AAE2B69-A93D-4045-B7E6-A32ED08D0D65}.Release|x64.Build.0 = Release|Any CPU
{2AAE2B69-A93D-4045-B7E6-A32ED08D0D65}.Release|x86.ActiveCfg = Release|Any CPU
{2AAE2B69-A93D-4045-B7E6-A32ED08D0D65}.Release|x86.Build.0 = Release|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Debug|x64.Build.0 = Debug|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Debug|x86.Build.0 = Debug|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Release|x64.ActiveCfg = Release|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Release|x64.Build.0 = Release|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Release|x86.ActiveCfg = Release|Any CPU
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113}.Release|x86.Build.0 = Release|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Debug|x64.Build.0 = Debug|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Debug|x86.Build.0 = Debug|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Release|x64.ActiveCfg = Release|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Release|x64.Build.0 = Release|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Release|x86.ActiveCfg = Release|Any CPU
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D480943C-764D-4A8A-B546-642ED10586BB} = {570184FD-ECE4-4EC8-86E1-C1265E17D647}
@@ -309,5 +337,7 @@ Global
{C49E07D0-CD32-4332-90FA-07494195CAC4} = {251D9C68-34EB-439D-B167-688BCC47DA17}
{0B74A4DE-4F92-44EE-8273-E5A15EAB4266} = {251D9C68-34EB-439D-B167-688BCC47DA17}
{2AAE2B69-A93D-4045-B7E6-A32ED08D0D65} = {251D9C68-34EB-439D-B167-688BCC47DA17}
+ {9A0D2BEE-859A-4E74-8CA7-5E0FB7C2B113} = {570184FD-ECE4-4EC8-86E1-C1265E17D647}
+ {7CCC3A82-D5FE-4D54-9751-5E7985DE1F26} = {251D9C68-34EB-439D-B167-688BCC47DA17}
EndGlobalSection
EndGlobal
diff --git a/src/MfGames.Nitride.Json/IsJson.cs b/src/MfGames.Nitride.Json/IsJson.cs
new file mode 100644
index 0000000..ec68980
--- /dev/null
+++ b/src/MfGames.Nitride.Json/IsJson.cs
@@ -0,0 +1,9 @@
+namespace MfGames.Nitride.Json;
+
+///
+/// A marker class that indicates that the entity is JSON.
+///
+public record IsJson
+{
+ public static IsJson Instance { get; } = new();
+}
diff --git a/src/MfGames.Nitride.Json/IsJsonExtensions.cs b/src/MfGames.Nitride.Json/IsJsonExtensions.cs
new file mode 100644
index 0000000..37e3291
--- /dev/null
+++ b/src/MfGames.Nitride.Json/IsJsonExtensions.cs
@@ -0,0 +1,16 @@
+using MfGames.Gallium;
+
+namespace MfGames.Nitride.Json;
+
+public static class IsJsonExtensions
+{
+ public static Entity RemoveIsJson(this Entity entity)
+ {
+ return entity.Remove();
+ }
+
+ public static Entity SetIsJson(this Entity entity)
+ {
+ return entity.Set(IsJson.Instance);
+ }
+}
diff --git a/src/MfGames.Nitride.Json/MfGames.Nitride.Json.csproj b/src/MfGames.Nitride.Json/MfGames.Nitride.Json.csproj
new file mode 100644
index 0000000..b32b6c1
--- /dev/null
+++ b/src/MfGames.Nitride.Json/MfGames.Nitride.Json.csproj
@@ -0,0 +1,33 @@
+
+
+
+ net6.0
+ enable
+
+
+
+ An extension to Nitride static site generator to parse JSON content.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+ Analyzer
+ False
+
+
+
+
diff --git a/src/MfGames.Nitride.Json/NitrideJsonBuilderExtensions.cs b/src/MfGames.Nitride.Json/NitrideJsonBuilderExtensions.cs
new file mode 100644
index 0000000..14a4b1d
--- /dev/null
+++ b/src/MfGames.Nitride.Json/NitrideJsonBuilderExtensions.cs
@@ -0,0 +1,12 @@
+using Autofac;
+
+namespace MfGames.Nitride.Json;
+
+public static class NitrideJsonBuilderExtensions
+{
+ public static NitrideBuilder UseJson(this NitrideBuilder builder)
+ {
+ return builder.ConfigureContainer(
+ x => x.RegisterModule());
+ }
+}
diff --git a/src/MfGames.Nitride.Json/NitrideJsonEntityExtensions.cs b/src/MfGames.Nitride.Json/NitrideJsonEntityExtensions.cs
new file mode 100644
index 0000000..36afd5d
--- /dev/null
+++ b/src/MfGames.Nitride.Json/NitrideJsonEntityExtensions.cs
@@ -0,0 +1,77 @@
+using System;
+
+using MfGames.Gallium;
+using MfGames.Nitride.Contents;
+
+using Newtonsoft.Json;
+
+namespace MfGames.Nitride.Json;
+
+public static class NitrideJsonEntityExtensions
+{
+ ///
+ /// Parses the entity text as a JSON file and returns the results.
+ ///
+ public static TType? GetTextContentJson(
+ this Entity entity,
+ Action configure)
+ {
+ JsonSerializerSettings settings = new();
+
+ configure.Invoke(settings);
+
+ return entity.GetTextContentJson(settings);
+ }
+
+ ///
+ /// Parses the entity text as a JSON file and returns the results.
+ ///
+ public static TType? GetTextContentJson(
+ this Entity entity,
+ JsonSerializerSettings? settings = null)
+ {
+ string? text = entity.GetTextContentString();
+
+ return text != null
+ ? JsonConvert.DeserializeObject(text, settings)
+ : default;
+ }
+
+ ///
+ /// Sets the text content to the serialized value. If this is null, then
+ /// the text content is removed. This uses the default serializer which
+ /// may be configured.
+ ///
+ /// The same entity for chaining methods.
+ public static Entity SetTextContentJson(
+ this Entity entity,
+ TType? value,
+ Action configure)
+ {
+ JsonSerializerSettings settings = new();
+
+ configure.Invoke(settings);
+
+ return SetTextContentJson(entity, value, settings);
+ }
+
+ ///
+ /// Sets the text content to the serialized value using the serializer
+ /// provided. If the value is null, then the text content is removed.
+ ///
+ /// The same entity for chaining methods.
+ public static Entity SetTextContentJson(
+ this Entity entity,
+ TType? value,
+ JsonSerializerSettings? settings = null)
+ {
+ if (value == null)
+ {
+ return entity.Remove();
+ }
+
+ string json = JsonConvert.SerializeObject(value, settings);
+
+ return entity.SetTextContent(json);
+ }
+}
diff --git a/src/MfGames.Nitride.Json/NitrideJsonModule.cs b/src/MfGames.Nitride.Json/NitrideJsonModule.cs
new file mode 100644
index 0000000..8d4b4b2
--- /dev/null
+++ b/src/MfGames.Nitride.Json/NitrideJsonModule.cs
@@ -0,0 +1,13 @@
+using Autofac;
+
+namespace MfGames.Nitride.Json;
+
+public class NitrideJsonModule : Module
+{
+ ///
+ protected override void Load(ContainerBuilder builder)
+ {
+ builder.RegisterOperators(this);
+ builder.RegisterValidators(this);
+ }
+}
diff --git a/src/MfGames.Nitride.Yaml/HasYamlModel.cs b/src/MfGames.Nitride.Yaml/HasYamlModel.cs
index 741824a..da59beb 100644
--- a/src/MfGames.Nitride.Yaml/HasYamlModel.cs
+++ b/src/MfGames.Nitride.Yaml/HasYamlModel.cs
@@ -1,7 +1,7 @@
namespace MfGames.Nitride.Yaml;
///
-/// A marker class that indicates that the has a YAML model.
+/// A marker class that indicates that entity has a YAML model.
///
public record HasYamlModel
{
diff --git a/src/MfGames.Nitride.Yaml/NitrideYamlEntityExtensions.cs b/src/MfGames.Nitride.Yaml/NitrideYamlEntityExtensions.cs
index cf8a6f1..c231308 100644
--- a/src/MfGames.Nitride.Yaml/NitrideYamlEntityExtensions.cs
+++ b/src/MfGames.Nitride.Yaml/NitrideYamlEntityExtensions.cs
@@ -10,9 +10,10 @@ namespace MfGames.Nitride.Yaml;
public static class NitrideYamlEntityExtensions
{
///
- /// Parses the entity text as a YAML file and returns the results.
+ /// Parses the entity text as a YAML file and returns the results. This
+ /// uses the default serializer, which may be configured.
///
- public static TType? GetYaml(
+ public static TType? GetTextContentYaml(
this Entity entity,
Action? configure = null)
{
@@ -22,13 +23,14 @@ public static class NitrideYamlEntityExtensions
IDeserializer deserializer = builder.Build();
- return entity.GetYaml(deserializer);
+ return entity.GetTextContentYaml(deserializer);
}
///
- /// Parses the entity text as a YAML file and returns the results.
+ /// Parses the entity text as a YAML file using the given serializer and
+ /// returns the results.
///
- public static TType? GetYaml(
+ public static TType? GetTextContentYaml(
this Entity entity,
IDeserializer deserializer)
{
@@ -38,4 +40,44 @@ public static class NitrideYamlEntityExtensions
? deserializer.Deserialize(text)
: default;
}
+
+ ///
+ /// Sets the text content to the serialized value. If this is null, then
+ /// the text content is removed. This uses the default serializer which
+ /// may be configured.
+ ///
+ /// The same entity for chaining methods.
+ public static Entity SetTextContentYaml(
+ this Entity entity,
+ TType? value,
+ Action? configure = null)
+ {
+ SerializerBuilder builder = new();
+
+ configure?.Invoke(builder);
+
+ ISerializer serializer = builder.Build();
+
+ return SetTextContentYaml(entity, value, serializer);
+ }
+
+ ///
+ /// Sets the text content to the serialized value using the serializer
+ /// provided. If the value is null, then the text content is removed.
+ ///
+ /// The same entity for chaining methods.
+ public static Entity SetTextContentYaml(
+ this Entity entity,
+ TType? value,
+ ISerializer serializer)
+ {
+ if (value == null)
+ {
+ return entity.Remove();
+ }
+
+ string yaml = serializer.Serialize(value);
+
+ return entity.SetTextContent(yaml);
+ }
}
diff --git a/tests/MfGames.Nitride.IO.Tests/MfGames.Nitride.IO.Tests.csproj b/tests/MfGames.Nitride.IO.Tests/MfGames.Nitride.IO.Tests.csproj
index 8c1fde0..f1f4f20 100644
--- a/tests/MfGames.Nitride.IO.Tests/MfGames.Nitride.IO.Tests.csproj
+++ b/tests/MfGames.Nitride.IO.Tests/MfGames.Nitride.IO.Tests.csproj
@@ -6,22 +6,22 @@
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/tests/MfGames.Nitride.Json.Tests/MfGames.Nitride.Json.Tests.csproj b/tests/MfGames.Nitride.Json.Tests/MfGames.Nitride.Json.Tests.csproj
new file mode 100644
index 0000000..e250840
--- /dev/null
+++ b/tests/MfGames.Nitride.Json.Tests/MfGames.Nitride.Json.Tests.csproj
@@ -0,0 +1,29 @@
+
+
+
+ net6.0
+ enable
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/MfGames.Nitride.Json.Tests/TextContentJsonTests.cs b/tests/MfGames.Nitride.Json.Tests/TextContentJsonTests.cs
new file mode 100644
index 0000000..8a4d5e2
--- /dev/null
+++ b/tests/MfGames.Nitride.Json.Tests/TextContentJsonTests.cs
@@ -0,0 +1,51 @@
+using MfGames.Gallium;
+using MfGames.Nitride.Tests;
+
+using Xunit;
+using Xunit.Abstractions;
+
+namespace MfGames.Nitride.Json.Tests;
+
+public class TextContentJsonTests : NitrideTestBase
+{
+ public TextContentJsonTests(ITestOutputHelper output)
+ : base(output)
+ {
+ }
+
+ [Fact]
+ public void NoTextContent()
+ {
+ Entity entity = new();
+ TestContent? output = entity.GetTextContentJson();
+
+ Assert.Null(output);
+ }
+
+ [Fact]
+ public void SetAndGetContent()
+ {
+ Entity entity = new Entity()
+ .SetTextContentJson(new TestContent { Value = "t1" });
+ TestContent? output = entity.GetTextContentJson();
+
+ Assert.NotNull(output);
+ Assert.Equal("t1", output.Value);
+ }
+
+ [Fact]
+ public void SetNullRemovesContent()
+ {
+ Entity entity = new Entity()
+ .SetTextContentJson(new TestContent { Value = "t1" })
+ .SetTextContentJson(null);
+ TestContent? output = entity.GetTextContentJson();
+
+ Assert.Null(output);
+ }
+
+ private class TestContent
+ {
+ public string? Value { get; set; }
+ }
+}
diff --git a/tests/MfGames.Nitride.Temporal.Tests/MfGames.Nitride.Temporal.Tests.csproj b/tests/MfGames.Nitride.Temporal.Tests/MfGames.Nitride.Temporal.Tests.csproj
index bd40748..1e9f90c 100644
--- a/tests/MfGames.Nitride.Temporal.Tests/MfGames.Nitride.Temporal.Tests.csproj
+++ b/tests/MfGames.Nitride.Temporal.Tests/MfGames.Nitride.Temporal.Tests.csproj
@@ -6,17 +6,17 @@
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/tests/MfGames.Nitride.Yaml.Tests/MfGames.Nitride.Yaml.Tests.csproj b/tests/MfGames.Nitride.Yaml.Tests/MfGames.Nitride.Yaml.Tests.csproj
index 0147bb0..ec613c8 100644
--- a/tests/MfGames.Nitride.Yaml.Tests/MfGames.Nitride.Yaml.Tests.csproj
+++ b/tests/MfGames.Nitride.Yaml.Tests/MfGames.Nitride.Yaml.Tests.csproj
@@ -6,10 +6,10 @@
-
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -21,9 +21,9 @@
-
-
-
+
+
+
diff --git a/tests/MfGames.Nitride.Yaml.Tests/ParseYamlHeaderTest.cs b/tests/MfGames.Nitride.Yaml.Tests/ParseYamlHeaderTests.cs
similarity index 96%
rename from tests/MfGames.Nitride.Yaml.Tests/ParseYamlHeaderTest.cs
rename to tests/MfGames.Nitride.Yaml.Tests/ParseYamlHeaderTests.cs
index ce304bf..1ac6c8e 100644
--- a/tests/MfGames.Nitride.Yaml.Tests/ParseYamlHeaderTest.cs
+++ b/tests/MfGames.Nitride.Yaml.Tests/ParseYamlHeaderTests.cs
@@ -10,9 +10,9 @@ using Xunit.Abstractions;
namespace MfGames.Nitride.Yaml.Tests;
-public class ParseYamlHeaderTest : NitrideTestBase
+public class ParseYamlHeaderTests : NitrideTestBase
{
- public ParseYamlHeaderTest(ITestOutputHelper output)
+ public ParseYamlHeaderTests(ITestOutputHelper output)
: base(output)
{
}
diff --git a/tests/MfGames.Nitride.Yaml.Tests/TextContentYamlTests.cs b/tests/MfGames.Nitride.Yaml.Tests/TextContentYamlTests.cs
new file mode 100644
index 0000000..67f2036
--- /dev/null
+++ b/tests/MfGames.Nitride.Yaml.Tests/TextContentYamlTests.cs
@@ -0,0 +1,51 @@
+using MfGames.Gallium;
+using MfGames.Nitride.Tests;
+
+using Xunit;
+using Xunit.Abstractions;
+
+namespace MfGames.Nitride.Yaml.Tests;
+
+public class TextContentYamlTests : NitrideTestBase
+{
+ public TextContentYamlTests(ITestOutputHelper output)
+ : base(output)
+ {
+ }
+
+ [Fact]
+ public void NoTextContent()
+ {
+ Entity entity = new();
+ TestContent? output = entity.GetTextContentYaml();
+
+ Assert.Null(output);
+ }
+
+ [Fact]
+ public void SetAndGetContent()
+ {
+ Entity entity = new Entity()
+ .SetTextContentYaml(new TestContent { Value = "t1" });
+ TestContent? output = entity.GetTextContentYaml();
+
+ Assert.NotNull(output);
+ Assert.Equal("t1", output.Value);
+ }
+
+ [Fact]
+ public void SetNullRemovesContent()
+ {
+ Entity entity = new Entity()
+ .SetTextContentYaml(new TestContent { Value = "t1" })
+ .SetTextContentYaml(null);
+ TestContent? output = entity.GetTextContentYaml();
+
+ Assert.Null(output);
+ }
+
+ private class TestContent
+ {
+ public string? Value { get; set; }
+ }
+}