mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 19:04:51 +08:00
Adding some admin UI for search index management. Not yet working end-to-end but it looks like it does *
* Waiting on some pieces of the index manager/provider are being added and/or reworked then we'll get it all hooked up. --HG-- branch : dev
This commit is contained in:
16
src/Orchard.Web/Modules/Orchard.Search/AdminMenu.cs
Normal file
16
src/Orchard.Web/Modules/Orchard.Search/AdminMenu.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Search {
|
||||
public class AdminMenu : INavigationProvider {
|
||||
public Localizer T { get; set; }
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Site"), "11",
|
||||
menu => menu
|
||||
.Add(T("Search Index"), "10.0", item => item.Action("Index", "Admin", new {area = "Orchard.Search"})
|
||||
.Permission(Permissions.ManageSearchIndex)));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Search.Services;
|
||||
using Orchard.Search.ViewModels;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Search.Controllers {
|
||||
public class AdminController : Controller {
|
||||
private readonly ISearchService _searchService;
|
||||
|
||||
public AdminController(ISearchService searchService, IOrchardServices services) {
|
||||
_searchService = searchService;
|
||||
Services = services;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; private set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public ActionResult Index() {
|
||||
var viewModel = new SearchIndexViewModel {HasIndexToManage = _searchService.HasIndexToManage};
|
||||
|
||||
if (!viewModel.HasIndexToManage)
|
||||
Services.Notifier.Information(T("There is not search index to manage for this site."));
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Update() {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageSearchIndex, T("Not allowed to manage the search index.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
_searchService.UpdateIndex();
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Rebuild() {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageSearchIndex, T("Not allowed to manage the search index.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
_searchService.RebuildIndex();
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
}
|
@@ -65,11 +65,15 @@
|
||||
<Reference Include="System.EnterpriseServices" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Controllers\SearchController.cs" />
|
||||
<Compile Include="Filters\SearchFilter.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Routes.cs" />
|
||||
<Compile Include="Services\ISearchService.cs" />
|
||||
<Compile Include="Services\SearchService.cs" />
|
||||
<Compile Include="ViewModels\SearchIndexViewModel.cs" />
|
||||
<Compile Include="ViewModels\SearchResultViewModel.cs" />
|
||||
<Compile Include="ViewModels\SearchViewModel.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -82,7 +86,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Module.txt" />
|
||||
<Content Include="Styles\admin.css" />
|
||||
<Content Include="Styles\search.css" />
|
||||
<Content Include="Views\Admin\Index.ascx" />
|
||||
<Content Include="Views\SearchForm.ascx" />
|
||||
<Content Include="Views\Search\Index.ascx" />
|
||||
<Content Include="Views\Web.config" />
|
||||
|
29
src/Orchard.Web/Modules/Orchard.Search/Permissions.cs
Normal file
29
src/Orchard.Web/Modules/Orchard.Search/Permissions.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Security.Permissions;
|
||||
|
||||
namespace Orchard.Search {
|
||||
public class Permissions : IPermissionProvider {
|
||||
public static readonly Permission ManageSearchIndex = new Permission { Description = "Manage Search Index", Name = "ManageSearchIndex" };
|
||||
|
||||
public string ModuleName {
|
||||
get {
|
||||
return "Search";
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Permission> GetPermissions() {
|
||||
return new Permission[] {
|
||||
ManageSearchIndex,
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
|
||||
return new[] {
|
||||
new PermissionStereotype {
|
||||
Name = "Administrator",
|
||||
Permissions = new[] {ManageSearchIndex}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,9 @@ using Orchard.Indexing;
|
||||
|
||||
namespace Orchard.Search.Services {
|
||||
public interface ISearchService : IDependency {
|
||||
bool HasIndexToManage { get; }
|
||||
IEnumerable<ISearchHit> Query(string term);
|
||||
void RebuildIndex();
|
||||
void UpdateIndex();
|
||||
}
|
||||
}
|
@@ -1,25 +1,58 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Indexing;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Search.Services
|
||||
{
|
||||
public class SearchService : ISearchService
|
||||
{
|
||||
private const string SearchIndexName = "search";
|
||||
private readonly IIndexManager _indexManager;
|
||||
|
||||
public SearchService(IIndexManager indexManager) {
|
||||
public SearchService(IOrchardServices services, IIndexManager indexManager) {
|
||||
Services = services;
|
||||
_indexManager = indexManager;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public bool HasIndexToManage {
|
||||
get { return _indexManager.HasIndexProvider(); }
|
||||
}
|
||||
|
||||
public IEnumerable<ISearchHit> Query(string term) {
|
||||
if (string.IsNullOrWhiteSpace(term) || !_indexManager.HasIndexProvider())
|
||||
return Enumerable.Empty<ISearchHit>();
|
||||
|
||||
return _indexManager.GetSearchIndexProvider().CreateSearchBuilder("search")
|
||||
return _indexManager.GetSearchIndexProvider().CreateSearchBuilder(SearchIndexName)
|
||||
.WithField("title", term)
|
||||
.WithField("body", term)
|
||||
.Search();
|
||||
}
|
||||
|
||||
public void RebuildIndex() {
|
||||
if (!_indexManager.HasIndexProvider()) {
|
||||
Services.Notifier.Warning(T("There is no search index to rebuild."));
|
||||
return;
|
||||
}
|
||||
|
||||
var searchProvider = _indexManager.GetSearchIndexProvider();
|
||||
if (searchProvider.Exists(SearchIndexName))
|
||||
searchProvider.DeleteIndex(SearchIndexName);
|
||||
|
||||
searchProvider.CreateIndex(SearchIndexName); // or just reset the updated date and let the background process recreate the index
|
||||
Services.Notifier.Information(T("The search index has been rebuilt."));
|
||||
}
|
||||
|
||||
public void UpdateIndex() {
|
||||
//todo: this
|
||||
//if (_indexManager.HasIndexProvider())
|
||||
// _indexManager.GetSearchIndexProvider().UpdateIndex(SearchIndexName);
|
||||
Services.Notifier.Information(T("The search index has been updated."));
|
||||
}
|
||||
}
|
||||
}
|
3
src/Orchard.Web/Modules/Orchard.Search/Styles/admin.css
Normal file
3
src/Orchard.Web/Modules/Orchard.Search/Styles/admin.css
Normal file
@@ -0,0 +1,3 @@
|
||||
#main button {
|
||||
display:block;
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Search.ViewModels {
|
||||
public class SearchIndexViewModel : BaseViewModel {
|
||||
public bool HasIndexToManage { get; set; }
|
||||
//todo: hang the index updated date off here to show in the admin UI (e.g. -> index updated: June 4, 2010 [update index])
|
||||
public DateTime IndexUpdatedUtc { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Search.ViewModels.SearchIndexViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Mvc.Html" %><%
|
||||
Html.RegisterStyle("admin.css"); %>
|
||||
<h1><%=Html.TitleForPage(T("Search Index Mangement").ToString()) %></h1><%
|
||||
using (Html.BeginForm("update", "admin", FormMethod.Post, new {area = "Orchard.Search"})) { %>
|
||||
<fieldset>
|
||||
<p><%=T("The search index was last updated {0}. <button type=\"submit\" title=\"Update the search index.\" class=\"primaryAction\">Update</button>", Html.DateTimeRelative(Model.IndexUpdatedUtc))%></p>
|
||||
<%=Html.AntiForgeryTokenOrchard() %>
|
||||
</fieldset><%
|
||||
}
|
||||
using (Html.BeginForm("rebuild", "admin", FormMethod.Post, new {area = "Orchard.Search"})) { %>
|
||||
<fieldset>
|
||||
<p><%=T("Rebuild the search index for a fresh start. <button type=\"submit\" title=\"Rebuild the search index.\">Rebuld</button>") %></p>
|
||||
<%=Html.AntiForgeryTokenOrchard() %>
|
||||
</fieldset><%
|
||||
} %>
|
@@ -1,14 +1,11 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Search.ViewModels.SearchViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Mvc.Html" %><%
|
||||
Html.RegisterStyle("search.css"); %>
|
||||
<h1><%=Html.TitleForPage(T("Search"))%></h1>
|
||||
<%
|
||||
Html.Zone("search"); %><%
|
||||
|
||||
<h1><%=Html.TitleForPage(T("Search"))%></h1><%
|
||||
Html.Zone("search");
|
||||
if (!string.IsNullOrWhiteSpace(Model.Query)) { %>
|
||||
<p class="search-summary"><%=T("<em>{0}</em> results", Model.Results.Count()) %></p><%
|
||||
<p class="search-summary"><%=T("<em>{0}</em> results", Model.Results.Count()) %></p><%
|
||||
}
|
||||
|
||||
if (Model.Results.Count() > 0) { %>
|
||||
<%=Html.UnorderedList(Model.Results, (r, i) => Html.DisplayForItem(r.Content).ToHtmlString(), "search-results contentItems") %><%
|
||||
<%=Html.UnorderedList(Model.Results, (r, i) => Html.DisplayForItem(r.Content).ToHtmlString(), "search-results contentItems") %><%
|
||||
} %>
|
@@ -57,7 +57,6 @@ body {
|
||||
}
|
||||
button {
|
||||
font-family:Segoe UI,Trebuchet,Arial,Sans-Serif;
|
||||
font-size:1.01em;
|
||||
}
|
||||
body#preview {
|
||||
min-width:0;
|
||||
@@ -157,6 +156,7 @@ table.items th, table.items td, table.items caption { font-size:1.4em; line-heig
|
||||
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 */
|
||||
form.link button { font-size:1.01em; }
|
||||
|
||||
/* Links
|
||||
----------------------------------------------------------*/
|
||||
@@ -450,9 +450,6 @@ button, .button, .button:link, .button:visited {
|
||||
text-align:center;
|
||||
padding:0 .8em .1em;
|
||||
}
|
||||
button {
|
||||
padding-top:.08em;
|
||||
}
|
||||
form.link button {
|
||||
background:inherit;
|
||||
border:0;
|
||||
@@ -681,7 +678,7 @@ table .button {
|
||||
.contentItems .properties .icon {
|
||||
margin:0 .2em -.2em;
|
||||
}
|
||||
.contentItems .related{
|
||||
.contentItems .related {
|
||||
float:right;
|
||||
font-size:1.4em;
|
||||
text-align:right;
|
||||
|
@@ -111,7 +111,7 @@ namespace Orchard.Mvc.Html {
|
||||
TimeSpan time = htmlHelper.Resolve<IClock>().UtcNow - value;
|
||||
|
||||
if (time.TotalDays > 7)
|
||||
return "at " + htmlHelper.DateTime(value);
|
||||
return "on " + htmlHelper.DateTime(value, "MMM d yyyy 'at' h:mm tt");
|
||||
if (time.TotalHours > 24)
|
||||
return string.Format("{0} day{1} ago", time.Days, time.Days == 1 ? "" : "s");
|
||||
if (time.TotalMinutes > 60)
|
||||
|
Reference in New Issue
Block a user