--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2010-02-15 12:07:08 -08:00
51 changed files with 499 additions and 168 deletions

View File

@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using JetBrains.Annotations;
using Orchard.Logging;
using Orchard.Mvc.ViewModels;
using Orchard.Services;
using Orchard.Settings;
namespace Orchard.Core.HomePage.Controllers {
[HandleError]
public class HomeController : Controller {
private readonly IEnumerable<IHomePageProvider> _homePageProviders;
public HomeController(IEnumerable<IHomePageProvider> homePageProviders) {
_homePageProviders = homePageProviders;
Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; }
public ActionResult Index() {
try {
string homepage = CurrentSite.HomePage;
if (String.IsNullOrEmpty(homepage)) {
return View(new BaseViewModel());
}
string[] homePageParameters = homepage.Split(';');
if (homePageParameters.Length != 2) {
return View(new BaseViewModel());
}
string providerName = homePageParameters[0];
int item = Int32.Parse(homePageParameters[1]);
foreach (var provider in _homePageProviders) {
if (String.Equals(provider.GetProviderName(), providerName)) {
ActionResult result = provider.GetHomePage(item);
if (result is ViewResultBase) {
ViewResultBase resultBase = result as ViewResultBase;
ViewData.Model = resultBase.ViewData.Model;
resultBase.ViewData = ViewData;
}
return result;
}
}
return View(new BaseViewModel());
}
catch {
return View(new BaseViewModel());
}
}
}
}

View File

@@ -0,0 +1 @@
name: HomePage

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.Mvc.Routes;
namespace Orchard.Core.HomePage {
public class Routes : IRouteProvider {
public void GetRoutes(ICollection<RouteDescriptor> routes) {
foreach (var routeDescriptor in GetRoutes())
routes.Add(routeDescriptor);
}
public IEnumerable<RouteDescriptor> GetRoutes() {
return new[] {
new RouteDescriptor {
Priority = 20,
Route = new Route(
"",
new RouteValueDictionary {
{"area", "HomePage"},
{"controller", "Home"},
{"action", "Index"}
},
new RouteValueDictionary {
{"area", "HomePage"},
{"controller", "Home"},
},
new RouteValueDictionary {
{"area", "HomePage"}
},
new MvcRouteHandler())
}
};
}
}
}

View File

@@ -5,9 +5,9 @@ namespace Orchard.Core.Navigation {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add("Navigation", "12",
builder.Add("Site", "12",
menu => menu
.Add("Manage Main Menu", "2.0", item => item.Action("Index", "Admin", new { area = "Navigation" }).Permission(Permissions.ManageMainMenu)));
.Add("Manage Main Menu", "6.0", item => item.Action("Index", "Admin", new { area = "Navigation" }).Permission(Permissions.ManageMainMenu)));
}
}
}

View File

@@ -1,21 +1,79 @@
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.Core.Navigation.Models;
using Orchard.Core.Navigation.ViewModels;
using Orchard.Localization;
using Orchard.UI.Navigation;
using MenuItem=Orchard.Core.Navigation.Models.MenuItem;
namespace Orchard.Core.Navigation.Controllers {
[ValidateInput(false)]
public class AdminController : Controller {
public IOrchardServices Services { get; private set; }
public class AdminController : Controller, IUpdateModel {
private readonly IOrchardServices _services;
private readonly INavigationManager _navigationManager;
public AdminController(IOrchardServices services) {
Services = services;
public AdminController(IOrchardServices services, INavigationManager navigationManager) {
_services = services;
_navigationManager = navigationManager;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
private Localizer T { get; set; }
public ActionResult Index() {
return View(new NavigationIndexViewModel());
if (!_services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Not allowed to manage the main menu")))
return new HttpUnauthorizedResult();
var model = new ViewModels.NavigationManagementViewModel { Menu = _navigationManager.BuildMenu("main") };
return View(model);
}
[HttpPost, ActionName("Index")]
public ActionResult IndexPOST() {
if (!_services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
return new HttpUnauthorizedResult();
return RedirectToAction("Index");
}
[HttpPost]
public ActionResult Create(CreateMenuItemViewModel model) {
if (!_services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
return new HttpUnauthorizedResult();
var menuItem = _services.ContentManager.New<MenuItem>(MenuItemDriver.ContentType.Name);
model.MenuItem = _services.ContentManager.UpdateEditorModel(menuItem, this);
if (!ModelState.IsValid) {
_services.TransactionManager.Cancel();
return Index();
}
menuItem.As<MenuPart>().OnMainMenu = true;
_services.ContentManager.Create(model.MenuItem.Item.ContentItem);
return RedirectToAction("Index");
}
//[ValidateAntiForgeryTokenOrchard, ActionName("Delete")]
[HttpPost, ActionName("Delete")]
public ActionResult DeletePOST(int menuItemId)
{
if (!_services.Authorizer.Authorize(Permissions.ManageMainMenu, T("Couldn't manage the main menu")))
return new HttpUnauthorizedResult();
//todo -> delete
return RedirectToAction("Index");
}
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
}
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
ModelState.AddModelError(key, errorMessage.ToString());
}
}
}

View File

@@ -1,21 +1,26 @@
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Security;
namespace Orchard.Core.Navigation.Models {
[UsedImplicitly]
public class MenuItemDriver : ContentItemDriver<MenuItem> {
private readonly IOrchardServices _orchardServices;
private readonly IAuthorizationService _authorizationService;
public readonly static ContentType ContentType = new ContentType {
Name = "menuitem",
DisplayName = "Menu Item"
};
public MenuItemDriver(IOrchardServices orchardServices) {
public MenuItemDriver(IOrchardServices orchardServices, IAuthorizationService authorizationService) {
_orchardServices = orchardServices;
_authorizationService = authorizationService;
}
public virtual IUser CurrentUser { get; set; }
protected override ContentType GetContentType() {
return ContentType;
}
@@ -25,5 +30,14 @@ namespace Orchard.Core.Navigation.Models {
protected override string GetDisplayText(MenuItem item) {
return item.Url;
}
protected override DriverResult Editor(MenuItem item, IUpdateModel updater) {
if (!_authorizationService.TryCheckAccess(Permissions.ManageMainMenu, CurrentUser, item))
return null;
updater.TryUpdateModel(item, Prefix, null, null);
return null;
}
}
}

View File

@@ -3,7 +3,7 @@ using Orchard.Mvc.Filters;
using Orchard.Mvc.ViewModels;
using Orchard.UI.Navigation;
namespace Orchard.Core.Navigation.Services {
namespace Orchard.Core.Navigation.Filters {
public class MainMenuFilter : FilterProvider, IResultFilter {
private readonly INavigationManager _navigationManager;
@@ -20,11 +20,10 @@ namespace Orchard.Core.Navigation.Services {
if (baseViewModel == null)
return;
baseViewModel.Menu = _navigationManager.BuildMenu("mainmenu");
baseViewModel.Menu = _navigationManager.BuildMenu("main");
}
public void OnResultExecuted(ResultExecutedContext filterContext) {
}
}
}
}

View File

@@ -14,7 +14,7 @@ namespace Orchard.Core.Navigation.Models {
Filters.Add(StorageFilter.For(menuPartRepository));
OnActivated<MenuPart>((ctx, x) => {
x.AddToMainMenu = false;
x.OnMainMenu = false;
x.MenuText = String.Empty;
});
}

View File

@@ -7,9 +7,9 @@ namespace Orchard.Core.Navigation.Models {
[HiddenInput(DisplayValue = false)]
public int Id { get { return ContentItem.Id; } }
public bool AddToMainMenu {
get { return Record.AddToMainMenu; }
set { Record.AddToMainMenu = value; }
public bool OnMainMenu {
get { return Record.OnMainMenu; }
set { Record.OnMainMenu = value; }
}
public string MenuText {

View File

@@ -4,6 +4,6 @@ namespace Orchard.Core.Navigation.Records {
public class MenuPartRecord : ContentPartRecord {
public virtual string MenuText { get; set; }
public virtual string MenuPosition { get; set; }
public virtual bool AddToMainMenu { get; set; }
public virtual bool OnMainMenu { get; set; }
}
}

View File

@@ -3,6 +3,7 @@ using Orchard.ContentManagement;
using Orchard.Core.Navigation.Models;
using Orchard.Core.Navigation.Records;
using Orchard.UI.Navigation;
using MenuItem=Orchard.Core.Navigation.Models.MenuItem;
namespace Orchard.Core.Navigation.Services {
public class MainMenu : INavigationProvider {
@@ -12,16 +13,23 @@ namespace Orchard.Core.Navigation.Services {
_contentManager = contentManager;
}
public string MenuName { get { return "mainmenu"; } }
public string MenuName { get { return "main"; } }
public void GetNavigation(NavigationBuilder builder) {
IEnumerable<MenuPart> menuParts = _contentManager.Query<MenuPart, MenuPartRecord>().Where(x => x.AddToMainMenu).List();
IEnumerable<MenuPart> menuParts = _contentManager.Query<MenuPart, MenuPartRecord>().Where(x => x.OnMainMenu).List();
foreach (var menuPart in menuParts) {
if (menuPart != null ) {
MenuPart part = menuPart;
// Add item url.
builder.Add(menu => menu
.Add(part.MenuText, part.MenuPosition));
if (part.Is<MenuItem>())
builder.Add(
menu => menu.Add(part.MenuText, part.MenuPosition, nib => nib.Url(part.As<MenuItem>().Url)));
else
builder.Add(
menu =>
menu.Add(part.MenuText, part.MenuPosition,
nib =>
nib.Action(_contentManager.GetItemMetadata(part.ContentItem).DisplayRouteValues)));
}
}
}

View File

@@ -0,0 +1,8 @@
using Orchard.Core.Navigation.Models;
using Orchard.Mvc.ViewModels;
namespace Orchard.Core.Navigation.ViewModels {
public class CreateMenuItemViewModel : AdminViewModel {
public ContentItemViewModel<MenuItem> MenuItem { get; set; }
}
}

View File

@@ -1,6 +1,6 @@
using Orchard.Mvc.ViewModels;
namespace Orchard.Core.Navigation.ViewModels {
public class NavigationIndexViewModel : AdminViewModel {
public class NavigationManagementViewModel : AdminViewModel {
}
}

View File

@@ -1,43 +1,60 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<NavigationIndexViewModel>" %>
<%@ Import Namespace="Orchard.Core.Navigation.ViewModels"%>
<h1><%=Html.TitleForPage(T("Edit Main Menu").ToString())%></h1><%
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<NavigationManagementViewModel>" %>
<%@ Import Namespace="Orchard.Core.Navigation.ViewModels"%><%
var menu = Model.Menu.FirstOrDefault(); %>
<h1><%=Html.TitleForPage(T("Manage Main Menu").ToString())%></h1><%
using (Html.BeginFormAntiForgeryPost()) { %>
<table>
<table class="items">
<colgroup>
<col id="Text" />
<col id="Position" />
<col id="Url" />
<col id="Actions" />
</colgroup>
<thead>
<tr>
<td>Text</td>
<td>Position</td>
<td>Url</td>
<td></td>
<td scope="col"><%=_Encoded("Text") %></td>
<td scope="col"><%=_Encoded("Position") %></td>
<td scope="col"><%=_Encoded("Url") %></td>
<td scope="col"></td>
</tr>
</thead>
<tbody>
<%-- loop over menu items --%>
<tbody><%
foreach (var menuItem in menu.Items) { %>
<tr>
<td><input type="text" name="text" /></td>
<td><input type="text" name="position" /></td>
<td><input type="text" name="url" /></td>
<td>Delete Button</td>
</tr>
<%-- end loop --%>
<tr>
<td></td>
<td></td>
<td></td>
<td>Update All Button</td>
</tr>
<td><%=Html.TextBox("text", menuItem.Text) %></td>
<td><%=Html.TextBox("position", menuItem.Position) %></td>
<td><%=Html.TextBox("url", menuItem.Url) %></td>
<td><a href="#" class="remove button">delete</a></td>
</tr><%
} %>
</tbody>
</table><%
</table>
<fieldset class="actions"><button type="submit"><%=_Encoded("Update All") %></button></fieldset><%
}
using (Html.BeginFormAntiForgeryPost()) { %>
<table>
%><h2><%=_Encoded("Add New Item") %></h2><%
using (Html.BeginFormAntiForgeryPost("/admin/navigation/create", FormMethod.Post)) { %>
<table class="menu items">
<colgroup>
<col id="AddText" />
<col id="AddPosition" />
<col id="AddUrl" />
<col id="AddActions" />
</colgroup>
<tbody>
<tr>
<td><input type="text" name="addtext" /></td>
<td><input type="text" name="addposition" /></td>
<td><input type="text" name="addurl" /></td>
<td>Add Button</td>
<td>
<label for="addtext"><%=_Encoded("Text") %></label>
<input type="text" name="MenuText" id="addtext" />
</td>
<td>
<label for="addposition"><%=_Encoded("Position")%></label>
<input type="text" name="MenuPosition" id="addposition" />
</td>
<td>
<label for="addurl"><%=_Encoded("Url")%></label>
<input type="text" name="Url" id="addurl" />
</td>
<td><button class="add" type="submit"><%=_Encoded("Add") %></button></td>
</tr>
</tbody>
</table><%

View File

@@ -1,9 +1,9 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MenuPart>" %>
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<MenuPart>" %>
<%@ Import Namespace="Orchard.Core.Navigation.Models"%>
<%@ Import Namespace="Orchard.Core.Navigation.ViewModels"%>
<fieldset>
<%=Html.LabelFor(m => m.AddToMainMenu) %>
<%=Html.EditorFor(m => m.AddToMainMenu) %>
<%=Html.LabelFor(m => m.MenuText) %>
<%=Html.EditorFor(m => m.OnMainMenu) %>
<label for="OnMainMenu" class="forcheckbox"><%=_Encoded("Add to the main menu") %></label>
<label for="MenuText"><%=_Encoded("Menu text") %></label>
<%=Html.TextBoxFor(m => m.MenuText, new { @class = "large text" })%>
</fieldset>

View File

@@ -102,20 +102,23 @@
<Compile Include="Feeds\Models\FeedResponse.cs" />
<Compile Include="Feeds\Rss\RssFeedBuilder.cs" />
<Compile Include="Feeds\Rss\RssResult.cs" />
<Compile Include="HomePage\Controllers\HomeController.cs" />
<Compile Include="HomePage\Routes.cs" />
<Compile Include="Navigation\AdminMenu.cs" />
<Compile Include="Navigation\Controllers\AdminController.cs" />
<Compile Include="Navigation\Models\MenuItem.cs" />
<Compile Include="Navigation\Models\MenuItemDriver.cs" />
<Compile Include="Navigation\Models\MenuItemHandler.cs" />
<Compile Include="Navigation\Drivers\MenuItemDriver.cs" />
<Compile Include="Navigation\Handlers\MenuItemHandler.cs" />
<Compile Include="Navigation\Models\MenuPart.cs" />
<Compile Include="Navigation\Models\MenuPartDriver.cs" />
<Compile Include="Navigation\Models\MenuPartHandler.cs" />
<Compile Include="Navigation\Drivers\MenuPartDriver.cs" />
<Compile Include="Navigation\Handlers\MenuPartHandler.cs" />
<Compile Include="Navigation\Permissions.cs" />
<Compile Include="Navigation\Records\MenuItemRecord.cs" />
<Compile Include="Navigation\Records\MenuPartRecord.cs" />
<Compile Include="Navigation\Services\MainMenu.cs" />
<Compile Include="Navigation\Services\MainMenuFilter.cs" />
<Compile Include="Navigation\ViewModels\NavigationIndexViewModel.cs" />
<Compile Include="Navigation\Filters\MainMenuFilter.cs" />
<Compile Include="Navigation\ViewModels\CreateMenuItemViewModel.cs" />
<Compile Include="Navigation\ViewModels\NavigationManagementViewModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Scheduling\Records\ScheduledTaskRecord.cs" />
<Compile Include="Scheduling\Services\PublishingTaskHandler.cs" />
@@ -216,6 +219,7 @@
<Content Include="Themes\Views\Web.config" />
</ItemGroup>
<ItemGroup>
<Content Include="HomePage\Module.txt" />
<Content Include="Navigation\Views\Admin\Index.ascx" />
<Content Include="Navigation\Views\EditorTemplates\Parts\Navigation.EditMenuPart.ascx" />
<Content Include="Navigation\Views\Web.config" />

View File

@@ -5,7 +5,7 @@ namespace Orchard.Core.Settings {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add("Settings", "11",
builder.Add("Site", "11",
menu => menu
.Add("Manage Settings", "2.0", item => item.Action("Index", "Admin", new { area = "Settings" }).Permission(Permissions.ManageSettings)));
}

View File

@@ -24,5 +24,9 @@ namespace Orchard.Core.Settings.Models {
get { return Record.SuperUser; }
set { Record.SuperUser = value; }
}
public string HomePage {
get { return Record.HomePage; }
set { Record.HomePage = value; }
}
}
}

View File

@@ -7,5 +7,6 @@ namespace Orchard.Core.Settings.Records {
public virtual string SiteName { get; set; }
public virtual string SuperUser { get; set; }
public virtual string PageTitleSeparator { get; set; }
public virtual string HomePage { get; set; }
}
}

View File

@@ -5,9 +5,9 @@ namespace Orchard.Core.Themes {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add("Themes", "11",
builder.Add("Site", "11",
menu => menu
.Add("Manage Themes", "2.0", item => item.Action("Index", "Admin", new { area = "Themes" })
.Add("Manage Themes", "4.0", item => item.Action("Index", "Admin", new { area = "Themes" })
.Permission(Permissions.ManageThemes).Permission(Permissions.ApplyTheme)));
}
}

View File

@@ -1,8 +1,30 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<object>" %>
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<BaseViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.ViewModels"%><%
var menu = Model.Menu.FirstOrDefault();
if (menu != null && menu.Items.Count() > 0) { %>
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink(T("Home").ToString(), "Index", "Home", new {Area = ""}, new {})%></li>
<li><%= Html.ActionLink(T("Blogs").ToString(), "List", "Blog", new { Area = "Orchard.Blogs" }, new { })%></li>
<li><%= Html.ActionLink(T("Admin").ToString(), "List", new { Area = "Orchard.Blogs", Controller = "BlogAdmin" })%></li>
<%-- todo: (heskew) *really* need a better way of doing this. ...and this is really, really ugly :) --%>
<%-- TODO: (erikpo) Really need a partial for rendering lists (and it should be templatable) to fix the above todo :) --%>
<ul id="menu"><%
int counter = 0, count = menu.Items.Count() - 1;
foreach (var menuItem in menu.Items) {
var sbClass = new StringBuilder(10);
if (counter == 0)
sbClass.Append("first ");
if (counter == count)
sbClass.Append("last ");
var url = !string.IsNullOrEmpty(menuItem.Url)
? menuItem.Url
: Url.RouteUrl(menuItem.RouteValues);
if (string.Equals(url, Request.Url.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
sbClass.Append("current ");
%>
<li class="<%=sbClass.ToString().TrimEnd() %>"><%=Html.Link(menuItem.Text, url) %></li><%
++counter;
} %>
</ul>
</div>
</div><%
} %>

View File

@@ -1,5 +1,7 @@
using System;
using System.Linq;
using System.Web.Mvc;
using JetBrains.Annotations;
using Orchard.Blogs.Extensions;
using Orchard.Blogs.Models;
using Orchard.Blogs.Services;
@@ -10,6 +12,7 @@ using Orchard.Data;
using Orchard.Localization;
using Orchard.Mvc.Results;
using Orchard.Security;
using Orchard.Settings;
using Orchard.UI.Notify;
namespace Orchard.Blogs.Controllers {
@@ -33,6 +36,7 @@ namespace Orchard.Blogs.Controllers {
}
private Localizer T { get; set; }
protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; }
public ActionResult Create() {
//TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute
@@ -100,12 +104,17 @@ namespace Orchard.Blogs.Controllers {
return new NotFoundResult();
var model = new BlogEditViewModel {
Blog = _services.ContentManager.UpdateEditorModel(blog, this)
Blog = _services.ContentManager.UpdateEditorModel(blog, this),
};
if (!ModelState.IsValid)
return View(model);
string setAsHomePage = input["PromoteToHomePage"];
if (!String.IsNullOrEmpty(setAsHomePage) && !setAsHomePage.Equals("false")) {
CurrentSite.HomePage = "BlogHomePageProvider;" + model.Blog.Item.Id;
}
_notifier.Information(T("Blog information updated"));
return Redirect(Url.BlogsForAdmin());

View File

@@ -85,6 +85,7 @@
<Compile Include="Permissions.cs" />
<Compile Include="Routing\IsArchiveConstraint.cs" />
<Compile Include="Routing\IsBlogConstraint.cs" />
<Compile Include="Services\BlogHomePageProvider.cs" />
<Compile Include="Services\BlogService.cs" />
<Compile Include="Controllers\BlogController.cs" />
<Compile Include="Models\Blog.cs" />

View File

@@ -0,0 +1,49 @@
using System.Linq;
using System.Web.Mvc;
using Orchard.Blogs.Extensions;
using Orchard.Blogs.Models;
using Orchard.Blogs.ViewModels;
using Orchard.Mvc.Results;
using Orchard.Services;
using Orchard.Core.Feeds;
namespace Orchard.Blogs.Services {
public class BlogHomePageProvider : IHomePageProvider {
private readonly IBlogService _blogService;
private readonly IFeedManager _feedManager;
public BlogHomePageProvider(IOrchardServices services, IBlogService blogService, IFeedManager feedManager) {
Services = services;
_feedManager = feedManager;
_blogService = blogService;
}
public IOrchardServices Services { get; private set; }
#region Implementation of IHomePageProvider
public string GetProviderName() {
return "BlogHomePageProvider";
}
public ActionResult GetHomePage(int itemId) {
Blog blog = _blogService.Get().Where(x => x.Id == itemId).FirstOrDefault();
if (blog == null)
return new NotFoundResult();
var model = new BlogViewModel {
Blog = Services.ContentManager.BuildDisplayModel(blog, "Detail")
};
_feedManager.Register(blog);
return new ViewResult {
ViewName = "~/Modules/Orchard.Blogs/Views/Blog/Item.ascx",
ViewData = new ViewDataDictionary<BlogViewModel>(model)
};
}
#endregion
}
}

View File

@@ -4,5 +4,6 @@ using Orchard.Mvc.ViewModels;
namespace Orchard.Blogs.ViewModels {
public class BlogEditViewModel : AdminViewModel {
public ContentItemViewModel<Blog> Blog { get; set; }
public bool PromoteToHomePage { get; set; }
}
}

View File

@@ -4,5 +4,7 @@
<% using (Html.BeginFormAntiForgeryPost()) { %>
<%=Html.ValidationSummary() %>
<%=Html.EditorForItem(m => m.Blog) %>
<%=Html.EditorFor(m => m.PromoteToHomePage) %>
<label for="PromoteToHomePage" class="forcheckbox"><%=_Encoded("Set as home page") %></label>
<fieldset><input class="button" type="submit" value="<%=_Encoded("Save") %>" /></fieldset><%
} %>

View File

@@ -3,12 +3,14 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using JetBrains.Annotations;
using Orchard.Localization;
using Orchard.ContentManagement;
using Orchard.Mvc.Results;
using Orchard.Pages.Models;
using Orchard.Pages.Services;
using Orchard.Pages.ViewModels;
using Orchard.Settings;
using Orchard.UI.Notify;
namespace Orchard.Pages.Controllers {
@@ -22,6 +24,7 @@ namespace Orchard.Pages.Controllers {
T = NullLocalizer.Instance;
}
protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; }
public IOrchardServices Services { get; private set; }
private Localizer T { get; set; }
@@ -189,6 +192,9 @@ namespace Orchard.Pages.Controllers {
case "PublishNow":
_pageService.Publish(model.Page.Item);
Services.Notifier.Information(T("Page has been published"));
if (model.PromoteToHomePage) {
CurrentSite.HomePage = "PagesHomePageProvider;" + model.Page.Item.Id;
}
break;
case "PublishLater":
_pageService.Publish(model.Page.Item, model.Page.Item.ScheduledPublishUtc.Value);

View File

@@ -77,6 +77,7 @@
<Compile Include="Security\Authorization.cs" />
<Compile Include="Services\IPageService.cs" />
<Compile Include="Services\PageService.cs" />
<Compile Include="Services\PagesHomePageProvider.cs" />
<Compile Include="Services\SlugConstraint.cs">
<SubType>Code</SubType>
</Compile>

View File

@@ -0,0 +1,51 @@
using System.Web.Mvc;
using Orchard.Localization;
using Orchard.Mvc.Results;
using Orchard.Pages.Models;
using Orchard.Pages.ViewModels;
using Orchard.Services;
namespace Orchard.Pages.Services {
public class PagesHomePageProvider : IHomePageProvider {
private readonly IPageService _pageService;
private readonly ISlugConstraint _slugConstraint;
public PagesHomePageProvider(IOrchardServices services, IPageService pageService, ISlugConstraint slugConstraint) {
Services = services;
_slugConstraint = slugConstraint;
_pageService = pageService;
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; private set; }
private Localizer T { get; set; }
#region Implementation of IHomePageProvider
public string GetProviderName() {
return "PagesHomePageProvider";
}
public ActionResult GetHomePage(int itemId) {
Page page = _pageService.Get(itemId);
var correctedSlug = _slugConstraint.LookupPublishedSlug(page.Slug);
if (correctedSlug == null)
return new NotFoundResult();
page = _pageService.Get(correctedSlug);
if (page == null)
return new NotFoundResult();
var model = new PageViewModel {
Page = Services.ContentManager.BuildDisplayModel(page, "Detail")
};
return new ViewResult {
ViewName = "~/Modules/Orchard.Pages/Views/Page/Item.ascx",
ViewData = new ViewDataDictionary<PageViewModel>(model)
};
}
#endregion
}
}

View File

@@ -4,5 +4,6 @@ using Orchard.Mvc.ViewModels;
namespace Orchard.Pages.ViewModels {
public class PageEditViewModel : AdminViewModel {
public ContentItemViewModel<Page> Page { get; set; }
public bool PromoteToHomePage { get; set; }
}
}

View File

@@ -4,5 +4,8 @@
<h1><%=Html.TitleForPage(T("Edit Page").ToString()) %></h1>
<% using (Html.BeginFormAntiForgeryPost()) { %>
<%=Html.ValidationSummary() %>
<%=Html.EditorForItem(m => m.Page) %><%
<%=Html.EditorForItem(m => m.Page) %>
<%=Html.EditorFor(m => m.PromoteToHomePage) %>
<label for="PromoteToHomePage" class="forcheckbox"><%=_Encoded("Set as home page") %></label>
<%
} %>

View File

@@ -1,4 +1,4 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<PageViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.Pages.ViewModels"%>
<%=Html.DisplayForItem(m=>m.Page) %>
<%=Html.DisplayForItem(m=>m.Page) %>

View File

@@ -4,6 +4,7 @@ using System.Web.Mvc;
using Orchard.Comments.Models;
using Orchard.ContentManagement;
using Orchard.Core.Common.Models;
using Orchard.Core.Navigation.Models;
using Orchard.Core.Settings.Models;
using Orchard.Data;
using Orchard.Data.Migrations;
@@ -14,6 +15,7 @@ using Orchard.Settings;
using Orchard.Setup.ViewModels;
using Orchard.Localization;
using Orchard.UI.Notify;
using MenuItem=Orchard.Core.Navigation.Models.MenuItem;
namespace Orchard.Setup.Controllers {
public class SetupController : Controller {
@@ -102,6 +104,23 @@ namespace Orchard.Setup.Controllers {
page.As<HasComments>().CommentsShown = false;
page.As<CommonAspect>().Owner = user;
contentManager.Publish(page);
siteSettings.Record.HomePage = "PagesHomePageProvider;" + page.Id;
// add a menu item for the shiny new home page
var homeMenuItem = contentManager.Create("menuitem");
homeMenuItem.As<MenuPart>().MenuPosition = "1";
homeMenuItem.As<MenuPart>().MenuText = T("Home").ToString();
homeMenuItem.As<MenuPart>().OnMainMenu = true;
homeMenuItem.As<MenuItem>().Url = Request.Url.AbsolutePath;
// add a menu item for the admin
var adminMenuItem = contentManager.Create("menuitem");
adminMenuItem.As<MenuPart>().MenuPosition = "2";
adminMenuItem.As<MenuPart>().MenuText = T("Admin").ToString();
adminMenuItem.As<MenuPart>().OnMainMenu = true;
//adminMenuItem.As<MenuItem>().Permissions = new [] {StandardPermissions.AccessAdminPanel};
//todo: (heskew) pull "/blogs" once the is a ~/admin
adminMenuItem.As<MenuItem>().Url = string.Format("{0}admin/blogs", Request.Url.AbsolutePath);
var authenticationService = finiteEnvironment.Resolve<IAuthenticationService>();
authenticationService.SignIn(user, true);

View File

@@ -182,7 +182,6 @@
<Content Include="Themes\Classic\Views\DisplayTemplates\Parts\Blogs.BlogPost.List.ascx" />
<Content Include="Themes\Classic\Views\Footer.ascx" />
<Content Include="Themes\Classic\Views\Layout.ascx" />
<Content Include="Themes\Classic\Views\Menu.ascx" />
<Content Include="Themes\Green\Content\Images\bodyBackground.gif" />
<Content Include="Themes\Green\Content\Images\bodyBackground.png" />
<Content Include="Themes\Green\Content\Images\commentpointer.gif" />
@@ -205,7 +204,6 @@
<Content Include="Themes\Green\Views\Footer.ascx" />
<Content Include="Themes\Green\Views\Layout.ascx" />
<Content Include="Themes\Green\Views\ListOfComments.ascx" />
<Content Include="Themes\Green\Views\Menu.ascx" />
<Content Include="Themes\Green\Views\User.ascx" />
<Content Include="Themes\Orange\Theme.png" />
<Content Include="Themes\Orange\Views\Orchard.Blogs\BlogPost\Item.ascx" />
@@ -220,7 +218,6 @@
<Content Include="Themes\Orchard\Theme.txt" />
<Content Include="Themes\Orchard\Views\Footer.ascx" />
<Content Include="Themes\Orchard\Views\Layout.ascx" />
<Content Include="Themes\Orchard\Views\Menu.ascx" />
<Content Include="Themes\SafeMode\Content\Images\background_content.jpg" />
<Content Include="Themes\SafeMode\Content\Images\background_footer.jpg" />
<Content Include="Themes\SafeMode\Content\Images\background_module.gif" />

View File

@@ -1,8 +0,0 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home", new {Area = ""}, new {})%></li>
<li><%= Html.ActionLink("Blogs", "List", "Blog", new {Area = "Orchard.Blogs"}, new {})%></li>
<li class="last"><%= Html.ActionLink("Admin", "List", new {Area = "Orchard.Blogs", Controller = "BlogAdmin"})%></li>
</ul>
</div>

View File

@@ -275,11 +275,11 @@ colgroup
color:#35550b;
}
#menucontainer ul li.tabon {
#menucontainer ul li.current {
background:url(../Content/Images/tabRightOn.gif) no-repeat top right;
}
#menucontainer ul li.tabon a {
#menucontainer ul li.current a {
background:url(../Content/Images/tabLeftOn.gif) no-repeat top left;
font-weight:600;
}

View File

@@ -1,7 +0,0 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div id="menucontainer" role="navigation" class="yui-g">
<ul id="menu">
<li class="tabon"><%= Html.ActionLink("Home", "Index", "Home", new {Area = ""}, new {})%></li>
<li><%= Html.ActionLink("Blogs", "List", "Blog", new {Area = "Orchard.Blogs"}, new {})%></li>
</ul>
</div>

View File

@@ -1,9 +0,0 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home", new {Area = ""}, new {})%></li>
<li><%= Html.ActionLink("About", "About", "Home", new {Area = ""}, new {})%></li>
<li><%= Html.ActionLink("Blogs", "List", "Blog", new {Area = "Orchard.Blogs"}, new {})%></li>
<li><%= Html.ActionLink("Admin", "List", new {Area = "Orchard.Blogs", Controller = "BlogAdmin"})%></li>
</ul>
</div>

View File

@@ -151,7 +151,8 @@ h5 { font-size:1.4em; } /* 14px */
h6, p, legend, label, input, select, .button,
.message, .validation-summary-errors,
table.items th, table.items td, table.items caption { font-size:1.4em; line-height:1.4em; } /* 15px */
table.items th, table.items td, table.items caption { font-size:1.4em; line-height:1.4em; } /* 14px */
table.items p, table.items label, table.items input, table.items .button { font-size:1em; line-height:1em; }
p .button { font-size:inherit; }
.meta, .hint { font-size:1.2em; } /* 12px */
@@ -640,10 +641,6 @@ table.items thead, table.items th {
overflow:hidden;
text-align:left;
}
/* todo: (heskew) hook back up */
table.items tr.hover {
background-color:#f0f3d6;
}
table.items tr.critical {background:#e68585; border:inherit;}
table.items tr.warning {background:#fdf5bc; border:inherit;}
table.items th, table.items td {

View File

@@ -64,6 +64,7 @@ namespace Orchard.ContentManagement.Records {
mapping.References(syntheticExpression)
.Access.NoOp()
.Column("Id")
.ForeignKey("none") // prevent foreign key constraint from ContentItem(Version)Record to TPartRecord
.Unique()
.Not.Insert()
.Not.Update()
@@ -71,55 +72,6 @@ namespace Orchard.ContentManagement.Records {
}
}
class ContentPartAlterationInternal<TPartRecord> : IAlteration<ContentItemRecord> where TPartRecord : ContentPartRecord {
public void Override(AutoMapping<ContentItemRecord> mapping) {
// public TPartRecord TPartRecord {get;set;}
var name = typeof(TPartRecord).Name;
var syntheticMethod = new DynamicMethod(name, typeof(TPartRecord), null, typeof(ContentItemRecord));
var syntheticProperty = new SyntheticPropertyInfo(syntheticMethod);
// record => record.TPartRecord
var parameter = Expression.Parameter(typeof(ContentItemRecord), "record");
var syntheticExpression = (Expression<Func<ContentItemRecord, TPartRecord>>)Expression.Lambda(
typeof(Func<ContentItemRecord, TPartRecord>),
Expression.Property(parameter, syntheticProperty),
parameter);
mapping.References(syntheticExpression)
.Access.NoOp()
.Column("Id")
.Unique()
.Not.Insert()
.Not.Update()
.Cascade.All();
}
}
class ContentPartVersionAlterationInternal<TPartRecord> : IAlteration<ContentItemVersionRecord> where TPartRecord : ContentPartVersionRecord {
public void Override(AutoMapping<ContentItemVersionRecord> mapping) {
// public TPartRecord TPartRecord {get;set;}
var name = typeof(TPartRecord).Name;
var syntheticMethod = new DynamicMethod(name, typeof(TPartRecord), null, typeof(ContentItemVersionRecord));
var syntheticProperty = new SyntheticPropertyInfo(syntheticMethod);
// record => record.TPartRecord
var parameter = Expression.Parameter(typeof(ContentItemVersionRecord), "record");
var syntheticExpression = (Expression<Func<ContentItemVersionRecord, TPartRecord>>)Expression.Lambda(
typeof(Func<ContentItemVersionRecord, TPartRecord>),
Expression.Property(parameter, syntheticProperty),
parameter);
mapping.References(syntheticExpression)
.Access.NoOp()
.Column("Id")
.Unique()
.Not.Insert()
.Not.Update()
.Cascade.All();
}
}
private class SyntheticPropertyInfo : PropertyInfo {
private readonly DynamicMethod _getMethod;

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
@@ -161,6 +162,11 @@ namespace Orchard.Environment.ShellBuilders {
public string SuperUser {
get { return ""; }
}
public string HomePage {
get { return ""; }
set { throw new NotImplementedException(); }
}
}
}

View File

@@ -156,6 +156,7 @@
<Compile Include="Security\IAuthorizationServiceEvents.cs" />
<Compile Include="Security\StandardPermissions.cs" />
<Compile Include="Security\OrchardSecurityException.cs" />
<Compile Include="Services\IHomePageProvider.cs" />
<Compile Include="Tasks\Scheduling\IPublishingTaskManager.cs" />
<Compile Include="Tasks\Scheduling\IScheduledTask.cs" />
<Compile Include="ContentManagement\ContentExtensions.cs" />
@@ -285,6 +286,7 @@
<Compile Include="Mvc\ViewEngines\WebFormsViewEngineProvider.cs" />
<Compile Include="Mvc\ViewModels\AdminViewModel.cs" />
<Compile Include="Mvc\ViewModels\BaseViewModel.cs" />
<Compile Include="UI\Navigation\INavigationManager.cs" />
<Compile Include="UI\PageClass\IPageClassBuilder.cs" />
<Compile Include="UI\PageClass\PageClassBuilder.cs" />
<Compile Include="UI\PageTitle\IPageTitleBuilder.cs" />

View File

@@ -0,0 +1,8 @@
using System.Web.Mvc;
namespace Orchard.Services {
public interface IHomePageProvider : IDependency {
string GetProviderName();
ActionResult GetHomePage(int itemId);
}
}

View File

@@ -10,5 +10,6 @@ namespace Orchard.Settings {
string SiteSalt { get; }
string SiteUrl { get; }
string SuperUser { get; }
string HomePage { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
using System.Collections.Generic;
namespace Orchard.UI.Navigation {
public interface INavigationManager : IDependency {
IEnumerable<MenuItem> BuildMenu(string menuName);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Routing;
@@ -11,6 +10,7 @@ namespace Orchard.UI.Navigation {
}
public string Text { get; set; }
public string Url { get; set; }
public string Position { get; set; }
public RouteValueDictionary RouteValues { get; set; }
public IEnumerable<MenuItem> Items { get; set; }

View File

@@ -7,6 +7,9 @@ namespace Orchard.UI.Navigation {
if (!string.Equals(x.Text, y.Text)) {
return false;
}
if (!string.Equals(x.Url, y.Url)) {
return false;
}
if (x.RouteValues != null || y.RouteValues != null) {
if (x.RouteValues == null || y.RouteValues == null) {
return false;
@@ -32,6 +35,9 @@ namespace Orchard.UI.Navigation {
if (obj.Text != null) {
hash ^= obj.Text.GetHashCode();
}
if (obj.Url != null) {
hash ^= obj.Url.GetHashCode();
}
if (obj.RouteValues != null) {
foreach (var item in obj.RouteValues) {
hash ^= item.Key.GetHashCode() ^ item.Value.GetHashCode();

View File

@@ -57,6 +57,11 @@ namespace Orchard.UI.Navigation {
return this;
}
public NavigationItemBuilder Url(string url) {
_item.Url = url;
return this;
}
public NavigationItemBuilder Permission(Permission permission) {
_item.Permissions = _item.Permissions.Concat(new[]{permission});
return this;
@@ -67,6 +72,12 @@ namespace Orchard.UI.Navigation {
return new[] { _item };
}
public NavigationItemBuilder Action(RouteValueDictionary values) {
return values != null
? Action(values["action"] as string, values["controller"] as string, values)
: Action(null, null, new RouteValueDictionary());
}
public NavigationItemBuilder Action(string actionName) {
return Action(actionName, null, new RouteValueDictionary());
}

View File

@@ -1,16 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Orchard.Security;
using Orchard.Security.Permissions;
namespace Orchard.UI.Navigation {
public interface INavigationManager : IDependency {
IEnumerable<MenuItem> BuildMenu(string menuName);
}
public class NavigationManager : INavigationManager {
private readonly IEnumerable<INavigationProvider> _providers;
private readonly IAuthorizationService _authorizationService;
@@ -45,6 +39,7 @@ namespace Orchard.UI.Navigation {
Position = item.Position,
RouteValues = item.RouteValues,
Text = item.Text,
Url = item.Url
};
}
}
@@ -75,6 +70,7 @@ namespace Orchard.UI.Navigation {
var joined = new MenuItem {
Text = items.First().Text,
Url = items.First().Url,
RouteValues = items.First().RouteValues,
Items = Merge(items.Select(x => x.Items)).ToArray(),
Position = SelectBestPositionValue(items.Select(x => x.Position)),