Skip to content

Commit

Permalink
adds appschema, and generator for it
Browse files Browse the repository at this point in the history
  • Loading branch information
skttl committed Nov 25, 2023
1 parent 1ef25d9 commit 4c00c6f
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/Our.Umbraco.FullTextSearch.SchemaGenerator/AppSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Our.Umbraco.FullTextSearch.Options;

namespace Our.Umbraco.FullTextSearch.SchemaGenerator
{
internal class AppSettings
{
public UmbracoDefinition Umbraco { get; set; }

/// <summary>
/// Configuration of settings
/// </summary>
internal class UmbracoDefinition
{
/// <summary>
/// FullTextSearch settings
/// </summary>
public FullTextSearchOptions FullTextSearch { get; set; }

}
}

}
12 changes: 12 additions & 0 deletions src/Our.Umbraco.FullTextSearch.SchemaGenerator/Options.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using CommandLine;

namespace Our.Umbraco.FullTextSearch.SchemaGenerator
{
internal class Options
{
[Option('o', "outputFile", Required = false,
HelpText = "",
Default = "Our.Umbraco.FullTextSearch\\appsettings-schema.umbraco-fulltextsearch.json")]
public string OutputFile { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NJsonSchema" Version="10.9.0" />
<PackageReference Include="CommandLineParser" Version="2.9.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Our.Umbraco.FullTextSearch\Our.Umbraco.FullTextSearch.csproj" />
</ItemGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\$(TargetFramework)\Our.Umbraco.FullTextSearch.SchemaGenerator.xml</DocumentationFile>
</PropertyGroup>

<Target Name="CopyPackagesXml" BeforeTargets="Build">
<ItemGroup>
<PackageReferenceFiles Include="$(NugetPackageRoot)%(PackageReference.Identity)\%(PackageReference.Version)%(PackageReference.CopyToOutputDirectory)\lib\**\*.xml" />
</ItemGroup>
<Copy SourceFiles="@(PackageReferenceFiles)" DestinationFolder="$(OutDir)" />
</Target>
</Project>
46 changes: 46 additions & 0 deletions src/Our.Umbraco.FullTextSearch.SchemaGenerator/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.IO;
using System.Threading.Tasks;
using CommandLine;

using NPoco.fastJSON;

namespace Our.Umbraco.FullTextSearch.SchemaGenerator
{
/// <summary>
/// Generate the JSON Schema file for Full Text Search.
/// just like in the Umbraco Core - https://github.com/umbraco/Umbraco-CMS/tree/v9/contrib/src/JsonSchema
/// #h5yr Kevin Jump!
/// </summary>
internal class Program
{
public static async Task Main(string[] args)
{
try
{
await Parser.Default.ParseArguments<Options>(args)
.WithParsedAsync(Execute);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

private static async Task Execute(Options options)
{
var generator = new SchemaGenerator();

var schema = generator.Generate();

var path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, options.OutputFile));
Console.WriteLine("Path to use {0}", path);
Directory.CreateDirectory(Path.GetDirectoryName(path));
Console.WriteLine("Ensured directory exists");
await File.WriteAllTextAsync(path, schema);

Console.WriteLine("File written at {0}", path);
}
}
}
84 changes: 84 additions & 0 deletions src/Our.Umbraco.FullTextSearch.SchemaGenerator/SchemaGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

using NJsonSchema.Generation;

namespace Our.Umbraco.FullTextSearch.SchemaGenerator
{
internal class SchemaGenerator
{
private readonly JsonSchemaGenerator _schemaGenerator;

public SchemaGenerator()
{
_schemaGenerator = new JsonSchemaGenerator(
new FullTextSearchSchemaGeneratorSettings());
}

public string Generate()
{
var schema = GenerateFullTextSearchSchema();
return schema.ToString();
}

private JObject GenerateFullTextSearchSchema()
{
var schema = _schemaGenerator.Generate(typeof(AppSettings));
return JsonConvert.DeserializeObject<JObject>(schema.ToJson());
}

}

internal class FullTextSearchSchemaGeneratorSettings : JsonSchemaGeneratorSettings
{
public FullTextSearchSchemaGeneratorSettings()
{
AlwaysAllowAdditionalObjectProperties = true;
SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new WritablePropertiesOnlyResolver(),
};
DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull;
SchemaNameGenerator = new NamespacePrefixedSchemaNameGenerator();
SerializerSettings.Converters.Add(new StringEnumConverter());
IgnoreObsoleteProperties = true;
GenerateExamples = true;
}

private class WritablePropertiesOnlyResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
var result = props.Where(p => p.Writable).ToList();
result.ForEach(x => x.PropertyName = ToPascalCase(x.PropertyName));
return result;
}

private string ToPascalCase(string str)
{
if (!string.IsNullOrEmpty(str))
{
return char.ToUpperInvariant(str[0]) + str.Substring(1);
}

return str;

}
}
}

internal class NamespacePrefixedSchemaNameGenerator : DefaultSchemaNameGenerator
{
public override string Generate(Type type) => type.Namespace.Replace(".", string.Empty) + base.Generate(type);
}
}
6 changes: 6 additions & 0 deletions src/Our.Umbraco.FullTextSearch.sln
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Our.Umbraco.FullTextSearch.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Our.Umbraco.FullTextSearch.Testsite13", "Testsites\Our.Umbraco.FullTextSearch.Testsite13\Our.Umbraco.FullTextSearch.Testsite13.csproj", "{9D899317-F4E7-4966-A03B-85FFA9B80E3C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Our.Umbraco.FullTextSearch.SchemaGenerator", "Our.Umbraco.FullTextSearch.SchemaGenerator\Our.Umbraco.FullTextSearch.SchemaGenerator.csproj", "{560727BD-EFD0-4D19-ADB7-706C504E6E86}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -61,6 +63,10 @@ Global
{9D899317-F4E7-4966-A03B-85FFA9B80E3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D899317-F4E7-4966-A03B-85FFA9B80E3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D899317-F4E7-4966-A03B-85FFA9B80E3C}.Release|Any CPU.Build.0 = Release|Any CPU
{560727BD-EFD0-4D19-ADB7-706C504E6E86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{560727BD-EFD0-4D19-ADB7-706C504E6E86}.Debug|Any CPU.Build.0 = Debug|Any CPU
{560727BD-EFD0-4D19-ADB7-706C504E6E86}.Release|Any CPU.ActiveCfg = Release|Any CPU
{560727BD-EFD0-4D19-ADB7-706C504E6E86}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
33 changes: 33 additions & 0 deletions src/Our.Umbraco.FullTextSearch/Options/FullTextSearchOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,56 @@ namespace Our.Umbraco.FullTextSearch.Options;

public class FullTextSearchOptions
{
/// <summary>
/// Indexing the full text content is by default enabled, but you can disable it by setting `Enabled` to false.
/// </summary>
[JsonProperty("enabled")]
public bool Enabled { get; set; } = true;

/// <summary>
/// The `DefaultTitleField` node contains the name of the field containing the title of the page in the index. The default value is `nodeName`. You can also override this when searching.
/// </summary>
[JsonProperty("defaultTitleField")]
public string DefaultTitleField { get; set; } = "nodeName";

[Obsolete("Use RenderingActiveKey instead")]
[JsonProperty("indexingActiveKey")]
public string IndexingActiveKey { get; set; } = "FullTextRenderingActive";

/// <summary>
/// When rendering, FullTextSearch adds the value of `RenderingActiveKey` as the value of a Request header named `X-Umbraco-FullTextSearch`, so you can use that to send different content to the renderer. The default value is FullTextRenderingActive. You can also use the `IsRenderingActive` helper method, in your views, to determine whether or not FullTextSearch is rendering the page. You can use this to exclude parts of the views from the content being rendered/indexed.
/// </summary>
[JsonProperty("renderingActiveKey")]
public string RenderingActiveKey { get; set; } = "FullTextRenderingActive";

/// <summary>
/// By default, all nodes with a template will be cached and indexed. You can control which nodes are being indexed, by adding the aliases of the disallowed content type aliases here.
/// </summary>
[JsonProperty("disallowedContentTypeAliases")]
public List<string> DisallowedContentTypeAliases { get; set; } = new List<string>();


/// <summary>
/// By default, all nodes with a template will be cached and indexed. You can control which nodes are being indexed, by adding the aliases of the properties containing a true/false editor, to control whether or not to include a node. A true value means it will be disallowed.
/// </summary>
[JsonProperty("disallowedPropertyAliases")]
public List<string> DisallowedPropertyAliases { get; set; } = new List<string>();

/// <summary>
/// Add specific Xpaths to remove from the rendered content. Using this, you can ie. remove scripts (`//script`) or the head area ('//head') of the page.
/// </summary>
[JsonProperty("xPathsToRemove")]
public List<string> XPathsToRemove { get; set; } = new List<string>();

/// <summary>
/// Field name to use in ExternalIndex for rendered full text content of pages.
/// </summary>
[JsonProperty("fullTextContentField")]
public string FullTextContentField { get; set; } = "FullTextContent";

/// <summary>
/// Field name to use for Full Text Searchs path field, used for determining hierarchy between pages.
/// </summary>
[JsonProperty("fullTextPathField")]
public string FullTextPathField { get; set; } = "FullTextPath";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "OurUmbracoFullTextSearchSchemaGeneratorAppSettings",
"type": "object",
"properties": {
"Umbraco": {
"$ref": "#/definitions/OurUmbracoFullTextSearchSchemaGeneratorUmbracoDefinition"
}
},
"definitions": {
"OurUmbracoFullTextSearchSchemaGeneratorUmbracoDefinition": {
"type": "object",
"description": "Configuration of settings",
"properties": {
"FullTextSearch": {
"description": "FullTextSearch settings",
"oneOf": [
{
"$ref": "#/definitions/OurUmbracoFullTextSearchOptionsFullTextSearchOptions"
}
]
}
}
},
"OurUmbracoFullTextSearchOptionsFullTextSearchOptions": {
"type": "object",
"properties": {
"Enabled": {
"type": "boolean"
},
"DefaultTitleField": {
"type": "string"
},
"RenderingActiveKey": {
"type": "string"
},
"DisallowedContentTypeAliases": {
"type": "array",
"items": {
"type": "string"
}
},
"DisallowedPropertyAliases": {
"type": "array",
"items": {
"type": "string"
}
},
"XPathsToRemove": {
"type": "array",
"items": {
"type": "string"
}
},
"FullTextContentField": {
"type": "string"
},
"FullTextPathField": {
"type": "string"
},
"HighlightPattern": {
"type": "string"
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<UmbracoJsonSchemaFiles Include="$(MSBuildThisFileDirectory)..\appsettings-schema.umbraco-fulltextsearch.json" Weight="-49" />
</ItemGroup>
</Project>

0 comments on commit 4c00c6f

Please sign in to comment.