--HG--
branch : dev
This commit is contained in:
Andre Rodrigues
2010-10-14 09:21:45 -07:00
17 changed files with 154 additions and 23 deletions

View File

@@ -33,14 +33,15 @@ namespace Orchard.Blogs {
item =>
item.Action("Item", "BlogAdmin", new {area = "Orchard.Blogs", blogSlug = singleBlog.Slug}).Permission(Permissions.MetaListBlogs));
menu.Add(T("Create New Blog"), "1.1",
if ( singleBlog != null )
menu.Add(T("Create New Post"), "1.1",
item =>
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogSlug = singleBlog.Slug }).Permission(Permissions.PublishBlogPost));
menu.Add(T("Create New Blog"), "1.2",
item =>
item.Action("Create", "BlogAdmin", new { area = "Orchard.Blogs" }).Permission(Permissions.ManageBlogs));
if (singleBlog != null)
menu.Add(T("Create New Post"), "1.2",
item =>
item.Action("Create", "BlogPostAdmin", new {area = "Orchard.Blogs", blogSlug = singleBlog.Slug}).Permission(Permissions.PublishBlogPost));
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
@@ -6,6 +7,7 @@ using System.Xml.Linq;
using Orchard.Blogs.Models;
using Orchard.Blogs.Routing;
using Orchard.Blogs.Services;
using Orchard.Blogs.ViewModels;
using Orchard.DisplayManagement;
using Orchard.Logging;
using Orchard.Mvc.Results;
@@ -16,12 +18,14 @@ namespace Orchard.Blogs.Controllers {
public class BlogController : Controller {
private readonly IOrchardServices _services;
private readonly IBlogService _blogService;
private readonly IBlogPostService _blogPostService;
private readonly IBlogSlugConstraint _blogSlugConstraint;
private readonly RouteCollection _routeCollection;
public BlogController(IOrchardServices services, IBlogService blogService, IBlogSlugConstraint blogSlugConstraint, RouteCollection routeCollection, IShapeHelperFactory shapeHelperFactory) {
public BlogController(IOrchardServices services, IBlogService blogService, IBlogPostService blogPostService, IBlogSlugConstraint blogSlugConstraint, RouteCollection routeCollection, IShapeHelperFactory shapeHelperFactory) {
_services = services;
_blogService = blogService;
_blogPostService = blogPostService;
_blogSlugConstraint = blogSlugConstraint;
_routeCollection = routeCollection;
Logger = NullLogger.Instance;
@@ -44,18 +48,31 @@ namespace Orchard.Blogs.Controllers {
}
//TODO: (erikpo) Should move the slug parameter and get call and null check up into a model binder
public ActionResult Item(string blogSlug) {
public ActionResult Item(string blogSlug, int page) {
const int pageSize = 10;
var correctedSlug = _blogSlugConstraint.FindSlug(blogSlug);
if (correctedSlug == null)
return new NotFoundResult();
var blog = _blogService.Get(correctedSlug);
BlogPart blog = _blogService.Get(correctedSlug);
if (blog == null)
return new NotFoundResult();
//todo: (heskew) "Blog" should be an alternative instead of a display type
var model = _services.ContentManager.BuildDisplay(blog, "Blog");
var blogPosts = _blogPostService.Get(blog, (page - 1)*pageSize, pageSize).Select(b => _services.ContentManager.BuildDisplay(b, "Summary.BlogPost"));
var list = Shape.List();
list.AddRange(blogPosts);
var model = new DisplayBlogViewModel {
BlogPostList = list,
BlogPart = blog,
Page = page,
PageSize = pageSize
};
return View(model);
}
public ActionResult LiveWriterManifest(string blogSlug) {

View File

@@ -107,6 +107,7 @@
<Compile Include="Services\IBlogService.cs" />
<Compile Include="Services\XmlRpcHandler.cs" />
<Compile Include="ViewModels\BlogPostArchiveViewModel.cs" />
<Compile Include="ViewModels\DisplayBlogViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\Admin\images\draft.gif" />
@@ -118,6 +119,7 @@
<Content Include="Scripts\archives.js" />
<Content Include="Styles\admin.css" />
<Content Include="Styles\archives.css" />
<Content Include="Styles\pagination.css" />
<Content Include="Views\BlogAdmin\Create.cshtml" />
<Content Include="Views\BlogAdmin\Edit.cshtml" />
<Content Include="Views\BlogAdmin\Item.cshtml" />
@@ -131,7 +133,6 @@
<Content Include="Views\Parts\Blogs.Blog.Manage.cshtml" />
<Content Include="Views\Parts\Blogs.Blog.Description.cshtml" />
<Content Include="Views\Parts\Common.Metadata.Admin.Blog.cshtml" />
<Content Include="Views\Parts\Blogs.BlogPost.List.cshtml" />
<Content Include="Views\EditorTemplates\Parts\Blogs.Blog.Fields.cshtml" />
<Content Include="Views\Parts\Blogs.BlogPost.List.Admin.cshtml">
<SubType>Code</SubType>
@@ -190,6 +191,7 @@
<None Include="Views\DisplayTemplates\Parts\Blogs.BlogArchives.cshtml" />
<None Include="Views\EditorTemplates\Parts\Blogs.RecentBlogPosts.cshtml" />
<None Include="Views\EditorTemplates\Parts\Blogs.BlogArchives.cshtml" />
<None Include="Views\Parts\Blogs.BlogPost.List.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

View File

@@ -259,6 +259,24 @@ namespace Orchard.Blogs {
Priority = 11,
Route = new Route(
"{blogSlug}",
new RouteValueDictionary {
{"area", "Orchard.Blogs"},
{"controller", "Blog"},
{"action", "Item"},
{"page", 1}
},
new RouteValueDictionary {
{"blogSlug", _blogSlugConstraint}
},
new RouteValueDictionary {
{"area", "Orchard.Blogs"}
},
new MvcRouteHandler())
},
new RouteDescriptor {
Priority = 11,
Route = new Route(
"{blogSlug}/Page/{*page}",
new RouteValueDictionary {
{"area", "Orchard.Blogs"},
{"controller", "Blog"},

View File

@@ -49,6 +49,11 @@ namespace Orchard.Blogs.Services {
return GetBlogQuery(blogPart, versionOptions).List().Select(ci => ci.As<BlogPostPart>());
}
public IEnumerable<BlogPostPart> Get(BlogPart blogPart, int skip, int count) {
return GetBlogQuery(blogPart, VersionOptions.Published).Slice(skip, count).ToList().Select(ci => ci.As<BlogPostPart>());
}
public IEnumerable<BlogPostPart> Get(BlogPart blogPart, ArchiveData archiveData) {
var query = GetBlogQuery(blogPart, VersionOptions.Published);

View File

@@ -12,6 +12,7 @@ namespace Orchard.Blogs.Services {
IEnumerable<BlogPostPart> Get(BlogPart blogPart);
IEnumerable<BlogPostPart> Get(BlogPart blogPart, VersionOptions versionOptions);
IEnumerable<BlogPostPart> Get(BlogPart blogPart, ArchiveData archiveData);
IEnumerable<BlogPostPart> Get(BlogPart blogPart, int skip, int count);
IEnumerable<KeyValuePair<ArchiveData, int>> GetArchives(BlogPart blogPart);
void Delete(BlogPostPart blogPostPart);
void Publish(BlogPostPart blogPostPart);

View File

@@ -0,0 +1,19 @@
ul.pagination
{
list-style-type:none;
}
ul.pagination li a
{
font-size:13px;
}
ul.pagination li.newer
{
float:left;
}
ul.pagination li.older
{
float:right;
}

View File

@@ -0,0 +1,10 @@
using Orchard.Blogs.Models;
namespace Orchard.Blogs.ViewModels {
public class DisplayBlogViewModel {
public BlogPart BlogPart { get; set; }
public dynamic BlogPostList { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
}
}

View File

@@ -1 +1,28 @@
@Display(Model)
@model Orchard.Blogs.ViewModels.DisplayBlogViewModel
@using Orchard.Blogs.Extensions;
@{
Style.Include("pagination.css");
}
@if (Model.BlogPostList.Items.Count > 0) {
@Display(Model.BlogPostList)
<ul class="pagination">
@if(Model.BlogPostList.Items.Count == Model.PageSize) {
<li class="older">
@Html.ActionLink(T("Older Posts").Text, "Item", new { Area = "Orchard.Blogs", blogSlug = Model.BlogPart.Slug, page = Model.Page + 1 })
</li>
}
@if(Model.Page > 1) {
<li class="newer">
@Html.ActionLink(T("Newer Posts").Text, "Item", new { Area = "Orchard.Blogs", blogSlug = Model.BlogPart.Slug, page = Model.Page - 1 })
</li>
}
</ul>
}
else {
<p>@T("There are no posts for this blog.")</p>
}

View File

@@ -81,6 +81,13 @@ namespace Orchard.Setup.Controllers {
ModelState.AddModelError("ConfirmPassword", T("Password confirmation must match").ToString());
}
if(!model.DatabaseOptions && !String.IsNullOrWhiteSpace(model.DatabaseTablePrefix)) {
model.DatabaseTablePrefix = model.DatabaseTablePrefix.Trim();
if(!Char.IsLetter(model.DatabaseTablePrefix[0])) {
ModelState.AddModelError("DatabaseTablePrefix", T("The table prefix must begin with a letter").Text);
}
}
ValidateMachineKey();
if (!ModelState.IsValid) {

View File

@@ -9,7 +9,7 @@ namespace Orchard.UI.Resources {
manifest.DefineScript("jQueryUI_Core").SetUrl("jquery.ui.core.js").SetVersion("1.8b1").SetDependencies("jQuery");
manifest.DefineScript("jQueryUI_Widget").SetUrl("jquery.ui.widget.js").SetVersion("1.8b1").SetDependencies("jQuery");
manifest.DefineScript("jQueryUI_DatePicker").SetUrl("jquery.ui.datepicker.js").SetVersion("1.8b1").SetDependencies("jQueryUI_Core", "jQueryUI_Widget");
manifest.DefineScript("jQueryUtils_TimePicker").SetUrl("ui.timepickr.js").SetVersion("0.7.0a").SetDependencies("jQueryUtils", "jQueryUI_Core");
manifest.DefineScript("jQueryUtils_TimePicker").SetUrl("ui.timepickr.js").SetVersion("0.7.0a").SetDependencies("jQueryUtils", "jQueryUI_Core", "jQueryUI_Widget");
manifest.DefineStyle("jQueryUtils_TimePicker").SetUrl("ui.timepickr.css");
manifest.DefineStyle("jQueryUI_Orchard").SetUrl("jquery-ui-1.7.2.custom.css").SetVersion("1.7.2");

View File

@@ -137,7 +137,7 @@
<Content Include="Themes\TheAdmin\Styles\images\menuOpen.gif" />
<Content Include="Themes\TheAdmin\Styles\images\menuOpenHover.gif" />
<Content Include="Themes\TheThemeMachine\draft.html" />
<Content Include="Themes\TheThemeMachine\Styles\site.css" />
<Content Include="Themes\TheThemeMachine\Styles\Site.css" />
<Content Include="Themes\TheThemeMachine\Theme.png" />
<Content Include="Themes\TheThemeMachine\Theme.txt" />
<None Include="Themes\Classic\App_Data\Localization\fr-FR\orchard.theme.po" />
@@ -145,6 +145,7 @@
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Themes\TheThemeMachine\Views\User.cshtml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Orchard\Orchard.Framework.csproj">

View File

@@ -80,6 +80,7 @@ header, footer, aside, nav, article { display: block; }
}
/* General
***************************************************************/
/* Default font settings.
@@ -165,7 +166,6 @@ pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height:
#layout-header
{
border-top: 1px solid #dbdbdb;
margin: 36px auto;
}
#branding
@@ -178,6 +178,11 @@ pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height:
text-decoration:none;
}
#layout-footer
{
border-top: 1px solid #dbdbdb;
}
/* Navigation */
#navigation
{
@@ -221,7 +226,7 @@ nav ul
.zone-header { }
.zone-footer { padding: 24px 0 12px 0px; float: left; font-size: 1.3em; color: #999999; }
.zone-content { padding: 12px 0 12px 0px; }
.zone-asidethird {}
.zone-asidethird { padding: 0 0 6px 0; }
/* Main
@@ -362,6 +367,8 @@ button:focus, .button:focus {
.bottom { margin-bottom:0; padding-bottom:0; }
.user-display { float: left; padding: 24px 12px 12px 12px; font-size: 1.3em; }
.user-display .welcome {}
.user-display .user-actions {}

View File

@@ -82,14 +82,17 @@
</aside>
}
</div>
@* span -> p (?) *@
@using(Capture(pbo => WorkContext.Layout.Footer.Add(pbo) )) {
<span>Powered by Orchard &#169; The Theme Machine 2010.</span>
<span class="poweredby">Powered by Orchard</span> <span class="copyright">&#169; The Theme Machine 2010.</span>
}
@if(Model.Footer != null) {
<footer id="layout-footer" class="group">
@Zone(Model.Footer)
@Display.User()
</footer>
}
@tag.EndElement

View File

@@ -0,0 +1,13 @@
@using System.Web.Mvc;
<div class="user-display">
@if (Request.IsAuthenticated) {
<span class="welcome">@T("Welcome, <strong>{0}</strong>!", WorkContext.CurrentUser.UserName)</span>
<span class="user-actions">
@Html.ActionLink(T("Log Off").ToString(), "LogOff", new { Controller = "Account", Area = "Orchard.Users", ReturnUrl = Context.Request.RawUrl })
@Html.ActionLink("Dashboard", "Index", new { Area = "Dashboard", Controller = "Admin" })
</span>
} else {
<span class="user-actions">@Html.ActionLink(T("Login").ToString(), "LogOn", new { Controller = "Account", Area = "Orchard.Users", ReturnUrl = Context.Request.RawUrl })</span>
}
</div>