Orchard cms Html from IContent Elements

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

Now I have a list of IContent elements using _taxonomyService.GetContentItems (term)

as @ Bertrand Le Roy suggested in the above question

But how can I turn this into a useful Html line that I can update on the client via 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 my IContent list, but how do I get the html for the displayed list?

I 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 orchard.blog module.

As an aside, I should return the result of the partial view, not the result of jason, but when I change the type of the result of Action, I get the result of 404. From the server.

+4
source share
1 answer

This will never work the way you think:

 var html = View((object)viewModel); 

The easiest way to return HTML representing a content element is:

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

It is also possible to render the shape / view for the line inside the action, but in a more complex way.

EDIT: I assumed that you already have the file /Views/ViewModel.cshtml . Like Bertrand Le Roy noted below - if it does not exist, you need to add it to create the form using Shape.ViewModel() .

+2
source

Source: https://habr.com/ru/post/1442332/


All Articles