HXH
HXH
Apr 30, 2012
visibility 4533
star star star star star
(0 votes)

EPiServer Workflow Replacement : Step 5–Bye bye, Save and Publish!

This is the fifth in a series of posts about how my company built a replacement workflow platform for EPiServer. Why we chose to do this is explained here: http://world.episerver.com/Blogs/Hans/Dates/2012/4/EPiServer-Workflow-Replacement--Step-1Explanation-and-Disabling-Edit-Tab/

I hate the Save and Publish button. This disdain essentially boils down to two issues:

  1. Humans are fallible creatures, so assuming that a page is ready to go live without actually looking at it is just asking yourself for trouble.
  2. A lot of companies use EPiServer in single instance production environments. We don’t ..but a lot do. Do you really want people to update content live on the web without looking at it?

That said, I do use Save and Publish in Development..and I get why it’s there…. I just wish there was a way to get rid of it through the application itself.

For our team, Save and Publish had to go.

  1. In CMS6, navigate to : C:\Program Files\EPiServer\CMS\6.1.379.0\Application\UI\CMS\Edit\EditPageButtonControl.ascx - if installed on 64 bit it will usually be “Program Files (x86)” instead
  2. In CMS5, navigate to C:\Program Files\EPiServer\CMS\5.2.375.7\Application\UI\Edit\EditPageButtonControl.ascx  - again, append (x86) if on a 64 bit operating system
  3. In the SaveAndPublish EPiServer UI ToolButton, change RequiredAccess to “Administer” – this prevents people with publish access from accessing the SaveAndPublish button
  4. Add RequiredAccess=”Administer” to the Publish EPiServerUI:ToolButton as well. This forces people to go to the “Workflow” tab to publish pages.

 

Here is how our CMS 6 EditPageButtonControl.ascx looks:

 

<%@ Control Language="C#" AutoEventWireup="false" CodeBehind="EditPageButtonControl.ascx.cs" Inherits="EPiServer.UI.Edit.EditPageButtonControl" %>
<asp:Panel ID="ButtonPanel" runat="server" CssClass="epitoolbararea epi-toolbarOnPage" Visible="true">
    <EPiServerUI:ToolButtonContainer runat="server">
        <EPiServerUI:ToolButton id="SaveOnly" OnClick="SaveOnly_Click" DisablePageLeaveCheck="true" SkinID="Save" text="<%$ Resources: EPiServer, button.saveonly %>" ToolTip="<%$ Resources: EPiServer, edit.editpanel.tooltipsaveonly %>" runat="server" />    
        <EPiServerUI:ToolButton id="SaveButton" OnClick="Save_Click" DisablePageLeaveCheck="true" SkinID="SaveShow" text="<%$ Resources: EPiServer, button.saveandview %>" ToolTip="<%$ Resources: EPiServer, edit.editpanel.tooltipsave %>" runat="server" />    
        <EPiServerUI:ToolButton id="SaveAndPublish" OnClick="Publish_Click" DisablePageLeaveCheck="true" SkinID="SavePublish" RequiredAccess="Administer" text="<%$ Resources: EPiServer, button.saveandpublish %>" ToolTip="<%$ Resources: EPiServer, edit.editpanel.tooltipapprove %>" runat="server" />
    </EPiServerUI:ToolButtonContainer>
    
    <EPiServerUI:ToolButtonContainer runat="server" CssClass="epitoolbuttoncontainernoborder">
        <EPiServerUI:ToolButton id="Publish" DisablePageLeaveCheck="true" OnClick="Publish_Click" SkinID="Publish" RequiredAccess="Administer" text="<%$ Resources: EPiServer, button.publish %>" ToolTip="<%$ Resources: EPiServer, button.publish %>" runat="server" />
        <EPiServerUI:ToolButton id="CheckIn" DisablePageLeaveCheck="true" OnClick="CheckIn_Click" SkinID="CheckIn" text="<%$ Resources: EPiServer, button.checkin %>" ToolTip="<%$ Resources: EPiServer, button.checkin %>" runat="server" />
    </EPiServerUI:ToolButtonContainer>
    <EPiServerUI:ToolButtonContainer runat="server" CssClass="epitoolbuttoncontainernoborder">
        <EPiServerUI:ToolButton id="Cancel" OnClick="Cancel_Click" SkinID="Cancel" DisablePageLeaveCheck="true" text="<%$ Resources: EPiServer, button.cancel %>" ToolTip="<%$ Resources: EPiServer, edit.editpanel.tooltipcancel %>" runat="server" />        
    </EPiServerUI:ToolButtonContainer>
    
    <EPiServerUI:ToolButtonContainer runat="server" CssClass="epitoolbuttoncontainernoborder epitoolbuttoncontainerright">
        <EPiServerUI:ToolButton id="StickyEdit" OnClick="StickyEdit_Click" OnClientClick="EPi.ToolTip.Hide();EPi.PreventDoubleClick(this);" SkinID="StickyEditOff" DisablePageLeaveCheck="true" text=" " RichToolTip="<%$ Resources: EPiServer, edit.editpanel.tooltipstickyedit %>" runat="server" />
        <EPiServerUI:ToolButton id="UnStickyEdit" OnClick="UnStickyEdit_Click" OnClientClick="EPi.ToolTip.Hide();EPi.PreventDoubleClick(this);" SkinID="StickyEditOn" DisablePageLeaveCheck="true" text=" " RichToolTip="<%$ Resources: EPiServer, edit.editpanel.tooltipunstickyedit %>" runat="server" />
    </EPiServerUI:ToolButtonContainer>
    
</asp:Panel>

...and now when anyone who isn’t an Administrator (basically everyone – we only grant Admin access to a very select few) goes to a page, they see the grayed out view seen below and are therefore forced to use our Workflow process.

image

 

In the next post, I will discuss how we hook the Ready to Publish action in order to send approval notifications when that button is pressed.

Apr 30, 2012

Comments

error Please login to comment.
Latest blogs
Add more scheduled job settings from the Optimizely CMS 12 admin UI -- with OptiScheduledJob.ExtraParameters

  Optimizely (EPiServer) CMS 12 ships a great scheduled-jobs framework, but it has one frustrating gap: a job has nowhere to store its own...

Binh Nguyen Thi | Jun 25, 2026

Automated Search & Navigation to Graph Migration with Claude Code

A Claude Code plugin that scans your S&N codebase, applies Graph SDK transformations, and validates the result. Install once, run one command. CMS ...

Connor Fortin | Jun 24, 2026

Migrating from Find to Graph: Lessons Learned from a Real CMS 13 Project

While migrating a search solution from Optimizely Search & Navigation (Find) to Optimizely Graph in CMS 13, I encountered several issues that were...

Binh Nguyen Thi | Jun 24, 2026

Optimizely: Upgrade Opti-ID and .NET 10 in CMS 12

Many Optimizely customers are planning their roadmap around a future migration to Optimizely CMS 13. As a result, upgrades such as Opti ID adoption...

Madhu | Jun 23, 2026 |

Understanding Optimizely Graph: Caching, Webhooks & Avoiding Stale Content (Optimizely SaaS CMS)

📌 Scope: This post covers Optimizely CMS (SaaS) only — using the official @optimizely/cms-sdk and @optimizely/cms-cli packages with Next.js 15. If...

Kiran Patil | Jun 23, 2026 |

Optimizely Content APIs: the Setup the Docs Don't Walk You Through

CMS 13 is pushing things firmly in the direction of Optimizely Graph, but plenty of teams are still running on older CMS versions, or have good...

Andre | Jun 22, 2026