diff --git a/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs b/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs index fb0fca24a..ba7f8f63d 100644 --- a/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs +++ b/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs @@ -15,29 +15,17 @@ namespace Orchard.Search.Controllers { _contentManager = contentManager; } - public ActionResult Index(string q, int page = 0, int pageSize = 0) { - var take = pageSize > 0 ? pageSize : 10; - var skip = (page > 0 ? page - 1 : 0) * take; + public ActionResult Index(string q, int page = 1, int pageSize = 10) { var searchViewModel = new SearchViewModel { Query = q, - Page = page > 0 ? page : 1, - PageSize = take + DefaultPageSize = 10, // <- yeah, I know :| + PageOfResults = _searchService.Query(q, page, pageSize, searchHit => new SearchResultViewModel { + Content = _contentManager.BuildDisplayModel(_contentManager.Get(searchHit.Id), "SummaryForSearch"), + SearchHit = searchHit + }) }; - var results = _searchService.Query(q, skip, take); - - if (results == null) - return View(searchViewModel); - - searchViewModel.Count = results.TotalCount; - searchViewModel.TotalPageCount = (int)Math.Ceiling((decimal)searchViewModel.Count/searchViewModel.PageSize); //todo: deal with page requests beyond result count - searchViewModel.ResultsPage = results.Page - .Select(result => new SearchResultViewModel { - Content = _contentManager.BuildDisplayModel(_contentManager.Get(result.Id), "SummaryForSearch"), - SearchHit = result - }) - .ToList(); return View(searchViewModel); } diff --git a/src/Orchard.Web/Modules/Orchard.Search/Services/ISearchService.cs b/src/Orchard.Web/Modules/Orchard.Search/Services/ISearchService.cs index 38e1b332f..0437e73ba 100644 --- a/src/Orchard.Web/Modules/Orchard.Search/Services/ISearchService.cs +++ b/src/Orchard.Web/Modules/Orchard.Search/Services/ISearchService.cs @@ -1,10 +1,11 @@ using System; -using Orchard.Search.Models; +using Orchard.Collections; +using Orchard.Indexing; namespace Orchard.Search.Services { public interface ISearchService : IDependency { bool HasIndexToManage { get; } - ISearchResult Query(string query, int skip, int? take); + IPageOfItems Query(string query, int skip, int? take, Func shapeResult); void RebuildIndex(); void UpdateIndex(); DateTime GetIndexUpdatedUtc(); diff --git a/src/Orchard.Web/Modules/Orchard.Search/Services/SearchService.cs b/src/Orchard.Web/Modules/Orchard.Search/Services/SearchService.cs index f10297398..f68d0919e 100644 --- a/src/Orchard.Web/Modules/Orchard.Search/Services/SearchService.cs +++ b/src/Orchard.Web/Modules/Orchard.Search/Services/SearchService.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Linq; +using Orchard.Collections; using Orchard.Indexing; using Orchard.Localization; using Orchard.Search.Models; @@ -27,23 +29,27 @@ namespace Orchard.Search.Services get { return _indexManager.HasIndexProvider(); } } - ISearchResult ISearchService.Query(string query, int skip, int? take) { + IPageOfItems ISearchService.Query(string query, int page, int? pageSize, Func shapeResult) { if (string.IsNullOrWhiteSpace(query) || !_indexManager.HasIndexProvider()) return null; - var searchBuilder = _indexManager.GetSearchIndexProvider().CreateSearchBuilder(SearchIndexName) + var searchBuilder = _indexManager.GetSearchIndexProvider().CreateSearchBuilder(SearchIndexName) .WithField("title", query) .WithField("body", query); var totalCount = searchBuilder.Count(); - if (take != null) + if (pageSize != null) searchBuilder = searchBuilder - .Slice(skip, (int)take); + .Slice((page > 0 ? page - 1 : 0) * (int)pageSize, (int)pageSize); - return new SearchResult { - Page = searchBuilder.Search(), - TotalCount = totalCount + + var pageOfItems = new PageOfItems(searchBuilder.Search().Select(shapeResult)) { + PageNumber = page, + PageSize = pageSize != null ? (int) pageSize : totalCount, + TotalItemCount = totalCount }; + + return pageOfItems; } void ISearchService.RebuildIndex() { diff --git a/src/Orchard.Web/Modules/Orchard.Search/ViewModels/SearchViewModel.cs b/src/Orchard.Web/Modules/Orchard.Search/ViewModels/SearchViewModel.cs index 95fe09102..3da6fc7cb 100644 --- a/src/Orchard.Web/Modules/Orchard.Search/ViewModels/SearchViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.Search/ViewModels/SearchViewModel.cs @@ -1,13 +1,10 @@ -using System.Collections.Generic; +using Orchard.Collections; using Orchard.Mvc.ViewModels; namespace Orchard.Search.ViewModels { public class SearchViewModel : BaseViewModel { - public IEnumerable ResultsPage { get; set; } - public int Count { get; set; } - public int Page { get; set; } - public int PageSize { get; set; } - public int TotalPageCount { get; set; } public string Query { get; set; } + public int DefaultPageSize { get; set; } + public IPageOfItems PageOfResults { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Search/Views/Search/Index.ascx b/src/Orchard.Web/Modules/Orchard.Search/Views/Search/Index.ascx index 7705343c5..472083772 100644 --- a/src/Orchard.Web/Modules/Orchard.Search/Views/Search/Index.ascx +++ b/src/Orchard.Web/Modules/Orchard.Search/Views/Search/Index.ascx @@ -4,14 +4,14 @@ Html.RegisterStyle("search.css"); %>

<%=Html.TitleForPage(T("Search").Text)%>

<% Html.Zone("search"); if (!string.IsNullOrWhiteSpace(Model.Query)) { - if (Model.Count == 0) { %> + if (Model.PageOfResults.Count() == 0) { %>

<%=T("zero results") %>

<% } else { %> -

<%=T("{0} - {1} of {2} results", (Model.Page - 1) * Model.PageSize + 1, Model.Page * Model.PageSize > Model.Count ? Model.Count : Model.Page * Model.PageSize, Model.Count)%>

<% +

<%=T("{0} - {1} of {2} results", Model.PageOfResults.StartPosition, Model.PageOfResults.EndPosition, Model.PageOfResults.TotalItemCount)%>

<% } } -if (Model.ResultsPage != null && Model.ResultsPage.Count() > 0) { %> -<%=Html.UnorderedList(Model.ResultsPage, (r, i) => Html.DisplayForItem(r.Content).ToHtmlString(), "search-results contentItems") %> -<%=Html.Pager(Model.TotalPageCount, Model.Page, new {q = Model.Query}) %><% +if (Model.PageOfResults != null && Model.PageOfResults.Count() > 0) { %> +<%=Html.UnorderedList(Model.PageOfResults, (r, i) => Html.DisplayForItem(r.Content).ToHtmlString() , "search-results contentItems") %> +<%=Html.Pager(Model.PageOfResults, Model.PageOfResults.PageNumber, Model.DefaultPageSize, new {q = Model.Query}) %><% } %> \ No newline at end of file diff --git a/src/Orchard/Collections/IPageOfItems.cs b/src/Orchard/Collections/IPageOfItems.cs new file mode 100644 index 000000000..4ed9362bd --- /dev/null +++ b/src/Orchard/Collections/IPageOfItems.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Orchard.Collections { + public interface IPageOfItems : IEnumerable { + int PageNumber { get; set; } + int PageSize { get; set; } + int TotalItemCount { get; set; } + int TotalPageCount { get; } + int StartPosition { get; } + int EndPosition { get; } + } +} \ No newline at end of file diff --git a/src/Orchard/Collections/PageOfItems.cs b/src/Orchard/Collections/PageOfItems.cs new file mode 100644 index 000000000..3e69aa696 --- /dev/null +++ b/src/Orchard/Collections/PageOfItems.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; + +namespace Orchard.Collections { + public class PageOfItems : List, IPageOfItems { + public PageOfItems(IEnumerable items) { + AddRange(items); + } + + #region IPageOfItems Members + + public int PageNumber { get; set; } + public int PageSize { get; set; } + public int TotalItemCount { get; set; } + + public int TotalPageCount { + get { return (int) Math.Ceiling((double) TotalItemCount/PageSize); } + } + public int StartPosition { + get { return (PageNumber - 1)*PageSize + 1; } + } + public int EndPosition { + get { return PageNumber * PageSize > TotalItemCount ? TotalItemCount : PageNumber * PageSize; } + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs b/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs index 5610daebe..c302658aa 100644 --- a/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs +++ b/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; -using System.Text.RegularExpressions; using System.Web.Mvc; using System.Web.Mvc.Html; using System.Web.Routing; +using Orchard.Collections; using Orchard.Mvc.ViewModels; using Orchard.Services; using Orchard.Settings; @@ -40,21 +40,25 @@ namespace Orchard.Mvc.Html { return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal)); } + #region Pager - public static string Pager(this HtmlHelper html, int pageCount, int currentPage, object values = null, string previousText = "<", string nextText = ">", bool alwaysShowPreviousAndNext = false) { - if (pageCount < 2) + public static string Pager(this HtmlHelper html, IPageOfItems pageOfItems, int currentPage, int defaultPageSize, object values = null, string previousText = "<", string nextText = ">", bool alwaysShowPreviousAndNext = false) { + if (pageOfItems.TotalPageCount < 2) return ""; var sb = new StringBuilder(75); + var rvd = new RouteValueDictionary {{"q", ""},{"page", 0}}; var viewContext = html.ViewContext; - var rvd = new RouteValueDictionary(); + var urlHelper = new UrlHelper(viewContext.RequestContext); + + if (pageOfItems.PageSize != defaultPageSize) + rvd.Add("pagesize", pageOfItems.PageSize); foreach (var item in viewContext.RouteData.Values) { rvd.Add(item.Key, item.Value); } - var urlHelper = new UrlHelper(viewContext.RequestContext); if (values != null) { var rvd2 = new RouteValueDictionary(values); @@ -77,18 +81,22 @@ namespace Orchard.Mvc.Html { } //todo: when there are many pages (> 15?) maybe do something like 1 2 3...6 7 8...13 14 15 - for (var p = 1; p <= pageCount; p++) { + for (var p = 1; p <= pageOfItems.TotalPageCount; p++) { if (p == currentPage) { sb.AppendFormat(" {0}", p); } else { - rvd["page"] = p; + if (p == 1) + rvd.Remove("page"); + else + rvd["page"] = p; + sb.AppendFormat(" {0}", p, urlHelper.RouteUrl(rvd)); } } - if (currentPage < pageCount || alwaysShowPreviousAndNext) { + if (currentPage < pageOfItems.TotalPageCount || alwaysShowPreviousAndNext) { rvd["page"] = currentPage + 1; sb.AppendFormat("{0}", nextText, urlHelper.RouteUrl(rvd)); diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 129d4177f..249a3dc12 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -130,6 +130,8 @@ + + Code