08448380779 Call Girls In Greater Kailash - I Women Seeking Men
Creating EPiServer Usage Reports
1. EPiServer Usage Reports
As EPiServer projects age, it's not unusual to find content starting to stagnate certain page
types event used. At this stage it's wise to gather some reporting. This was the situation i
faced on a previous project.
It's possible to gather some information via EPiServer Admin and Reports section. However
if we want comprehensive information we too access EPiServer and create a custom report.
A feature that introduce in version 5.
2. Creating the Interface
Firstly, I need a web site where i can create the reports. Luckily EPiServer provides a couple
of options with the easiest being the new Alloy Demo Kit available from GitHub.
3. We have the option to create a Reports as a Web Forms ASPX page or a an MVC View. I've
chosen to use an ASPX page for its simplicity. To do this we simply need to create a ASPX
page, in Visual Studio. I would suggest you create a new folder under the modules , my
reasoning will become clear in a later post.
When creating the ASPX Page it's important to select Web Form without a MasterPage. We
will be assigning an EPiServer MasterPage, which needs to be done in code.
4. Next we need to replace the entire body with the code below, leaving only the first line
<%@ Page Language="C#" .
<asp:content contentplaceholderid="FullRegion" runat="Server">
<div class="epi-contentContainer epi-padding epi-contentArea">
<h1 class="EP-prefix">Report Heading</h1>
</div>
</asp:content>
Now we need to navigate to the code behind and update the class this page inherits,
from System.Web.UI.Page to EPiServer.Shell.WebForms.WebFormsBase .
5. Next we add the GuiPlugIn attribute, to tell EPiServer this is a Report and where it's located,
plus give it a friendly name.
[GuiPlugIn(Area = PlugInArea.ReportMenu,
DisplayName = "Page Types Usage Report",
Description = "Lists pages of a specific page type",
Category = "Usage Reports",
RequiredAccess = AccessLevel.Administer,
Url = "~/modules/UsageReports/PageTypeUsageReport.aspx")]
public partial class PageTypesUsageReport : WebFormsBase
Additional, with the Category property we can separate reports and withRequired
Access control access. how it should be listed in the Reports menu. The final step is to
override the OnPreInit method to set the master page.
6. protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
MasterPageFile =
UriSupport.ResolveUrlFromUIBySettings("MasterPages/EPiServerUI.master")
;
}
Now that we have a basic report we can look into populating it.
7. Populating the report
Our first task is to override the OnLoad method, that will contain our logic. We could have
used the 'PageLoad' methods and participate in the AutoEventWireup. However, as a rule
set I AutoEventWireup="false" and delete the 'PageLoad' methods for performance
reasons. Additional I've added a Property to hold all the
public IEnumerable<ContentTypeUsageVm> ReportItems { get; private set;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
First we need to get a copy an instance of the PageTypeRepository , we can
use ServiceLocator to do this.
8. Then we simple call the List method to return all the pages. I've also added a simple property
which will to generate the HTML.
var serviceLocator = ServiceLocator.Current;
var pageTypeRepo =
serviceLocator.GetInstance<IContentTypeRepository>();
ReportsItems = from contentType in contentTypeRepo.List()
select new ContentTypeUsageVm {
ContentTypeName = contentType.Name,
Available = contentType.IsAvailable,
Description = contentType.Description
};
}
9. If we require any Web Form Controls that use the uses the view state we also need to
set EnableViewState="true" on the <%@ Page declaration.
<% if (ReportItems != null && ReportItems.Any())
{ %> <table>
<thead>
<tr>
<th>
Page Type
</th>
<th>
Available
</th>
<th>
Description
</th>
</tr>
</thead>
<% foreach (var item in ReportItems)
{ %>
10. <tbody>
<tr>
<td><%= item.ContentTypeName %></td>
<td><%= item.Available %></td>
<td><%= item.Description %></td>
</tr>
</tbody>
<% } %>
</table>
<% } %>
This will give us a basic report, however i won't tell us about usage, for this we need to do
some additional work.
11. Generating Usage Data
We need to introduce two new services. IContentModelUsage returns reference to content
thats implements a particular types andIContentRepository for loading the content. By
combining both these services we can generate some sensible usage data.
//insert code below the IContentTypeRepository and replace lines 5-8.
var contentUsage = serviceLocator.GetInstance<IContentModelUsage>();
var contentRepo = serviceLocator.GetInstance<IContentRepository>();
ReportsItems = from contentType in contentTypeRepo.List()
let usage = from u in contentUsage
.ListContentOfContentType(contentType)
select u.ContentLink
.ToReferenceWithoutVersion()).Distinct())
let content = contentRepo.GetItems(usage
, LanguageSelector.AutoDetect())
let pages = usage.OfType<PageData>()
select new ContentTypeUsageVM {
Total = usage.Count(),
12. Deleted = content.Count(p => p.IsDeleted),
To get the number of times content of a type has been created, we only need to count the
usages references with versions removed. More detailed information will require us to load
the content data.
With the Content Repository we can load the list of IContent from the content references.
This gives us access IsDelete Property, however for more information we must cast the back
into it's base type, PageData, BlockData or MediaData.
Whats next
Now that I've create one report, i now create multiple reports to cover all my needs. Next i
need to extract these reports into a separate project and upload it to GitHub. My finial task
will be to create a Nuget package. This final task will become my next blog entry.
Resources
CreatevYour Own Reports in the New Report Center
Iintroducing Alloy demo kit