Adding Markup to a SharePoint Page
How many times have you had the need to add ASP.NET markup – HTML and server-side control declarations – in a SharePoint page? Yes, there is the Script Editor Web Part and the Content Editor Web Part, but none of these allow you to enter server-side control declarations, just plain HTML, CSS and JavaScript.
So, enter the Markup Editor Web Part!
This web part allows you to enter any markup including server-side controls in a nice configurable web part. Without further delay, here is the code:
1: [ToolboxItemAttribute(false)]
2: public class MarkupEditorWebPart : WebPart, INamingContainer
3: {
4: public MarkupEditorWebPart()
5: {
6: this.ExportMode = WebPartExportMode.All;
7: }
8:
9: [Category("Markup")]
10: [Personalizable(true)]
11: [WebBrowsable(true)]
12: [WebDescription("The markup to render")]
13: [DefaultValue("")]
14: public String Markup
15: {
16: get;
17: set;
18: }
19:
20: protected override void CreateChildControls()
21: {
22: if (String.IsNullOrWhiteSpace(this.Markup) == false)
23: {
24: if (SPContext.Current.FormContext.FormMode == SPControlMode.Edit)
25: {
26: var edition = String.Empty;
27:
28: if (this.WebPartManager.SelectedWebPart == this)
29: {
30: edition = String.Concat(" contenteditable=\"true\" oninput=\"document.querySelector('input[id$=\\'", this.ID, "_ctl03_Markup_EDITOR\\']').value = this.innerHTML.replace(/</g, '<').replace(/>/g, '>')\"");
31: }
32:
33: this.Controls.Add(new LiteralControl(String.Concat("<div style=\"border: dashed 1px; width: 500px; height: 300px; overflow: auto;\"", edition, ">", this.Markup.Replace("<", "<").Replace(">", ">"), "</div>")));
34: }
35: else
36: {
37: var control = null as Control;
38:
39: try
40: {
41: control = this.Page.ParseControl(this.Markup.Replace("<", "<").Replace(">", ">"), true);
42: }
43: catch (Exception ex)
44: {
45: control = new LiteralControl(String.Concat(ex.GetType().Name, ": ", ex.Message, "<br/>", ex.StackTrace));
46: }
47:
48: if (control != null)
49: {
50: control.ID = "content";
51: this.Controls.Add(control);
52: }
53: }
54: }
55: }
It will detect if you are in edit mode and display the markup contents as HTML instead of actually rendering the controls. Also, if the web part is being edited, it will allow you to change the markup inline and will persist the edition. If there is an exception, due to invalid markup code, it will instead display the exception message and stack trace.
The magic happens in the ParseControl method, which takes a string containing markup and translates it into server-side controls (HTML is also translated, mind you). It implements INamingContainer to prevent control ID clashes. If you wish, you can register your own registrations, for example, the following is valid markup:
1: <my:MarkupWebPart runat="server" Markup="<%@ register assembly="My.Assembly" namespace="My.Namespace" tagPrefix="my" %><my:MyControl runat="server" />"/>
Translated markup:
1: <%@ register assembly="My.Assembly" namespace="My.Namespace" tagPrefix="my" %>
2: <my:MyControl runat="server"/>
Of course, it is better to use the built-in property editor or the inline version:
And the result:
As always, hope you find this useful!