AI OnAI Off
Hi, late night and on vacation but you can use something called "tags" in episerver. When rendiering a contentarea you can say that only content with a specific "tag" can be used in the area. You set this with code. If you have a look in the templatepackage from EPiServer you can find examples where this is done.
You use templatedescriptor for this and RenderSettings. Have a look at Johan Björnfots blogpost: http://world.episerver.com/Blogs/Johan-Bjornfot/Dates1/2012/9/EPiServer-7--Rendering-of-content/
He will explain most of the stuff. :)
Try the below class for controlling the Block items.
//Original URL: http://www.menzies-smith.co.uk/?p=76
[AttributeUsage(AttributeTargets.Property)]
public class AvailableContentTypesAttribute : ValidationAttribute
{
public Type[] Include { get; set; }
public Type[] Exclude { get; set; }
public override bool IsValid(object value)
{
if (value == null) return true; // If the Content area property not have the Block type value then return true
if (!(value is ContentArea))
{
throw new ValidationException("AvailableContentTypesAttribute is intended only for use with ContentArea properties");
}
var contentArea = value as ContentArea;
var notAllowedcontentNames = new List<string>();
if (contentArea != null)
{
if (Include != null)
{
var notAllowedContent = contentArea.Contents.Where(x => !ContainsType(Include, x.GetType()));
if (notAllowedContent.Any())
{
notAllowedcontentNames.AddRange(notAllowedContent.Select(x => string.Format("{0} ({1})", x.Name, x.ContentLink.ID)));
}
}
if (Exclude != null)
{
var notAllowedContent = contentArea.Contents.Where(x => ContainsType(Exclude, x.GetType()));
if (notAllowedContent.Any())
{
notAllowedcontentNames.AddRange(notAllowedContent.Select(x => string.Format("{0} ({1})", x.Name, x.ContentLink.ID)));
}
}
}
if (notAllowedcontentNames.Any())
{
ErrorMessage = "contains invalid content items:";
foreach (var notAllowedcontentName in notAllowedcontentNames)
{
ErrorMessage += " " + notAllowedcontentName + ",";
}
ErrorMessage += " Please select ";
foreach (Type type in Include)
{
ErrorMessage += type.Name + ",";
}
ErrorMessage = ErrorMessage.TrimEnd(',');
return false;
}
return true;
}
private bool ContainsType(Type[] include, Type type)
{
return include.Any(inc => inc.IsAssignableFrom(type));
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var result = base.IsValid(value, validationContext);
if (result != null && !string.IsNullOrEmpty(result.ErrorMessage))
{
result.ErrorMessage = string.Format("{0} {1}", validationContext.DisplayName, ErrorMessage);
}
return result;
}
}
PageType:
[AvailableContentTypes(Include = new[] { typeof(BlockType1), typeof(BlockType2) })]
[ContentAmount(Maximum = 1)]
[Display(
Name = "Sample",
GroupName = SystemTabNames.Content,
Order = 100)]
public virtual ContentArea Sample { get; set; }
I'm new to EpiServer and EpiServer 7 and I'm right now learning how to build a episerver 7 MVC website and thought of a question I can't find a solution for. Hopefully I'm only a little blind and there is a solution. My question.
Is it possible to make a content area only accept specific blocks or pages?
How I do now. (Best practice)
My solution right now is to have an abstract class that all page types inherits from so that I know I always can output something for each block in a content area. Is this how "real" epi-developers do or what's the best way?
I hope it's OK to put two questions/thoughts in one post and that it's not to fuzzy.
Thanks!