Adding scope ctor parameter to localization component.

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4041484
This commit is contained in:
loudej
2009-11-20 02:49:20 +00:00
parent b759bba2ec
commit 35b1b5a1d4
18 changed files with 207 additions and 83 deletions

View File

@@ -1,9 +1,51 @@
using Orchard.Core.Common.Records;
using System;
using Orchard.Core.Common.Records;
using Orchard.Models;
using Orchard.Security;
namespace Orchard.Core.Common.Models {
public class CommonPart : ContentPartForRecord<CommonRecord> {
public IUser Owner { get; set; }
private readonly Lazy<IUser> _owner = new Lazy<IUser>();
private readonly Lazy<ContentItem> _container = new Lazy<ContentItem>();
public IUser Owner {
get { return _owner.Value; }
set { _owner.Value = value; }
}
public ContentItem Container {
get { return _container.Value; }
set { _container.Value = value; }
}
public void LoadOwner(Func<IUser> loader) {
_owner.Loader(loader);
}
public void LoadContainer(Func<ContentItem> loader) {
_container.Loader(loader);
}
}
public class Lazy<T> {
private Func<T> _loader;
private T _value;
public void Loader(Func<T> loader) {
_loader = loader;
}
public T Value {
get {
if (_loader != null) {
_value = _loader();
_loader = null;
}
return _value;
}
set {
_value = value;
_loader = null;
}
}
}
}

View File

@@ -40,10 +40,17 @@ namespace Orchard.Core.Common.Models {
}
}
void LoadOwnerModel(LoadContentContext context, CommonPart instance) {
if (instance.Record.OwnerId != 0) {
instance.Owner = _contentManager.Get(instance.Record.OwnerId).As<IUser>();
}
protected override void UpdateEditors(UpdateContentContext context) {
var part = context.ContentItem.As<CommonPart>();
if (part==null)
return;
part.Record.ModifiedUtc = _clock.UtcNow;
}
void LoadOwnerModel(LoadContentContext context, CommonPart part) {
part.LoadOwner(() => _contentManager.Get<IUser>(part.Record.OwnerId));
part.LoadContainer(() => part.Record.Container == null ? null : _contentManager.Get(part.Record.Container.Id));
}
}
}

View File

@@ -4,6 +4,7 @@ using Orchard.Models.Records;
namespace Orchard.Core.Common.Records {
public class CommonRecord : ContentPartRecord {
public virtual int OwnerId { get; set; }
public virtual ContentItemRecord Container { get; set; }
public virtual DateTime? CreatedUtc { get; set; }
public virtual DateTime? ModifiedUtc { get; set; }
}

View File

@@ -1,4 +1,5 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.DevTools.ViewModels.ContentDetailsViewModel>" %>
<%@ Import Namespace="Orchard.Models"%>
<%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="Orchard.Mvc.Html" %>
@@ -36,13 +37,23 @@
<%=Html.Encode(" (" + partType.GetGenericArguments().First().Namespace + ")")%><%}
else {%><%=Html.Encode(partType.Name)%></span>
<%=Html.Encode( " (" + partType.Namespace + ")")%><%
}%>
}
%>
<ul style="margin-left: 20px">
<%foreach (var prop in partType.GetProperties().Where(x => x.DeclaringType == partType)) {
var value = prop.GetValue(Model.Locate(partType), null);%>
<li style="font-weight: normal;">
<%=Html.Encode(prop.Name) %>:
<%=Html.Encode(value) %>
<%var valueItem = value as ContentItem;
if (valueItem == null && value is IContentItemPart) {
valueItem = (value as IContentItemPart).ContentItem;
}
if (valueItem != null) {
%><%=Html.ActionLink(valueItem.ContentType + " #" + valueItem.Id, "details", new { valueItem.Id }, new { })%><%
}
%>
<ul style="margin-left: 20px">
<%if (value == null || prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)) { }
else if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)) {

View File

@@ -1,14 +1,14 @@
using Orchard.UI.Navigation;
namespace Orchard.Wikis {
public class AdminMenu : INavigationProvider {
public string MenuName { get { return "admin"; } }
//public class AdminMenu : INavigationProvider {
// public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add("Wiki", "9",
menu => menu
.Add("Wiki Pages", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Wikis" }))
);
}
}
// public void GetNavigation(NavigationBuilder builder) {
// builder.Add("Wiki", "9",
// menu => menu
// .Add("Wiki Pages", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Wikis" }))
// );
// }
//}
}

View File

@@ -6,28 +6,28 @@ using Orchard.Security;
namespace Orchard.Wikis.Controllers {
public class AdminController : Controller {
private readonly IContentManager _contentManager;
//private readonly IContentManager _contentManager;
public AdminController(IContentManager contentManager) {
_contentManager = contentManager;
}
//public AdminController(IContentManager contentManager) {
// _contentManager = contentManager;
//}
public ActionResult Index() {
return View(new AdminViewModel());
}
//public ActionResult Index() {
// return View(new AdminViewModel());
//}
public IUser CurrentUser { get; set; }
//public IUser CurrentUser { get; set; }
public ActionResult Create() {
var page = _contentManager.New("wikipage");
_contentManager.Create(page);
//public ActionResult Create() {
// var page = _contentManager.New("wikipage");
// _contentManager.Create(page);
return RedirectToAction("View", new{page.Id});
}
// return RedirectToAction("View", new{page.Id});
//}
public ActionResult View(int id) {
var page = _contentManager.Get(id).As<CommonPart>();
return View(page);
}
//public ActionResult View(int id) {
// var page = _contentManager.Get(id).As<CommonPart>();
// return View(page);
//}
}
}

View File

@@ -1,9 +1,11 @@
using System;
using System.Linq;
using System.Web.Mvc;
using Orchard.Core.Common.Models;
using Orchard.Data;
using Orchard.Models;
using Orchard.Models.Driver;
using Orchard.Settings;
using Orchard.Wikis.Models;
using Orchard.Wikis.ViewModels;
@@ -39,10 +41,13 @@ namespace Orchard.Wikis.Controllers
return View(new PageCreateViewModel());
}
public ISite CurrentSite { get; set; }
[HttpPost]
public ActionResult Create(PageCreateViewModel model) {
var page = _contentManager.New<WikiPage>("wikipage");
page.Record.Name = model.Name;
page.As<CommonPart>().Container = CurrentSite.ContentItem;
_contentManager.Create(page);
return RedirectToAction("show", new {page.ContentItem.Id});
}

View File

@@ -20,14 +20,10 @@ todo: (heskew) rework how/what pages are assembled when we get into theming --%>
</head>
<body>
<div id="banner" role="banner">
<h1><%=Html.ActionLink(_("Project Orchard"), "Index", new { Area = "", Controller = "Home" })%></h1>
<div><%=Html.ActionLink(_("Your Site"), "Index", new { Area = "", Controller = "Home" })%></div>
<h1><%=Html.ActionLink(T("Project Orchard").ToString(), "Index", new { Area = "", Controller = "Home" })%></h1>
<div><%=Html.ActionLink(T("Your Site").ToString(), "Index", new { Area = "", Controller = "Home" })%></div>
<% if (Model.CurrentUser != null) {
%><div id="login"><%=_(
"User: {0} | {1}",
Model.CurrentUser.UserName, /* todo: (heskew) need some encode extension methods */
Html.ActionLink("Logout", "LogOff", new { Area = "", Controller = "Account" }).ToString()
)%></div><%
%><div id="login"><%=T("User")%><%=H(Model.CurrentUser.UserName)%> | <%=Html.ActionLink(T("Logout").ToString(), "LogOff", new { Area = "", Controller = "Account" }) %></div><%
} %>
</div>
<div id="main" role="main">

View File

@@ -2,15 +2,27 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Orchard.Logging;
namespace Orchard.Localization {
public interface IText : IDependency {
public interface IText {
LocalizedString Get(string textHint, params object[] args);
}
public class Text : IText {
private readonly string _scope;
public Text(string scope) {
_scope = scope;
Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
public LocalizedString Get(string textHint, params object[] args) {
Logger.Debug("{0} localizing '{1}'", _scope, textHint);
var localizedFormat = textHint;
var localizedText = string.Format(localizedFormat, args);
return new LocalizedString(localizedText);

View File

@@ -3,22 +3,28 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Module=Autofac.Builder.Module;
using Module = Autofac.Builder.Module;
namespace Orchard.Localization {
public class LocalizationModule : Module{
public class LocalizationModule : Module {
protected override void Load(Autofac.Builder.ContainerBuilder builder) {
builder.Register<Text>().As<IText>().FactoryScoped();
}
protected override void AttachToComponentRegistration(Autofac.IContainer container, Autofac.IComponentRegistration registration) {
var userProperty = FindUserProperty(registration.Descriptor.BestKnownImplementationType);
if (userProperty != null) {
registration.Activated += (sender, e) => {
//var authenticationService = e.Context.Resolve<IAuthenticationService>();
//var currentUser = authenticationService.GetAuthenticatedUser();
var scope = registration.Descriptor.BestKnownImplementationType.FullName;
var text = e.Context.Resolve<IText>();
var textDelegate = new Localizer(text.Get);
userProperty.SetValue(e.Instance, textDelegate, null);
registration.Activated += (sender, e) => {
//var authenticationService = e.Context.Resolve<IAuthenticationService>();
//var currentUser = authenticationService.GetAuthenticatedUser();
var localizer = LocalizationUtilities.Resolve(e.Context, scope);
userProperty.SetValue(e.Instance, localizer, null);
};
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Autofac;
using Orchard.Mvc;
namespace Orchard.Localization {
public class LocalizationUtilities {
public static Localizer Resolve(ControllerContext controllerContext, string scope) {
var context = OrchardControllerFactory.GetRequestContainer(controllerContext.RouteData);
return context == null ? NullLocalizer.Instance : Resolve(context, scope);
}
public static Localizer Resolve(IContext context, string scope) {
var text = context.Resolve<IText>(new NamedParameter("scope", scope));
return text.Get;
}
}
}

View File

@@ -16,35 +16,41 @@ namespace Orchard.Models {
}
public static T Get<T>(this IContentManager manager, int id) where T : class, IContentItemPart {
return manager.Get(id).Get<T>();
var contentItem = manager.Get(id);
return contentItem == null ? null : contentItem.Get<T>();
}
public static void Create(this IContentManager manager, IContentItemPart part) {
manager.Create(part.ContentItem);
}
public static bool Has<T>(this IContentItemPart part) {
return part.ContentItem.Has<T>();
public static bool Is<T>(this ContentItem contentItem) {
return contentItem == null ? false : contentItem.Has(typeof(T));
}
public static T Get<T>(this IContentItemPart part) {
return part.ContentItem.Get<T>();
public static bool Has<T>(this ContentItem contentItem) {
return contentItem == null ? false : contentItem.Has(typeof(T));
}
public static T As<T>(this ContentItem contentItem) where T : class {
return contentItem == null ? null : (T)contentItem.Get(typeof(T));
}
public static T Get<T>(this ContentItem contentItem) where T : class {
return contentItem == null ? null : (T)contentItem.Get(typeof(T));
}
public static bool Is<T>(this IContentItemPart part) {
return part.ContentItem.Has<T>();
return part == null ? false : part.ContentItem.Has(typeof(T));
}
public static bool Has<T>(this IContentItemPart part) {
return part == null ? false : part.ContentItem.Has(typeof(T));
}
public static T As<T>(this IContentItemPart part) where T : class {
return part == null ? null : (T)part.ContentItem.Get(typeof(T));
}
public static T Get<T>(this IContentItemPart part) where T : class {
return part == null ? null : (T)part.ContentItem.Get(typeof(T));
}
public static T As<T>(this IContentItemPart part) {
return part.ContentItem.Get<T>();
}
public static bool Is<T>(this ContentItem contentItem) {
return contentItem.Has<T>();
}
public static T As<T>(this ContentItem contentItem) {
return contentItem.Get<T>();
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.Models.Records;
namespace Orchard.Models {
public class ContentItem {
@@ -11,14 +13,17 @@ namespace Orchard.Models {
public int Id { get; set; }
public string ContentType { get; set; }
public ContentItemRecord ContentItemRecord { get; set; }
public IEnumerable<IContentItemPart> Parts { get { return _parts; } }
public bool Has<TPart>() {
return _parts.Any(part => part is TPart);
public bool Has(Type partType) {
return _parts.Any(part => partType.IsAssignableFrom(part.GetType()));
}
public TPart Get<TPart>() {
return _parts.OfType<TPart>().FirstOrDefault();
public IContentItemPart Get(Type partType) {
return _parts.FirstOrDefault(part => partType.IsAssignableFrom(part.GetType()));
}
public void Weld(IContentItemPart part) {

View File

@@ -63,12 +63,16 @@ namespace Orchard.Models {
if (contentItemRecord == null)
return null;
// allocate instance and set record property
var contentItem = New(contentItemRecord.ContentType.Name);
contentItem.ContentItemRecord = contentItemRecord;
// create a context with a new instance to load
var context = new LoadContentContext {
Id = contentItemRecord.Id,
ContentType = contentItemRecord.ContentType.Name,
ContentItemRecord = contentItemRecord,
ContentItem = New(contentItemRecord.ContentType.Name)
ContentItem = contentItem
};
// set the id
@@ -89,6 +93,7 @@ namespace Orchard.Models {
// produce root record to determine the model id
var modelRecord = new ContentItemRecord { ContentType = AcquireContentTypeRecord(contentItem.ContentType) };
_contentItemRepository.Create(modelRecord);
contentItem.ContentItemRecord = modelRecord;
// build a context with the initialized instance to create
var context = new CreateContentContext {

View File

@@ -2,7 +2,7 @@
namespace Orchard.Models.Driver {
public class ContentItemBuilder {
private ContentItem _item;
private readonly ContentItem _item;
public ContentItemBuilder(string contentType) {
_item = new ContentItem { ContentType = contentType };

View File

@@ -35,7 +35,7 @@ namespace Orchard.Mvc {
return null;
}
private static IContext GetRequestContainer(RouteData routeData) {
public static IContext GetRequestContainer(RouteData routeData) {
object dataTokenValue;
if (routeData != null &&
routeData.DataTokens != null &&

View File

@@ -3,20 +3,26 @@ using Orchard.Localization;
namespace Orchard.Mvc {
public class ViewPage<TModel> : System.Web.Mvc.ViewPage<TModel> {
public string _(string textHint)
{
return new LocalizedString(textHint).ToString();
public ViewPage() {
T = NullLocalizer.Instance;
}
public string _(string textHint, params string[] formatTokens)
{
return string.Format(_(textHint), formatTokens);
public override void RenderView(ViewContext viewContext) {
T = LocalizationUtilities.Resolve(viewContext, AppRelativeVirtualPath);
base.RenderView(viewContext);
}
public MvcHtmlString _Encoded(string textHint)
{
return MvcHtmlString.Create(Html.Encode(_(textHint)));
public Localizer T { get; set; }
public MvcHtmlString H(string value) {
return MvcHtmlString.Create(Html.Encode(value));
}
public MvcHtmlString _Encoded(string textHint) {
return MvcHtmlString.Create(Html.Encode(T(textHint)));
}
public MvcHtmlString _Encoded(string textHint, params string[] formatTokens) {
return MvcHtmlString.Create(Html.Encode(_(textHint, formatTokens)));
return MvcHtmlString.Create(Html.Encode(T(textHint, formatTokens)));
}
}
}

View File

@@ -121,6 +121,7 @@
<Compile Include="Data\Conventions\CascadeAllDeleteOrphanAttribute.cs" />
<Compile Include="Localization\IText.cs" />
<Compile Include="Localization\LocalizationModule.cs" />
<Compile Include="Localization\LocalizationUtilities.cs" />
<Compile Include="Localization\Localizer.cs" />
<Compile Include="Localization\LocalizedString.cs" />
<Compile Include="Localization\NullLocalizer.cs" />