#18075: Fixing localization resolution in alternates

Work Item: 18075

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2011-09-21 22:03:28 -07:00
parent 0512f4cb78
commit 7ac2bfbcea
5 changed files with 54 additions and 4 deletions

View File

@@ -47,7 +47,8 @@ namespace Orchard.DisplayManagement.Descriptors {
var alterations = alterationSets
.SelectMany(shapeAlterations => shapeAlterations)
.Where(alteration => IsModuleOrRequestedTheme(alteration, themeName))
.OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority);
.OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority)
.ToList();
var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase)
.Select(group => group.Aggregate(
@@ -57,6 +58,14 @@ namespace Orchard.DisplayManagement.Descriptors {
return descriptor;
})).ToList();
foreach(var descriptor in descriptors) {
foreach(var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList()) {
var local = new ShapeDescriptor { ShapeType = descriptor.ShapeType };
alteration.Alter(local);
descriptor.BindingSources.Add(local.BindingSource);
}
}
var result = new ShapeTable {
Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase),
Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase),

View File

@@ -12,6 +12,7 @@ namespace Orchard.DisplayManagement.Descriptors {
Displaying = Enumerable.Empty<Action<ShapeDisplayingContext>>();
Displayed = Enumerable.Empty<Action<ShapeDisplayedContext>>();
Wrappers = new List<string>();
BindingSources = new List<string>();
Bindings = new Dictionary<string, ShapeBinding>(StringComparer.OrdinalIgnoreCase);
Placement = ctx => new PlacementInfo {Location = DefaultPlacement};
}
@@ -47,6 +48,7 @@ namespace Orchard.DisplayManagement.Descriptors {
public string DefaultPlacement { get; set; }
public IList<string> Wrappers { get; set; }
public IList<string> BindingSources { get; set; }
}
public class ShapeBinding {

View File

@@ -68,6 +68,9 @@ namespace Orchard.DisplayManagement.Implementation {
shapeBinding.ShapeDescriptor.Displaying.Invoke(action => action(displayingContext), Logger);
}
// copy all binding sources (all templates for this shape) in order to use them as Localization scopes
shapeMetadata.BindingSources = shapeBinding.ShapeDescriptor.BindingSources;
// invoking ShapeMetadata displaying events
shapeMetadata.Displaying.Invoke(action => action(displayingContext), Logger);

View File

@@ -9,6 +9,7 @@ namespace Orchard.DisplayManagement.Shapes {
public ShapeMetadata() {
Wrappers = new List<string>();
Alternates = new List<string>();
BindingSources = new List<string>();
Displaying = Enumerable.Empty<Action<ShapeDisplayingContext>>();
Displayed = Enumerable.Empty<Action<ShapeDisplayedContext>>();
}
@@ -27,6 +28,8 @@ namespace Orchard.DisplayManagement.Shapes {
public IEnumerable<Action<ShapeDisplayingContext>> Displaying { get; private set; }
public IEnumerable<Action<ShapeDisplayedContext>> Displayed { get; private set; }
public IList<string> BindingSources { get; set; }
public void OnDisplaying(Action<ShapeDisplayingContext> action) {
var existing = Displaying ?? Enumerable.Empty<Action<ShapeDisplayingContext>>();
Displaying = existing.Concat(new[] { action });

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
@@ -22,7 +23,40 @@ namespace Orchard.Mvc.ViewEngines.Razor {
private object _layout;
private WorkContext _workContext;
public Localizer T { get { return _localizer; } }
public Localizer T {
get {
// first time used, create it
if(_localizer == NullLocalizer.Instance) {
// if the Model is a shape, get localization scopes from binding sources
// e.g., Logon.cshtml in a theme, overriging Users/Logon.cshtml, needs T to
// fallback to the one in Users
var shape = Model as IShape;
if(shape != null && shape.Metadata.BindingSources.Count > 1) {
var localizers = shape.Metadata.BindingSources.Reverse().Select(scope => LocalizationUtilities.Resolve(ViewContext, scope)).ToList();
_localizer = (text, args) => {
foreach(var localizer in localizers) {
var hint = localizer(text, args);
// if not localized using this scope, use next scope
if(hint.Text != text) {
return hint;
}
}
// no localization found, return default value
return new LocalizedString(text, VirtualPath, text, args);
};
}
else {
// not a shape, use the VirtualPath as scope
_localizer = LocalizationUtilities.Resolve(ViewContext, VirtualPath);
}
}
return _localizer;
}
}
public dynamic Display { get { return _display; } }
// review: (heskew) is it going to be a problem?
public new dynamic Layout { get { return _layout; } }
@@ -82,8 +116,7 @@ namespace Orchard.Mvc.ViewEngines.Razor {
_workContext = ViewContext.GetWorkContext();
_workContext.Resolve<IComponentContext>().InjectUnsetProperties(this);
_localizer = LocalizationUtilities.Resolve(ViewContext, VirtualPath);
_display = DisplayHelperFactory.CreateHelper(ViewContext, this);
_layout = _workContext.Layout;
}