mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
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:
@@ -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>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 %>
|
||||
<%--
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user