Not exactly the most glorious post for the first from our Sitecore blog, but nevertheless, the team asked for it so here it is.
There are occasions where a developer needs to create some simple page to run “against” items contained within a Sitecore database. This can be used to modify items in the content tree as a sort of utility function, or to provide reporting on items based on some criteria.
There is an easy way to create a page within Sitecore that would be hosted on either the CD server, the CM server (one or the other or both), and would require access from an administrative (or developer role) account to execute outside of the context of a hosted site within the instance.
First, a reminder about some of the more useful /sitecore/admin scripts – I am sure you have used them.
/sitecore/admin/cache.aspx
/sitecore/admin/showconfig.aspx
/sitecore/admin/dbbrowser.aspx
/sitecore/admin/serialization.aspx
/sitecore/admin/stats.aspx, etc. etc. – there is an article from Mark Ursino, Sitecore MVP on the matter at Sitecore Admin Pages Explained.
In addition, some modules such as Email Campaign Manager and the Active Directory Module add pages to this folder as well.
For the most part, these pages require administrative access to run them, and even if you completely disable the Sitecore desktop on your content delivery servers, you can still utilize these pages if you choose.
You can also add your own pages to this area. Here’s an example – this is a fairly non-sensical script that resets items in the content tree back to the presentation details specified in the standard values of a particular template.
<%@ Page Language="c#" Inherits="Sitecore.sitecore.admin.AdminPage" %> <%@ Import Namespace="MyCode.Extensions" %> <%@ Import Namespace="Sitecore.Configuration" %> <%@ Import Namespace="Sitecore.Data" %> <%@ Import Namespace="Sitecore.Data.Items" %> <script runat="server"> protected override void OnInit(EventArgs args) { CheckSecurity(true); base.OnInit(args); } private void Run(Database database, Item root, TemplateItem template) { foreach (Item item in root.Children) { Run(database, item, template); } if (root.TemplateID.ToString() != template.ID.ToString()) return; litResult.Text += "<br/>Fixing " + root.Name; root.CopyPresentationDetails(database, template.ID); litResult.Text += " done"; } protected void tbRun_Click(object sender, EventArgs e) { if (!Page.IsValid) return; Database database = Factory.GetDatabase("master"); Item rootItem = database.GetItem(tbRootItem.Text); if (rootItem == null) { vlcRoot.IsValid = false; return; } TemplateItem template = database.GetTemplate(new ID(tbTargetTemplateId.Text)); if (template == null) { vlcTemplate.IsValid = false; return; } Run(database, rootItem, template); } </script> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <html> <head> <title>Reset Item Presentation Details</title> </head> <body> <form id="Form1" method="post" runat="server"> Root Item of Search: <asp:TextBox runat="server" ID="tbRootItem" Columns="50" MaxLength="200" Text="/sitecore/content/" /> <asp:RequiredFieldValidator runat="server" ID="vlrRoot" ErrorMessage="Root item is required" ControlToValidate="tbRootItem" /> <asp:CustomValidator runat="server" ID="vlcRoot" ErrorMessage="Root Item Not Found" /> <br /> <br /> Item Template ID to look for (resets presentation details for all items of this type): <asp:TextBox runat="server" ID="tbTargetTemplateId" Columns="100" MaxLength="50" Text="{D20CC720-EE60-455D-B57F-E82F95ED13FF}" /> <asp:RequiredFieldValidator runat="server" ID="vlrTemplate" ErrorMessage="Template is required" ControlToValidate="tbRootItem" /> <asp:CustomValidator runat="server" ID="vlcTemplate" ErrorMessage="Template Not Found" /> <br /> <br /> <asp:Button runat="server" Text="Run" OnClick="tbRun_Click" ID="tbRun" /> <br /> <br /> <asp:Literal runat="server" ID="litResult" /> </form> </body> </html>
We can break this script down to explain the relevant parts. The page is a simple .NET aspx page with the option of specifying the server side code in the script along with the markup for the client (instead of using a code-behind file).
<%@ Page Language="c#" Inherits="Sitecore.sitecore.admin.AdminPage" %>
Notice that we specify a base type of Sitecore.sitecore.admin.AdminPage – this declares some useful functions such as what’s used in the init event handler –
protected override void OnInit(EventArgs args) { CheckSecurity(true); base.OnInit(args); }
CheckSecurity(true) calls a method in the base type that checks to see if the user is an administrator, or (with the param true) if the user is a developer. If not, access to execute the page is not granted.