Skip to content

Instantly share code, notes, and snippets.

@PNergard
Created June 17, 2019 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PNergard/8a1037dcea6918dfc558676bded4e7b9 to your computer and use it in GitHub Desktop.
Save PNergard/8a1037dcea6918dfc558676bded4e7b9 to your computer and use it in GitHub Desktop.
Content cleaner. A Episerver admin mode plugin to let you find content of a specific type and delete all or selected instances
<%@ Page Language="c#" CodeBehind="Cleaner.aspx.cs" AutoEventWireup="False" Inherits="LatestEpi.modules.TypeContentCleaner.Cleaner" Title="" %>
<%@ Import Namespace="EPiServer.Web.Mvc.Html" %>
<asp:content contentplaceholderid="MainRegion" runat="server">
<asp:HiddenField runat="server" id="SelectedScheduledJobGUID" ClientIDMode="static" />
<asp:HiddenField runat="server" id="SelectedMedia" ClientIDMode="static" />
<script type="text/javascript">
function SetCheckBoxes(getAll) {
var checkboxValues = [];
if (getAll) {
$('input[type="checkbox"]').map(function () {
checkboxValues.push($(this).val());
});
}
else {
$('input:checked').map(function () {
checkboxValues.push($(this).val());
});
}
$('#SelectedMedia').val(checkboxValues.join(','));
//console.log(checkboxValues);
};
function SetSelected() {
$('#SelectedScheduledJobGUID').val($('#TypeID').val());
///console.log($('#TypeID option:selected').text());
}
</script>
<div class="epi-formArea epi-paddingHorizontal">
<fieldset>
<legend>Select content type</legend>
<asp:Repeater id="rptTypes" runat="server">
<HeaderTemplate>
<select id="TypeID">
</HeaderTemplate>
<ItemTemplate>
<option value="<%#CType.ID %>"><%#CType.Name %></option>
</ItemTemplate>
<FooterTemplate>
</select>
</FooterTemplate>
</asp:Repeater>
<div class="epi-buttonContainer epi-marginVertical">
<span class="epi-cmsButton">
<asp:Button OnClientClick="SetSelected()" ClientIDMode="Static" Text="List content" CssClass="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Save" id="btnList" onmouseover="EPi.ToolButton.MouseDownHandler(this)" onmouseout="EPi.ToolButton.ResetMouseDownHandler(this)" runat="server" />
</span>
</div>
</fieldset>
<div class="epi-buttonContainer">
<span class="epi-cmsButton">
<asp:Button OnClientClick="SetCheckBoxes(1)" ClientIDMode="Static" Text="Delete all" CssClass="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Save" id="btnDeleteAll" onmouseover="EPi.ToolButton.MouseDownHandler(this)" onmouseout="EPi.ToolButton.ResetMouseDownHandler(this)" runat="server" />
</span>
<span class="epi-cmsButton">
<asp:Button OnClientClick="SetCheckBoxes(0)" ClientIDMode="Static" Text="Delete selected" CssClass="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Save" id="btnDeleteSelected" onmouseover="EPi.ToolButton.MouseDownHandler(this)" onmouseout="EPi.ToolButton.ResetMouseDownHandler(this)" runat="server" />
</span>
</div>
<div class="epi-buttonContainer"></div>
<fieldset>
<legend>Content</legend>
<dl>
<dd>
<asp:Repeater runat="server" id="rptContentUsage">
<ItemTemplate>
<div class="epi-size25">
<input type="checkbox" value="<%#CUsage.ContentLink %>" /> <label><a href="<%#Url.ContentUrl(CUsage.ContentLink) %>" target="_blank"><%# BreadCrumb(CUsage.ContentLink)%></a></label>
</div>
</ItemTemplate>
</asp:Repeater>
<asp:Literal runat="server" id="Literal4" />
</dd>
</dl>
</fieldset>
</div>
</asp:content>
using System;
using System.Collections.Generic;
using System.Web.Security;
using System.Web.UI.WebControls;
using EPiServer.Personalization;
using EPiServer.PlugIn;
using EPiServer.Security;
using EPiServer.Util.PlugIns;
using System.Web.UI;
using EPiServer.Shell.WebForms;
using EPiServer;
using EPiServer.Core;
using EPiServer.ServiceLocation;
using System.Linq;
using System.Web.Mvc;
using EPiServer.DataAbstraction;
namespace LatestEpi.modules.TypeContentCleaner
{
[GuiPlugIn(DisplayName = "Content cleaner", Description = "", Area = PlugInArea.AdminMenu, Url = "~/modules/TypeContentCleaner/Cleaner.aspx")]
public partial class Cleaner : WebFormsBase
{
private IContentRepository contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
protected UrlHelper Url = ServiceLocator.Current.GetInstance<UrlHelper>();
protected ContentType CType{ get { return Page.GetDataItem() as ContentType; } }
protected ContentUsage CUsage { get { return Page.GetDataItem() as ContentUsage; } }
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
MasterPageFile = UriSupport.ResolveUrlFromUIBySettings("MasterPages/EPiServerUI.master");
SystemMessageContainer.Heading = "Content Cleaner";
SystemMessageContainer.Description = "A plugin that fgets all content for a type and let you delete all or selected.";
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
btnList.Click += BtnList_Click;
btnDeleteAll.Click += BtnbtnDelete_Click;
btnDeleteSelected.Click += BtnbtnDelete_Click;
}
protected override void OnLoad(EventArgs e)
{
rptTypes.DataSource = ServiceLocator.Current.GetInstance<IContentTypeRepository>().List().OrderBy(p => p.Name); ;
rptTypes.DataBind();
}
protected string BreadCrumb(ContentReference cReference)
{
var ancestor = contentRepository.GetAncestors(cReference).ToList();
var content = contentRepository.Get<IContent>(cReference);
string path = "";
for (int x = ancestor.Count() - 1; x >= 0; x--)
{
path += "\\" + ancestor[x].Name;
}
return (path + "\\" + content.Name).Trim("\\".ToCharArray());
}
protected string UiUrl()
{
return EPiServer.Configuration.Settings.Instance.UIUrl.ToString().Trim('~');
}
private void BtnList_Click(object sender, EventArgs e)
{
var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
var selectedTypeID = SelectedScheduledJobGUID.Value;
var contentType = ServiceLocator.Current.GetInstance<IContentTypeRepository>().Load(Int32.Parse(selectedTypeID));
var usages = contentModelUsage.ListContentOfContentType(contentType).OrderBy(x => x.Name);
rptContentUsage.DataSource = usages;
rptContentUsage.DataBind();
}
private void BtnbtnDelete_Click(object sender, EventArgs e)
{
var selectedContentLinks = SelectedMedia.Value.Split(",".ToCharArray());
foreach (var contentLink in selectedContentLinks)
{
contentRepository.Delete(ContentReference.Parse(contentLink), false, AccessLevel.NoAccess);
}
}
}
}
//------------------------------------------------------------------------------
// <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 LatestEpi.modules.TypeContentCleaner {
public partial class Cleaner {
/// <summary>
/// SelectedScheduledJobGUID 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.HiddenField SelectedScheduledJobGUID;
/// <summary>
/// SelectedMedia 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.HiddenField SelectedMedia;
/// <summary>
/// rptTypes 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.Repeater rptTypes;
/// <summary>
/// btnList 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.Button btnList;
/// <summary>
/// btnDeleteAll 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.Button btnDeleteAll;
/// <summary>
/// btnDeleteSelected 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.Button btnDeleteSelected;
/// <summary>
/// rptContentUsage 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.Repeater rptContentUsage;
/// <summary>
/// Literal4 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.Literal Literal4;
}
}
@PNergard
Copy link
Author

You can read my blog post for more information at the following link:

https://world.episerver.com/blogs/Per-Nergard/Dates/2019/6/find-and-delete-content-based-on-type/

@j3rbr0wn
Copy link

Based on this nice solution from @PNergard, I have created something similar for Optimizely CMS 12:
Content Cleaner Tool for Optimizely CMS 12

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