Axe
Axe

Reputation: 739

Orchard cms Html from IContent items

My question is related to this one, but instead of changing a question I thought it Would be better to ask a new one.

I've now got a list of IContent items using the _taxonomyService.GetContentItems(term)

as suggested by @Bertrand Le Roy in the question mentioned above

But how do I turn this into a useful Html string, that I can update on the client via an ajax post?

public class HomeController : Controller
    {
        private readonly IOrchardServices _services;
        private readonly IBlogService _blogService;
        private readonly IBlogPostService _blogPostService;
        private readonly IFeedManager _feedManager;
        private readonly IArchiveConstraint _archiveConstraint;
        private readonly ITaxonomyService _taxonomyService;

        public HomeController(
            IOrchardServices services, 
            IBlogService blogService, 
            IBlogPostService blogPostService,
            IFeedManager feedManager,
            IShapeFactory shapeFactory,
            IArchiveConstraint archiveConstraint,
            ITaxonomyService taxonomyService) {
            _services = services;
            _blogService = blogService;
            _blogPostService = blogPostService;
            _feedManager = feedManager;
            _archiveConstraint = archiveConstraint;
            T = NullLocalizer.Instance;
            Shape = shapeFactory;
            _taxonomyService = taxonomyService;
            }

        dynamic Shape { get; set; }
        public Localizer T { get; set; }

        public ActionResult Index()
        {
            return View();
        }


    [HttpPost]
    public JsonResult ListByArchive(string path, IEnumerable<string> category)
    {
    try
    {
        // get year and month from path
        path = path.ToLower().Substring(path.LastIndexOf(@"/archive/", StringComparison.Ordinal) + 9);

        var date = path.Split('/');
        var month = int.Parse(date[1]);
        var year = int.Parse(date[0]);

        // get list of terms ids from strings 
        var taxonomyPart = _taxonomyService.GetTaxonomyByName("Category");

        var terms = category.Select(cat => _taxonomyService.GetTermByName(taxonomyPart.Id, cat)).ToList();

        // get list of content items by term avoiding duplicates 
        var posts = new List<IContent>();

        foreach (var term in terms)
        {
            var items = _taxonomyService.GetContentItems(term);

            foreach (var item in items)
            {
                if (!posts.Select(p => p.Id).Contains(item.Id))
                {
                    posts.Add(item);
                }
            }
        }


        // filter by date 
        var byDate = posts.Where(x =>
                    {
                        var publishedUtc = x.ContentItem.As<CommonPart>().CreatedUtc;
                        return
                            publishedUtc != null 
                            && publishedUtc.Value.Month == month 
                            && publishedUtc.Value.Year == year;
                    });

....

This gets me my list of IContent, but how do I get a the html for the rendered list ?

I've tried

var range = byDate.Select(x => _services.ContentManager.BuildDisplay(x, "Summary"));

                var list = Shape.List();

                list.AddRange(range);


                dynamic viewModel = Shape.ViewModel().ContentItems(list);

                var html = View((object)viewModel);

 return Json(new { html = html });

but it returns an empty view,

{"html":{"MasterName":"","Model":[],"TempData":[],"View":null,"ViewBag":{},"ViewData":[],"ViewEngineCollection":[{"HostContainer":{}}],"ViewName":""}}

I have a view called ListByArchive.cshtml, that matches the one it the orchard.blog module.

As an aside, I should be returning a partial view result, instead of a jason result, but when I change the Action result type I get a 404. result from the server.

Upvotes: 4

Views: 1595

Answers (1)

Piotr Szmyd
Piotr Szmyd

Reputation: 13366

This is never going to work the way you think it does:

var html = View((object)viewModel);

The easiest way to return HTML representing the content item is to:

  • Mark your action with ThemedAttribute, ie. [Themed(false)]
  • Return new ShapeResult(this, viewModel) (full view) or new ShapePartialResult(this, viewModel) (partial view) instead of Json(new { html = html })

Rendering a shape/view to string inside the action is also possible, but way more tricky.

EDIT: I assumed you already have /Views/ViewModel.cshtml file in place. Like Bertrand Le Roy noted below - if it's not there, you need to add one to be able to create a shape using Shape.ViewModel().

Upvotes: 2

Related Questions