Created
September 23, 2015 20:25
-
-
Save PNergard/f0e555a1e9eb2e00161a to your computer and use it in GitHub Desktop.
Overview of ContentArea AllowedTypesAttribute
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ Page Language="C#" AutoEventWireup="false" CodeFile="Quality.aspx.cs" Inherits="EPiServer.Templates.Alloy.Quality" %> | |
<%@ Import Namespace="Castle.MicroKernel.Registration" %> | |
<%@ Import Namespace="EPiServer.ClientScript.Events" %> | |
<%@ Import Namespace="System.Web.Management" %> | |
<!doctype html> | |
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]--> | |
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]--> | |
<!--[if IE 8]> <html class="no-js lt-ie9" lang=""> <![endif]--> | |
<!--[if gt IE 8]><!--> | |
<html class="no-js" lang=""> | |
<!--<![endif]--> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | |
<title>Content Creator</title> | |
<meta name="description" content=""> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="apple-touch-icon" href="apple-touch-icon.png"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css"> | |
<style> | |
body { | |
padding-top: 50px; | |
padding-bottom: 20px; | |
} | |
</style> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap-theme.min.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"></script> | |
</head> | |
<body> | |
<form id="Form1" runat="server"> | |
<!--[if lt IE 8]> | |
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> | |
<![endif]--> | |
<asp:ScriptManager EnablePartialRendering="true" | |
ID="ScriptManager1" runat="server"> | |
</asp:ScriptManager> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-xs-12"> | |
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> | |
<div class="container"> | |
<div class="navbar-header"> | |
<a class="navbar-brand" href="#">Site information</a> | |
</div> | |
</div> | |
</nav> | |
<!-- Content Start --> | |
<ul class="nav nav-tabs"> | |
<li class="active"><a href="#ett" role="tab" data-toggle="tab">Page types - available page types</a></li> | |
<li><a href="#tva" role="tab" data-toggle="tab">Page types - number of pages</a></li> | |
<li><a href="#tre" role="tab" data-toggle="tab">ContentAreas - allowed types</a></li> | |
</ul> | |
<br /> | |
<div class="tab-content"> | |
<div role="tabpanel" class="tab-pane active" id="ett"> | |
<asp:Repeater ID="rptContentType" runat="server"> | |
<HeaderTemplate> | |
<table> | |
<tr> | |
<td><strong>Name</strong></td> | |
<td> </td> | |
<td><strong>Available content types</strong></td> | |
</tr> | |
<tr> | |
<td> </td> | |
<td> </td> | |
<td> </td> | |
</tr> | |
</HeaderTemplate> | |
<ItemTemplate> | |
<tr> | |
<td></td> | |
<td></td> | |
</tr> | |
<asp:Repeater runat="server" DataSource='<%# Eval("value")%>'> | |
<ItemTemplate> | |
<tr> | |
<td><i><%# Container.ItemIndex == 0 ? DataBinder.Eval(Container.Parent.Parent, "DataItem.key") : ""%></i></td> | |
<td> </td> | |
<td><%#contentType.Name %></td> | |
</tr> | |
</ItemTemplate> | |
</asp:Repeater> | |
<tr> | |
<td> </td> | |
<td> </td> | |
<td> </td> | |
</tr> | |
</ItemTemplate> | |
<FooterTemplate> | |
</table> | |
</FooterTemplate> | |
</asp:Repeater> | |
</div> | |
<div role="tabpanel" class="tab-pane" id="tva"> | |
<asp:UpdatePanel ID="UpdatePanel1" runat="server" | |
UpdateMode="Conditional"> | |
<ContentTemplate> | |
<div class="row"> | |
<asp:Button runat="server" ID="btnCount" Text="GO!" OnClick="btnCount_OnClick" /> | |
</div> | |
<asp:Repeater runat="server" ID="rptTypeCount"> | |
<HeaderTemplate> | |
<div class="row"> | |
<ul class="list-group"> | |
</HeaderTemplate> | |
<ItemTemplate> | |
<li class="list-group-item"> | |
<span class="badge"><%#Eval("value") %></span> | |
<%#Eval("key") %> | |
</li> | |
</ItemTemplate> | |
<FooterTemplate> | |
</ul | |
</div> | |
</FooterTemplate> | |
</asp:Repeater> | |
</ContentTemplate> | |
</asp:UpdatePanel> | |
</div> | |
<div role="tabpanel" class="tab-pane" id="tre"> | |
<asp:Repeater runat="server" ID="rptContentAreas"> | |
<ItemTemplate> | |
<div <%#Container.ItemIndex % 2 == 0 ? @"class=""row alert alert-success""" : @"class=""row alert alert-info""" %>> | |
<div class="row"><strong>Page type: </strong><%#AreaDetail.PageTypeName %></div> | |
<asp:Repeater runat="server" DataSource="<%#AreaDetail.AreaInformations %>"> | |
<HeaderTemplate></HeaderTemplate> | |
<ItemTemplate> | |
<div class="row"> | |
<br /> | |
</div> | |
<div style="margin-bottom: 5px" class="row"><strong>Property Name: </strong><%#AreaAttribute.Name %></div> | |
<div class="col-md-6"> | |
<div><strong>AllowedTypes</strong></div> | |
<asp:Repeater runat="server" DataSource="<%#AreaAttribute.AllowedTypes %>"> | |
<ItemTemplate> | |
<%#((Type)Container.DataItem).Name %> | |
</ItemTemplate> | |
</asp:Repeater> | |
</div> | |
<div class="col-md-6"> | |
<div><strong>RestrictedTypes</strong></div> | |
<asp:Repeater runat="server" DataSource="<%#AreaAttribute.RestrictedTypes %>"> | |
<ItemTemplate> | |
<%#((Type)Container.DataItem).Name %> | |
</ItemTemplate> | |
</asp:Repeater> | |
</div> | |
<div class="row" style="margin-bottom: 10px"></div> | |
</ItemTemplate> | |
</asp:Repeater> | |
</div> | |
</ItemTemplate> | |
</asp:Repeater> | |
</div> | |
</div> | |
<!-- Content end --> | |
</div> | |
</div> | |
</div> | |
<!-- /container --> | |
</form> | |
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> | |
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.2.min.js"><\/script>')</script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js"></script> | |
</body> | |
</html> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Web; | |
using System.Web.UI; | |
using System.Web.UI.WebControls; | |
using EPiServer.Core; | |
using EPiServer.Core.Transfer; | |
using EPiServer.DataAbstraction; | |
using EPiServer.DataAnnotations; | |
using EPiServer.Filters; | |
using EPiServer.ServiceLocation; | |
namespace EPiServer.Templates.Alloy | |
{ | |
public partial class Quality : SimplePage | |
{ | |
protected ContentType contentType { get { return Page.GetDataItem() as ContentType; } } | |
protected PropertyDefinitionType typ { get { return Page.GetDataItem() as PropertyDefinitionType; } } | |
protected ContentAreaDetail AreaDetail { get { return Page.GetDataItem() as ContentAreaDetail; } } | |
protected ContentAreaAttributeInformation AreaAttribute { get { return Page.GetDataItem() as ContentAreaAttributeInformation; } } | |
#region Classes | |
public class ContentAreaDetail | |
{ | |
public string PageTypeName { get; set; } | |
public List<ContentAreaAttributeInformation> AreaInformations { get; set; } | |
public ContentAreaDetail() | |
{ | |
AreaInformations = new List<ContentAreaAttributeInformation>(); | |
} | |
} | |
public class ContentAreaAttributeInformation | |
{ | |
public string Name { get; set; } | |
public Type[] AllowedTypes { get; set; } | |
public Type[] RestrictedTypes { get; set; } | |
} | |
#endregion | |
protected override void OnLoad(EventArgs e) | |
{ | |
rptContentType.DataSource = PageTypes(); | |
rptContentType.DataBind(); | |
rptContentAreas.DataSource = ContentAreasAllowedTypes(); | |
rptContentAreas.DataBind(); | |
} | |
private List<ContentAreaDetail> ContentAreasAllowedTypes() | |
{ | |
IEnumerable<PageType> allPageTypes = GetAllPageTypes(); | |
List<PropertyDefinitionType> areaPropertyDefinitions = new List<PropertyDefinitionType>(); | |
List<ContentAreaDetail> pageTypeDetails = new List<ContentAreaDetail>(); | |
foreach (PageType ptype in allPageTypes) | |
{ | |
var detail = new ContentAreaDetail(); | |
detail.PageTypeName = ptype.Name; | |
try | |
{ | |
var propertiesWithAllowedTypesAttribute = from p in ptype.ModelType.GetProperties() | |
let attr = p.GetCustomAttributes(typeof(AllowedTypesAttribute), true) | |
where attr.Length == 1 | |
select new { Property = p, Attribute = attr.First() as AllowedTypesAttribute }; | |
foreach (var prop in propertiesWithAllowedTypesAttribute) | |
{ | |
var information = new ContentAreaAttributeInformation(); | |
information.Name = prop.Property.Name; | |
information.AllowedTypes = prop.Attribute.AllowedTypes; | |
information.RestrictedTypes = prop.Attribute.RestrictedTypes; | |
detail.AreaInformations.Add((information)); | |
} | |
pageTypeDetails.Add(detail); | |
} | |
catch (Exception) | |
{ | |
//Some types fail like SysRoot | |
continue; | |
} | |
} | |
return pageTypeDetails; | |
} | |
private Dictionary<string, List<PageType>> PageTypes() | |
{ | |
Dictionary<string, List<PageType>> resultDictionary = new Dictionary<string, List<PageType>>(); | |
IEnumerable<PageType> allPageTypes = GetAllPageTypes(); | |
foreach (PageType ptype in allPageTypes) | |
{ | |
resultDictionary.Add(ptype.Name, GetAvailableContentTypes(ptype)); | |
} | |
return resultDictionary; | |
} | |
private IEnumerable<PageType> GetAllPageTypes() | |
{ | |
IContentTypeRepository contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>(); | |
return contentTypeRepository.List().OfType<PageType>(); | |
} | |
private int NumberOfPagesForContentType(ContentType contentType) | |
{ | |
PropertyCriteria criteria = new PropertyCriteria(); | |
criteria.Condition = CompareCondition.Equal; | |
criteria.Name = "PageTypeID"; | |
criteria.Type = PropertyDataType.PageType; | |
criteria.Value = contentType.ID.ToString(); | |
criteria.Required = true; | |
PropertyCriteriaCollection collection = new PropertyCriteriaCollection { (criteria) }; | |
return DataFactory.Instance.FindPagesWithCriteria(ContentReference.RootPage, collection).Count(); | |
} | |
private List<PageType> GetAvailableContentTypes(ContentType cType) | |
{ | |
ContentTypeAvailabilityService contentTypeAvailablilityService = ServiceLocator.Current.GetInstance<ContentTypeAvailabilityService>(); | |
// Get Available settings | |
AvailableSetting setting = contentTypeAvailablilityService.GetSetting(cType.Name); | |
bool allAvailable = setting.Availability == Availability.All || | |
setting.Availability == Availability.Undefined && | |
!setting.AllowedContentTypeNames.Any(); | |
List<PageType> availableList = new List<PageType>(); | |
if (!allAvailable) | |
{ | |
foreach (PageType pageType in this.GetAllPageTypes()) | |
{ | |
foreach (string str in setting.AllowedContentTypeNames) | |
{ | |
if (str.Equals(pageType.Name)) | |
{ | |
availableList.Add(pageType); | |
} | |
} | |
} | |
} | |
if (allAvailable) | |
{ | |
PageType allType = new PageType { Name = "All" }; | |
return new List<PageType> { allType }; | |
} | |
else | |
{ | |
return availableList; | |
} | |
} | |
#region Events | |
protected void btnCount_OnClick(object sender, EventArgs e) | |
{ | |
SortedDictionary<string, int> results = new SortedDictionary<string, int>(); | |
IEnumerable<PageType> allPageTypes = GetAllPageTypes(); | |
foreach (PageType ptype in allPageTypes) | |
{ | |
results.Add(ptype.Name, NumberOfPagesForContentType(ptype)); | |
} | |
rptTypeCount.DataSource = results; | |
rptTypeCount.DataBind(); | |
} | |
#endregion | |
} //Class | |
} //Namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------------------------------------------------------------ | |
// <auto-generated> | |
// This code was generated by a tool. | |
// | |
// Changes to this file may cause incorrect behavior and will be lost if | |
// the code is regenerated. | |
// </auto-generated> | |
//------------------------------------------------------------------------------ | |
namespace EPiServer.Templates.Alloy { | |
public partial class Quality { | |
/// <summary> | |
/// Form1 control. | |
/// </summary> | |
/// <remarks> | |
/// Auto-generated field. | |
/// To modify move field declaration from designer file to code-behind file. | |
/// </remarks> | |
protected global::System.Web.UI.HtmlControls.HtmlForm Form1; | |
/// <summary> | |
/// Content control. | |
/// </summary> | |
/// <remarks> | |
/// Auto-generated field. | |
/// To modify move field declaration from designer file to code-behind file. | |
/// </remarks> | |
protected global::System.Web.UI.WebControls.ContentPlaceHolder Content; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Haven't checked the code- but would be nice to see a list of all page instances and links to it for "Page types - number of pages". Have you considered to "alter" built-in content type editor pages and provide this functionality also there? :) This can be done via Asp.Net web page adapters.