Skip to content

Instantly share code, notes, and snippets.

@hishaamn
Created September 19, 2025 12:06
Show Gist options
  • Select an option

  • Save hishaamn/1f2daab4559066c6a62d49a3e72c6d74 to your computer and use it in GitHub Desktop.

Select an option

Save hishaamn/1f2daab4559066c6a62d49a3e72c6d74 to your computer and use it in GitHub Desktop.
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Shell.Applications.ContentEditor.Pipelines.RenderContentEditor;
using Sitecore.Shell.Framework.CommandBuilders;
using Sitecore.Shell.Framework.Commands.TemplateBuilder;
using Sitecore.Shell.Web.UI.WebControls;
using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
namespace SCXM.Panels.Pipelines.RenderContentEditor
{
public class SlidePanelInjector
{
private static readonly ID ParentItemId = new ID("{2CE1C92E-2338-4C6A-AE86-A742A32A0A6F}");
public void Process(RenderContentEditorArgs args)
{
Assert.ArgumentNotNull(args, nameof(args));
var coreDb = Factory.GetDatabase("core");
var parent = coreDb?.GetItem(ParentItemId);
var commandsBuilder = new StringBuilder();
if (parent != null && parent.HasChildren)
{
foreach (Item child in parent.Children)
{
this.RenderControl(child, commandsBuilder);
}
}
else
{
commandsBuilder.AppendLine("<p style = 'margin:10px;' > No commands found in Core DB parent folder.</ p > ");
}
// style + script + panel markup
var injectDoc = $@"
<style>
#scxmPanel {{position: fixed;
top: 60px;
right: -300px;
width: 300px;
height: calc(100% - 60px);
background: #fff;
box-shadow: -2px 0 5px rgba(0,0,0,0.2);
transition: right 0.3s ease;
z-index: 9998;
}}
#scxmPanel.open {{right: 0; }}
#openPanel {{position: fixed;
bottom: 4px;
right: 12px;
z-index: 9999;
background: #fff;
border-radius: 4px;
border: 1px solid #ccc;
padding: 3px 6px;
cursor: pointer;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
font-size: 10px;
}}
.panel-command-fallback button {{
background: #f7f7f7;
border: 1px solid #e1e1e1;
border-radius: 3px;
}}
.scxm-overlay-largebutton .scRibbonToolbarLargeButton {{
display:block;
width:100% !important;
}}
</style>
<div id='scxmPanel' aria-hidden='true'>
<h3 style='margin:6px 0 12px 0;'>Quick Shortcuts</h3>
<div id='scxmPanelCommands'>
{commandsBuilder}
</div>
</div>
<div id='openPanel' title='Open panel' role='button' aria-pressed='false'>☰</div>
<script>
window.toggleOverlayPanel = function() {{
var panel = document.getElementById('scxmPanel');
if (!panel) return;
var isOpen = panel.classList.toggle('open');
}};
(function(){{
var btn = document.getElementById('openPanel');
if (btn) {{
btn.addEventListener('click', function() {{
window.toggleOverlayPanel();
}});
}}
}})();
</script>
";
args.EditorFormatter.AddLiteralControl(args.Parent, injectDoc);
}
private void RenderControl(Item child, StringBuilder commandsBuilder)
{
var header = child["Header"];
if (string.IsNullOrEmpty(header)) header = child.DisplayName;
var icon = child["Icon"] ?? child["__Icon"];
var click = child["Click"];
commandsBuilder.AppendLine("<div style='margin:6px 0;'>");
try
{
var largeButton = new LargeButton
{
ID = "lb_" + child.ID.ToShortID(),
Header = header,
Icon = icon ?? string.Empty,
Command = click ?? string.Empty,
BorderWidth = 100,
CssClass = "scxm-overlay-largebutton"
};
using (var sw = new StringWriter())
using (var htw = new HtmlTextWriter(sw))
{
largeButton.RenderControl(htw);
commandsBuilder.AppendLine(sw.ToString());
}
}
catch (Exception ex)
{
Log.Warn($"SlidePanelInjector: Failed to render LargeButton for item {child.Paths.FullPath}. Falling back to HTML button.", ex, this);
var safeClick = string.IsNullOrEmpty(click)
? ""
: $"javascript:scForm.postEvent(this,event,'{HttpUtility.JavaScriptStringEncode(click)}')";
commandsBuilder.AppendLine($@"
<div class='panel-command-fallback' style='margin:6px 0;'>
<button style='width:100%;padding:8px;text-align:left;' onclick=""{safeClick}"">
{(string.IsNullOrEmpty(icon) ? "" : $"<img src='/sitecore/shell/themes/standard/{icon}' style='width:16px;height:16px;margin-right:8px;vertical-align:middle;' />")}
<span style='vertical-align:middle;'>{System.Web.HttpUtility.HtmlEncode(header)}</span>
</button>
</div>");
}
commandsBuilder.AppendLine("</div>");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment