Partially complete refactoring. Adding transactions. Adjusting template locations. CURRENTLY BROKEN

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4044385
This commit is contained in:
loudej
2009-12-21 01:30:24 +00:00
parent 3312bdd55f
commit 8d99ca8bee
65 changed files with 720 additions and 503 deletions

View File

@@ -50,6 +50,7 @@ namespace Orchard.Tests.Packages {
[TearDown] [TearDown]
public void Cleanup() { public void Cleanup() {
_container.Dispose();
_session.Close(); _session.Close();
} }

View File

@@ -9,6 +9,7 @@ using Autofac.Builder;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using Orchard.Data; using Orchard.Data;
using Orchard.Environment;
using Orchard.Models; using Orchard.Models;
using Orchard.Models.Driver; using Orchard.Models.Driver;
using Orchard.Models.Records; using Orchard.Models.Records;
@@ -30,7 +31,10 @@ namespace Orchard.Tests.Packages.Users.Controllers {
builder.Register<DefaultContentQuery>().As<IContentQuery>().FactoryScoped(); builder.Register<DefaultContentQuery>().As<IContentQuery>().FactoryScoped();
builder.Register<MembershipService>().As<IMembershipService>(); builder.Register<MembershipService>().As<IMembershipService>();
builder.Register<UserHandler>().As<IContentHandler>(); builder.Register<UserHandler>().As<IContentHandler>();
builder.Register<OrchardServices>().As<IOrchardServices>();
builder.Register<TransactionManager>().As<ITransactionManager>();
builder.Register(new Mock<INotifier>().Object); builder.Register(new Mock<INotifier>().Object);
builder.Register(new Mock<IAuthorizer>().Object);
} }
protected override IEnumerable<Type> DatabaseTypes { protected override IEnumerable<Type> DatabaseTypes {
@@ -76,10 +80,42 @@ namespace Orchard.Tests.Packages.Users.Controllers {
Assert.That(model.Rows, Is.Not.Null); Assert.That(model.Rows, Is.Not.Null);
} }
public static class Values {
public static IValueProvider Of<T>(T obj) {
return new ValueProvider<T>(obj);
}
class ValueProvider<T> : IValueProvider {
private readonly T _obj;
public ValueProvider(T obj) {
_obj = obj;
}
public bool ContainsPrefix(ControllerContext controllerContext, string prefix) {
return typeof(T).GetProperties().Any(x => x.Name.StartsWith(prefix));
}
public ValueProviderResult GetValue(ControllerContext controllerContext, string key) {
var property = typeof(T).GetProperty(key);
if (property == null)
return null;
return new ValueProviderResult(
property.GetValue(_obj, null),
Convert.ToString(property.GetValue(_obj, null)),
null);
}
}
}
[Test] [Test]
public void CreateShouldAddUserAndRedirect() { public void CreateShouldAddUserAndRedirect() {
var controller = _container.Resolve<AdminController>(); var controller = _container.Resolve<AdminController>();
var result = controller.Create(new UserCreateViewModel { UserName = "four",Password="five",ConfirmPassword="five" }); controller.ValueProvider = Values.Of(new {
UserName = "four",
Password = "five",
ConfirmPassword = "five"
});
var result = controller._Create();
Assert.That(result, Is.TypeOf<RedirectToRouteResult>()); Assert.That(result, Is.TypeOf<RedirectToRouteResult>());
var redirect = (RedirectToRouteResult)result; var redirect = (RedirectToRouteResult)result;
@@ -97,8 +133,12 @@ namespace Orchard.Tests.Packages.Users.Controllers {
var model = (UserEditViewModel)result.ViewData.Model; var model = (UserEditViewModel)result.ViewData.Model;
Assert.That(model.UserName, Is.EqualTo("two")); Assert.That(model.UserName, Is.EqualTo("two"));
var input = new FormCollection { { "UserName", "bubba" }, { "Email", "hotep" } }; var controller = _container.Resolve<AdminController>();
var result2 = _container.Resolve<AdminController>().Edit(id, input); controller.ValueProvider = Values.Of(new {
UserName = "bubba",
Email = "hotep",
});
var result2 = controller._Edit(id);
Assert.That(result2, Is.TypeOf<RedirectToRouteResult>()); Assert.That(result2, Is.TypeOf<RedirectToRouteResult>());
} }
} }

View File

@@ -175,7 +175,7 @@ namespace Orchard.Tests.Models {
[Test] [Test]
public void EditorsShouldBeOrderedByPositionAndDefaultPositionIsSix() { public void EditorsShouldBeOrderedByPositionAndDefaultPositionIsSix() {
var alpha = _manager.New("alpha"); var alpha = _manager.New("alpha");
var templates = _manager.BuildDisplayModel(alpha, null, null).Displays; var templates = _manager.BuildDisplayModel(alpha, null).Displays;
Assert.That(templates.Count(), Is.EqualTo(3)); Assert.That(templates.Count(), Is.EqualTo(3));
var t0 = templates.First(); var t0 = templates.First();

View File

@@ -41,7 +41,7 @@ namespace Orchard.Tests.Models {
}); });
var contentHandler = _container.Resolve<IContentHandler>(); var contentHandler = _container.Resolve<IContentHandler>();
var ctx = new BuildDisplayModelContext(new ItemDisplayModel(new ContentItem()), null, null, null); var ctx = new BuildDisplayModelContext(new ItemDisplayModel(new ContentItem()), null);
driver1.Verify(x => x.BuildDisplayModel(ctx), Times.Never()); driver1.Verify(x => x.BuildDisplayModel(ctx), Times.Never());
contentHandler.BuildDisplayModel(ctx); contentHandler.BuildDisplayModel(ctx);
@@ -58,7 +58,7 @@ namespace Orchard.Tests.Models {
var item = new ContentItem(); var item = new ContentItem();
item.Weld(new StubPart { Foo = new[] { "a", "b", "c" } }); item.Weld(new StubPart { Foo = new[] { "a", "b", "c" } });
var ctx = new BuildDisplayModelContext(new ItemDisplayModel(item), "", "", null); var ctx = new BuildDisplayModelContext(new ItemDisplayModel(item), "");
Assert.That(ctx.DisplayModel.Displays.Count(), Is.EqualTo(0)); Assert.That(ctx.DisplayModel.Displays.Count(), Is.EqualTo(0));
contentHandler.BuildDisplayModel(ctx); contentHandler.BuildDisplayModel(ctx);
Assert.That(ctx.DisplayModel.Displays.Count(), Is.EqualTo(1)); Assert.That(ctx.DisplayModel.Displays.Count(), Is.EqualTo(1));
@@ -71,7 +71,7 @@ namespace Orchard.Tests.Models {
get { return "Stub"; } get { return "Stub"; }
} }
protected override DriverResult Display(StubPart part, string groupName, string displayType) { protected override DriverResult Display(StubPart part, string displayType) {
var viewModel = new StubViewModel { Foo = string.Join(",", part.Foo) }; var viewModel = new StubViewModel { Foo = string.Join(",", part.Foo) };
if (displayType.StartsWith("Summary")) if (displayType.StartsWith("Summary"))
return PartialView(viewModel, "StubViewModelTerse").Location("topmeta"); return PartialView(viewModel, "StubViewModelTerse").Location("topmeta");
@@ -79,12 +79,12 @@ namespace Orchard.Tests.Models {
return PartialView(viewModel).Location("topmeta"); return PartialView(viewModel).Location("topmeta");
} }
protected override DriverResult Editor(StubPart part, string groupName) { protected override DriverResult Editor(StubPart part) {
var viewModel = new StubViewModel { Foo = string.Join(",", part.Foo) }; var viewModel = new StubViewModel { Foo = string.Join(",", part.Foo) };
return PartialView(viewModel).Location("last", "10"); return PartialView(viewModel).Location("last", "10");
} }
protected override DriverResult Editor(StubPart part, string groupName, IUpdateModel updater) { protected override DriverResult Editor(StubPart part, IUpdateModel updater) {
var viewModel = new StubViewModel { Foo = string.Join(",", part.Foo) }; var viewModel = new StubViewModel { Foo = string.Join(",", part.Foo) };
updater.TryUpdateModel(viewModel, Prefix, null, null); updater.TryUpdateModel(viewModel, Prefix, null, null);
part.Foo = viewModel.Foo.Split(new[] { ',' }).Select(x => x.Trim()).ToArray(); part.Foo = viewModel.Foo.Split(new[] { ',' }).Select(x => x.Trim()).ToArray();

View File

@@ -141,7 +141,7 @@
<Content Include="Common\Views\Shared\EditorTemplates\OwnerEditorViewModel.ascx" /> <Content Include="Common\Views\Shared\EditorTemplates\OwnerEditorViewModel.ascx" />
<Content Include="Themes\Styles\site.css" /> <Content Include="Themes\Styles\site.css" />
<Content Include="Themes\Views\Admin\Install.aspx" /> <Content Include="Themes\Views\Admin\Install.aspx" />
<Content Include="Themes\Views\Shared\document.aspx" /> <Content Include="Themes\Views\document.aspx" />
<Content Include="Themes\Views\Shared\EditorTemplates\ThemeSiteSettingsRecord.ascx" /> <Content Include="Themes\Views\Shared\EditorTemplates\ThemeSiteSettingsRecord.ascx" />
<Content Include="Themes\Views\Shared\layout.ascx" /> <Content Include="Themes\Views\Shared\layout.ascx" />
<Content Include="Themes\Views\Shared\user.ascx" /> <Content Include="Themes\Views\Shared\user.ascx" />

View File

@@ -26,14 +26,14 @@ namespace Orchard.Core.Settings.Controllers {
public ActionResult Index(string tabName) { public ActionResult Index(string tabName) {
var model = new Orchard.Core.Settings.ViewModels.SettingsIndexViewModel { var model = new Orchard.Core.Settings.ViewModels.SettingsIndexViewModel {
Site = _siteService.GetSiteSettings().As<SiteSettings>() }; Site = _siteService.GetSiteSettings().As<SiteSettings>() };
model.EditorModel = _modelManager.BuildEditorModel(model.Site, tabName); model.EditorModel = _modelManager.BuildEditorModel(model.Site);
return View(model); return View(model);
} }
[AcceptVerbs(HttpVerbs.Post)] [AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string tabName, FormCollection input) { public ActionResult Index(string tabName, FormCollection input) {
var viewModel = new SettingsIndexViewModel { Site = _siteService.GetSiteSettings().As<SiteSettings>() }; var viewModel = new SettingsIndexViewModel { Site = _siteService.GetSiteSettings().As<SiteSettings>() };
viewModel.EditorModel = _modelManager.UpdateEditorModel(viewModel.Site.ContentItem, tabName, this); viewModel.EditorModel = _modelManager.UpdateEditorModel(viewModel.Site.ContentItem, this);
if (!TryUpdateModel(viewModel, input.ToValueProvider())) { if (!TryUpdateModel(viewModel, input.ToValueProvider())) {
return View(viewModel); return View(viewModel);

View File

@@ -1,10 +1,28 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.Core.Settings.ViewModels.SettingsIndexViewModel>" %> <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.Core.Settings.ViewModels.SettingsIndexViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.Html"%>
<h2>Edit Settings</h2> <%@ Import Namespace="Orchard.Mvc.Html" %>
<h2>
Edit Settings</h2>
<%using (Html.BeginForm()) { %> <%using (Html.BeginForm()) { %>
<%= Html.ValidationSummary() %> <%= Html.ValidationSummary() %>
<%= Html.EditorForModel() %> <fieldset>
<legend>Global Settings</legend>
<fieldset> <fieldset>
<input class="button" type="submit" value="Save" /> <%=Html.LabelFor(x=>x.SiteName) %>
<%=Html.EditorFor(x=>x.SiteName) %>
<%=Html.ValidationMessage("SiteName", "*") %>
</fieldset> </fieldset>
<fieldset>
<%=Html.LabelFor(x => x.SuperUser) %>
<%=Html.EditorFor(x=>x.SuperUser) %>
<%=Html.ValidationMessage("SuperUser", "*") %>
</fieldset>
<%=Html.EditorFor(s=>s.Id) %>
</fieldset>
<% foreach (var e in Model.EditorModel.Editors) { %>
<%=Html.EditorFor(m => e.Model, e.TemplateName, e.Prefix)%>
<% } %>
<fieldset>
<input class="button" type="submit" value="Save" />
</fieldset>
<% } %> <% } %>

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using Orchard.Mvc.ViewModels;
namespace Orchard.Core.Themes.ViewModels {
public class CreateThemeViewModel : AdminViewModel {
[Required]
public string Name { get; set; }
[Required]
public string Author { get; set; }
[Required]
public string Description { get; set; }
[Required]
public string Version { get; set; }
[Required]
public string Tags { get; set; }
[Required]
public string Homepage { get; set; }
}
}

View File

@@ -165,6 +165,7 @@
<Content Include="Content\Images\title_background.gif" /> <Content Include="Content\Images\title_background.gif" />
<Content Include="Content\Site2.css" /> <Content Include="Content\Site2.css" />
<Content Include="Content\Site3.css" /> <Content Include="Content\Site3.css" />
<Content Include="Themes\BlueSky\Views\layout.ascx" />
<Content Include="Views\Shared\Messages.ascx" /> <Content Include="Views\Shared\Messages.ascx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -20,7 +20,7 @@ namespace Orchard.Blogs.Controllers {
public ActionResult List() { public ActionResult List() {
//TODO: (erikpo) Need to make templatePath be more convention based so if my controller name has "Admin" in it then "Admin/{type}" is assumed //TODO: (erikpo) Need to make templatePath be more convention based so if my controller name has "Admin" in it then "Admin/{type}" is assumed
var model = new AdminBlogsViewModel { var model = new AdminBlogsViewModel {
Blogs = _blogService.Get().Select(b => _contentManager.BuildDisplayModel(b, null, "Summary", "Admin/Blog")) Blogs = _blogService.Get().Select(b => _contentManager.BuildDisplayModel(b, "SummaryAdmin"))
}; };
return View(model); return View(model);
@@ -35,7 +35,7 @@ namespace Orchard.Blogs.Controllers {
//TODO: (erikpo) Need to make templatePath be more convention based so if my controller name has "Admin" in it then "Admin/{type}" is assumed //TODO: (erikpo) Need to make templatePath be more convention based so if my controller name has "Admin" in it then "Admin/{type}" is assumed
var model = new BlogForAdminViewModel { var model = new BlogForAdminViewModel {
Blog = _contentManager.BuildDisplayModel(blog, null, "Detail", "Admin/Blog") Blog = _contentManager.BuildDisplayModel(blog, "DetailAdmin")
}; };
return View(model); return View(model);

View File

@@ -37,7 +37,7 @@ namespace Orchard.Blogs.Controllers {
public ActionResult List() { public ActionResult List() {
var model = new BlogsViewModel { var model = new BlogsViewModel {
Blogs = _blogService.Get().Select(b => _contentManager.BuildDisplayModel(b, null, "Summary")) Blogs = _blogService.Get().Select(b => _contentManager.BuildDisplayModel(b, "Summary"))
}; };
return View(model); return View(model);
@@ -51,7 +51,7 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult(); return new NotFoundResult();
var model = new BlogViewModel { var model = new BlogViewModel {
Blog = _contentManager.BuildDisplayModel(blog, null, "Detail") Blog = _contentManager.BuildDisplayModel(blog, "Detail")
}; };
return View(model); return View(model);
@@ -68,7 +68,7 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult(); return new NotFoundResult();
var model = new CreateBlogViewModel { var model = new CreateBlogViewModel {
Blog = _contentManager.BuildEditorModel(blog, null) Blog = _contentManager.BuildEditorModel(blog)
}; };
return View(model); return View(model);
@@ -80,7 +80,7 @@ namespace Orchard.Blogs.Controllers {
if (!_authorizer.Authorize(Permissions.CreateBlog, T("Couldn't create blog"))) if (!_authorizer.Authorize(Permissions.CreateBlog, T("Couldn't create blog")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
model.Blog = _contentManager.UpdateEditorModel(_contentManager.New<Blog>("blog"), null, this); model.Blog = _contentManager.UpdateEditorModel(_contentManager.New<Blog>("blog"), this);
if (!ModelState.IsValid) if (!ModelState.IsValid)
return View(model); return View(model);
@@ -106,7 +106,7 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult(); return new NotFoundResult();
var model = new BlogEditViewModel { var model = new BlogEditViewModel {
Blog = _contentManager.BuildEditorModel(blog, "") Blog = _contentManager.BuildEditorModel(blog)
}; };
return View(model); return View(model);
@@ -124,7 +124,7 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult(); return new NotFoundResult();
var model = new BlogEditViewModel { var model = new BlogEditViewModel {
Blog = _contentManager.UpdateEditorModel(blog, "", this) Blog = _contentManager.UpdateEditorModel(blog, this)
}; };
if (!ModelState.IsValid) if (!ModelState.IsValid)

View File

@@ -56,7 +56,7 @@ namespace Orchard.Blogs.Controllers {
var model = new BlogPostViewModel { var model = new BlogPostViewModel {
Blog = blog, Blog = blog,
BlogPost = _contentManager.BuildDisplayModel(post, null, "Detail") BlogPost = _contentManager.BuildDisplayModel(post, "Detail")
}; };
return View(model); return View(model);
@@ -95,7 +95,7 @@ namespace Orchard.Blogs.Controllers {
if (blog == null) if (blog == null)
return new NotFoundResult(); return new NotFoundResult();
var blogPost = _contentManager.BuildEditorModel(_contentManager.New<BlogPost>("blogpost"), null); var blogPost = _contentManager.BuildEditorModel(_contentManager.New<BlogPost>("blogpost"));
blogPost.Item.Blog = blog; blogPost.Item.Blog = blog;
var model = new CreateBlogPostViewModel { var model = new CreateBlogPostViewModel {
@@ -117,7 +117,7 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult(); return new NotFoundResult();
BlogPost blogPost = _contentManager.Create<BlogPost>("blogpost", bp => { bp.Blog = blog; }); BlogPost blogPost = _contentManager.Create<BlogPost>("blogpost", bp => { bp.Blog = blog; });
model.BlogPost = _contentManager.UpdateEditorModel(blogPost, null, this); model.BlogPost = _contentManager.UpdateEditorModel(blogPost, this);
if (!ModelState.IsValid) if (!ModelState.IsValid)
return View(model); return View(model);
@@ -145,7 +145,7 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult(); return new NotFoundResult();
var model = new BlogPostEditViewModel { var model = new BlogPostEditViewModel {
BlogPost = _contentManager.BuildEditorModel(post, null) BlogPost = _contentManager.BuildEditorModel(post)
}; };
return View(model); return View(model);
@@ -168,7 +168,7 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult(); return new NotFoundResult();
var model = new BlogPostEditViewModel { var model = new BlogPostEditViewModel {
BlogPost = _contentManager.UpdateEditorModel(post, null, this) BlogPost = _contentManager.UpdateEditorModel(post, this)
}; };
IValueProvider values = input.ToValueProvider(); IValueProvider values = input.ToValueProvider();

View File

@@ -16,7 +16,7 @@ namespace Orchard.Blogs.Models {
Filters.Add(new ActivatingFilter<CommonAspect>("blog")); Filters.Add(new ActivatingFilter<CommonAspect>("blog"));
Filters.Add(new ActivatingFilter<RoutableAspect>("blog")); Filters.Add(new ActivatingFilter<RoutableAspect>("blog"));
Filters.Add(new StorageFilter<BlogRecord>(repository)); Filters.Add(new StorageFilter<BlogRecord>(repository));
Filters.Add(new ContentItemTemplates<Blog>("Detail", "Summary")); Filters.Add(new ContentItemTemplates<Blog>("Items/Blogs.Blog", "Detail Summary"));
OnGetEditorViewModel<Blog>((context, blog) => OnGetEditorViewModel<Blog>((context, blog) =>
context.AddEditor(new TemplateViewModel(blog) { TemplateName = "Blog/Fields", ZoneName = "primary", Position = "1" }) context.AddEditor(new TemplateViewModel(blog) { TemplateName = "Blog/Fields", ZoneName = "primary", Position = "1" })

View File

@@ -24,7 +24,7 @@ namespace Orchard.Blogs.Models {
Filters.Add(new ActivatingFilter<RoutableAspect>("blogpost")); Filters.Add(new ActivatingFilter<RoutableAspect>("blogpost"));
Filters.Add(new ActivatingFilter<BodyAspect>("blogpost")); Filters.Add(new ActivatingFilter<BodyAspect>("blogpost"));
Filters.Add(new StorageFilter<BlogPostRecord>(repository)); Filters.Add(new StorageFilter<BlogPostRecord>(repository));
Filters.Add(new ContentItemTemplates<BlogPost>("Detail", "Summary")); Filters.Add(new ContentItemTemplates<BlogPost>("Items/Blogs.BlogPost", "Detail Summary"));
OnCreated<BlogPost>((context, bp) => bp.Blog.PostCount++); OnCreated<BlogPost>((context, bp) => bp.Blog.PostCount++);
@@ -59,10 +59,15 @@ namespace Orchard.Blogs.Models {
switch(context.DisplayType) { switch(context.DisplayType) {
case "Detail": case "Detail":
context.AddDisplay( context.AddDisplay(
//TODO: (erikpo) Need to make templatePath be more convention based so if my controller name has "Admin" in it then "Admin/{type}" is assumed new TemplateViewModel(posts.Select(bp => contentManager.BuildDisplayModel(bp, "Summary"))) {
new TemplateViewModel(posts.Select(bp => contentManager.BuildDisplayModel(bp, null, "Summary", "Admin/BlogPost"))) TemplateName = "BlogPost/List",
{ ZoneName = "body"
TemplateName = "Admin/BlogPost/List", });
break;
case "DetailAdmin":
context.AddDisplay(
new TemplateViewModel(posts.Select(bp => contentManager.BuildDisplayModel(bp, "SummaryAdmin"))) {
TemplateName = "BlogPost/ListAdmin",
ZoneName = "body" ZoneName = "body"
}); });
break; break;

View File

@@ -158,9 +158,8 @@
<IISUrl> <IISUrl>
</IISUrl> </IISUrl>
<NTLMAuthentication>False</NTLMAuthentication> <NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer> <UseCustomServer>True</UseCustomServer>
<CustomServerUrl> <CustomServerUrl>http://orchard.codeplex.com/</CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile> <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties> </WebProjectProperties>
</FlavorProperties> </FlavorProperties>

View File

@@ -36,8 +36,8 @@ namespace Orchard.DevTools.Controllers {
.Select(x => x.GetType()) .Select(x => x.GetType())
.SelectMany(x => AllTypes(x)) .SelectMany(x => AllTypes(x))
.Distinct(); .Distinct();
model.DisplayModel = _contentManager.BuildDisplayModel(model.Item, null, null); model.DisplayModel = _contentManager.BuildDisplayModel(model.Item, null);
model.EditorModel = _contentManager.BuildEditorModel(model.Item, null); model.EditorModel = _contentManager.BuildEditorModel(model.Item);
return View(model); return View(model);
} }

View File

@@ -4,10 +4,10 @@ using Orchard.Models.ViewModels;
namespace Orchard.DevTools.Models { namespace Orchard.DevTools.Models {
public class DebugLinkHandler : ContentHandler { public class DebugLinkHandler : ContentHandler {
protected override void BuildDisplayModel(BuildDisplayModelContext context) { protected override void BuildDisplayModel(BuildDisplayModelContext context) {
context.AddDisplay(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { ZoneName = "recap", Position = "9999" }); context.AddDisplay(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { TemplateName="Parts/DevTools.ShowDebugLink", ZoneName = "recap", Position = "9999" });
} }
protected override void BuildEditorModel(BuildEditorModelContext context) { protected override void BuildEditorModel(BuildEditorModelContext context) {
context.AddEditor(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { ZoneName = "recap", Position = "9999" }); context.AddEditor(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { TemplateName = "Parts/DevTools.ShowDebugLink", ZoneName = "recap", Position = "9999" });
} }
} }
} }

View File

@@ -75,8 +75,8 @@
<Content Include="Views\Content\Details.aspx" /> <Content Include="Views\Content\Details.aspx" />
<Content Include="Views\Content\Index.aspx" /> <Content Include="Views\Content\Index.aspx" />
<Content Include="Views\Home\Index.aspx" /> <Content Include="Views\Home\Index.aspx" />
<Content Include="Views\Shared\DisplayTemplates\ShowDebugLink.ascx" /> <Content Include="Views\DisplayTemplates\Parts\DevTools.ShowDebugLink.ascx" />
<Content Include="Views\Shared\EditorTemplates\ShowDebugLink.ascx" /> <Content Include="Views\EditorTemplates\Parts\DevTools.ShowDebugLink.ascx" />
<Content Include="Web.config" /> <Content Include="Web.config" />
<Content Include="Views\Web.config" /> <Content Include="Views\Web.config" />
</ItemGroup> </ItemGroup>
@@ -88,6 +88,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="App_Data\" /> <Folder Include="App_Data\" />
<Folder Include="Views\Shared\DisplayTemplates\" />
<Folder Include="Views\Shared\EditorTemplates\" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

View File

@@ -3,121 +3,100 @@
<%@ Import Namespace="System.Reflection" %> <%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="Orchard.Mvc.Html" %> <%@ Import Namespace="Orchard.Mvc.Html" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TwoColumns</title>
<link href="<%=ResolveUrl("~/Content/Site2.css") %>" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header">
<div id="innerheader">
<% Html.Include("header"); %>
</div>
</div>
<div id="page">
<div id="sideBar">
<% Html.Include("Navigation"); %>
</div>
<div id="main">
<h3>
Content Item</h3>
<p>
Id:
<%=Model.Item.ContentItem.Id %></p>
<p>
ContentType:
<%=Model.Item.ContentItem.ContentType%> <%=Html.ItemDisplayLink(Model.Item) %> <%=Html.ItemEditLink("edit", Model.Item) %></p>
<h3>
Content Item Parts</h3>
<ul>
<%foreach (var partType in Model.PartTypes.OrderBy(x => x.Name)) {%>
<li><span style="font-weight: bold;">
<%if (partType.IsGenericType) {%><%=Html.Encode(partType.Name +" "+partType.GetGenericArguments().First().Name)%></span>
<%=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 IContent) {
valueItem = (value as IContent).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)) {
foreach (var item in value as IEnumerable) {
%>
<li><%=Html.Encode(item.GetType().Name) %>:<%=Html.Encode(item) %></li>
<%
}
} <h3>Content Item</h3>
else {%> <p>
<%foreach (var prop2 in value.GetType().GetProperties().Where(x => x.GetIndexParameters().Count() == 0)) {%> Id:
<li> <%=Model.Item.ContentItem.Id %></p>
<%=Html.Encode(prop2.Name)%> <p>
<%=Html.Encode(prop2.GetValue(value, null))%></li> ContentType:
<%} %> <%=Model.Item.ContentItem.ContentType%> <%=Html.ItemDisplayLink(Model.Item) %> <%=Html.ItemEditLink("edit", Model.Item) %></p>
<%} %>
</ul>
</li> <h3>Content Item Parts</h3>
<%} %> <ul>
</ul> <%foreach (var partType in Model.PartTypes.OrderBy(x => x.Name)) {%>
</li> <li><span style="font-weight: bold;">
<%}%> <%if (partType.IsGenericType) {%><%=Html.Encode(partType.Name +" "+partType.GetGenericArguments().First().Name)%></span>
</ul> <%=Html.Encode(" (" + partType.GetGenericArguments().First().Namespace + ")")%><%}
<h3> else {%><%=Html.Encode(partType.Name)%></span>
Displays</h3> <%=Html.Encode( " (" + partType.Namespace + ")")%><%
<ul> }
<%foreach (var display in Model.Displays) {%>
<li><span style="font-weight: bold"> %>
<%=Html.Encode(display.Prefix)%></span> <ul style="margin-left: 20px">
<%=Html.Encode(display.Model.GetType().Name)%> <%foreach (var prop in partType.GetProperties().Where(x => x.DeclaringType == partType)) {
(<%=Html.Encode(display.Model.GetType().Namespace)%>) var value = prop.GetValue(Model.Locate(partType), null);%>
Prefix:<%=Html.Encode(display.Prefix ?? "(null)")%> <li style="font-weight: normal;">
Zone:<%=Html.Encode(display.ZoneName ?? "(null)")%> <%=Html.Encode(prop.Name) %>:
Position:<%=Html.Encode(display.Position ?? "(null)")%> <%=Html.Encode(value) %>
<div style="margin-left: 20px; border: solid 1px black;"> <%var valueItem = value as ContentItem;
<%=Html.DisplayFor(x => display.Model, display.TemplateName, display.Prefix)%> if (valueItem == null && value is IContent) {
</div> valueItem = (value as IContent).ContentItem;
</li> }
<% if (valueItem != null) {
}%> %><%=Html.ActionLink(valueItem.ContentType + " #" + valueItem.Id, "details", new { valueItem.Id }, new { })%><%
</ul> }
<h3> %>
Editors</h3> <ul style="margin-left: 20px">
<ul> <%if (value == null || prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)) { }
<%foreach (var editor in Model.Editors) {%> else if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)) {
<li><span style="font-weight: bold"> foreach (var item in value as IEnumerable) {
<%=Html.Encode(editor.Prefix) %></span> %>
<%=Html.Encode(editor.Model.GetType().Name) %> <li><%=Html.Encode(item.GetType().Name) %>:<%=Html.Encode(item) %></li>
(<%=Html.Encode(editor.Model.GetType().Namespace) %>) <%
Prefix:<%=Html.Encode(editor.Prefix ?? "(null)")%> }
Zone:<%=Html.Encode(editor.ZoneName ?? "(null)")%>
Position:<%=Html.Encode(editor.Position??"(null)") %> }
<div style="margin-left: 20px; border: solid 1px black;"> else {%>
<%=Html.EditorFor(x=>editor.Model, editor.TemplateName, editor.Prefix) %> <%foreach (var prop2 in value.GetType().GetProperties().Where(x => x.GetIndexParameters().Count() == 0)) {%>
</div> <li>
</li> <%=Html.Encode(prop2.Name)%>
<% <%=Html.Encode(prop2.GetValue(value, null))%></li>
}%> <%} %>
</ul> <%} %>
</ul>
</li>
<%} %>
</ul>
</li>
<%}%>
</ul>
<h3>Displays</h3>
<ul>
<%foreach (var display in Model.Displays) {%>
<li><span style="font-weight: bold">
<%=Html.Encode(display.Prefix)%></span>
<%=Html.Encode(display.Model.GetType().Name)%>
(<%=Html.Encode(display.Model.GetType().Namespace)%>)
Prefix:<%=Html.Encode(display.Prefix ?? "(null)")%>
Zone:<%=Html.Encode(display.ZoneName ?? "(null)")%>
Position:<%=Html.Encode(display.Position ?? "(null)")%>
<div style="margin-left: 20px; border: solid 1px black;">
<%=Html.DisplayFor(x => display.Model, display.TemplateName, display.Prefix)%>
</div> </div>
<div id="footer"> </li>
<% Html.Include("footer"); %> <%
}%>
</ul>
<h3>Editors</h3>
<ul>
<%foreach (var editor in Model.Editors) {%>
<li><span style="font-weight: bold">
<%=Html.Encode(editor.Prefix) %></span>
<%=Html.Encode(editor.Model.GetType().Name) %>
(<%=Html.Encode(editor.Model.GetType().Namespace) %>)
Prefix:<%=Html.Encode(editor.Prefix ?? "(null)")%>
Zone:<%=Html.Encode(editor.ZoneName ?? "(null)")%>
Position:<%=Html.Encode(editor.Position??"(null)") %>
<div style="margin-left: 20px; border: solid 1px black;">
<%=Html.EditorFor(x=>editor.Model, editor.TemplateName, editor.Prefix) %>
</div> </div>
</div> </li>
</body> <%
</html> }%>
</ul>

View File

@@ -1,27 +1,7 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.DevTools.ViewModels.ContentIndexViewModel>" %> <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.DevTools.ViewModels.ContentIndexViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.Html"%> <%@ Import Namespace="Orchard.Mvc.Html"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TwoColumns</title>
<link href="<%=ResolveUrl("~/Content/Site2.css") %>" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header">
<div id="innerheader">
<% Html.Include("header"); %>
</div>
</div>
<div id="page">
<div id="sideBar">
<% Html.Include("Navigation"); %>
</div>
<div id="main">
<h3>Content Types</h3> <h3>Content Types</h3>
<ul> <ul>
<%foreach(var item in Model.Types.OrderBy(x=>x.Name)){%> <%foreach(var item in Model.Types.OrderBy(x=>x.Name)){%>
@@ -38,13 +18,3 @@
<%}%> <%}%>
</ul> </ul>
</div>
<div id="footer">
<% Html.Include("footer"); %>
</div>
</div>
</body>
</html>

View File

@@ -2,37 +2,4 @@
<%@ Import Namespace="Orchard.Mvc.ViewModels"%> <%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Mvc.Html"%> <%@ Import Namespace="Orchard.Mvc.Html"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TwoColumns</title>
<link href="<%=ResolveUrl("~/Content/Site2.css") %>" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header">
<div id="innerheader">
<% Html.Include("header"); %>
</div>
</div>
<div id="page">
<div id="sideBar">
<% Html.Include("Navigation"); %>
</div>
<div id="main">
<p><%=Html.ActionLink("Contents", "Index", "Content") %></p> <p><%=Html.ActionLink("Contents", "Index", "Content") %></p>
</div>
<div id="footer">
<% Html.Include("footer"); %>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.Data;
using Orchard.Models;
using Orchard.Models.Driver;
using Orchard.Models.ViewModels;
using Orchard.Roles.Models.NoRecord;
using Orchard.Roles.Records;
using Orchard.Roles.Services;
using Orchard.Roles.ViewModels;
using Orchard.Security;
using Orchard.UI.Notify;
namespace Orchard.Roles.Controllers {
public class UserRolesDriver : PartDriver<UserRoles> {
private readonly IRepository<UserRolesRecord> _userRolesRepository;
private readonly IRoleService _roleService;
private readonly INotifier _notifier;
public UserRolesDriver(
IRepository<UserRolesRecord> userRolesRepository,
IRoleService roleService,
INotifier notifier) {
_userRolesRepository = userRolesRepository;
_roleService = roleService;
_notifier = notifier;
}
protected override string Prefix {
get {
return "UserRoles";
}
}
protected override DriverResult Editor(UserRoles userRoles) {
var roles =
_roleService.GetRoles().Select(
x => new UserRoleEntry {
RoleId = x.Id,
Name = x.Name,
Granted = userRoles.Roles.Contains(x.Name)
});
var model = new UserRolesViewModel {
User = userRoles.As<IUser>(),
UserRoles = userRoles,
Roles = roles.ToList(),
};
return PartialView(model, "Parts/Roles.UserRoles");
}
protected override DriverResult Editor(UserRoles userRoles, IUpdateModel updater) {
var model = new UserRolesViewModel {
User = userRoles.As<IUser>(),
UserRoles = userRoles,
};
if (updater.TryUpdateModel(model, "UserRoles", null, null)) {
var currentUserRoleRecords = _userRolesRepository.Fetch(x => x.UserId == model.User.Id);
var currentRoleRecords = currentUserRoleRecords.Select(x => x.Role);
var targetRoleRecords = model.Roles.Where(x => x.Granted).Select(x => _roleService.GetRole(x.RoleId));
foreach (var addingRole in targetRoleRecords.Where(x => !currentRoleRecords.Contains(x))) {
_notifier.Warning(string.Format("Adding role {0} to user {1}", addingRole.Name, userRoles.As<IUser>().UserName));
_userRolesRepository.Create(new UserRolesRecord { UserId = model.User.Id, Role = addingRole });
}
foreach (var removingRole in currentUserRoleRecords.Where(x => !targetRoleRecords.Contains(x.Role))) {
_notifier.Warning(string.Format("Removing role {0} from user {1}", removingRole.Role.Name, userRoles.As<IUser>().UserName));
_userRolesRepository.Delete(removingRole);
}
}
return PartialView(model, "Parts/Roles.UserRoles");
}
}
}

View File

@@ -13,13 +13,9 @@ using Orchard.UI.Notify;
namespace Orchard.Roles.Models { namespace Orchard.Roles.Models {
public class UserRolesHandler : ContentHandler { public class UserRolesHandler : ContentHandler {
private readonly IRepository<UserRolesRecord> _userRolesRepository; private readonly IRepository<UserRolesRecord> _userRolesRepository;
private readonly IRoleService _roleService;
private readonly INotifier _notifier;
public UserRolesHandler(IRepository<UserRolesRecord> userRolesRepository, IRoleService roleService, INotifier notifier) { public UserRolesHandler(IRepository<UserRolesRecord> userRolesRepository) {
_userRolesRepository = userRolesRepository; _userRolesRepository = userRolesRepository;
_roleService = roleService;
_notifier = notifier;
Filters.Add(new ActivatingFilter<UserRoles>("user")); Filters.Add(new ActivatingFilter<UserRoles>("user"));
OnLoaded<UserRoles>((context, userRoles) => { OnLoaded<UserRoles>((context, userRoles) => {
@@ -29,51 +25,6 @@ namespace Orchard.Roles.Models {
}); });
} }
protected override void BuildEditorModel(BuildEditorModelContext context) {
var userRoles = context.ContentItem.As<UserRoles>();
if (userRoles != null) {
var roles =
_roleService.GetRoles().Select(
x => new UserRoleEntry {
RoleId = x.Id,
Name = x.Name,
Granted = userRoles.Roles.Contains(x.Name)
});
var viewModel = new UserRolesViewModel {
User = userRoles.As<IUser>(),
UserRoles = userRoles,
Roles = roles.ToList(),
};
context.AddEditor(new TemplateViewModel(viewModel, "UserRoles"));
}
}
protected override void UpdateEditorModel(UpdateEditorModelContext context) {
var userRoles = context.ContentItem.As<UserRoles>();
if (userRoles != null) {
var viewModel = new UserRolesViewModel();
if (context.Updater.TryUpdateModel(viewModel, "UserRoles", null, null)) {
var currentUserRoleRecords = _userRolesRepository.Fetch(x => x.UserId == context.ContentItem.Id);
var currentRoleRecords = currentUserRoleRecords.Select(x => x.Role);
var targetRoleRecords = viewModel.Roles.Where(x => x.Granted).Select(x => _roleService.GetRole(x.RoleId));
foreach (var addingRole in targetRoleRecords.Where(x => !currentRoleRecords.Contains(x))) {
_notifier.Warning(string.Format("Adding role {0} to user {1}", addingRole.Name, userRoles.As<IUser>().UserName));
_userRolesRepository.Create(new UserRolesRecord { UserId = context.ContentItem.Id, Role = addingRole });
}
foreach (var removingRole in currentUserRoleRecords.Where(x => !targetRoleRecords.Contains(x.Role))) {
_notifier.Warning(string.Format("Removing role {0} from user {1}", removingRole.Role.Name, userRoles.As<IUser>().UserName));
_userRolesRepository.Delete(removingRole);
}
}
context.AddEditor(new TemplateViewModel(viewModel, "UserRoles"));
}
}
} }
} }

View File

@@ -63,6 +63,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="AdminMenu.cs" /> <Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" /> <Compile Include="Controllers\AdminController.cs" />
<Compile Include="Controllers\UserRolesDriver.cs" />
<Compile Include="Records\PermissionRecord.cs" /> <Compile Include="Records\PermissionRecord.cs" />
<Compile Include="Records\RoleRecord.cs" /> <Compile Include="Records\RoleRecord.cs" />
<Compile Include="Models\UserRoles.cs" /> <Compile Include="Models\UserRoles.cs" />
@@ -82,7 +83,7 @@
<Content Include="Views\Admin\Create.aspx" /> <Content Include="Views\Admin\Create.aspx" />
<Content Include="Views\Admin\Edit.aspx" /> <Content Include="Views\Admin\Edit.aspx" />
<Content Include="Views\Admin\Index.aspx" /> <Content Include="Views\Admin\Index.aspx" />
<Content Include="Views\Shared\EditorTemplates\UserRolesViewModel.ascx" /> <Content Include="Views\EditorTemplates\Parts\Roles.UserRoles.ascx" />
<Content Include="Web.config" /> <Content Include="Web.config" />
<Content Include="Content\Site.css" /> <Content Include="Content\Site.css" />
<Content Include="Views\Web.config" /> <Content Include="Views\Web.config" />

View File

@@ -0,0 +1,18 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Orchard.Roles.ViewModels.UserRolesViewModel>" %>
<fieldset>
<legend>Roles</legend>
<% if (Model.Roles.Count > 0) {
var index = 0;
foreach (var entry in Model.Roles) {%>
<%=Html.Hidden("Roles[" + index + "].RoleId", entry.RoleId)%>
<%=Html.Hidden("Roles[" + index + "].Name", entry.Name)%>
<label for="<%="Roles[" + index + "]_Granted"%>">
<%= Html.CheckBox("Roles[" + index + "].Granted", entry.Granted)%>
<%=Html.Encode(entry.Name)%></label>
<%++index;
}
}
else {
%><p>There are no roles</p><%
} %>
</fieldset>

View File

@@ -32,7 +32,7 @@ namespace Orchard.Sandbox.Controllers {
Pages = _contentManager.Query<SandboxPage, SandboxPageRecord>() Pages = _contentManager.Query<SandboxPage, SandboxPageRecord>()
.OrderBy(x => x.Name) .OrderBy(x => x.Name)
.List() .List()
.Select(x => _contentManager.BuildDisplayModel(x, null, "SummaryList")) .Select(x => _contentManager.BuildDisplayModel(x, "SummaryList"))
}; };
return View(model); return View(model);
} }
@@ -40,7 +40,7 @@ namespace Orchard.Sandbox.Controllers {
public ActionResult Show(int id) { public ActionResult Show(int id) {
var page = _contentManager.Get<SandboxPage>(id); var page = _contentManager.Get<SandboxPage>(id);
var model = new PageShowViewModel { var model = new PageShowViewModel {
Page = _contentManager.BuildDisplayModel(page, null, "Detail") Page = _contentManager.BuildDisplayModel(page, "Detail")
}; };
return View(model); return View(model);
} }
@@ -80,7 +80,7 @@ namespace Orchard.Sandbox.Controllers {
var page = _contentManager.Get<SandboxPage>(id); var page = _contentManager.Get<SandboxPage>(id);
var model = new PageEditViewModel { var model = new PageEditViewModel {
Page = _contentManager.BuildEditorModel(page, null) Page = _contentManager.BuildEditorModel(page)
}; };
return View(model); return View(model);
} }
@@ -95,7 +95,7 @@ namespace Orchard.Sandbox.Controllers {
var page = _contentManager.Get<SandboxPage>(id); var page = _contentManager.Get<SandboxPage>(id);
var model = new PageEditViewModel { var model = new PageEditViewModel {
Page = _contentManager.UpdateEditorModel(page, null, this) Page = _contentManager.UpdateEditorModel(page, this)
}; };
if (!ModelState.IsValid) if (!ModelState.IsValid)
return View(model); return View(model);

View File

@@ -22,7 +22,7 @@ namespace Orchard.Sandbox.Models {
Filters.Add(new ActivatingFilter<RoutableAspect>(SandboxPage.ContentType.Name)); Filters.Add(new ActivatingFilter<RoutableAspect>(SandboxPage.ContentType.Name));
Filters.Add(new ActivatingFilter<BodyAspect>(SandboxPage.ContentType.Name)); Filters.Add(new ActivatingFilter<BodyAspect>(SandboxPage.ContentType.Name));
Filters.Add(new StorageFilter<SandboxPageRecord>(pageRepository) { AutomaticallyCreateMissingRecord = true }); Filters.Add(new StorageFilter<SandboxPageRecord>(pageRepository) { AutomaticallyCreateMissingRecord = true });
Filters.Add(new ContentItemTemplates<SandboxPage>("Summary")); Filters.Add(new ContentItemTemplates<SandboxPage>("Items/Sandbox.Page", "Summary"));
OnGetItemMetadata<SandboxPage>((context, page) => { OnGetItemMetadata<SandboxPage>((context, page) => {
context.Metadata.DisplayText = page.Record.Name; context.Metadata.DisplayText = page.Record.Name;

View File

@@ -102,7 +102,7 @@ namespace Orchard.Tags.Controllers {
var tag = _tagService.GetTagByName(tagName); var tag = _tagService.GetTagByName(tagName);
var items = var items =
_tagService.GetTaggedContentItems(tag.Id).Select( _tagService.GetTaggedContentItems(tag.Id).Select(
ic => _contentManager.BuildDisplayModel(ic, null, "SummaryForSearch")); ic => _contentManager.BuildDisplayModel(ic, "SummaryForSearch"));
var viewModel = new TagsSearchViewModel { var viewModel = new TagsSearchViewModel {
TagName = tag.TagName, TagName = tag.TagName,

View File

@@ -13,65 +13,64 @@ using Orchard.Users.ViewModels;
namespace Orchard.Users.Controllers { namespace Orchard.Users.Controllers {
public class AdminController : Controller, IUpdateModel { public class AdminController : Controller, IUpdateModel {
private readonly IMembershipService _membershipService; private readonly IMembershipService _membershipService;
private readonly IContentManager _contentManager;
private readonly IRepository<UserRecord> _userRepository;
private readonly INotifier _notifier;
public AdminController( public AdminController(
IMembershipService membershipService, IOrchardServices services,
IContentManager contentManager, IMembershipService membershipService) {
IRepository<UserRecord> userRepository, Services = services;
INotifier notifier) {
_membershipService = membershipService; _membershipService = membershipService;
_contentManager = contentManager;
_userRepository = userRepository;
_notifier = notifier;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
public IUser CurrentUser { get; set; } public IOrchardServices Services { get; set; }
public Localizer T { get; set; } public Localizer T { get; set; }
public ActionResult Index() {
var model = new UsersIndexViewModel();
var users = _contentManager.Query<User, UserRecord>("user") public ActionResult Index() {
var users = Services.ContentManager
.Query<User, UserRecord>(Models.User.ContentType.Name)
.Where(x => x.UserName != null) .Where(x => x.UserName != null)
.List(); .List();
model.Rows = users.Select(x => new UsersIndexViewModel.Row { User = x }).ToList(); var model = new UsersIndexViewModel {
Rows = users
.Select(x => new UsersIndexViewModel.Row { User = x })
.ToList()
};
return View(model); return View(model);
} }
public ActionResult Create() { public ActionResult Create() {
var user = _contentManager.New("user"); var user = Services.ContentManager.New<IUser>(Models.User.ContentType.Name);
var model = new UserCreateViewModel { var model = new UserCreateViewModel {
EditorModel = _contentManager.BuildEditorModel(user, null) User = Services.ContentManager.BuildEditorModel(user)
}; };
return View(model); return View(model);
} }
[HttpPost] [HttpPost, ActionName("Create")]
public ActionResult Create(UserCreateViewModel model) { public ActionResult _Create() {
var model = new UserCreateViewModel();
UpdateModel(model);
if (model.Password != model.ConfirmPassword) {
ModelState.AddModelError("ConfirmPassword", T("Password confirmation must match").ToString());
}
if (ModelState.IsValid == false) {
model.EditorModel = _contentManager.UpdateEditorModel(_contentManager.New("user"), null, this);
return View(model);
}
var user = _membershipService.CreateUser(new CreateUserParams( var user = _membershipService.CreateUser(new CreateUserParams(
model.UserName, model.UserName,
model.Password, model.Password,
model.Email, model.Email,
null, null, true)); null, null, true));
model.EditorModel = _contentManager.UpdateEditorModel(user, null, this);
model.User = Services.ContentManager.UpdateEditorModel(user, this);
if (model.Password != model.ConfirmPassword) {
AddModelError("ConfirmPassword", T("Password confirmation must match"));
}
if (ModelState.IsValid == false) { if (ModelState.IsValid == false) {
//TODO: rollback transaction Services.TransactionManager.Cancel();
return View(model); return View(model);
} }
@@ -79,29 +78,33 @@ namespace Orchard.Users.Controllers {
} }
public ActionResult Edit(int id) { public ActionResult Edit(int id) {
var model = new UserEditViewModel { User = _contentManager.Get<User>(id) }; return View(new UserEditViewModel {
model.EditorModel = _contentManager.BuildEditorModel(model.User.ContentItem, null); User = Services.ContentManager.BuildEditorModel<User>(id)
return View(model); });
} }
[HttpPost] [HttpPost, ActionName("Edit")]
public ActionResult Edit(int id, FormCollection input) { public ActionResult _Edit(int id) {
var model = new UserEditViewModel { User = _contentManager.Get<User>(id) }; var model = new UserEditViewModel {
model.EditorModel = _contentManager.UpdateEditorModel(model.User.ContentItem, null, this); User = Services.ContentManager.UpdateEditorModel<User>(id, this)
};
if (!TryUpdateModel(model, input.ToValueProvider())) { // apply additional model properties that were posted on form
UpdateModel(model);
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
return View(model); return View(model);
} }
_notifier.Information(T("User information updated")); Services.Notifier.Information(T("User information updated"));
return RedirectToAction("Edit", new { id }); return RedirectToAction("Edit", new { id });
} }
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) { bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
return TryUpdateModel(model, prefix, includeProperties, excludeProperties); return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
} }
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) { public void AddModelError(string key, LocalizedString errorMessage) {
ModelState.AddModelError(key, errorMessage.ToString()); ModelState.AddModelError(key, errorMessage.ToString());
} }
} }

View File

@@ -1,10 +0,0 @@
using System.Web.Mvc;
namespace Orchard.Users.Controllers {
[HandleError]
public class HomeController : Controller {
public ActionResult Index() {
return View();
}
}
}

View File

@@ -12,6 +12,7 @@ namespace Orchard.Users.Models {
public UserHandler(IRepository<UserRecord> repository) { public UserHandler(IRepository<UserRecord> repository) {
Filters.Add(new ActivatingFilter<User>("user")); Filters.Add(new ActivatingFilter<User>("user"));
Filters.Add(new StorageFilter<UserRecord>(repository)); Filters.Add(new StorageFilter<UserRecord>(repository));
Filters.Add(new ContentItemTemplates<User>("Items/Users.User"));
} }
} }
} }

View File

@@ -62,7 +62,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Controllers\AdminController.cs" /> <Compile Include="Controllers\AdminController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Models\User.cs" /> <Compile Include="Models\User.cs" />
<Compile Include="Models\UserHandler.cs" /> <Compile Include="Models\UserHandler.cs" />
<Compile Include="Models\UserRecord.cs" /> <Compile Include="Models\UserRecord.cs" />
@@ -78,10 +77,9 @@
<Content Include="Views\Admin\Edit.aspx" /> <Content Include="Views\Admin\Edit.aspx" />
<Content Include="Views\Admin\Create.aspx" /> <Content Include="Views\Admin\Create.aspx" />
<Content Include="Views\Admin\EditorTemplates\inputPasswordLarge.ascx" /> <Content Include="Views\Admin\EditorTemplates\inputPasswordLarge.ascx" />
<Content Include="Views\Admin\EditorTemplates\UserEditViewModel.ascx" />
<Content Include="Views\Admin\EditorTemplates\inputTextLarge.ascx" /> <Content Include="Views\Admin\EditorTemplates\inputTextLarge.ascx" />
<Content Include="Views\Admin\EditorTemplates\UserCreateViewModel.ascx" />
<Content Include="Views\Admin\Index.aspx" /> <Content Include="Views\Admin\Index.aspx" />
<Content Include="Views\EditorTemplates\Items\Users.User.ascx" />
<Content Include="Web.config" /> <Content Include="Web.config" />
<Content Include="Views\Web.config" /> <Content Include="Views\Web.config" />
</ItemGroup> </ItemGroup>

View File

@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Orchard.Models.ViewModels; using Orchard.Models.ViewModels;
using Orchard.Mvc.ViewModels; using Orchard.Mvc.ViewModels;
using Orchard.Security;
using Orchard.Users.Models;
namespace Orchard.Users.ViewModels { namespace Orchard.Users.ViewModels {
public class UserCreateViewModel : AdminViewModel { public class UserCreateViewModel : AdminViewModel {
@@ -18,6 +20,6 @@ namespace Orchard.Users.ViewModels {
[Required, DataType(DataType.Password)] [Required, DataType(DataType.Password)]
public string ConfirmPassword { get; set; } public string ConfirmPassword { get; set; }
public ItemEditorModel EditorModel { get; set; } public ItemEditorModel<IUser> User { get; set; }
} }
} }

View File

@@ -7,26 +7,23 @@ using Orchard.Users.Models;
namespace Orchard.Users.ViewModels { namespace Orchard.Users.ViewModels {
public class UserEditViewModel : AdminViewModel { public class UserEditViewModel : AdminViewModel {
public User User { get; set; }
public ItemEditorModel EditorModel { get; set; }
[HiddenInput(DisplayValue = false)] [HiddenInput(DisplayValue = false)]
public int Id { public int Id {
get { return User.Id; } get { return User.Item.Id; }
} }
[Required] [Required]
public string UserName { public string UserName {
get { return User.As<User>().Record.UserName; } get { return User.Item.Record.UserName; }
set { User.As<User>().Record.UserName = value; } set { User.Item.Record.UserName = value; }
} }
[Required] [Required]
public string Email { public string Email {
get { return User.As<User>().Record.Email; } get { return User.Item.Record.Email; }
set { User.As<User>().Record.Email = value; } set { User.Item.Record.Email = value; }
} }
public ItemEditorModel<User> User { get; set; }
} }
} }

View File

@@ -1,11 +1,16 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.Users.ViewModels.UserCreateViewModel>" %> <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.Users.ViewModels.UserCreateViewModel>" %>
<%@ Import Namespace="Orchard.Security" %> <%@ Import Namespace="Orchard.Security" %>
<%@ Import Namespace="Orchard.Mvc.Html" %> <%@ Import Namespace="Orchard.Mvc.Html" %>
<h2>Add User</h2> <h2>Add User</h2>
<%using (Html.BeginForm()) { %> <%using (Html.BeginForm()) { %>
<%= Html.ValidationSummary() %> <%=Html.ValidationSummary() %>
<%= Html.EditorForModel() %> <%=Html.EditorFor(m=>m.UserName, "inputTextLarge") %>
<%=Html.EditorFor(m=>m.Email, "inputTextLarge") %>
<%=Html.EditorFor(m=>m.Password, "inputPasswordLarge") %>
<%=Html.EditorFor(m=>m.ConfirmPassword, "inputPasswordLarge") %>
<%=Html.EditorForItem(Model.User) %>
<fieldset> <fieldset>
<input class="button" type="submit" value="Create" /> <input class="button" type="submit" value="Create" />
</fieldset> </fieldset>
<% } %> <% } %>

View File

@@ -1,12 +1,16 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.Users.ViewModels.UserEditViewModel>" %> <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Orchard.Users.ViewModels.UserEditViewModel>" %>
<%@ Import Namespace="Orchard.Security" %> <%@ Import Namespace="Orchard.Security" %>
<%@ Import Namespace="Orchard.Mvc.Html" %> <%@ Import Namespace="Orchard.Mvc.Html" %>
<h2>Edit User</h2> <h2>
Edit User</h2>
<%using (Html.BeginForm()) { %> <%using (Html.BeginForm()) { %>
<ol> <%=Html.ValidationSummary() %>
<%= Html.ValidationSummary() %> <%=Html.EditorFor(m=>m.Id) %>
<%= Html.EditorForModel() %> <%=Html.EditorFor(m=>m.UserName, "inputTextLarge") %>
<fieldset> <%=Html.EditorFor(m=>m.Email, "inputTextLarge") %>
<input class="button" type="submit" value="Save" /> <%=Html.EditorForItem(Model.User) %>
</fieldset> <fieldset>
<% } %> <input class="button" type="submit" value="Save" />
</fieldset>
<% } %>

View File

@@ -1,11 +0,0 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Orchard.Users.ViewModels.UserCreateViewModel>" %>
<%@ Import Namespace="Orchard.Utility" %>
<%=Html.EditorFor(m=>m.UserName, "inputTextLarge") %>
<%=Html.EditorFor(m=>m.Email, "inputTextLarge") %>
<%=Html.EditorFor(m=>m.Password, "inputPasswordLarge") %>
<%=Html.EditorFor(m=>m.ConfirmPassword, "inputPasswordLarge") %>
<%
foreach(var e in Model.EditorModel.Editors) {
var editor = e;%>
<%=Html.EditorFor(m => editor.Model, editor.TemplateName, editor.Prefix)%>
<% } %>

View File

@@ -1,8 +0,0 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Orchard.Users.ViewModels.UserEditViewModel>" %>
<%@ Import Namespace="Orchard.Utility" %>
<%=Html.EditorFor(m=>m.Id) %>
<%=Html.EditorFor(m=>m.UserName, "inputTextLarge") %>
<%=Html.EditorFor(m=>m.Email, "inputTextLarge") %>
<% foreach(var e in Model.EditorModel.Editors) {%>
<%=Html.EditorFor(m => e.Model, e.TemplateName, e.Prefix)%>
<%} %>

View File

@@ -0,0 +1,5 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ItemEditorModel<User>>" %>
<%@ Import Namespace="Orchard.Mvc.Html" %>
<%@ Import Namespace="Orchard.Models.ViewModels" %>
<%@ Import Namespace="Orchard.Users.Models" %>
<%=Html.EditorZonesAny() %>

View File

@@ -0,0 +1,16 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BaseViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Mvc.Html" %>
<% Html.RegisterStyle(ResolveUrl("~/Themes/BlueSky/Styles/site.css")); %>
<div class="page">
<div id="header">
<div id="title"><h1>My MVC Application</h1></div>
<%Html.Zone("header"); Html.Zone("menu"); %>
</div>
<div id="main">
<%Html.Zone("content", () => Html.RenderBody() );%>
<div id="footer"><%Html.Zone("footer");%></div>
</div>
</div>

View File

@@ -78,7 +78,7 @@ namespace Orchard.Data {
public void Dispose() { public void Dispose() {
if (_session != null) { if (_session != null) {
_session.Flush(); //_session.Flush();
_session.Close(); _session.Close();
} }
} }

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Web.Mvc;
using Orchard.Mvc.Filters;
namespace Orchard.Data {
public interface ITransactionManager : IDependency {
void Cancel();
}
public class TransactionManager : ITransactionManager, IDisposable {
private readonly TransactionScope _scope;
private bool _cancelled;
public TransactionManager() {
_scope = new TransactionScope(TransactionScopeOption.Required);
}
void IDisposable.Dispose() {
if (!_cancelled)
_scope.Complete();
_scope.Dispose();
}
void ITransactionManager.Cancel() {
_cancelled = true;
}
}
public class TransactionFilter : FilterProvider, IExceptionFilter{
private readonly ITransactionManager _transactionManager;
public TransactionFilter(ITransactionManager transactionManager) {
_transactionManager = transactionManager;
}
public void OnException(ExceptionContext filterContext) {
_transactionManager.Cancel();
}
}
}

View File

@@ -5,6 +5,7 @@ using Autofac.Builder;
using Autofac.Integration.Web; using Autofac.Integration.Web;
using System.Collections.Generic; using System.Collections.Generic;
using Orchard.Mvc; using Orchard.Mvc;
using Orchard.Mvc.ViewEngines;
namespace Orchard.Environment { namespace Orchard.Environment {
public class DefaultOrchardHost : IOrchardHost { public class DefaultOrchardHost : IOrchardHost {
@@ -36,6 +37,7 @@ namespace Orchard.Environment {
shell.Activate(); shell.Activate();
_current = shell; _current = shell;
ViewEngines.Engines.Insert(0, new LayoutViewEngine(null));
_controllerBuilder.SetControllerFactory(new OrchardControllerFactory()); _controllerBuilder.SetControllerFactory(new OrchardControllerFactory());
ServiceLocator.SetLocator(t=>_containerProvider.RequestContainer.Resolve(t)); ServiceLocator.SetLocator(t=>_containerProvider.RequestContainer.Resolve(t));
} }

View File

@@ -39,40 +39,40 @@ namespace Orchard.Environment {
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
static IEnumerable<string> OrchardLocationFormats() { //static IEnumerable<string> OrchardLocationFormats() {
return new[] { // return new[] {
"~/Packages/{2}/Views/{1}/{0}.aspx", // "~/Packages/{2}/Views/{1}/{0}.aspx",
"~/Packages/{2}/Views/{1}/{0}.ascx", // "~/Packages/{2}/Views/{1}/{0}.ascx",
"~/Packages/{2}/Views/Shared/{0}.aspx", // "~/Packages/{2}/Views/Shared/{0}.aspx",
"~/Packages/{2}/Views/Shared/{0}.ascx", // "~/Packages/{2}/Views/Shared/{0}.ascx",
"~/Core/{2}/Views/{1}/{0}.aspx", // "~/Core/{2}/Views/{1}/{0}.aspx",
"~/Core/{2}/Views/{1}/{0}.ascx", // "~/Core/{2}/Views/{1}/{0}.ascx",
"~/Core/{2}/Views/Shared/{0}.aspx", // "~/Core/{2}/Views/Shared/{0}.aspx",
"~/Core/{2}/Views/Shared/{0}.ascx", // "~/Core/{2}/Views/Shared/{0}.ascx",
}; // };
} //}
public void Activate() { public void Activate() {
_routePublisher.Publish(_routeProviders.SelectMany(provider => provider.GetRoutes())); _routePublisher.Publish(_routeProviders.SelectMany(provider => provider.GetRoutes()));
_modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders())); _modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders()));
var viewEngine = _viewEngines.OfType<VirtualPathProviderViewEngine>().Single(); //var viewEngine = _viewEngines.OfType<VirtualPathProviderViewEngine>().Single();
viewEngine.AreaViewLocationFormats = OrchardLocationFormats() //viewEngine.AreaViewLocationFormats = OrchardLocationFormats()
.Concat(viewEngine.AreaViewLocationFormats) // .Concat(viewEngine.AreaViewLocationFormats)
.Distinct() // .Distinct()
.ToArray(); // .ToArray();
viewEngine.AreaPartialViewLocationFormats = OrchardLocationFormats() //viewEngine.AreaPartialViewLocationFormats = OrchardLocationFormats()
.Concat(viewEngine.AreaPartialViewLocationFormats) // .Concat(viewEngine.AreaPartialViewLocationFormats)
.Distinct() // .Distinct()
.ToArray(); // .ToArray();
var activePackageDescriptors = _extensionManager.ActiveExtensions().Select(x => x.Descriptor); //var activePackageDescriptors = _extensionManager.ActiveExtensions().Select(x => x.Descriptor);
var sharedLocationFormats = activePackageDescriptors.Select(x => ModelsLocationFormat(x)); //var sharedLocationFormats = activePackageDescriptors.Select(x => ModelsLocationFormat(x));
viewEngine.PartialViewLocationFormats = sharedLocationFormats //viewEngine.PartialViewLocationFormats = sharedLocationFormats
.Concat(viewEngine.PartialViewLocationFormats) // .Concat(viewEngine.PartialViewLocationFormats)
.Distinct() // .Distinct()
.ToArray(); // .ToArray();
_events.Invoke(x => x.Activated(), Logger); _events.Invoke(x => x.Activated(), Logger);
} }

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JetBrains.Annotations;
using Orchard.Data;
using Orchard.Models;
using Orchard.Security;
using Orchard.UI.Notify;
namespace Orchard.Environment {
[UsedImplicitly]
public class OrchardServices : IOrchardServices {
public OrchardServices(
IContentManager contentManager,
ITransactionManager transactionManager,
IAuthorizer authorizer,
INotifier notifier) {
ContentManager = contentManager;
TransactionManager = transactionManager;
Authorizer = authorizer;
Notifier = notifier;
}
public IContentManager ContentManager { get; set; }
public ITransactionManager TransactionManager {get;set;}
public IAuthorizer Authorizer { get; set; }
public INotifier Notifier { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Orchard.Data;
using Orchard.Models;
using Orchard.Security;
using Orchard.UI.Notify;
namespace Orchard {
public interface IOrchardServices : IDependency {
IContentManager ContentManager { get; }
ITransactionManager TransactionManager { get; }
IAuthorizer Authorizer { get; set; }
INotifier Notifier { get; }
}
}

View File

@@ -1,11 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.Models.Driver;
using Orchard.Models.Records; using Orchard.Models.Records;
using Orchard.Models.ViewModels;
namespace Orchard.Models { namespace Orchard.Models {
public static class ContentExtensions { public static class ContentExtensions {
/* Item creation and accessing extension methods */
public static T New<T>(this IContentManager manager, string contentType) where T : class, IContent { public static T New<T>(this IContentManager manager, string contentType) where T : class, IContent {
var contentItem = manager.New(contentType); var contentItem = manager.New(contentType);
if (contentItem == null) if (contentItem == null)
@@ -18,6 +23,10 @@ namespace Orchard.Models {
return part; return part;
} }
public static T Create<T>(this IContentManager manager, string contentType) where T : class, IContent {
return manager.Create<T>(contentType, init => { });
}
public static T Create<T>(this IContentManager manager, string contentType, Action<T> initialize) where T : class, IContent { public static T Create<T>(this IContentManager manager, string contentType, Action<T> initialize) where T : class, IContent {
var content = manager.New<T>(contentType); var content = manager.New<T>(contentType);
if (content == null) if (content == null)
@@ -34,6 +43,23 @@ namespace Orchard.Models {
} }
/* Display and editor convenience extension methods */
public static ItemDisplayModel<T> BuildDisplayModel<T>(this IContentManager manager, int id, string displayType) where T : class, IContent {
return manager.BuildDisplayModel(manager.Get<T>(id), displayType);
}
public static ItemEditorModel<T> BuildEditorModel<T>(this IContentManager manager, int id) where T : class, IContent {
return manager.BuildEditorModel(manager.Get<T>(id));
}
public static ItemEditorModel<T> UpdateEditorModel<T>(this IContentManager manager, int id, IUpdateModel updater) where T : class, IContent {
return manager.UpdateEditorModel(manager.Get<T>(id), updater);
}
/* Query related extension methods */
public static IContentQuery<TPart> Query<TPart>(this IContentManager manager) public static IContentQuery<TPart> Query<TPart>(this IContentManager manager)
where TPart : ContentPart { where TPart : ContentPart {
return manager.Query().ForPart<TPart>(); return manager.Query().ForPart<TPart>();
@@ -69,6 +95,7 @@ namespace Orchard.Models {
} }
/* Aggregate item/part type casting extension methods */
public static bool Is<T>(this IContent content) { public static bool Is<T>(this IContent content) {
return content == null ? false : content.ContentItem.Has(typeof(T)); return content == null ? false : content.ContentItem.Has(typeof(T));

View File

@@ -136,13 +136,9 @@ namespace Orchard.Models {
return context.Metadata; return context.Metadata;
} }
public ItemDisplayModel<TContentPart> BuildDisplayModel<TContentPart>(TContentPart content, string groupName, string displayType) where TContentPart : IContent { public ItemDisplayModel<TContentPart> BuildDisplayModel<TContentPart>(TContentPart content, string displayType) where TContentPart : IContent {
return BuildDisplayModel(content, groupName, displayType, null); var itemView = new ItemDisplayModel<TContentPart> {Item = content, Displays = Enumerable.Empty<TemplateViewModel>()};
} var context = new BuildDisplayModelContext(itemView, displayType);
public ItemDisplayModel<TContent> BuildDisplayModel<TContent>(TContent content, string groupName, string displayType, string templatePath) where TContent : IContent {
var itemView = new ItemDisplayModel<TContent> { Item = content, Displays = Enumerable.Empty<TemplateViewModel>() };
var context = new BuildDisplayModelContext(itemView, groupName, displayType, templatePath);
foreach (var handler in Handlers) { foreach (var handler in Handlers) {
handler.BuildDisplayModel(context); handler.BuildDisplayModel(context);
} }
@@ -150,13 +146,9 @@ namespace Orchard.Models {
return itemView; return itemView;
} }
public ItemEditorModel<TContent> BuildEditorModel<TContent>(TContent content, string groupName) where TContent : IContent { public ItemEditorModel<TContentPart> BuildEditorModel<TContentPart>(TContentPart content) where TContentPart : IContent {
return BuildEditorModel(content, groupName, null); var itemView = new ItemEditorModel<TContentPart> { Item = content, Editors = Enumerable.Empty<TemplateViewModel>() };
} var context = new BuildEditorModelContext(itemView);
public ItemEditorModel<TContent> BuildEditorModel<TContent>(TContent content, string groupName, string templatePath) where TContent : IContent {
var itemView = new ItemEditorModel<TContent> { Item = content, Editors = Enumerable.Empty<TemplateViewModel>() };
var context = new BuildEditorModelContext(itemView, groupName, templatePath);
foreach (var handler in Handlers) { foreach (var handler in Handlers) {
handler.BuildEditorModel(context); handler.BuildEditorModel(context);
} }
@@ -164,13 +156,10 @@ namespace Orchard.Models {
return itemView; return itemView;
} }
public ItemEditorModel<TContent> UpdateEditorModel<TContent>(TContent content, string groupName, IUpdateModel updater) where TContent : IContent { public ItemEditorModel<TContentPart> UpdateEditorModel<TContentPart>(TContentPart content, IUpdateModel updater) where TContentPart : IContent {
return UpdateEditorModel(content, groupName, updater, null); var itemView = new ItemEditorModel<TContentPart> { Item = content, Editors = Enumerable.Empty<TemplateViewModel>() };
}
public ItemEditorModel<TContent> UpdateEditorModel<TContent>(TContent content, string groupName, IUpdateModel updater, string templatePath) where TContent : IContent { var context = new UpdateEditorModelContext(itemView, updater);
var itemView = new ItemEditorModel<TContent> { Item = content, Editors = Enumerable.Empty<TemplateViewModel>() };
var context = new UpdateEditorModelContext(itemView, groupName, updater, templatePath);
foreach (var handler in Handlers) { foreach (var handler in Handlers) {
handler.UpdateEditorModel(context); handler.UpdateEditorModel(context);
} }

View File

@@ -3,19 +3,15 @@ using Orchard.Models.ViewModels;
namespace Orchard.Models.Driver { namespace Orchard.Models.Driver {
public class BuildDisplayModelContext { public class BuildDisplayModelContext {
public BuildDisplayModelContext(ItemDisplayModel displayModel, string groupName, string displayType, string templatePath) { public BuildDisplayModelContext(ItemDisplayModel displayModel, string displayType) {
ContentItem = displayModel.Item; ContentItem = displayModel.Item;
GroupName = groupName;
DisplayType = displayType; DisplayType = displayType;
DisplayModel = displayModel; DisplayModel = displayModel;
TemplatePath = templatePath;
} }
public ContentItem ContentItem { get; private set; } public ContentItem ContentItem { get; private set; }
public string GroupName { get; private set; }
public string DisplayType { get; private set; } public string DisplayType { get; private set; }
public ItemDisplayModel DisplayModel { get; private set; } public ItemDisplayModel DisplayModel { get; private set; }
public string TemplatePath { get; private set; }
public void AddDisplay(TemplateViewModel display) { public void AddDisplay(TemplateViewModel display) {
DisplayModel.Displays = DisplayModel.Displays.Concat(new[] { display }); DisplayModel.Displays = DisplayModel.Displays.Concat(new[] { display });

View File

@@ -3,17 +3,13 @@ using Orchard.Models.ViewModels;
namespace Orchard.Models.Driver { namespace Orchard.Models.Driver {
public class BuildEditorModelContext { public class BuildEditorModelContext {
public BuildEditorModelContext(ItemEditorModel editorModel, string groupName, string templatePath) { public BuildEditorModelContext(ItemEditorModel editorModel) {
ContentItem = editorModel.Item; ContentItem = editorModel.Item;
GroupName = groupName;
EditorModel = editorModel; EditorModel = editorModel;
TemplatePath = templatePath;
} }
public ContentItem ContentItem { get; private set; } public ContentItem ContentItem { get; set; }
public string GroupName { get; private set; } public ItemEditorModel EditorModel { get; set; }
public ItemEditorModel EditorModel { get; private set; }
public string TemplatePath { get; private set; }
public void AddEditor(TemplateViewModel editor) { public void AddEditor(TemplateViewModel editor) {
EditorModel.Editors = EditorModel.Editors.Concat(new[] { editor }); EditorModel.Editors = EditorModel.Editors.Concat(new[] { editor });

View File

@@ -5,19 +5,29 @@ using Orchard.Models.ViewModels;
namespace Orchard.Models.Driver { namespace Orchard.Models.Driver {
public class ContentItemTemplates<TContent> : TemplateFilterBase<TContent> where TContent : class, IContent { public class ContentItemTemplates<TContent> : TemplateFilterBase<TContent> where TContent : class, IContent {
private readonly string _templateName;
// todo: (heskew) use _prefix? // todo: (heskew) use _prefix?
private readonly string _prefix; private readonly string _prefix;
private readonly string[] _displayTypes; private readonly string[] _displayTypes;
private Action<UpdateEditorModelContext, ItemEditorModel<TContent>> _updater; private Action<UpdateEditorModelContext, ItemEditorModel<TContent>> _updater;
public ContentItemTemplates(params string[] displayTypes) { public ContentItemTemplates(string templateName)
_displayTypes = displayTypes; : this(templateName, "") {
}
public ContentItemTemplates(string templateName, string displayTypes) {
_templateName = templateName;
_displayTypes = (displayTypes ?? "").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
_updater = (context, viewModel) => context.Updater.TryUpdateModel(viewModel, "", null, null); _updater = (context, viewModel) => context.Updater.TryUpdateModel(viewModel, "", null, null);
} }
protected override void BuildDisplayModel(BuildDisplayModelContext context, TContent instance) { protected override void BuildDisplayModel(BuildDisplayModelContext context, TContent instance) {
context.DisplayModel.TemplateName = _templateName;
var longestMatch = LongestMatch(context.DisplayType); var longestMatch = LongestMatch(context.DisplayType);
context.DisplayModel.TemplateName = (!string.IsNullOrEmpty(context.TemplatePath) ? context.TemplatePath : typeof(TContent).Name) + "/" + longestMatch; if (!string.IsNullOrEmpty(longestMatch))
context.DisplayModel.TemplateName += "." + longestMatch;
context.DisplayModel.Prefix = _prefix; context.DisplayModel.Prefix = _prefix;
if (context.DisplayModel.GetType() != typeof(ItemDisplayModel<TContent>)) { if (context.DisplayModel.GetType() != typeof(ItemDisplayModel<TContent>)) {
@@ -45,7 +55,7 @@ namespace Orchard.Models.Driver {
} }
protected override void BuildEditorModel(BuildEditorModelContext context, TContent instance) { protected override void BuildEditorModel(BuildEditorModelContext context, TContent instance) {
context.EditorModel.TemplateName = (!string.IsNullOrEmpty(context.TemplatePath) ? context.TemplatePath : typeof(TContent).Name) + "/Detail"; context.EditorModel.TemplateName = _templateName;
context.EditorModel.Prefix = _prefix; context.EditorModel.Prefix = _prefix;
if (context.EditorModel.GetType() != typeof(ItemEditorModel<TContent>)) { if (context.EditorModel.GetType() != typeof(ItemEditorModel<TContent>)) {
context.EditorModel.Adaptor = (html, viewModel) => { context.EditorModel.Adaptor = (html, viewModel) => {
@@ -62,7 +72,7 @@ namespace Orchard.Models.Driver {
_updater(context, (ItemEditorModel<TContent>)context.EditorModel); _updater(context, (ItemEditorModel<TContent>)context.EditorModel);
else else
_updater(context, new ItemEditorModel<TContent>(context.EditorModel)); _updater(context, new ItemEditorModel<TContent>(context.EditorModel));
context.EditorModel.TemplateName = (!string.IsNullOrEmpty(context.TemplatePath) ? context.TemplatePath : typeof(TContent).Name) + "/Detail"; context.EditorModel.TemplateName = _templateName;
context.EditorModel.Prefix = _prefix; context.EditorModel.Prefix = _prefix;
} }

View File

@@ -2,8 +2,8 @@ using Orchard.Models.ViewModels;
namespace Orchard.Models.Driver { namespace Orchard.Models.Driver {
public class UpdateEditorModelContext : BuildEditorModelContext { public class UpdateEditorModelContext : BuildEditorModelContext {
public UpdateEditorModelContext(ItemEditorModel editorModel, string groupName, IUpdateModel updater, string templatePath) public UpdateEditorModelContext(ItemEditorModel editorModel, IUpdateModel updater)
: base(editorModel, groupName, templatePath) { : base(editorModel) {
Updater = updater; Updater = updater;
} }

View File

@@ -15,11 +15,8 @@ namespace Orchard.Models {
ContentItemMetadata GetItemMetadata(IContent contentItem); ContentItemMetadata GetItemMetadata(IContent contentItem);
ItemDisplayModel<TContent> BuildDisplayModel<TContent>(TContent content, string groupName, string displayType) where TContent : IContent; ItemDisplayModel<TContent> BuildDisplayModel<TContent>(TContent content, string displayType) where TContent : IContent;
ItemDisplayModel<TContent> BuildDisplayModel<TContent>(TContent content, string groupName, string displayType, string templatePath) where TContent : IContent; ItemEditorModel<TContent> BuildEditorModel<TContent>(TContent content) where TContent : IContent;
ItemEditorModel<TContent> BuildEditorModel<TContent>(TContent content, string groupName) where TContent : IContent; ItemEditorModel<TContent> UpdateEditorModel<TContent>(TContent content, IUpdateModel updater) where TContent : IContent;
ItemEditorModel<TContent> BuildEditorModel<TContent>(TContent content, string groupName, string templatePath) where TContent : IContent;
ItemEditorModel<TContent> UpdateEditorModel<TContent>(TContent content, string groupName, IUpdateModel updater) where TContent : IContent;
ItemEditorModel<TContent> UpdateEditorModel<TContent>(TContent content, string groupName, IUpdateModel updater, string templatePath) where TContent : IContent;
} }
} }

View File

@@ -17,28 +17,28 @@ namespace Orchard.Models {
public abstract class PartDriver<TPart> : IPartDriver where TPart : class, IContent { public abstract class PartDriver<TPart> : IPartDriver where TPart : class, IContent {
DriverResult IPartDriver.BuildDisplayModel(BuildDisplayModelContext context) { DriverResult IPartDriver.BuildDisplayModel(BuildDisplayModelContext context) {
var part = context.ContentItem.As<TPart>(); var part = context.ContentItem.As<TPart>();
return part == null ? null : Display(part, context.GroupName, context.DisplayType); return part == null ? null : Display(part, context.DisplayType);
} }
DriverResult IPartDriver.BuildEditorModel(BuildEditorModelContext context) { DriverResult IPartDriver.BuildEditorModel(BuildEditorModelContext context) {
var part = context.ContentItem.As<TPart>(); var part = context.ContentItem.As<TPart>();
return part == null ? null : Editor(part, context.GroupName); return part == null ? null : Editor(part);
} }
DriverResult IPartDriver.UpdateEditorModel(UpdateEditorModelContext context) { DriverResult IPartDriver.UpdateEditorModel(UpdateEditorModelContext context) {
var part = context.ContentItem.As<TPart>(); var part = context.ContentItem.As<TPart>();
return part == null ? null : Editor(part, context.GroupName, context.Updater); return part == null ? null : Editor(part, context.Updater);
} }
protected virtual DriverResult Display(TPart part, string groupName, string displayType) { protected virtual DriverResult Display(TPart part, string displayType) {
return null; return null;
} }
protected virtual DriverResult Editor(TPart part, string groupName) { protected virtual DriverResult Editor(TPart part) {
return null; return null;
} }
protected virtual DriverResult Editor(TPart part, string groupName, IUpdateModel updater) { protected virtual DriverResult Editor(TPart part, IUpdateModel updater) {
return null; return null;
} }
@@ -62,13 +62,13 @@ namespace Orchard.Models {
return (typeof (TPart).Name); return (typeof (TPart).Name);
} }
} }
protected override DriverResult Display(TPart part, string groupName, string displayType) { protected override DriverResult Display(TPart part, string displayType) {
return PartialView(part); return PartialView(part);
} }
protected override DriverResult Editor(TPart part, string groupName) { protected override DriverResult Editor(TPart part) {
return PartialView(part); return PartialView(part);
} }
protected override DriverResult Editor(TPart part, string groupName, IUpdateModel updater) { protected override DriverResult Editor(TPart part, IUpdateModel updater) {
updater.TryUpdateModel(part, Prefix, null, null); updater.TryUpdateModel(part, Prefix, null, null);
return PartialView(part); return PartialView(part);
} }

View File

@@ -8,13 +8,13 @@ using Orchard.Models.ViewModels;
namespace Orchard.Mvc.Html { namespace Orchard.Mvc.Html {
public static class ItemDisplayExtensions { public static class ItemDisplayExtensions {
public static MvcHtmlString DisplayForItem<TModel, TItemViewModel>(this HtmlHelper<TModel> html, TItemViewModel itemViewModel) where TItemViewModel : ItemDisplayModel { public static MvcHtmlString DisplayForItem<TModel, TItemModel>(this HtmlHelper<TModel> html, TItemModel item) where TItemModel : ItemDisplayModel {
return html.DisplayForItem(x => itemViewModel); return html.DisplayForItem(x => item);
} }
public static MvcHtmlString DisplayForItem<TModel, TItemViewModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, TItemViewModel>> expression) where TItemViewModel : ItemDisplayModel { public static MvcHtmlString DisplayForItem<TModel, TItemModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, TItemModel>> expression) where TItemModel : ItemDisplayModel {
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var model = (TItemViewModel)metadata.Model; var model = (TItemModel)metadata.Model;
if (model.Adaptor != null) { if (model.Adaptor != null) {
return model.Adaptor(html, model).DisplayForModel(model.TemplateName, model.Prefix ?? ""); return model.Adaptor(html, model).DisplayForModel(model.TemplateName, model.Prefix ?? "");

View File

@@ -8,15 +8,18 @@ using Orchard.Models.ViewModels;
namespace Orchard.Mvc.Html { namespace Orchard.Mvc.Html {
public static class ItemEditorExtensions { public static class ItemEditorExtensions {
public static MvcHtmlString EditorForItem<TModel, TItemViewModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, TItemViewModel>> expression) where TItemViewModel : ItemEditorModel { public static MvcHtmlString EditorForItem<TModel, TItemModel>(this HtmlHelper<TModel> html, TItemModel item) where TItemModel : ItemEditorModel {
return html.EditorForItem(x => item);
}
public static MvcHtmlString EditorForItem<TModel, TItemModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, TItemModel>> expression) where TItemModel : ItemEditorModel {
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var model = (TItemViewModel)metadata.Model; var model = (TItemModel)metadata.Model;
if (model.Adaptor != null) { if (model.Adaptor != null) {
return model.Adaptor(html, model).EditorForModel(model.TemplateName, model.Prefix ?? ""); return model.Adaptor(html, model).EditorForModel(model.TemplateName, model.Prefix ?? "");
} }
return html.EditorFor(expression, model.TemplateName, model.Prefix ?? ""); return html.EditorFor(expression, model.TemplateName, model.Prefix ?? "");
} }

View File

@@ -7,26 +7,29 @@ using System.Web.Mvc;
namespace Orchard.Mvc.ViewEngines { namespace Orchard.Mvc.ViewEngines {
public class LayoutView : IView { public class LayoutView : IView {
private readonly LayoutViewEngine _viewEngine;
private ViewEngineResult[] _viewEngineResults; private ViewEngineResult[] _viewEngineResults;
public LayoutView(ViewEngineResult[] views) { public LayoutView(LayoutViewEngine viewEngine, ViewEngineResult[] views) {
_viewEngine = viewEngine;
_viewEngineResults = views; _viewEngineResults = views;
} }
public void Render(ViewContext viewContext, TextWriter writer) { public void Render(ViewContext viewContext, TextWriter writer) {
using (_viewEngine.CreateScope(viewContext)) {
var layoutViewContext = LayoutViewContext.From(viewContext);
var layoutViewContext = LayoutViewContext.From(viewContext); for (var index = 0; index != _viewEngineResults.Length; ++index) {
var viewEngineResult = _viewEngineResults[index];
for (var index = 0; index != _viewEngineResults.Length; ++index) { if (index == _viewEngineResults.Length - 1) {
var viewEngineResult = _viewEngineResults[index]; viewEngineResult.View.Render(viewContext, writer);
if (index == _viewEngineResults.Length - 1) { }
viewEngineResult.View.Render(viewContext, writer); else {
} //TEMP: to be replaced with an efficient spooling writer
else { var childWriter = new StringWriter();
//TEMP: to be replaced with an efficient spooling writer viewEngineResult.View.Render(viewContext, childWriter);
var childWriter = new StringWriter(); layoutViewContext.BodyContent = childWriter.ToString();
viewEngineResult.View.Render(viewContext, childWriter); }
layoutViewContext.BodyContent = childWriter.ToString();
} }
} }
} }

View File

@@ -1,4 +1,5 @@
using System.Linq; using System;
using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.Mvc.ViewModels; using Orchard.Mvc.ViewModels;
@@ -11,6 +12,11 @@ namespace Orchard.Mvc.ViewEngines {
} }
public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) { public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) {
var scope = Scope.From(controllerContext);
if (scope != null && scope.LayoutViewEngine != null) {
return scope.LayoutViewEngine._viewEngines.FindPartialView(controllerContext, partialViewName);
}
return new ViewEngineResult(Enumerable.Empty<string>()); return new ViewEngineResult(Enumerable.Empty<string>());
} }
@@ -20,15 +26,17 @@ namespace Orchard.Mvc.ViewEngines {
string masterName, string masterName,
bool useCache) { bool useCache) {
// TODO: is there an optimization around useCache for var skipLayoutViewEngine = false;
// this implementation? since IView can't re-execute, maybe not... if (string.IsNullOrEmpty(masterName)==false)
skipLayoutViewEngine = true;
// if action returned a View with explicit master - if (!(controllerContext.Controller.ViewData.Model is BaseViewModel))
// this will bypass the multi-pass layout strategy skipLayoutViewEngine = true;
if (!string.IsNullOrEmpty(masterName) if (_viewEngines == null || _viewEngines.Count== 0)
|| !(controllerContext.Controller.ViewData.Model is BaseViewModel)) skipLayoutViewEngine = true;
if (skipLayoutViewEngine)
return new ViewEngineResult(Enumerable.Empty<string>()); return new ViewEngineResult(Enumerable.Empty<string>());
var bodyView = _viewEngines.FindPartialView(controllerContext, viewName); var bodyView = _viewEngines.FindPartialView(controllerContext, viewName);
var layoutView = _viewEngines.FindPartialView(controllerContext, "layout"); var layoutView = _viewEngines.FindPartialView(controllerContext, "layout");
var documentView = _viewEngines.FindPartialView(controllerContext, "document"); var documentView = _viewEngines.FindPartialView(controllerContext, "document");
@@ -36,7 +44,7 @@ namespace Orchard.Mvc.ViewEngines {
if (bodyView.View == null || if (bodyView.View == null ||
layoutView.View == null || layoutView.View == null ||
documentView.View == null) { documentView.View == null) {
var missingTemplatesResult = new ViewEngineResult( var missingTemplatesResult = new ViewEngineResult(
(bodyView.SearchedLocations ?? Enumerable.Empty<string>()) (bodyView.SearchedLocations ?? Enumerable.Empty<string>())
.Concat((layoutView.SearchedLocations ?? Enumerable.Empty<string>())) .Concat((layoutView.SearchedLocations ?? Enumerable.Empty<string>()))
@@ -46,7 +54,7 @@ namespace Orchard.Mvc.ViewEngines {
return missingTemplatesResult; return missingTemplatesResult;
} }
var view = new LayoutView(new[] { var view = new LayoutView(this, new[] {
bodyView, bodyView,
layoutView, layoutView,
documentView, documentView,
@@ -56,9 +64,34 @@ namespace Orchard.Mvc.ViewEngines {
} }
public void ReleaseView(ControllerContext controllerContext, IView view) { public void ReleaseView(ControllerContext controllerContext, IView view) {
var layoutView = (LayoutView) view; var layoutView = (LayoutView)view;
layoutView.ReleaseViews(controllerContext); layoutView.ReleaseViews(controllerContext);
} }
public IDisposable CreateScope(ViewContext context) {
return new Scope(context) { LayoutViewEngine = this };
}
class Scope : IDisposable {
private readonly ControllerContext _context;
private readonly Scope _prior;
public Scope(ControllerContext context) {
_context = context;
_prior = From(context);
context.HttpContext.Items[typeof(Scope)] = this;
}
public LayoutViewEngine LayoutViewEngine { get; set; }
public void Dispose() {
_context.HttpContext.Items[typeof(Scope)] = _prior;
}
public static Scope From(ControllerContext context) {
return (Scope)context.HttpContext.Items[typeof(Scope)];
}
}
} }

View File

@@ -57,12 +57,11 @@ namespace Orchard.Mvc.ViewEngines {
var requestViewEngines = new ViewEngineCollection( var requestViewEngines = new ViewEngineCollection(
themeViewEngines themeViewEngines
.Concat(packageViewEngines) .Concat(packageViewEngines)
.Concat(_viewEngines)
.ToArray()); .ToArray());
var layoutViewEngine = new LayoutViewEngine(requestViewEngines); var layoutViewEngine = new LayoutViewEngine(requestViewEngines);
viewResultBase.ViewEngineCollection = new ViewEngineCollection(_viewEngines.ToList()); viewResultBase.ViewEngineCollection = new ViewEngineCollection();
viewResultBase.ViewEngineCollection.Insert(0, layoutViewEngine); viewResultBase.ViewEngineCollection.Insert(0, layoutViewEngine);
} }

View File

@@ -23,14 +23,15 @@ namespace Orchard.Mvc.ViewEngines {
ViewLocationFormats = DisabledFormats, ViewLocationFormats = DisabledFormats,
AreaMasterLocationFormats = DisabledFormats, AreaMasterLocationFormats = DisabledFormats,
AreaViewLocationFormats = DisabledFormats, AreaViewLocationFormats = DisabledFormats,
AreaPartialViewLocationFormats=DisabledFormats,
}; };
// enable /Views/Shared/{partialName} // enable /Views/{partialName}
// enable /Views/Shared/"DisplayTemplates/"+{templateName} // enable /Views/"DisplayTemplates/"+{templateName}
// enable /Views/Shared/"EditorTemplates/+{templateName} // enable /Views/"EditorTemplates/+{templateName}
viewEngine.PartialViewLocationFormats = new[] { viewEngine.PartialViewLocationFormats = new[] {
parameters.VirtualPath + "/Views/Shared/{0}.ascx", parameters.VirtualPath + "/Views/{0}.ascx",
parameters.VirtualPath + "/Views/Shared/{0}.aspx", parameters.VirtualPath + "/Views/{0}.aspx",
}; };
// for "routed" request views... // for "routed" request views...
@@ -44,19 +45,29 @@ namespace Orchard.Mvc.ViewEngines {
} }
public IViewEngine CreatePackagesViewEngine(CreatePackagesViewEngineParams parameters) { public IViewEngine CreatePackagesViewEngine(CreatePackagesViewEngineParams parameters) {
var areaFormats = new[] {
"~/Core/{2}/Views/{1}/{0}.ascx",
"~/Core/{2}/Views/{1}/{0}.aspx",
"~/Packages/{2}/Views/{1}/{0}.ascx",
"~/Packages/{2}/Views/{1}/{0}.aspx",
};
var universalFormats = parameters.VirtualPaths
.SelectMany(x => new[] {
x + "/Views/{0}.ascx",
x + "/Views/{0}.aspx",
})
.ToArray();
var viewEngine = new WebFormViewEngine { var viewEngine = new WebFormViewEngine {
MasterLocationFormats = DisabledFormats, MasterLocationFormats = DisabledFormats,
ViewLocationFormats = DisabledFormats, ViewLocationFormats = universalFormats,
PartialViewLocationFormats = universalFormats,
AreaMasterLocationFormats = DisabledFormats, AreaMasterLocationFormats = DisabledFormats,
AreaViewLocationFormats = DisabledFormats, AreaViewLocationFormats = areaFormats,
AreaPartialViewLocationFormats = DisabledFormats, AreaPartialViewLocationFormats = areaFormats,
}; };
viewEngine.PartialViewLocationFormats = parameters.VirtualPaths
.Select(x => x + "/Views/Shared/{0}.ascx")
.Concat(parameters.VirtualPaths.Select(s => s + "/Views/Shared/{0}.aspx"))
.ToArray();
return viewEngine; return viewEngine;
} }
} }

View File

@@ -66,6 +66,7 @@
<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="System.Transactions" />
<Reference Include="System.Web" /> <Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions"> <Reference Include="System.Web.Abstractions">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -122,10 +123,13 @@
<Compile Include="Controllers\HomeController.cs" /> <Compile Include="Controllers\HomeController.cs" />
<Compile Include="Data\Conventions\AttributeCollectionConvention.cs" /> <Compile Include="Data\Conventions\AttributeCollectionConvention.cs" />
<Compile Include="Data\Conventions\CascadeAllDeleteOrphanAttribute.cs" /> <Compile Include="Data\Conventions\CascadeAllDeleteOrphanAttribute.cs" />
<Compile Include="Data\TransactionManager.cs" />
<Compile Include="Environment\IOrchardShellEvents.cs" /> <Compile Include="Environment\IOrchardShellEvents.cs" />
<Compile Include="Environment\OrchardServices.cs" />
<Compile Include="Extensions\ExtensionDescriptor.cs" /> <Compile Include="Extensions\ExtensionDescriptor.cs" />
<Compile Include="Extensions\ExtensionEntry.cs" /> <Compile Include="Extensions\ExtensionEntry.cs" />
<Compile Include="Mvc\Filters\AdminFilter.cs" /> <Compile Include="Mvc\Filters\AdminFilter.cs" />
<Compile Include="IOrchardServices.cs" />
<Compile Include="Mvc\Html\FileRegistrationContext.cs" /> <Compile Include="Mvc\Html\FileRegistrationContext.cs" />
<Compile Include="Themes\ExtensionManagerExtensions.cs" /> <Compile Include="Themes\ExtensionManagerExtensions.cs" />
<Compile Include="Extensions\Helpers\PathHelpers.cs" /> <Compile Include="Extensions\Helpers\PathHelpers.cs" />