mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-23 04:43:35 +08:00
Field template alternates based on field name and content part/type name
When a ContentShape is returned from a ContentFieldDriver alternates are added automatically Patterns include: ShapeName ShapeName__FieldName ShapeName__PartName ShapeName__FieldName__PartName For content fields the part name is, essentially, always the same as the content type name Field drivers must add a ContentPart property to the shape they return, or only the field name will be a valid alternate Updated TextFieldDriver Fixed a bug where a dash after a dot in a file name was preventing proper harvesting --HG-- branch : dev extra : rebase_source : cae3d8cf544628b5f35cfc584ebbedf4d505c8ce
This commit is contained in:
@@ -100,5 +100,22 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
VerifyShapeType("Views", "Parts.Common.Body.Summary", "Parts_Common_Body_Summary");
|
||||
VerifyShapeType("Views", "Parts.Localization.ContentTranslations.Summary", "Parts_Localization_ContentTranslations_Summary");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FieldNamesMayBeInSubfolderOrPrefixed() {
|
||||
VerifyShapeType("Views/Fields", "Common.Text", "Fields_Common_Text");
|
||||
VerifyShapeType("Views", "Fields.Common.Text", "Fields_Common_Text");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FieldNamesMayHaveLongOrShortAlternates() {
|
||||
VerifyShapeType("Views/Fields", "Common.Text-FirstName", "Fields_Common_Text__FirstName");
|
||||
VerifyShapeType("Views/Fields", "Common.Text-FirstName.SpecialCase", "Fields_Common_Text_SpecialCase__FirstName");
|
||||
VerifyShapeType("Views/Fields", "Common.Text-FirstName-MyContentType", "Fields_Common_Text__FirstName__MyContentType");
|
||||
|
||||
VerifyShapeType("Views", "Fields.Common.Text-FirstName", "Fields_Common_Text__FirstName");
|
||||
VerifyShapeType("Views", "Fields.Common.Text-FirstName.SpecialCase", "Fields_Common_Text_SpecialCase__FirstName");
|
||||
VerifyShapeType("Views", "Fields.Common.Text-FirstName-MyContentType", "Fields_Common_Text__FirstName__MyContentType");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
|
||||
protected override DriverResult Display(ContentPart part, TextField field, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Common_Text", GetDifferentiator(field, part),
|
||||
() => shapeHelper.Fields_Common_Text(ContentField: field, Name: field.Name, Value: field.Value));
|
||||
() => shapeHelper.Fields_Common_Text(ContentPart: part, ContentField: field, Name: field.Name, Value: field.Value));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, TextField field, dynamic shapeHelper) {
|
||||
|
@@ -20,11 +20,6 @@ namespace Orchard.Core.Common {
|
||||
string flavor = displaying.Shape.EditorFlavor;
|
||||
displaying.ShapeMetadata.Alternates.Add("Body_Editor__" + flavor);
|
||||
});
|
||||
builder.Describe("Fields_Common_Text")
|
||||
.OnDisplaying(displaying => {
|
||||
string textFieldName = displaying.Shape.Name;
|
||||
displaying.ShapeMetadata.Alternates.Add("Fields_Common_Text__" + textFieldName);
|
||||
});
|
||||
}
|
||||
|
||||
[Shape]
|
||||
|
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
namespace Orchard.ContentManagement.Drivers {
|
||||
public abstract class ContentFieldDriver<TField> : IContentFieldDriver where TField : ContentField, new() {
|
||||
@@ -65,7 +66,30 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
}
|
||||
|
||||
private ContentShapeResult ContentShapeImplementation(string shapeType, string differentiator, Func<BuildShapeContext, object> shapeBuilder) {
|
||||
return new ContentShapeResult(shapeType, Prefix, shapeBuilder).Differentiator(differentiator);
|
||||
return new ContentShapeResult(shapeType, Prefix, ctx => AddAlternates(shapeBuilder(ctx), differentiator)).Differentiator(differentiator);
|
||||
}
|
||||
|
||||
private object AddAlternates(dynamic shape, string differentiator) {
|
||||
// automatically add shape alternates for shapes added by fields
|
||||
// [ShapeType__FieldName] for ShapeType-FieldName templates
|
||||
// [ShapeType__Part] for ShapeType-Part templates
|
||||
// [ShapeType__Part_FieldName] for ShapeType-FieldName.Part templates
|
||||
|
||||
// for fields on dynamic parts the part name is the same as the content type name
|
||||
// ex. Fields/Common.Text-Something.FirstName
|
||||
|
||||
ShapeMetadata metadata = shape.Metadata;
|
||||
if (!string.IsNullOrEmpty(differentiator))
|
||||
metadata.Alternates.Add(metadata.Type + "__" + differentiator);
|
||||
|
||||
ContentPart part = shape.ContentPart;
|
||||
if (part != null) {
|
||||
metadata.Alternates.Add(metadata.Type + "__" + part.PartDefinition.Name);
|
||||
if (!string.IsNullOrEmpty(differentiator))
|
||||
metadata.Alternates.Add(metadata.Type + "__" + part.PartDefinition.Name + "__" + differentiator);
|
||||
}
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
private object CreateShape(BuildShapeContext context, string shapeType) {
|
||||
|
@@ -17,8 +17,9 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
}
|
||||
|
||||
public IEnumerable<HarvestShapeHit> HarvestShape(HarvestShapeInfo info) {
|
||||
var lastDash = info.FileName.LastIndexOf('-');
|
||||
var lastDot = info.FileName.LastIndexOf('.');
|
||||
if (lastDot <= 0) {
|
||||
if (lastDot <= 0 || lastDot < lastDash) {
|
||||
yield return new HarvestShapeHit {
|
||||
ShapeType = Adjust(info.SubPath, info.FileName, null)
|
||||
};
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -11,6 +12,7 @@ using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
public class ShapeTemplateBindingStrategy : IShapeTableProvider {
|
||||
@@ -38,8 +40,11 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
_virtualPathMonitor = virtualPathMonitor;
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
_shapeTemplateViewEngines = shapeTemplateViewEngines;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
private static IEnumerable<ExtensionDescriptor> Once(IEnumerable<FeatureDescriptor> featureDescriptors) {
|
||||
var once = new ConcurrentDictionary<string, object>();
|
||||
return featureDescriptors.Select(fd => fd.Extension).Where(ed => once.TryAdd(ed.Id, null)).ToList();
|
||||
@@ -92,6 +97,11 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
var hit = iter;
|
||||
var featureDescriptors = iter.extensionDescriptor.Features.Where(fd => fd.Id == hit.extensionDescriptor.Id);
|
||||
foreach (var featureDescriptor in featureDescriptors) {
|
||||
Logger.Debug("Binding {0} as shape [{1}] for feature {2}",
|
||||
hit.shapeContext.harvestShapeInfo.TemplateVirtualPath,
|
||||
iter.shapeContext.harvestShapeHit.ShapeType,
|
||||
featureDescriptor.Id);
|
||||
|
||||
builder.Describe(iter.shapeContext.harvestShapeHit.ShapeType)
|
||||
.From(new Feature { Descriptor = featureDescriptor })
|
||||
.BoundAs(
|
||||
|
Reference in New Issue
Block a user