Update CMS Pages template provider to use YAML parser

Also add calls to logging service when things are ignored or erroneous in the template metadata text.

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4039982
This commit is contained in:
rpaquay
2009-11-12 22:56:51 +00:00
parent 60804ae95a
commit aa232445c8
8 changed files with 149 additions and 7 deletions

View File

@@ -32,6 +32,7 @@ namespace Orchard.CmsPages.Tests.Controllers {
builder.Register<TemplatesController>();
builder.Register<PageManager>().As<IPageManager>();
builder.Register<TemplateProvider>().As<ITemplateProvider>();
builder.Register<TemplateMetadataParser>().As<ITemplateMetadataParser>();
builder.Register(new StubTemplateEntryProvider()).As<ITemplateEntryProvider>();
}

View File

@@ -82,7 +82,7 @@
<Compile Include="Services\Templates\TestTemplateProvider.cs" />
<Compile Include="Services\Templates\TemplateProviderTests.cs" />
<Compile Include="Services\Templates\CommentExtractorTests.cs" />
<Compile Include="Services\Templates\MetadataParserTests.cs" />
<Compile Include="Services\Templates\TemplateMetadataParserTests.cs" />
<Compile Include="Controllers\AdminControllerTests.cs" />
<Compile Include="Controllers\TemplatesControllerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

View File

@@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;
using Orchard.CmsPages.Services.Templates;
namespace Orchard.CmsPages.Tests.Services.Templates {
[TestFixture]
public class TemplateMetadataParserTests {
[Test]
public void ParserShouldReturnEmptyListForEmptyMetadata() {
var reader = new StringReader(" \r\n ");
var parser = new TemplateMetadataParser();
IList<MetadataEntry> result = parser.Parse(reader);
Assert.That(result.Count, Is.EqualTo(0));
}
[Test]
public void ParserShouldIgnoreEmptyTags() {
var reader = new StringReader(" : test value \r\n ");
var parser = new TemplateMetadataParser();
IList<MetadataEntry> result = parser.Parse(reader);
Assert.That(result.Count, Is.EqualTo(0));
}
[Test]
public void ParserShouldReturnMetadata() {
var reader = new StringReader("Description: test");
var parser = new TemplateMetadataParser();
IList<MetadataEntry> result = parser.Parse(reader);
Assert.That(result.Count, Is.EqualTo(1));
Assert.That(result[0].Tag, Is.EqualTo("Description"));
Assert.That(result[0].Value, Is.EqualTo("test"));
}
[Test]
public void ParserShouldReturnMultiMetadata() {
var reader = new StringReader("Description: test\r\nTag2: this is my test ");
var parser = new TemplateMetadataParser();
IList<MetadataEntry> result = parser.Parse(reader);
Assert.That(result.Count, Is.EqualTo(2));
Assert.That(result[0].Tag, Is.EqualTo("Description"));
Assert.That(result[0].Value, Is.EqualTo("test"));
Assert.That(result[1].Tag, Is.EqualTo("Tag2"));
Assert.That(result[1].Value, Is.EqualTo("this is my test"));
}
[Test]
public void ParserShouldSupportMultiLineValues() {
var reader = new StringReader("Description: test Tag2 this\r\n is my test\r\nName:\r\n FooBar");
var parser = new TemplateMetadataParser();
IList<MetadataEntry> result = parser.Parse(reader);
Assert.That(result.Count, Is.EqualTo(2));
Assert.That(result[0].Tag, Is.EqualTo("Description"));
Assert.That(result[0].Value, Is.EqualTo("test Tag2 this is my test"));
Assert.That(result[1].Tag, Is.EqualTo("Name"));
Assert.That(result[1].Value, Is.EqualTo("FooBar"));
}
}
}

View File

@@ -10,7 +10,7 @@ namespace Orchard.CmsPages.Tests.Services.Templates {
[SetUp]
public void Init() {
_entryProvider = new StubTemplateEntryProvider();
_provider = new TemplateProvider(_entryProvider);
_provider = new TemplateProvider(_entryProvider, new TemplateMetadataParser());
_entryProvider.AddTemplate("test1", @"
<%@Page %>
<%--

View File

@@ -66,6 +66,10 @@
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Web.Mobile" />
<Reference Include="Yaml, Version=1.0.3370.39839, Culture=neutral, PublicKeyToken=187a3d240e44a135, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\yaml\Yaml.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
@@ -90,7 +94,7 @@
<Compile Include="Services\Templates\TemplateEntryProvider.cs" />
<Compile Include="Services\Templates\TemplateDescriptor.cs" />
<Compile Include="Services\Templates\MetadataEntry.cs" />
<Compile Include="Services\Templates\MetadataParser.cs" />
<Compile Include="Services\Templates\TemplateMetadataParser.cs" />
<Compile Include="Services\XmlRpcHandler.cs" />
<Compile Include="ViewModels\ChooseTemplateViewModel.cs" />
<Compile Include="ViewModels\PageCreateViewModel.cs" />

View File

@@ -2,5 +2,9 @@ namespace Orchard.CmsPages.Services.Templates {
public class MetadataEntry {
public string Tag { get; set; }
public string Value { get; set; }
public override string ToString() {
return string.Format("Tag:{0}, Value:{1}", Tag, Value);
}
}
}

View File

@@ -0,0 +1,68 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Orchard.Logging;
using Orchard.Utility;
using Yaml.Grammar;
namespace Orchard.CmsPages.Services.Templates {
public interface ITemplateMetadataParser : IDependency {
IList<MetadataEntry> Parse(TextReader reader);
}
/// <summary>
/// Parse the content of a text reader into a list of metadata entries.
/// </summary>
public class TemplateMetadataParser : ITemplateMetadataParser {
public TemplateMetadataParser() {
Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
private static IList<MetadataEntry> EmptyList { get { return new MetadataEntry[0]; } }
public IList<MetadataEntry> Parse(TextReader reader) {
string content = reader.ReadToEnd();
var yamlInput = new TextInput(content);
var parser = new YamlParser();
bool success;
var stream = parser.ParseYamlStream(yamlInput, out success);
if (!success) {
Logger.Error("Error parsing template metadata. Detailed YAML parsing error: {0}", parser.ErrorMessages);
return EmptyList;
}
if (stream.Documents.Count == 0) {
Logger.Warning("No template metadata found.");
return EmptyList;
}
if (stream.Documents.Count >= 2) {
Logger.Information("Some entries where ignored in the template metadata because the metadata text contains more than one YAML 'document'.");
}
YamlDocument doc = stream.Documents.Single();
var root = doc.Root as Mapping;
if (root == null) {
Logger.Error("Invalid template metadata: The YAML root element is not a 'mapping'.");
return EmptyList;
}
var result = root.Entities
.Where(x => x.Key is Scalar && x.Value is Scalar)
.Select(x => new MetadataEntry { Tag = ((Scalar)x.Key).Text, Value = ((Scalar)x.Value).Text })
.ToReadOnlyCollection();
if (root.Entities.Count != result.Count) {
Logger.Information("Some entries were ignored in template metadata because they are not YAML 'scalars'.");
}
return result;
}
}
}

View File

@@ -11,9 +11,11 @@ namespace Orchard.CmsPages.Services.Templates {
public class TemplateProvider : ITemplateProvider {
private readonly ITemplateEntryProvider _entryProvider;
private readonly ITemplateMetadataParser _parser;
public TemplateProvider(ITemplateEntryProvider entryProvider) {
public TemplateProvider(ITemplateEntryProvider entryProvider, ITemplateMetadataParser parser) {
_entryProvider = entryProvider;
_parser = parser;
}
public IList<TemplateDescriptor> List() {
@@ -33,9 +35,8 @@ namespace Orchard.CmsPages.Services.Templates {
.SingleOrDefault();
}
private static TemplateDescriptor CreateDescriptor(TemplateEntry entry) {
var parser = new MetadataParser();
var metadataEntries = parser.Parse(new CommentExtractor().FirstComment(entry.Content));
private TemplateDescriptor CreateDescriptor(TemplateEntry entry) {
var metadataEntries = _parser.Parse(new CommentExtractor().FirstComment(entry.Content));
var descriptor = new TemplateDescriptor {Name = entry.Name};