sebasuy
sebasuy

Reputation: 494

Orchard Query that filters by Content Type BlogPost and certain BlogId

I have a Orchard installation with two Blogs, one of them for Company News and the other for member publications.

I want to create a widget that shows a subset of posts from the Company News blog.

Is it possible in Orchard to create a Query that filters by the ContentType BlogPost and BlogId? I found a filter by Content Type, but I did not find a filter by BlogId.

Upvotes: 4

Views: 1554

Answers (2)

manudea
manudea

Reputation: 371

I have played a bit with filter and this is what I did. This filter allows you to filter BlogPost based on one of the Blog you have in the site. It is useful if you have more than one blog and you want to show recent posts from just one or two.

It works for me.

Any comment will be appreciated.

using System;
using System.Linq;
using System.Web.Mvc;
using Orchard.Blogs.Models;
using Orchard.ContentManagement;
using Orchard.Core.Common.Models;
using Orchard.DisplayManagement;
using Orchard.Forms.Services;
using Orchard.Localization;
using Orchard.Projections.Descriptors.Filter;
using IFilterProvider = Orchard.Projections.Services.IFilterProvider;

namespace Orchard.Projections.Providers.Filters
{
    public class BlogPostFilter : IFilterProvider
    {
        private readonly IContentManager _contentManager;
        public BlogPostFilter(
            IContentManager contentManager)
        {
            _contentManager = contentManager;
            T = NullLocalizer.Instance;
        }

        public Localizer T { get; set; }

        public void Describe(DescribeFilterContext describe)
        {
            describe.For("Blogs", T("Blogs"), T("Blogs"))
                .Element("Blogs", T("Blogs"), T("Posts in blogs"),
                ApplyFilter,
                DisplayFilter,
                "BlogPostFilter");
        }

        public void ApplyFilter(dynamic context)
        {
            var blogIds = (string)context.State.Blogs;
            if (!String.IsNullOrEmpty(blogIds)) {
                var ids = blogIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var query = (IHqlQuery)context.Query;
                context.Query = query.Where(x => x.ContentPartRecord<CommonPartRecord>(), x => x.In("Container.Id", ids));
            }
        }

        public LocalizedString DisplayFilter(dynamic context)
        {
            var blogIds = (string)context.State.Blogs;
            if (!String.IsNullOrEmpty(blogIds)) {
                var ids = Array.ConvertAll(blogIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => int.Parse(s));;
                var names = _contentManager.GetMany<BlogPart>(ids, VersionOptions.Published, QueryHints.Empty);
                return T("Posts in blogs: " + string.Join(", ", names.Select(x => x.Name)));
            }
            return T("Posts in blogs");
        }
    }

    public class BlogPostFilterForms : IFormProvider
    {
        private readonly IContentManager _contentManager;
        protected dynamic Shape { get; set; }
        public Localizer T { get; set; }

        public BlogPostFilterForms(
            IShapeFactory shapeFactory,
            IContentManager contentManager)
        {
            _contentManager = contentManager;
            Shape = shapeFactory;
            T = NullLocalizer.Instance;
        }

        public void Describe(DescribeContext context)
        {
            Func<IShapeFactory, object> form =
                shape => {

                    var f = Shape.Form(
                        Id: "AnyOfBlogPart",
                        _Parts: Shape.SelectList(
                            Id: "blogs", Name: "Blogs",
                            Title: T("Blogs"),
                            Description: T("Select some blogs."),
                            Size: 10,
                            Multiple: true
                            )
                        );

                    f._Parts.Add(new SelectListItem { Value = "", Text = T("Any").Text });

                    foreach (var blog in _contentManager.Query<BlogPart>().List().OrderBy(x => x.Name)) {
                        f._Parts.Add(new SelectListItem { Value = blog.Id.ToString(), Text = blog.Name });
                    }

                    return f;
                };

            context.Form("BlogPostFilter", form);

        }
    }
}

Upvotes: 1

Brandon Joyce
Brandon Joyce

Reputation: 3110

This would be a pretty simple filter to add within a module. Here is a bit of a hard-coded example that filters by id...

public class ContentIdFilter : IFilterProvider {
    private const int HardCodedId = 99;

    public ContentIdFilter() {            
        T = NullLocalizer.Instance;
    }

    public Localizer T { get; set; }

    public void Describe(DescribeFilterContext describe) {
        describe.For("Content", T("Content"), T("Content"))
            .Element("ContentId", T("Content Id"), T("Content w/ Id: " + HardCodedId.ToString()), 
            ApplyFilter, 
            DisplayFilter, 
            null);
    }

    public void ApplyFilter(dynamic context) {
        var query = (IHqlQuery)context.Query;
        context.Query = query.Where(x => x.ContentItem(), x => x.Eq("Id", HardCodedId));
    }

    public LocalizedString DisplayFilter(dynamic context) {
        return T("Content w/ Id: " + HardCodedId.ToString());
    }
}

There's a little more to it to make the Id number configurable, but this should put you on the right track.

Upvotes: 4

Related Questions