Updating to MVC 2 RC. Adjusting for some differences. Adding record for HasComments part.

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4044540
This commit is contained in:
loudej
2009-12-24 04:49:43 +00:00
parent b7f63c7131
commit 9264a6bb73
23 changed files with 175 additions and 119 deletions

Binary file not shown.

View File

@@ -91,11 +91,11 @@ namespace Orchard.Tests.Packages.Users.Controllers {
_obj = obj;
}
public bool ContainsPrefix(ControllerContext controllerContext, string prefix) {
public bool ContainsPrefix( string prefix) {
return typeof(T).GetProperties().Any(x => x.Name.StartsWith(prefix));
}
public ValueProviderResult GetValue(ControllerContext controllerContext, string key) {
public ValueProviderResult GetValue( string key) {
var property = typeof(T).GetProperty(key);
if (property == null)
return null;

View File

@@ -41,7 +41,7 @@ namespace Orchard.Web {
protected void Application_Start() {
// This is temporary until MVC2 is officially released.
// We want to avoid running against an outdated preview installed in the GAC
CheckMvcVersion(new Version("2.0.41116.0")/*MVC2 Beta file version #*/);
CheckMvcVersion(new Version("2.0.41211.0")/*MVC2 RC file version #*/);
RegisterRoutes(RouteTable.Routes);
_host = OrchardStarter.CreateHost(MvcSingletons);

View File

@@ -23,11 +23,13 @@ namespace Orchard.Blogs.Controllers {
private readonly IBlogPostService _blogPostService;
public BlogPostController(
IOrchardServices services,
ISessionLocator sessionLocator, IContentManager contentManager,
IAuthorizer authorizer,
INotifier notifier,
IBlogService blogService,
IBlogPostService blogPostService) {
Services = services;
_sessionLocator = sessionLocator;
_contentManager = contentManager;
_authorizer = authorizer;
@@ -37,6 +39,7 @@ namespace Orchard.Blogs.Controllers {
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; set; }
private Localizer T { get; set; }
//TODO: (erikpo) Should think about moving the slug parameters and get calls and null checks up into a model binder or action filter
@@ -151,8 +154,8 @@ namespace Orchard.Blogs.Controllers {
return View(model);
}
[HttpPost]
public ActionResult Edit(string blogSlug, string postSlug, FormCollection input) {
[HttpPost, ActionName("Edit")]
public ActionResult EditPOST(string blogSlug, string postSlug) {
if (!_authorizer.Authorize(Permissions.ModifyPost, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult();
@@ -171,13 +174,15 @@ namespace Orchard.Blogs.Controllers {
BlogPost = _contentManager.UpdateEditorModel(post, this)
};
IValueProvider values = input.ToValueProvider();
TryUpdateModel(model, values);
TryUpdateModel(model);
if (ModelState.IsValid==false) {
Services.TransactionManager.Cancel();
return View(model);
}
_notifier.Information(T("Blog post information updated."));
//TODO: (erikpo) Since the model isn't actually updated yet and it's possible the slug changed I'm getting the slug from input. Lame?!?!
return Redirect(Url.BlogPostEdit(blog.Slug, values.GetValue(ControllerContext, "Slug").AttemptedValue));
return Redirect(Url.BlogPostEdit(blog.Slug, post.Slug));
}
[HttpPost]

View File

@@ -111,10 +111,10 @@ namespace Orchard.Comments.Controllers {
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection input, string returnUrl) {
public ActionResult Create(string returnUrl) {
var viewModel = new CommentsCreateViewModel();
try {
UpdateModel(viewModel, input.ToValueProvider());
UpdateModel(viewModel);
if (CurrentSite.As<CommentSettings>().Record.RequireLoginToAddComment) {
if (!_authorizer.Authorize(Permissions.AddComment, T("Couldn't add comment")))
return new HttpUnauthorizedResult();

View File

@@ -0,0 +1,30 @@
using Orchard.Comments.Models;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
namespace Orchard.Comments.Controllers {
public class HasCommentsDriver : PartDriver<HasComments> {
protected override DriverResult Display(HasComments part, string displayType) {
if (part.CommentsShown == false) {
return null;
}
if (displayType.StartsWith("Detail")) {
return Combined(
PartTemplate(part, "Parts/Comments.Count").Location("body", "above.5"),
PartTemplate(part, "Parts/Comments.HasComments").Location("body", "below.5"));
}
return PartTemplate(part, "Parts/Comments.HasComments").Location("body", "below.5");
}
protected override DriverResult Editor(HasComments part) {
return PartTemplate(part, "Parts/Comments.HasComments");
}
protected override DriverResult Editor(HasComments part, IUpdateModel updater) {
updater.TryUpdateModel(part, Prefix, null, null);
return PartTemplate(part, "Parts/Comments.HasComments");
}
}
}

View File

@@ -1,73 +1,28 @@
using System;
using JetBrains.Annotations;
using Orchard.Data;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement.ViewModels;
using Orchard.Comments.Services;
namespace Orchard.Comments.Models {
[UsedImplicitly]
public class HasCommentsHandler : ContentHandler {
private readonly IRepository<Comment> _commentsRepository;
private readonly IRepository<ClosedComments> _closedCommentsRepository;
private readonly ICommentService _commentService;
public HasCommentsHandler(
IRepository<Comment> commentsRepository,
IRepository<HasCommentsRecord> hasCommentsRepository) {
public HasCommentsHandler(IRepository<Comment> commentsRepository, IRepository<ClosedComments> closedCommentsRepository, ICommentService commentService) {
_commentsRepository = commentsRepository;
_closedCommentsRepository = closedCommentsRepository;
_commentService = commentService;
Filters.Add(new ActivatingFilter<HasComments>("sandboxpage"));
Filters.Add(new ActivatingFilter<HasComments>("blogpost"));
Filters.Add(new StorageFilter<HasCommentsRecord>(hasCommentsRepository) { AutomaticallyCreateMissingRecord = true });
OnActivated<HasComments>((ctx, x) => {
x.CommentsActive = true;
x.CommentsShown = true;
});
OnLoading<HasComments>((context, comments) => {
comments.Comments = commentsRepository.Fetch(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Approved);
});
}
protected override void BuildDisplayModel(BuildDisplayModelContext context) {
if (context.ContentItem.Has<HasComments>() == false) {
return;
}
context.AddDisplay(new TemplateViewModel(context.ContentItem.Get<HasComments>()) { TemplateName = "Parts/Comments.Count", ZoneName="body", Position = "above" });
context.AddDisplay(new TemplateViewModel(context.ContentItem.Get<HasComments>()) { TemplateName = "Parts/Comments.HasComments", Position = "999" });
}
protected override void BuildEditorModel(BuildEditorModelContext context) {
if (context.ContentItem.Has<HasComments>() == false) {
return;
}
context.AddEditor(new TemplateViewModel(context.ContentItem.Get<HasComments>()) { TemplateName = "Parts/Comments.HasComments" });
}
protected override void UpdateEditorModel(UpdateEditorModelContext context) {
if (context.ContentItem.Has<HasComments>() == false) {
return;
}
CommentsViewModel viewModel = new CommentsViewModel();
context.Updater.TryUpdateModel(viewModel, String.Empty, null, null);
bool closed = viewModel.Closed == null ? false : true;
bool currentStatus = _commentService.CommentsClosedForCommentedContent(context.ContentItem.Id);
if (currentStatus != closed) {
if (closed) {
_commentService.CloseCommentsForCommentedContent(context.ContentItem.Id);
}
else {
_commentService.EnableCommentsForCommentedContent(context.ContentItem.Id);
}
}
context.AddEditor(new TemplateViewModel(context.ContentItem.Get<HasComments>()) { TemplateName = "Parts/Comments.HasComments" });
}
protected override void Loading(LoadContentContext context) {
if (context.ContentItem.Has<HasComments>() == false) {
return;
}
HasComments comments = context.ContentItem.Get<HasComments>();
comments.Comments = _commentsRepository.Fetch(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Approved);
if (_closedCommentsRepository.Get(x => x.ContentItemId == context.ContentItem.Id) != null) {
comments.Closed = true;
}
}
public class CommentsViewModel {
public String Closed { get; set; }
}
}
}

View File

@@ -1,14 +1,29 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Records;
namespace Orchard.Comments.Models {
public class HasComments : ContentPart {
public HasComments() {
Comments = Enumerable.Empty<Comment>();
}
public class HasComments : ContentPart<HasCommentsRecord> {
public int CommentCount { get { return Comments.Count(); } }
public IEnumerable<Comment> Comments { get; set; }
public bool Closed { get; set; }
public bool CommentsShown {
get { return Record.CommentsShown; }
set { Record.CommentsShown = value; }
}
public bool CommentsActive {
get { return Record.CommentsActive; }
set { Record.CommentsActive = value; }
}
}
public class HasCommentsRecord : ContentPartRecord {
public virtual bool CommentsShown { get; set; }
public virtual bool CommentsActive { get; set; }
}
}

View File

@@ -67,6 +67,7 @@
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Controllers\HasCommentsDriver.cs" />
<Compile Include="Models\Comment.cs" />
<Compile Include="Models\CommentSettings.cs" />
<Compile Include="Models\CommentSettingsHandler.cs" />
@@ -82,6 +83,7 @@
<Compile Include="ViewModels\CommentsDetailsViewModel.cs" />
<Compile Include="ViewModels\CommentsEditViewModel.cs" />
<Compile Include="ViewModels\CommentsIndexViewModel.cs" />
<Compile Include="ViewModels\EditCommentsViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Package.txt" />

View File

@@ -29,19 +29,22 @@ namespace Orchard.Comments.Services {
public class CommentService : ICommentService {
private readonly IRepository<Comment> _commentRepository;
private readonly IRepository<ClosedComments> _closedCommentsRepository;
private readonly IRepository<HasCommentsRecord> _hasCommentsRepository;
private readonly ICommentValidator _commentValidator;
private readonly IContentManager _contentManager;
private readonly IAuthorizer _authorizer;
private readonly INotifier _notifier;
public CommentService(IRepository<Comment> commentRepository,
public CommentService(IRepository<Comment> commentRepository,
IRepository<ClosedComments> closedCommentsRepository,
IRepository<HasCommentsRecord> hasCommentsRepository,
ICommentValidator commentValidator,
IContentManager contentManager,
IAuthorizer authorizer,
IAuthorizer authorizer,
INotifier notifier) {
_commentRepository = commentRepository;
_closedCommentsRepository = closedCommentsRepository;
_hasCommentsRepository = hasCommentsRepository;
_commentValidator = commentValidator;
_contentManager = contentManager;
_authorizer = authorizer;
@@ -51,7 +54,7 @@ namespace Orchard.Comments.Services {
public ILogger Logger { get; set; }
protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; }
#region Implementation of ICommentService

View File

@@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Orchard.Comments.ViewModels {
public class EditCommentsViewModel {
}
}

View File

@@ -1,3 +1,3 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HasComments>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<span class="commentcount"><a href="#comments"><%=Model.Comments.Count() %> Comment<%=Model.Comments.Count() == 1 ? "" : "s" %></a></span>
<span class="commentcount"><a href="#comments"><%=Model.CommentCount %> Comment<%=Model.CommentCount == 1 ? "" : "s" %></a></span>

View File

@@ -1,6 +1,6 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HasComments>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<h3 id="comments"><a name="comments"><%=Model.Comments.Count() %> Comment<%=Model.Comments.Count() == 1 ? "" : "s" %></a></h3><%
<h3 id="comments"><a name="comments"><%=Model.CommentCount %> Comment<%=Model.CommentCount == 1 ? "" : "s" %></a></h3><%
foreach (var comment in Model.Comments) { %>
<div>
<div class="comment">
@@ -13,7 +13,7 @@
</div>
</div><%
}
if (Model.Closed) { %>
if (Model.CommentsActive == false) { %>
<p>Comments have been disabled for this content.</p><%
} else { %>
<% using(Html.BeginForm("Create", "Admin", new { area = "Orchard.Comments" }, FormMethod.Post, new { @class = "comments" })) { %>
@@ -35,4 +35,6 @@ if (Model.Closed) { %>
<%=Html.AntiForgeryTokenOrchard() %>
</fieldset><%
}
} %>
} %>

View File

@@ -1,20 +1,21 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HasComments>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<HasComments>" %>
<%@ Import Namespace="Orchard.Comments.Models" %>
<fieldset>
<legend>Comments<% if (Model.ContentItem.Id != 0) { %>: <% var commentCount = Model.Comments.Count(); %>
<%=Html.ActionLink(
<legend>Comments<% if (Model.ContentItem.Id != 0) { %>:
<%
var commentCount = Model.CommentCount; %>
<%=Html.ActionLink(
string.Format("{0} comment{1}", commentCount, commentCount == 1 ? "" : "s"),
"Details",
new { Area = "Orchard.Comments", Controller = "Admin", id = Model.ContentItem.Id, returnUrl = Context.Request.Url }
) %>
- <a href="#">0 pending</a><% } %></legend>
<label for="Closed">
<% if (Model.Closed) {%>
<input id="Closed" name="Closed" type="checkbox" checked="checked" />
<% } else { %>
<input id="Closed" name="Closed" type="checkbox" />
<% } %>
Comments are disabled
</label>
- <a href="#">0 pending</a><% } %></legend>
<label for="CommentsShown">
<%=Html.EditorFor(x=>x.CommentsShown) %>
<%= T("Comments are shown. Existing comments are displayed.")%>
</label>
<label for="CommentsActive">
<%=Html.EditorFor(x=>x.CommentsActive) %>
<%= T("Comments active. Users may add comments.")%>
</label>
</fieldset>

View File

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

View File

@@ -1,5 +1,7 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<AdminViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.ViewModels"%><%
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Mvc.Html"%>
<%
Html.RegisterStyle("site.css"); %>
<div id="header" role="banner">
<h1><%=Html.ActionLink("Project Orchard", "Index", new { Area = "", Controller = "Home" })%></h1>

View File

@@ -1,11 +1,13 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement.Handlers;
namespace Orchard.ContentManagement.Drivers {
public class CombinedResult : DriverResult {
private readonly DriverResult[] _results;
private readonly IEnumerable<DriverResult> _results;
public CombinedResult(DriverResult[] results) {
_results = results;
public CombinedResult(IEnumerable<DriverResult> results) {
_results = results.Where(x => x != null);
}
public override void Apply(BuildDisplayModelContext context) {
@@ -15,9 +17,9 @@ namespace Orchard.ContentManagement.Drivers {
}
public override void Apply(BuildEditorModelContext context) {
foreach(var result in _results) {
foreach (var result in _results) {
result.Apply(context);
}
}
}
}
}

View File

@@ -26,7 +26,7 @@ namespace Orchard.ContentManagement.Handlers {
instance.Record = record;
}
else if (AutomaticallyCreateMissingRecord) {
instance.Record = new TRecord {ContentItemRecord = context.ContentItemRecord};
instance.Record.ContentItemRecord = context.ContentItemRecord;
_repository.Create(instance.Record);
}
}

View File

@@ -20,7 +20,7 @@ namespace Orchard.Mvc.Html {
return null;
return html.ActionLink(
linkText ?? metadata.DisplayText,
linkText ?? metadata.DisplayText ?? "view",
Convert.ToString(metadata.DisplayRouteValues["action"]),
metadata.DisplayRouteValues);
}
@@ -35,7 +35,7 @@ namespace Orchard.Mvc.Html {
return null;
return html.ActionLink(
linkText ?? metadata.DisplayText,
linkText ?? metadata.DisplayText ?? "edit",
Convert.ToString(metadata.EditorRouteValues["action"]),
metadata.EditorRouteValues);
}

View File

@@ -26,9 +26,14 @@ namespace Orchard.Mvc.ViewEngines {
}
else {
//TEMP: to be replaced with an efficient spooling writer
var childWriter = new StringWriter();
viewEngineResult.View.Render(viewContext, childWriter);
layoutViewContext.BodyContent = childWriter.ToString();
var childContext = new ViewContext(
viewContext,
viewEngineResult.View,
viewContext.ViewData,
viewContext.TempData,
new StringWriter());
viewEngineResult.View.Render(childContext, childContext.Writer);
layoutViewContext.BodyContent = childContext.Writer.ToString();
}
}
}

View File

@@ -119,12 +119,12 @@ namespace Orchard.Mvc.ViewEngines {
private static void Monitor(ViewEngineResult result, string viewName) {
if (result.View == null) {
Trace.WriteLine("Unable to find " + viewName);
foreach (var search in result.SearchedLocations) {
Trace.WriteLine(" location " + search);
}
}
//if (result.View == null) {
// Trace.WriteLine("Unable to find " + viewName);
// foreach (var search in result.SearchedLocations) {
// Trace.WriteLine(" location " + search);
// }
//}
}
public void ReleaseView(ControllerContext controllerContext, IView view) {

View File

@@ -25,4 +25,28 @@ namespace Orchard.Mvc {
return MvcHtmlString.Create(Html.Encode(T(textHint, formatTokens)));
}
}
public class ViewUserControl<TModel> : System.Web.Mvc.ViewUserControl<TModel> {
public ViewUserControl() {
T = NullLocalizer.Instance;
}
public override void RenderView(ViewContext viewContext) {
T = LocalizationUtilities.Resolve(viewContext, AppRelativeVirtualPath);
base.RenderView(viewContext);
}
public Localizer T { get; set; }
public MvcHtmlString H(string value) {
return MvcHtmlString.Create(Html.Encode(value));
}
public MvcHtmlString _Encoded(string textHint) {
return MvcHtmlString.Create(Html.Encode(T(textHint)));
}
public MvcHtmlString _Encoded(string textHint, params string[] formatTokens) {
return MvcHtmlString.Create(Html.Encode(T(textHint, formatTokens)));
}
}
}

View File

@@ -37,7 +37,8 @@ namespace Orchard.UI.Notify {
foreach (var entry in _notifier.List()) {
sb.Append(Convert.ToString(entry.Type))
.Append(':')
.AppendLine(entry.Message.ToString());
.AppendLine(entry.Message.ToString())
.AppendLine("-");
}
// assign values into temp data
@@ -62,7 +63,7 @@ namespace Orchard.UI.Notify {
return;// nothing to do, really
var messageEntries = new List<NotifyEntry>();
foreach (var line in messages.Split(new[] { System.Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) {
foreach (var line in messages.Split(new[] { System.Environment.NewLine + "-" + System.Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) {
var delimiterIndex = line.IndexOf(':');
if (delimiterIndex != -1) {
var type = (NotifyType)Enum.Parse(typeof(NotifyType), line.Substring(0, delimiterIndex));