Sitecore Core Development

Tuesday, September 27, 2005

Restricting files from being uploaded.

The uiUpload pipeline is not run as part of a Sheer event, but as part of loading a form in response to a post back. This is because the uploaded files are only available during a "real" post back and not a Sheer UI event. In this sense the uiUpload pipeline has not been designed to provide UI.

To restrict what kind of files that are uploaded, a developer should provide his own upload processor instead of the default.

The default upload processor looks like this:

using System;
using System.IO;
using System.Web;
using Sitecore.Diagnostics;
using Sitecore.IO;

namespace Sitecore.Pipelines.Upload {

///===============================================================
///
///===============================================================
public class Save {

#region Public methods

///-------------------------------------------------------------
///
///-------------------------------------------------------------
public void Process(UploadArgs args) {
foreach(string key in args.Files) {
HttpPostedFile file = args.Files[key];

if (file.FileName.Length > 0 && file.ContentLength > 0) {
string filename = FileUtil.MakePath(args.Folder, Path.GetFileName(file.FileName), '\\');

try {
if (!args.Overwrite) {
filename = FileUtil.GetUniqueFilename(filename);
}

file.SaveAs(filename);

EventDispatcher.DispatchTrace("File has been uploaded: " + filename);
}
catch(Exception ex) {
Log.Error("Could not save posted file: " + filename, ex, this);
}
}
}
}

#endregion
}
}

To provide feed back to the user, a processor could emit script code that shows an alert to the user.

HttpContext.Current.Response.Write("<script>alert('You are prohibited from uploading these kinds of files.')</script>");

Monday, September 26, 2005

Another Sitecore blog.

Ole has a blog on:

http://spaces.msn.com/members/sitecore

Customizing the HTML Editor

The following relates to the Sitecore 5.1 Beta.

To add a custom button for the HTML Editor do the following:

1. Create an item of template "Html Editor Custom Button" under "/sitecore/system/Settings/Html Editor Custom Buttons".

2. Fill in the 4 fields: Name, Icon, Tooltip and Click. The click field contains the javascript function to be called. Remember to include parentheses.

3. Create an item of template "Html Editor Button" in the HTML profile(s) where the button should appear. The Click field corresponds to the Name of the custom button.

4. In the web.config add a script tag to the clientscripts/htmleditor section. This will include the script file in the HTML editor.

5. Test that it works.

Tuesday, September 06, 2005

ViewState difficulties

The following article describes some of the difficulties with ViewState. It is great to read, and it has saved me a lot of work.

http://scottonwriting.net/sowblog/posts/2129.aspx

Optimizing

A natural phase of software development is optimizing and Sitecore version 5 has just passed through the first iteration of optimizing - probably one of many to come.

My greatest task was to optimize the Sheer UI and the Content Editor was the main problem. After using the dotTrace profiler from JetBrains, it became apparent that the performance of the Content Editor depended greatly on the number of web controls on the page. When the number exceeded about 200 controls performance decreased drastically. This is not problem with Sitecore, but more with ASP.NET as it seems that ASP.NET scales pourly. The Content Editor has about 1.200 webcontrols when all sections are expanded, so we quickly realised the we had to reduce the number of webcontrol on the page.

ASP.NET uses the runat="server" attribute to identify tag that should be converted into web controls. It is therefore a manual process to create a web control in a standard ASP.NET page and it is therefore unlikely that there will be many web controls.

The Content Editor is however built using XML Controls in which every tag is converted into a web controls. Naturally the creates a lot more web controls than ASP.NET normally does.

In ASP.NET everything that is not marked by a runat="server" attribute is converted into a LiteralControl. We thought about using the same approach. We would convert every tag that did not have an ID into a LiteralControl and then merge adjacent literal controls into a single control. Unfortunately this was working and we had to use a more simple method.

The solution was to use an attribute that was sort of the opposite of the runat="server" attribute - an attribute that describes that a web control is not needed on the server once it has been rendered. We settled on the name renderas="literal", which means that the web control and any subcontrols are rendered as a LiteralControl. When the page renderes, ClientPage walks the control tree and any web controls that have the renderas="literal" are rendered and replaced by a LiteralControl containing the result. Afterwards it is not possible to use the web controls in Sheer UI as it has now been replaced by the LiteralControl.

When placed with care, the number of web controls is reduced dramatically. The Content Editor went from 1.200 web controls to about 200 and this has greatly improved the performance.