mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : 1.x
This commit is contained in:
@@ -639,5 +639,24 @@ namespace Orchard.Tests.Modules.Indexing {
|
||||
.WithField("field3", 3).Mandatory().AsFilter()
|
||||
.Count(), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShouldReturnFacetedResults() {
|
||||
_provider.CreateIndex("default");
|
||||
_provider.Store("default", _provider.New(1).Add("body", "michael is in the kitchen").Analyze());
|
||||
_provider.Store("default", _provider.New(2).Add("body", "michael has a cousin named michel").Analyze());
|
||||
_provider.Store("default", _provider.New(3).Add("body", "speak inside the mic").Analyze());
|
||||
_provider.Store("default", _provider.New(4).Add("body", "a dog is pursuing a cat").Analyze());
|
||||
_provider.Store("default", _provider.New(5).Add("body", "michael speaks to elephants").Analyze());
|
||||
|
||||
var michael = SearchBuilder.WithField("body", "michael").GetBits();
|
||||
var speak = SearchBuilder.WithField("body", "speak").GetBits();
|
||||
Assert.That(michael.Count(), Is.EqualTo(3));
|
||||
Assert.That(speak.Count(), Is.EqualTo(2));
|
||||
|
||||
Assert.That(speak.And(michael).Count(), Is.EqualTo(1));
|
||||
Assert.That(speak.Or(michael).Count(), Is.EqualTo(4));
|
||||
Assert.That(speak.Xor(michael).Count(), Is.EqualTo(3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -37,5 +37,11 @@ namespace Orchard.Tests.DisplayManagement {
|
||||
dynamic nil = Nil.Instance;
|
||||
Assert.That(nil.Foo.Bar.ToString(), Is.EqualTo(""));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertingToStringShouldReturnNullString() {
|
||||
dynamic nil = Nil.Instance;
|
||||
Assert.That((string)nil == null, Is.True);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
@@ -28,20 +27,24 @@ namespace Orchard.Core.Shapes {
|
||||
private readonly Work<WorkContext> _workContext;
|
||||
private readonly Work<IResourceManager> _resourceManager;
|
||||
private readonly Work<IHttpContextAccessor> _httpContextAccessor;
|
||||
private readonly Work<IShapeFactory> _shapeFactory;
|
||||
|
||||
public CoreShapes(
|
||||
Work<WorkContext> workContext,
|
||||
Work<IResourceManager> resourceManager,
|
||||
Work<IHttpContextAccessor> httpContextAccessor
|
||||
Work<IHttpContextAccessor> httpContextAccessor,
|
||||
Work<IShapeFactory> shapeFactory
|
||||
) {
|
||||
_workContext = workContext;
|
||||
_resourceManager = resourceManager;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_shapeFactory = shapeFactory;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public dynamic New { get { return _shapeFactory.Value; } }
|
||||
|
||||
public void Discover(ShapeTableBuilder builder) {
|
||||
// the root page shape named 'Layout' is wrapped with 'Document'
|
||||
@@ -490,49 +493,49 @@ namespace Orchard.Core.Shapes {
|
||||
routeData.Remove(pageKey); // to keep from having "page=1" in the query string
|
||||
}
|
||||
// first
|
||||
Shape.Add(Display.Pager_First(Value: firstText, RouteValues: routeData, Pager: Shape));
|
||||
Shape.Add(New.Pager_First(Value: firstText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
|
||||
|
||||
// previous
|
||||
if (currentPage > 2) { // also to keep from having "page=1" in the query string
|
||||
routeData[pageKey] = currentPage - 1;
|
||||
}
|
||||
Shape.Add(Display.Pager_Previous(Value: previousText, RouteValues: routeData, Pager: Shape));
|
||||
Shape.Add(New.Pager_Previous(Value: previousText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
|
||||
}
|
||||
|
||||
// gap at the beginning of the pager
|
||||
if (firstPage > 1 && numberOfPagesToShow > 0) {
|
||||
Shape.Add(Display.Pager_Gap(Value: gapText, Pager: Shape));
|
||||
Shape.Add(New.Pager_Gap(Value: gapText, Pager: Shape));
|
||||
}
|
||||
|
||||
// page numbers
|
||||
if (numberOfPagesToShow > 0 && firstPage != lastPage) {
|
||||
if (numberOfPagesToShow > 0) {
|
||||
for (var p = firstPage; p <= lastPage; p++) {
|
||||
if (p == currentPage) {
|
||||
Shape.Add(Display.Pager_CurrentPage(Value: p, RouteValues: routeData, Pager: Shape));
|
||||
Shape.Add(New.Pager_CurrentPage(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
|
||||
}
|
||||
else {
|
||||
if (p == 1)
|
||||
routeData.Remove(pageKey);
|
||||
else
|
||||
routeData[pageKey] = p;
|
||||
Shape.Add(Display.Pager_Link(Value: p, RouteValues: routeData, Pager: Shape));
|
||||
Shape.Add(New.Pager_Link(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gap at the end of the pager
|
||||
if (lastPage < totalPageCount && numberOfPagesToShow > 0) {
|
||||
Shape.Add(Display.Pager_Gap(Value: gapText, Pager: Shape));
|
||||
Shape.Add(New.Pager_Gap(Value: gapText, Pager: Shape));
|
||||
}
|
||||
|
||||
// next and last pages
|
||||
if (Page < totalPageCount) {
|
||||
// next
|
||||
routeData[pageKey] = Page + 1;
|
||||
Shape.Add(Display.Pager_Next(Value: nextText, RouteValues: routeData, Pager: Shape));
|
||||
Shape.Add(New.Pager_Next(Value: nextText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
|
||||
// last
|
||||
routeData[pageKey] = totalPageCount;
|
||||
Shape.Add(Display.Pager_Last(Value: lastText, RouteValues: routeData, Pager: Shape));
|
||||
Shape.Add(New.Pager_Last(Value: lastText, RouteValues: new RouteValueDictionary(routeData), Pager: Shape));
|
||||
}
|
||||
|
||||
return Display(Shape);
|
||||
@@ -562,7 +565,7 @@ namespace Orchard.Core.Shapes {
|
||||
[Shape]
|
||||
public IHtmlString Pager_CurrentPage(HtmlHelper Html, dynamic Display, object Value) {
|
||||
var tagBuilder = new TagBuilder("span");
|
||||
tagBuilder.InnerHtml = Html.Encode(Value is string ? (string)Value : Display(Value));
|
||||
tagBuilder.InnerHtml = EncodeOrDisplay(Value, Display, Html).ToString();
|
||||
|
||||
return MvcHtmlString.Create(tagBuilder.ToString());
|
||||
}
|
||||
@@ -583,21 +586,13 @@ namespace Orchard.Core.Shapes {
|
||||
|
||||
[Shape]
|
||||
public IHtmlString Pager_Link(HtmlHelper Html, dynamic Shape, dynamic Display, object Value) {
|
||||
var RouteValues = (object)Shape.RouteValues;
|
||||
RouteValueDictionary rvd;
|
||||
if (RouteValues == null) {
|
||||
rvd = new RouteValueDictionary();
|
||||
}
|
||||
else {
|
||||
rvd = RouteValues is RouteValueDictionary ? (RouteValueDictionary)RouteValues : new RouteValueDictionary(RouteValues);
|
||||
}
|
||||
|
||||
string value = Html.Encode(Value is string ? (string)Value : Display(Value));
|
||||
return @Html.ActionLink(value, (string)rvd["action"], (string)rvd["controller"], rvd, null);
|
||||
Shape.Metadata.Alternates.Clear();
|
||||
Shape.Metadata.Type = "ActionLink";
|
||||
return Display(Shape);
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public IHtmlString ActionLink(HtmlHelper Html, dynamic Shape, dynamic Display, object Value) {
|
||||
public IHtmlString ActionLink(HtmlHelper Html, UrlHelper Url, dynamic Shape, dynamic Display, object Value) {
|
||||
var RouteValues = (object)Shape.RouteValues;
|
||||
RouteValueDictionary rvd;
|
||||
if (RouteValues == null) {
|
||||
@@ -606,15 +601,23 @@ namespace Orchard.Core.Shapes {
|
||||
else {
|
||||
rvd = RouteValues is RouteValueDictionary ? (RouteValueDictionary)RouteValues : new RouteValueDictionary(RouteValues);
|
||||
}
|
||||
|
||||
string value = Html.Encode(Value is string ? (string)Value : Display(Value));
|
||||
return @Html.ActionLink(value, (string)rvd["action"], (string)rvd["controller"], rvd, null);
|
||||
|
||||
var action = Url.Action((string)rvd["action"], (string)rvd["controller"], rvd);
|
||||
|
||||
IEnumerable<string> classes = Shape.Classes;
|
||||
IDictionary<string, string> attributes = Shape.Attributes;
|
||||
attributes.Add("href", action);
|
||||
string id = Shape.Id;
|
||||
var tag = GetTagBuilder("a", id, classes, attributes);
|
||||
tag.InnerHtml = EncodeOrDisplay(Value, Display, Html).ToString();
|
||||
|
||||
return Html.Raw(tag.ToString());
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public IHtmlString Pager_Gap(HtmlHelper Html, dynamic Display, object Value) {
|
||||
var tagBuilder = new TagBuilder("span");
|
||||
tagBuilder.InnerHtml = Html.Encode(Value is string ? (string)Value : Display(Value));
|
||||
tagBuilder.InnerHtml = EncodeOrDisplay(Value, Display, Html).ToString();
|
||||
|
||||
return MvcHtmlString.Create(tagBuilder.ToString());
|
||||
}
|
||||
@@ -628,37 +631,88 @@ namespace Orchard.Core.Shapes {
|
||||
string Id,
|
||||
IEnumerable<string> Classes,
|
||||
IDictionary<string, string> Attributes,
|
||||
string ItemTag,
|
||||
IEnumerable<string> ItemClasses,
|
||||
IDictionary<string, string> ItemAttributes) {
|
||||
|
||||
if (Items == null)
|
||||
return;
|
||||
|
||||
// prevent multiple enumerations
|
||||
var items = Items.ToList();
|
||||
|
||||
var itemDisplayOutputs = Items.Select(item => Display(item)).Where(output => !string.IsNullOrWhiteSpace(output.ToHtmlString())).ToList();
|
||||
var count = itemDisplayOutputs.Count();
|
||||
// var itemDisplayOutputs = Items.Select(item => Display(item)).Where(output => !string.IsNullOrWhiteSpace(output.ToHtmlString())).ToList();
|
||||
var count = items.Count();
|
||||
if (count < 1)
|
||||
return;
|
||||
|
||||
var listTagName = string.IsNullOrEmpty(Tag) ? "ul" : Tag;
|
||||
const string itemTagName = "li";
|
||||
string listTagName = null;
|
||||
|
||||
if (Tag != "-") {
|
||||
listTagName = string.IsNullOrEmpty(Tag) ? "ul" : Tag;
|
||||
}
|
||||
|
||||
var listTag = GetTagBuilder(listTagName, Id, Classes, Attributes);
|
||||
Output.Write(listTag.ToString(TagRenderMode.StartTag));
|
||||
var listTag = String.IsNullOrEmpty(listTagName) ? null : GetTagBuilder(listTagName, Id, Classes, Attributes);
|
||||
|
||||
string itemTagName = null;
|
||||
if (ItemTag != "-") {
|
||||
itemTagName = string.IsNullOrEmpty(ItemTag) ? "li" : ItemTag;
|
||||
}
|
||||
|
||||
if (listTag != null) {
|
||||
Output.Write(listTag.ToString(TagRenderMode.StartTag));
|
||||
}
|
||||
|
||||
var itemTags = new List<TagBuilder>();
|
||||
var itemOutputs = new List<string>();
|
||||
|
||||
// give the item shape the possibility to alter its container tag
|
||||
var index = 0;
|
||||
foreach (var itemDisplayOutput in itemDisplayOutputs) {
|
||||
var itemTag = GetTagBuilder(itemTagName, null, ItemClasses, ItemAttributes);
|
||||
if (index == 0)
|
||||
itemTag.AddCssClass("first");
|
||||
if (index == count - 1)
|
||||
itemTag.AddCssClass("last");
|
||||
Output.Write(itemTag.ToString(TagRenderMode.StartTag));
|
||||
Output.Write(itemDisplayOutput);
|
||||
Output.Write(itemTag.ToString(TagRenderMode.EndTag));
|
||||
foreach (var item in items) {
|
||||
|
||||
var itemTag = String.IsNullOrEmpty(itemTagName) ? null : GetTagBuilder(itemTagName, null, ItemClasses, ItemAttributes);
|
||||
|
||||
if (item is IShape) {
|
||||
item.Tag = itemTag;
|
||||
}
|
||||
|
||||
var itemOutput = Display(item).ToHtmlString();
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(itemOutput)) {
|
||||
itemTags.Add(itemTag);
|
||||
itemOutputs.Add(itemOutput);
|
||||
}
|
||||
else {
|
||||
count--;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
Output.Write(listTag.ToString(TagRenderMode.EndTag));
|
||||
index = 0;
|
||||
foreach(var itemOutput in itemOutputs) {
|
||||
var itemTag = itemTags[index];
|
||||
|
||||
if (itemTag != null) {
|
||||
if (index == 0)
|
||||
itemTag.AddCssClass("first");
|
||||
if (index == count - 1)
|
||||
itemTag.AddCssClass("last");
|
||||
Output.Write(itemTag.ToString(TagRenderMode.StartTag));
|
||||
}
|
||||
|
||||
Output.Write(itemOutput);
|
||||
|
||||
if (itemTag != null) {
|
||||
Output.Write(itemTag.ToString(TagRenderMode.EndTag));
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
if (listTag != null) {
|
||||
Output.Write(listTag.ToString(TagRenderMode.EndTag));
|
||||
}
|
||||
}
|
||||
|
||||
[Shape]
|
||||
@@ -718,5 +772,20 @@ namespace Orchard.Core.Shapes {
|
||||
private string EncodeAlternateElement(string alternateElement) {
|
||||
return alternateElement.Replace("-", "__").Replace(".", "_");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode a value if it's a string, or render it if it's a Shape
|
||||
/// </summary>
|
||||
private IHtmlString EncodeOrDisplay(dynamic Value, dynamic Display, HtmlHelper Html) {
|
||||
if (Value is IHtmlString) {
|
||||
return Value;
|
||||
}
|
||||
|
||||
if (Value is IShape) {
|
||||
return Display(Value).ToString();
|
||||
}
|
||||
|
||||
return Html.Raw(Html.Encode(Value.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,10 @@
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -66,6 +70,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\LuceneIndexProvider.cs" />
|
||||
<Compile Include="Services\LuceneSearchBuilder.cs" />
|
||||
<Compile Include="Services\SearchBits.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Module.txt" />
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -6,6 +7,7 @@ using Lucene.Models;
|
||||
using Lucene.Net.Index;
|
||||
using Lucene.Net.Search;
|
||||
using Lucene.Net.Store;
|
||||
using Lucene.Net.Util;
|
||||
using Orchard.Indexing;
|
||||
using Orchard.Logging;
|
||||
using Lucene.Net.Documents;
|
||||
@@ -355,6 +357,30 @@ namespace Lucene.Services {
|
||||
|
||||
}
|
||||
|
||||
public ISearchBits GetBits() {
|
||||
var query = CreateQuery();
|
||||
IndexSearcher searcher;
|
||||
|
||||
try {
|
||||
searcher = new IndexSearcher(_directory, true);
|
||||
}
|
||||
catch {
|
||||
// index might not exist if it has been rebuilt
|
||||
Logger.Information("Attempt to read a none existing index");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
var filter = new QueryWrapperFilter(query);
|
||||
var bits = filter.GetDocIdSet(searcher.GetIndexReader());
|
||||
var disi = new OpenBitSetDISI(bits.Iterator(), searcher.MaxDoc());
|
||||
return new SearchBits(disi);
|
||||
}
|
||||
finally {
|
||||
searcher.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public ISearchHit Get(int documentId) {
|
||||
var query = new TermQuery(new Term("id", documentId.ToString(CultureInfo.InvariantCulture)));
|
||||
|
||||
|
43
src/Orchard.Web/Modules/Lucene/Services/SearchBits.cs
Normal file
43
src/Orchard.Web/Modules/Lucene/Services/SearchBits.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using Lucene.Net.Util;
|
||||
using Orchard.Indexing;
|
||||
|
||||
namespace Lucene.Services {
|
||||
public class SearchBits : ISearchBits {
|
||||
internal readonly OpenBitSet _openBitSet;
|
||||
|
||||
public SearchBits(OpenBitSet openBitSet) {
|
||||
_openBitSet = openBitSet;
|
||||
}
|
||||
|
||||
public ISearchBits And(ISearchBits other) {
|
||||
return Apply(other, (x, y) => x.And(y));
|
||||
}
|
||||
|
||||
public ISearchBits Or(ISearchBits other) {
|
||||
return Apply(other, (x, y) => x.Or(y));
|
||||
}
|
||||
|
||||
public ISearchBits Xor(ISearchBits other) {
|
||||
return Apply(other, (x, y) => x.Xor(y));
|
||||
}
|
||||
|
||||
public long Count() {
|
||||
return _openBitSet.Cardinality();
|
||||
}
|
||||
|
||||
private ISearchBits Apply(ISearchBits other, Action<OpenBitSet, OpenBitSet> operation) {
|
||||
var bitset = (OpenBitSet)_openBitSet.Clone();
|
||||
var otherBitSet = other as SearchBits;
|
||||
|
||||
if (otherBitSet == null) {
|
||||
throw new InvalidOperationException("The other bitset must be of type OpenBitSet");
|
||||
}
|
||||
|
||||
operation(bitset, otherBitSet._openBitSet);
|
||||
|
||||
return new SearchBits(bitset);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
@{
|
||||
Html.AddTitleParts(T("Manage Blog").ToString());
|
||||
Layout.Title = T("Manage Blog").ToString();
|
||||
}
|
||||
@* Model is a Shape, calling Display() so that it is rendered using the most specific template for its Shape type *@
|
||||
@Display(Model)
|
||||
|
@@ -1,7 +1,8 @@
|
||||
@using Orchard.Blogs.Extensions;
|
||||
@using Orchard.Blogs.Models;
|
||||
@using Orchard.ContentManagement
|
||||
|
||||
@{ Layout.Title = (string)Model.Title; }
|
||||
@{ Layout.Title = T("Manage {0}", Html.ItemDisplayText((IContent)Model.ContentItem)); }
|
||||
|
||||
@Display(Model.Header)
|
||||
@Display(Model.Actions)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
@using Orchard.Mvc.Html;
|
||||
@{
|
||||
Html.AddTitleParts((string)Model.Title);
|
||||
Layout.Title = T("New Blog");
|
||||
}
|
||||
<div class="edit-item">
|
||||
<div class="edit-item-primary">
|
||||
|
@@ -2,13 +2,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentPicker.Settings;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Core.Contents.ViewModels;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Themes;
|
||||
@@ -18,23 +21,71 @@ namespace Orchard.ContentPicker.Controllers {
|
||||
public class AdminController : Controller {
|
||||
private readonly ISiteService _siteService;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly INavigationManager _navigationManager;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices orchardServices,
|
||||
ISiteService siteService,
|
||||
IContentDefinitionManager contentDefinitionManager) {
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
INavigationManager navigationManager) {
|
||||
_siteService = siteService;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_navigationManager = navigationManager;
|
||||
Services = orchardServices;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
[Themed(false)]
|
||||
public ActionResult Index(ListContentsViewModel model, PagerParameters pagerParameters) {
|
||||
public ActionResult Index(ListContentsViewModel model, PagerParameters pagerParameters, string part, string field) {
|
||||
|
||||
IEnumerable<MenuItem> menuItems = _navigationManager.BuildMenu("content-picker").ToList();
|
||||
|
||||
var contentPickerMenuItem = menuItems.FirstOrDefault();
|
||||
if (contentPickerMenuItem == null) {
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
if (contentPickerMenuItem.Items.All(x => x.Text.ToString() != T("Recent Content").Text)) {
|
||||
// the default tab should not be displayed, redirect to the next one
|
||||
|
||||
var routeData = new RouteValueDictionary(menuItems.First().RouteValues);
|
||||
var queryString = Request.QueryString;
|
||||
foreach (var key in queryString.AllKeys) {
|
||||
routeData[key] = queryString[key];
|
||||
}
|
||||
|
||||
return RedirectToRoute(routeData);
|
||||
}
|
||||
|
||||
ContentPickerFieldSettings settings = null;
|
||||
|
||||
// if the picker is loaded for a specific field, apply custom settings
|
||||
if (!String.IsNullOrEmpty(part) && !String.IsNullOrEmpty(field)) {
|
||||
var definition = _contentDefinitionManager.GetPartDefinition(part).Fields.FirstOrDefault(x => x.Name == field);
|
||||
if (definition != null) {
|
||||
settings = definition.Settings.GetModel<ContentPickerFieldSettings>();
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<ContentTypeDefinition> contentTypes;
|
||||
if (settings != null && !String.IsNullOrEmpty(settings.DisplayedContentTypes)) {
|
||||
var rawTypes = settings.DisplayedContentTypes.Split(new[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
contentTypes = _contentDefinitionManager
|
||||
.ListTypeDefinitions()
|
||||
.Where(x => x.Parts.Any(p => rawTypes.Contains(p.PartDefinition.Name)))
|
||||
.ToArray();
|
||||
}
|
||||
else {
|
||||
contentTypes = GetCreatableTypes(false).ToList();
|
||||
}
|
||||
|
||||
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
||||
|
||||
var query = Services.ContentManager.Query(VersionOptions.Latest, GetCreatableTypes(false).Select(ctd => ctd.Name).ToArray());
|
||||
var query = Services.ContentManager.Query(VersionOptions.Latest, contentTypes.Select(ctd => ctd.Name).ToArray());
|
||||
|
||||
if (!string.IsNullOrEmpty(model.Options.SelectedFilter)) {
|
||||
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.Options.SelectedFilter);
|
||||
@@ -60,7 +111,7 @@ namespace Orchard.ContentPicker.Controllers {
|
||||
break;
|
||||
}
|
||||
|
||||
model.Options.FilterOptions = GetCreatableTypes(false)
|
||||
model.Options.FilterOptions = contentTypes
|
||||
.Select(ctd => new KeyValuePair<string, string>(ctd.Name, ctd.DisplayName))
|
||||
.ToList().OrderBy(kvp => kvp.Value);
|
||||
|
||||
|
@@ -39,6 +39,7 @@ namespace Orchard.ContentPicker.Drivers {
|
||||
() => {
|
||||
var model = new ContentPickerFieldViewModel {
|
||||
Field = field,
|
||||
Part = part,
|
||||
ContentItems = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Published, QueryHints.Empty).ToList(),
|
||||
};
|
||||
|
||||
|
@@ -20,11 +20,14 @@
|
||||
// remove trailing slash if any
|
||||
if (baseUrl.substr(-1) == '/')
|
||||
baseUrl = baseUrl.substr(0, baseUrl.length - 1);
|
||||
|
||||
|
||||
var url = baseUrl
|
||||
+ "/Admin/Orchard.ContentPicker?"
|
||||
+ "callback=" + callbackName
|
||||
+ "&" + (new Date() - 0);
|
||||
+ "&" + (new Date() - 0)
|
||||
+ "&part=" + encodeURIComponent(data.part)
|
||||
+ "&field=" + encodeURIComponent(data.field);
|
||||
|
||||
var w = window.open(url, "_blank", data.windowFeatures || "width=685,height=700,status=no,toolbar=no,location=no,menubar=no,resizable=no,scrollbars=yes");
|
||||
});
|
||||
});
|
@@ -1,9 +1,20 @@
|
||||
using Orchard.Localization;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentPicker.Settings;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.ContentPicker.Services {
|
||||
public class ContentPickerNavigationProvider : INavigationProvider {
|
||||
public ContentPickerNavigationProvider() {
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
|
||||
public ContentPickerNavigationProvider(
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
IWorkContextAccessor workContextAccessor) {
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@@ -14,9 +25,36 @@ namespace Orchard.ContentPicker.Services {
|
||||
}
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
var workContext = _workContextAccessor.GetContext();
|
||||
var httpContext = workContext.HttpContext;
|
||||
|
||||
if (httpContext == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var queryString = workContext.HttpContext.Request.QueryString;
|
||||
|
||||
string part = queryString["part"];
|
||||
string field = queryString["field"];
|
||||
|
||||
ContentPickerFieldSettings settings = null;
|
||||
|
||||
// if the picker is loaded for a specific field, apply custom settings
|
||||
if (!String.IsNullOrEmpty(part) && !String.IsNullOrEmpty(field)) {
|
||||
var definition = _contentDefinitionManager.GetPartDefinition(part).Fields.FirstOrDefault(x => x.Name == field);
|
||||
if (definition != null) {
|
||||
settings = definition.Settings.GetModel<ContentPickerFieldSettings>();
|
||||
}
|
||||
}
|
||||
|
||||
if (settings != null && !settings.ShowContentTab) {
|
||||
return;
|
||||
}
|
||||
|
||||
builder.Add(T("Content Picker"),
|
||||
menu => menu
|
||||
.Add(T("Recent Content"), "5", item => item.Action("Index", "Admin", new {area = "Orchard.ContentPicker"}).LocalNav()));
|
||||
.Add(T("Recent Content"), "5", item => item.Action("Index", "Admin", new { area = "Orchard.ContentPicker" }).LocalNav()));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement;
|
||||
|
@@ -26,6 +26,8 @@ namespace Orchard.ContentPicker.Settings {
|
||||
builder.WithSetting("ContentPickerFieldSettings.Hint", model.Hint);
|
||||
builder.WithSetting("ContentPickerFieldSettings.Required", model.Required.ToString(CultureInfo.InvariantCulture));
|
||||
builder.WithSetting("ContentPickerFieldSettings.Multiple", model.Multiple.ToString(CultureInfo.InvariantCulture));
|
||||
builder.WithSetting("ContentPickerFieldSettings.ShowContentTab", model.ShowContentTab.ToString(CultureInfo.InvariantCulture));
|
||||
builder.WithSetting("ContentPickerFieldSettings.DisplayedContentTypes", model.DisplayedContentTypes);
|
||||
}
|
||||
|
||||
yield return DefinitionTemplate(model);
|
||||
|
@@ -1,7 +1,14 @@
|
||||
namespace Orchard.ContentPicker.Settings {
|
||||
public class ContentPickerFieldSettings {
|
||||
public ContentPickerFieldSettings() {
|
||||
ShowContentTab = true;
|
||||
}
|
||||
|
||||
public string Hint { get; set; }
|
||||
public bool Required { get; set; }
|
||||
public bool Multiple { get; set; }
|
||||
|
||||
public bool ShowContentTab { get; set; }
|
||||
public string DisplayedContentTypes { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -9,5 +9,6 @@ namespace Orchard.ContentPicker.ViewModels {
|
||||
public ICollection<ContentItem> ContentItems { get; set; }
|
||||
public string SelectedIds { get; set; }
|
||||
public ContentPickerField Field { get; set; }
|
||||
public ContentPart Part { get; set; }
|
||||
}
|
||||
}
|
@@ -18,3 +18,16 @@
|
||||
<span class="hint">@T("The help text is written under the field when authors are selecting content items.")</span>
|
||||
@Html.ValidationMessageFor(m => m.Hint)
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<div>
|
||||
@Html.CheckBoxFor(m => m.ShowContentTab) <label for="@Html.FieldIdFor(m => m.ShowContentTab)" class="forcheckbox">@T("Show Content tab")</label>
|
||||
<span class="hint">@T("Uncheck to hide the Content tab from the picker window.")</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.DisplayedContentTypes)">@T("Content Types and Parts")</label>
|
||||
@Html.TextBoxFor(m => m.DisplayedContentTypes)
|
||||
<span class="hint">@T("A comma separated value of all the content types or content parts to display.")</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
@@ -87,7 +87,9 @@
|
||||
refreshIds();
|
||||
$('#save-message-@Html.FieldIdFor(m => m.Field.Ids)').show();
|
||||
},
|
||||
baseUrl: '@Url.Content("~/")'
|
||||
baseUrl: '@Url.Content("~/")',
|
||||
part: '@HttpUtility.JavaScriptStringEncode(Model.Part.PartDefinition.Name)',
|
||||
field: '@HttpUtility.JavaScriptStringEncode(Model.Field.PartFieldDefinition.Name)'
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -63,13 +63,14 @@ namespace Orchard.Projections.Drivers {
|
||||
var pageKey = String.IsNullOrWhiteSpace(part.Record.PagerSuffix) ? "page" : "page-" + part.Record.PagerSuffix;
|
||||
var page = 0;
|
||||
|
||||
if(queryString.AllKeys.Contains(pageKey)) {
|
||||
// default page size
|
||||
int pageSize = part.Record.Items;
|
||||
|
||||
// don't try to page if not necessary
|
||||
if (part.Record.DisplayPager && queryString.AllKeys.Contains(pageKey)) {
|
||||
Int32.TryParse(queryString[pageKey], out page);
|
||||
}
|
||||
|
||||
// default page size
|
||||
int pageSize = part.Record.Items;
|
||||
|
||||
// if 0, then assume "All"
|
||||
if (pageSize == 0) {
|
||||
pageSize = Int32.MaxValue;
|
||||
|
@@ -66,7 +66,7 @@ namespace Orchard.Projections.Providers.SortCriteria {
|
||||
}
|
||||
|
||||
public void ApplySortCriterion(SortCriterionContext context, IFieldTypeEditor fieldTypeEditor, string storageName, Type storageType, ContentPartDefinition part, ContentPartFieldDefinition field) {
|
||||
bool ascending = Convert.ToBoolean(context.State.Sort);
|
||||
bool ascending = (bool)context.State.Sort;
|
||||
var propertyName = String.Join(".", part.Name, field.Name, storageName ?? "");
|
||||
|
||||
// use an alias with the join so that two filters on the same Field Type wont collide
|
||||
@@ -87,7 +87,7 @@ namespace Orchard.Projections.Providers.SortCriteria {
|
||||
}
|
||||
|
||||
public LocalizedString DisplaySortCriterion(SortCriterionContext context, ContentPartDefinition part, ContentPartFieldDefinition fieldDefinition) {
|
||||
bool ascending = Convert.ToBoolean(context.State.Sort);
|
||||
bool ascending = (bool)context.State.Sort;
|
||||
|
||||
return ascending
|
||||
? T("Ordered by field {0}, ascending", fieldDefinition.Name)
|
||||
|
@@ -1,11 +1,23 @@
|
||||
using Orchard.Environment.Extensions;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Search.Settings;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Search {
|
||||
[OrchardFeature("Orchard.Search.ContentPicker")]
|
||||
public class ContentPickerNavigationProvider : INavigationProvider {
|
||||
public ContentPickerNavigationProvider() {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
|
||||
public ContentPickerNavigationProvider(
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IContentDefinitionManager contentDefinitionManager
|
||||
) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@@ -16,6 +28,33 @@ namespace Orchard.Search {
|
||||
}
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
|
||||
var workContext = _workContextAccessor.GetContext();
|
||||
var httpContext = workContext.HttpContext;
|
||||
|
||||
if (httpContext == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var queryString = workContext.HttpContext.Request.QueryString;
|
||||
|
||||
string part = queryString["part"];
|
||||
string field = queryString["field"];
|
||||
|
||||
ContentPickerSearchFieldSettings settings = null;
|
||||
|
||||
// if the picker is loaded for a specific field, apply custom settings
|
||||
if (!String.IsNullOrEmpty(part) && !String.IsNullOrEmpty(field)) {
|
||||
var definition = _contentDefinitionManager.GetPartDefinition(part).Fields.FirstOrDefault(x => x.Name == field);
|
||||
if (definition != null) {
|
||||
settings = definition.Settings.GetModel<ContentPickerSearchFieldSettings>();
|
||||
}
|
||||
}
|
||||
|
||||
if (settings != null && !settings.ShowSearchTab) {
|
||||
return;
|
||||
}
|
||||
|
||||
builder.Add(T("Content Picker"),
|
||||
menu => menu
|
||||
.Add(T("Search Content"), "5", item => item.Action("Index", "ContentPicker", new {area = "Orchard.Search"}).LocalNav()));
|
||||
|
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Collections;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Indexing;
|
||||
@@ -10,7 +10,7 @@ using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Search.Models;
|
||||
using Orchard.Search.Services;
|
||||
using Orchard.Search.Settings;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Admin;
|
||||
@@ -21,15 +21,18 @@ namespace Orchard.Search.Controllers {
|
||||
[Admin]
|
||||
[OrchardFeature("Orchard.Search.ContentPicker")]
|
||||
public class ContentPickerController : Controller {
|
||||
private readonly ISearchService _searchService;
|
||||
private readonly ISiteService _siteService;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IIndexManager _indexManager;
|
||||
|
||||
public ContentPickerController(
|
||||
IOrchardServices orchardServices,
|
||||
ISearchService searchService,
|
||||
ISiteService siteService) {
|
||||
_searchService = searchService;
|
||||
ISiteService siteService,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
IIndexManager indexManager) {
|
||||
_siteService = siteService;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_indexManager = indexManager;
|
||||
Services = orchardServices;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
@@ -40,35 +43,68 @@ namespace Orchard.Search.Controllers {
|
||||
public Localizer T { get; set; }
|
||||
|
||||
[Themed(false)]
|
||||
public ActionResult Index(PagerParameters pagerParameters, string searchText = "") {
|
||||
public ActionResult Index(PagerParameters pagerParameters, string part, string field, string searchText = "") {
|
||||
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
||||
var searchFields = Services.WorkContext.CurrentSite.As<SearchSettingsPart>().SearchedFields;
|
||||
|
||||
IPageOfItems<ISearchHit> searchHits = new PageOfItems<ISearchHit>(new ISearchHit[] { });
|
||||
try {
|
||||
int totalCount = 0;
|
||||
int[] foundIds = new int[0];
|
||||
|
||||
searchHits = _searchService.Query(searchText, pager.Page, pager.PageSize,
|
||||
Services.WorkContext.CurrentSite.As<SearchSettingsPart>().Record.FilterCulture,
|
||||
searchFields,
|
||||
searchHit => searchHit);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Logger.Error(T("Invalid search query: {0}", exception.Message).Text);
|
||||
Services.Notifier.Error(T("Invalid search query: {0}", exception.Message));
|
||||
if (!String.IsNullOrWhiteSpace(searchText)) {
|
||||
ContentPickerSearchFieldSettings settings = null;
|
||||
// if the picker is loaded for a specific field, apply custom settings
|
||||
if (!String.IsNullOrEmpty(part) && !String.IsNullOrEmpty(field)) {
|
||||
var definition = _contentDefinitionManager.GetPartDefinition(part).Fields.FirstOrDefault(x => x.Name == field);
|
||||
if (definition != null) {
|
||||
settings = definition.Settings.GetModel<ContentPickerSearchFieldSettings>();
|
||||
}
|
||||
}
|
||||
|
||||
if (!_indexManager.HasIndexProvider()) {
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
var builder = _indexManager.GetSearchIndexProvider().CreateSearchBuilder("Search");
|
||||
try {
|
||||
builder.Parse(searchFields, searchText);
|
||||
|
||||
if (settings != null && !String.IsNullOrEmpty(settings.DisplayedContentTypes)) {
|
||||
var rawTypes = settings.DisplayedContentTypes.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
var contentTypes = _contentDefinitionManager
|
||||
.ListTypeDefinitions()
|
||||
.Where(x => x.Parts.Any(p => rawTypes.Contains(p.PartDefinition.Name)))
|
||||
.ToArray();
|
||||
|
||||
|
||||
foreach (string type in contentTypes.Select(x => x.Name)) {
|
||||
builder.WithField("type", type).AsFilter();
|
||||
}
|
||||
}
|
||||
|
||||
totalCount = builder.Count();
|
||||
builder = builder.Slice((pager.Page > 0 ? pager.Page - 1 : 0) * pager.PageSize, pager.PageSize);
|
||||
var searchResults = builder.Search();
|
||||
|
||||
foundIds = searchResults.Select(searchHit => searchHit.ContentItemId).ToArray();
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Logger.Error(T("Invalid search query: {0}", exception.Message).Text);
|
||||
Services.Notifier.Error(T("Invalid search query: {0}", exception.Message));
|
||||
}
|
||||
}
|
||||
|
||||
var list = Services.New.List();
|
||||
foreach (var contentItem in Services.ContentManager.GetMany<IContent>(searchHits.Select(x => x.ContentItemId), VersionOptions.Published, QueryHints.Empty)) {
|
||||
foreach (var contentItem in Services.ContentManager.GetMany<IContent>(foundIds, VersionOptions.Published, QueryHints.Empty)) {
|
||||
// ignore search results which content item has been removed or unpublished
|
||||
if (contentItem == null) {
|
||||
searchHits.TotalItemCount--;
|
||||
totalCount--;
|
||||
continue;
|
||||
}
|
||||
|
||||
list.Add(Services.ContentManager.BuildDisplay(contentItem, "SummaryAdmin"));
|
||||
}
|
||||
|
||||
var pagerShape = Services.New.Pager(pager).TotalItemCount(searchHits.TotalItemCount);
|
||||
var pagerShape = Services.New.Pager(pager).TotalItemCount(totalCount);
|
||||
|
||||
|
||||
foreach(IShape item in list.Items) {
|
||||
|
@@ -21,6 +21,10 @@
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -68,6 +72,8 @@
|
||||
<Compile Include="Handlers\SearchSettingsPartHandler.cs" />
|
||||
<Compile Include="Services\ISearchService.cs" />
|
||||
<Compile Include="Services\SearchService.cs" />
|
||||
<Compile Include="Settings\ContentPickerFieldEditorEvents.cs" />
|
||||
<Compile Include="Settings\ContentPickerFieldSettings.cs" />
|
||||
<Compile Include="ViewModels\SearchSettingsViewModel.cs" />
|
||||
<Compile Include="ViewModels\SearchResultViewModel.cs" />
|
||||
<Compile Include="ViewModels\SearchViewModel.cs" />
|
||||
@@ -109,6 +115,9 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Admin\Index.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\DefinitionTemplates\ContentPickerSearchFieldSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.Environment.Extensions;
|
||||
|
||||
namespace Orchard.Search.Settings {
|
||||
[OrchardFeature("Orchard.Search.ContentPicker")]
|
||||
public class ContentPickerFieldEditorEvents : ContentDefinitionEditorEventsBase {
|
||||
|
||||
public override IEnumerable<TemplateViewModel> PartFieldEditor(ContentPartFieldDefinition definition) {
|
||||
if (definition.FieldDefinition.Name == "ContentPickerField") {
|
||||
var model = definition.Settings.GetModel<ContentPickerSearchFieldSettings>();
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
if (builder.FieldType != "ContentPickerField") {
|
||||
yield break;
|
||||
}
|
||||
|
||||
var model = new ContentPickerSearchFieldSettings();
|
||||
if (updateModel.TryUpdateModel(model, "ContentPickerSearchFieldSettings", null, null)) {
|
||||
builder.WithSetting("ContentPickerSearchFieldSettings.ShowSearchTab", model.ShowSearchTab.ToString(CultureInfo.InvariantCulture));
|
||||
builder.WithSetting("ContentPickerSearchFieldSettings.DisplayedContentTypes", model.DisplayedContentTypes);
|
||||
}
|
||||
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace Orchard.Search.Settings {
|
||||
public class ContentPickerSearchFieldSettings {
|
||||
public ContentPickerSearchFieldSettings() {
|
||||
ShowSearchTab = true;
|
||||
}
|
||||
|
||||
public bool ShowSearchTab { get; set; }
|
||||
public string DisplayedContentTypes { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
@model Orchard.Search.Settings.ContentPickerSearchFieldSettings
|
||||
|
||||
<fieldset>
|
||||
<div>
|
||||
@Html.CheckBoxFor(m => m.ShowSearchTab) <label for="@Html.FieldIdFor(m => m.ShowSearchTab)" class="forcheckbox">@T("Show Content tab")</label>
|
||||
<span class="hint">@T("Uncheck to hide the Search tab from the picker window.")</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.DisplayedContentTypes)">@T("Content Types and Parts")</label>
|
||||
@Html.TextBoxFor(m => m.DisplayedContentTypes)
|
||||
<span class="hint">@T("A comma separated value of all the content types or content parts to display.")</span>
|
||||
</div>
|
||||
</fieldset>
|
@@ -1,32 +1,8 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Core.Contents.Extensions;
|
||||
using Orchard.Data.Migration;
|
||||
using Orchard.Widgets.Models;
|
||||
|
||||
namespace Orchard.Widgets {
|
||||
public interface IDefaultLayersInitializer : IDependency {
|
||||
void CreateDefaultLayers();
|
||||
}
|
||||
|
||||
public class DefaultLayersInitializer : IDefaultLayersInitializer {
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public DefaultLayersInitializer(IContentManager contentManager) {
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public void CreateDefaultLayers() {
|
||||
IContent defaultLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Default"; t.Record.LayerRule = "true"; });
|
||||
_contentManager.Publish(defaultLayer.ContentItem);
|
||||
IContent authenticatedLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Authenticated"; t.Record.LayerRule = "authenticated"; });
|
||||
_contentManager.Publish(authenticatedLayer.ContentItem);
|
||||
IContent anonymousLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Anonymous"; t.Record.LayerRule = "not authenticated"; });
|
||||
_contentManager.Publish(anonymousLayer.ContentItem);
|
||||
IContent disabledLayer = _contentManager.Create<LayerPart>("Layer", t => { t.Record.Name = "Disabled"; t.Record.LayerRule = "false"; });
|
||||
_contentManager.Publish(disabledLayer.ContentItem);
|
||||
}
|
||||
}
|
||||
|
||||
public class WidgetsDataMigration : DataMigrationImpl {
|
||||
public int Create() {
|
||||
|
@@ -1,3 +0,0 @@
|
||||
Ceci est une actualite parlant de :
|
||||
|
||||
@Model.ContentItem.Actualite.Sommaire.Value
|
@@ -1,5 +1,7 @@
|
||||
@{
|
||||
// number of page number links to show, 0 means no link, 1 means only the current page, or more accepted.
|
||||
Model.Quantity = 0;
|
||||
|
||||
Model.PreviousText = T("Newer");
|
||||
Model.NextText = T("Older");
|
||||
Model.Classes.Add("group");
|
||||
|
@@ -6,14 +6,9 @@ namespace Orchard.DisplayManagement {
|
||||
/// This may be used directly, or through the IShapeHelperFactory.
|
||||
/// </summary>
|
||||
public interface IShapeFactory : IDependency {
|
||||
IShape Create(string shapeType);
|
||||
IShape Create(string shapeType, INamedEnumerable<object> parameters);
|
||||
IShape Create(string shapeType, INamedEnumerable<object> parameters, Func<dynamic> createShape);
|
||||
}
|
||||
|
||||
public static class ShapeFactoryExtensions {
|
||||
public static IShape Create(this IShapeFactory factory, string shapeType) {
|
||||
return factory.Create(shapeType, Arguments.Empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,10 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
return true;
|
||||
}
|
||||
|
||||
public IShape Create(string shapeType) {
|
||||
return Create(shapeType, Arguments.Empty(), () => new Shape());
|
||||
}
|
||||
|
||||
public IShape Create(string shapeType, INamedEnumerable<object> parameters) {
|
||||
return Create(shapeType, parameters, () => new Shape());
|
||||
}
|
||||
|
8
src/Orchard/Indexing/ISearchBits.cs
Normal file
8
src/Orchard/Indexing/ISearchBits.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Orchard.Indexing {
|
||||
public interface ISearchBits {
|
||||
ISearchBits And(ISearchBits other);
|
||||
ISearchBits Or(ISearchBits other);
|
||||
ISearchBits Xor(ISearchBits other);
|
||||
long Count();
|
||||
}
|
||||
}
|
@@ -57,6 +57,7 @@ namespace Orchard.Indexing {
|
||||
ISearchBuilder Slice(int skip, int count);
|
||||
IEnumerable<ISearchHit> Search();
|
||||
ISearchHit Get(int documentId);
|
||||
ISearchBits GetBits();
|
||||
int Count();
|
||||
|
||||
}
|
||||
|
@@ -127,6 +127,11 @@ namespace Orchard.Indexing {
|
||||
public ISearchHit Get(int documentId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ISearchBits GetBits() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int Count() {
|
||||
return 0;
|
||||
}
|
||||
|
@@ -238,6 +238,7 @@
|
||||
<Compile Include="FileSystems\LockFile\LockFile.cs" />
|
||||
<Compile Include="FileSystems\LockFile\DefaultLockFileManager.cs" />
|
||||
<Compile Include="FileSystems\Media\FileSystemStorageProvider.cs" />
|
||||
<Compile Include="Indexing\ISearchBits.cs" />
|
||||
<Compile Include="Localization\Services\CurrentCultureWorkContext.cs" />
|
||||
<Compile Include="Localization\Services\DefaultLocalizedStringManager.cs" />
|
||||
<Compile Include="Localization\Services\ILocalizedStringManager.cs" />
|
||||
|
@@ -139,7 +139,16 @@ namespace Orchard.UI.Zones {
|
||||
}
|
||||
|
||||
public override bool TryConvert(System.Dynamic.ConvertBinder binder, out object result) {
|
||||
result = Nil.Instance;
|
||||
if (binder.ReturnType == typeof (string)) {
|
||||
result = null;
|
||||
}
|
||||
else if (binder.ReturnType.IsValueType) {
|
||||
result = Activator.CreateInstance(binder.ReturnType);
|
||||
}
|
||||
else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user