November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
What is rendered instead? If you are using Alloy block preview template - what is shown under `Global.ContentAreaTags.Grid` and `Global.ContentAreaTags.List` preview regions in that template?
I just replicate your setup in Alloy and correct templates are picked up..
Hi Valdis
Just checked in the admin and the display option is showing correctly.
I have the following in Global:
public static class ContentAreaTags
{
public const string Grid = "grid";
public const string List = "list";
public const string FullWidth = "span12";
public const string TwoThirdsWidth = "span8";
public const string HalfWidth = "span6";
public const string OneThirdWidth = "span4";
public const string NoRenderer = "norenderer";
}
I think what I am getting confused with is how does this know how to select either grid.cshtml or list.cshtml?
Thanks
Tags are added to block instance when placed inside content area - content area item. You can change display option for block via context menu for that block - when editting content of the area.
When you open that block in Edit (where all supported display modes are shown) - what is shown in "Grid" and "List" regions?
Here should be some screenshots of the views in episerver,
https://www.dropbox.com/s/atf3sqgojsht3ic/Block%20Edit.JPG?dl=0
Source
https://www.dropbox.com/s/405n5zcnsrxdlr7/Block%20Edit%20Source.JPG?dl=0
From what I can see all this is doing is added a class of grid or list not actually taking the grid.cshtml view or list.cshtml view
Thanks
Paul
Yip sure do see below:
public class PageListBlockController : BlockController<PageListBlock> { private ContentLocator contentLocator; private IContentLoader contentLoader; public PageListBlockController(ContentLocator contentLocator, IContentLoader contentLoader) { this.contentLocator = contentLocator; this.contentLoader = contentLoader; } public override ActionResult Index(PageListBlock currentBlock) { var pages = FindPages(currentBlock); pages = Sort(pages, currentBlock.SortOrder); if(currentBlock.Count > 0) { pages = pages.Take(currentBlock.Count); } var model = new PageListModel(currentBlock) { Pages = pages }; ViewData.GetEditHints<PageListModel, PageListBlock>() .AddConnection(x => x.Heading, x => x.Heading); return PartialView(model); } private IEnumerable<PageData> FindPages(PageListBlock currentBlock) { IEnumerable<PageData> pages; var listRoot = currentBlock.Root; if (currentBlock.Recursive) { if (currentBlock.PageTypeFilter != null) { pages = contentLocator.FindPagesByPageType(listRoot, true, currentBlock.PageTypeFilter.ID); } else { pages = contentLocator.GetAll<PageData>(listRoot); } } else { if (currentBlock.PageTypeFilter != null) { pages = contentLoader.GetChildren<PageData>(listRoot) .Where(p => p.PageTypeID == currentBlock.PageTypeFilter.ID); } else { pages = contentLoader.GetChildren<PageData>(listRoot); } } if (currentBlock.CategoryFilter != null && currentBlock.CategoryFilter.Any()) { pages = pages.Where(x => x.Category.Intersect(currentBlock.CategoryFilter).Any()); } return pages; } private IEnumerable<PageData> Sort(IEnumerable<PageData> pages, FilterSortOrder sortOrder) { var asCollection = new PageDataCollection(pages); var sortFilter = new FilterSort(sortOrder); sortFilter.Sort(asCollection); return asCollection; }
I am guessing here I need to add some sort of Template Descriptor?
Please dump content of `templates` list:
var repo = ServiceLocator.Current.GetInstance<TemplateModelRepository>(); var templates = repo.List(typeof(PageListBlock)).Where(t => t.TemplateTypeCategory == TemplateTypeCategories.MvcPartialView);
Here is the output, it is only returning the norendertemplate.
https://www.dropbox.com/s/ayvqk1jpwqyuvfr/templates.JPG?dl=0
So as you see - template registration has failed for those tags. Can you verify that grid.cshtml and list.cshtml is really located in those folders, that view engine is capable to find them?
I have changed the paths on the template resolver and they are now point tothe correct templates.
However I get an error 'The model item passed into the dictionary is of type 'Castle.Proxies.PageListBlockProxy', but this dictionary requires a model item of type 'Project.Models.ViewModels.PageListModel'.'
Would I need to add something to the PageListBlockController to handle the Grid or List view tags now and return a PageListModel?
Oh, ok. Now I got it (I hope).
So, this is the detailed explanation: when you are using template registrator - you are instructing EPiServer - "please, if you see this block type and these tags applied and maybe these settings also applied, please go to specified path and render block using that template". This will prevent your controller to kick in. Basically you are helping EPiServer to complete registration for content templates that were not automatically discovered.
What you need to do instead is
a) delete template registrator entries for grid and list
b) add following attribute to your page list block controller:
[TemplateDescriptor(AvailableWithoutTag = false, ModelType = typeof(PageListBlock), Name = "pagelistblock", Default = true, Tags = new[] { Global.ContentAreaTags.Grid, Global.ContentAreaTags.List })]
Then template selection is up to the controller to decide. You can retrieve currently selected display option with following code (not sure that this is the most optimal though):
var settings = RouteData.Values["RenderSettings"] as Dictionary<string, object>; if (settings != null) { var displayOption = settings["tag"] as string; if (displayOption == Global.ContentAreaTags.Grid) { return PartialView("~/Views/Shared/Blocks/grid.cshtml", model); } }
Keep in mind if editor will select other display option for that content and there will be no registered renderer for that `tag` - content will not be rendered.
I have been doing some reading up on blocks, display options, rendering and template discriptors, and trying to imlement a display option for either a grid view listing or a list view listing.
I have the display options added for grid and list options but, and correct me if I am wrong, I now want to select a different template based on the display option that has been selected upon the block.
I am working with the Alloy Template and the below is what I have added so far:
DisplayRegistryInitialization
var options = ServiceLocator.Current.GetInstance();
options
.Add("grid", "/displayoptions/grid", Global.ContentAreaTags.Grid, "", "epi-icon__layout--full")
.Add("list", "/displayoptions/list", Global.ContentAreaTags.List, "", "epi-icon__layout--full")
TemplateCoordinator
viewTemplateModelRegistrator.Add(typeof(PageListBlock), new TemplateModel
{
Name = "PageListBlockGrid",
Tags = new[] { Global.ContentAreaTags.Grid},
AvailableWithoutTag = false,
Path = BlockPath("Grid.cshtml")
});
viewTemplateModelRegistrator.Add(typeof(PageListBlock), new TemplateModel
{
Name = "PageListBlockList",
Tags = new[] { Global.ContentAreaTags.List },
AvailableWithoutTag = false,
Path = BlockPath("List.cshtml")
});
But it doesn't seem to pick-up my grid.cshtml template and list.cshtml template.
Would anybody be able to point me in the right direction?