Skip to content

Instantly share code, notes, and snippets.

@PNergard
Created September 23, 2015 20:25
Show Gist options
  • Save PNergard/f0e555a1e9eb2e00161a to your computer and use it in GitHub Desktop.
Save PNergard/f0e555a1e9eb2e00161a to your computer and use it in GitHub Desktop.
Overview of ContentArea AllowedTypesAttribute
<%@ 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>&nbsp;</td>
<td><strong>Available content types</strong></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</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>&nbsp;</td>
<td><%#contentType.Name %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</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>
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
//------------------------------------------------------------------------------
// <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;
}
}
@valdisiljuconoks
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment