diff --git a/ln.templates.test/HtmlTests.cs b/ln.templates.test/HtmlTests.cs index 920e463..47de7bc 100644 --- a/ln.templates.test/HtmlTests.cs +++ b/ln.templates.test/HtmlTests.cs @@ -47,5 +47,25 @@ namespace ln.templates.test Console.WriteLine("Rendered Document:\n{0}", targetWriter.ToString()); } + [TestCase()] + public void Test_Slots_Recursive() + { + RecursiveResolver templateSource = new RecursiveResolver("tests"); + + foreach (var prefix in new string[] { "", "custom/option1", "custom/option2" }) + { + RecursiveResolver finalResolver = templateSource.FindResolver(prefix); + StringWriter targetWriter = new StringWriter(); + Template template = finalResolver.GetTemplateByPath("test_slots_recursive.html"); + + template.Render(targetWriter); + + template = null; + Console.WriteLine("Rendered Document (prefixed: {1}):\n{0}", targetWriter.ToString(), prefix); + } + } + + + } } diff --git a/ln.templates.test/ln.templates.test.csproj b/ln.templates.test/ln.templates.test.csproj index 4c3df6f..34740a3 100644 --- a/ln.templates.test/ln.templates.test.csproj +++ b/ln.templates.test/ln.templates.test.csproj @@ -29,6 +29,15 @@ Always + + Always + + + Always + + + Always + diff --git a/ln.templates.test/tests/custom/option1/test_slot_a.html b/ln.templates.test/tests/custom/option1/test_slot_a.html new file mode 100644 index 0000000..93b79e0 --- /dev/null +++ b/ln.templates.test/tests/custom/option1/test_slot_a.html @@ -0,0 +1,3 @@ +
+

Option 1

+
\ No newline at end of file diff --git a/ln.templates.test/tests/custom/option2/test_slot_a.html b/ln.templates.test/tests/custom/option2/test_slot_a.html new file mode 100644 index 0000000..1676d18 --- /dev/null +++ b/ln.templates.test/tests/custom/option2/test_slot_a.html @@ -0,0 +1,3 @@ +
+

Option 2

+
\ No newline at end of file diff --git a/ln.templates.test/tests/test_slots_recursive.html b/ln.templates.test/tests/test_slots_recursive.html new file mode 100644 index 0000000..60e2534 --- /dev/null +++ b/ln.templates.test/tests/test_slots_recursive.html @@ -0,0 +1,15 @@ + + + +

Recursive Slot Test

+
+ +
+
+

This should always be the default:

+ +
+ + \ No newline at end of file diff --git a/ln.templates/RecursiveResolver.cs b/ln.templates/RecursiveResolver.cs index 92d7fbf..5565ccf 100644 --- a/ln.templates/RecursiveResolver.cs +++ b/ln.templates/RecursiveResolver.cs @@ -16,9 +16,9 @@ public class RecursiveResolver : ITemplateResolver private RecursiveResolver(RecursiveResolver parent, string path) { Parent = parent; - Path = path; - if (!Directory.Exists(path)) - throw new DirectoryNotFoundException(path); + Path = System.IO.Path.Combine(Parent?.Path ?? "", path); + if (!Directory.Exists(Path)) + throw new DirectoryNotFoundException(Path); } public RecursiveResolver Root => Parent?.Root ?? this; @@ -32,33 +32,47 @@ public class RecursiveResolver : ITemplateResolver public RecursiveResolver FindResolver(string path) => FindResolver( - System.IO.Path.GetDirectoryName(path)?.Split(System.IO.Path.PathSeparator) ?? Array.Empty()); + path.Split(System.IO.Path.DirectorySeparatorChar) ?? Array.Empty()); + private RecursiveResolver FindResolver(Span pathElements) { if (pathElements.Length == 0) - throw new ArgumentOutOfRangeException(nameof(pathElements)); - - if (_children.TryGetValue(pathElements[0], out RecursiveResolver child)) + return this; + + if (!_children.TryGetValue(pathElements[0], out RecursiveResolver child)) { - if (!child.IsAlive) + if (Directory.Exists(System.IO.Path.Combine(Path, pathElements[0]))) { - _children.Remove(pathElements[0]); - return null; + child = new RecursiveResolver(this, pathElements[0]); + _children.Add(pathElements[0], child); } - if (pathElements.Length > 1) - return child.FindResolver(pathElements.Slice(1)); - return child; } + if (child?.IsAlive ?? false) + return child.FindResolver(pathElements.Slice(1)); + + if (child is not null) + _children.Remove(pathElements[0]); + return null; } - - + + public Template GetTemplateByPath(string templatePath) { + RecursiveResolver resolver; Span pathElements = templatePath.Split(System.IO.Path.DirectorySeparatorChar); - RecursiveResolver resolver = FindResolver(pathElements.Slice(0, pathElements.Length - 1)); - return resolver?.GetTemplate(pathElements[^1]); + if (string.Empty.Equals(pathElements[0])) + resolver = Root; + else + resolver = FindResolver(pathElements.Slice(0, pathElements.Length - 1)); + + Template template = resolver?.GetTemplate(pathElements[^1]); + if (template is null) + return null; + + template.Resolver = this; + return template; } public Template GetTemplate(string name) @@ -75,8 +89,14 @@ public class RecursiveResolver : ITemplateResolver return template; } + if (Parent is not null) + return Parent.GetTemplate(name); + return null; } - - + + public override string ToString() + { + return String.Format("[RecursiveResolver {0}]", Path); + } } \ No newline at end of file diff --git a/ln.templates/Template.cs b/ln.templates/Template.cs index c9341e2..04c40ef 100644 --- a/ln.templates/Template.cs +++ b/ln.templates/Template.cs @@ -33,7 +33,7 @@ public class Template } - public ITemplateResolver Resolver { get; } + public ITemplateResolver Resolver { get; set; } public string FileName { get; } public TemplateDocument Document { get; private set; } public DateTime LastWriteTime { get; private set; }