HXH
HXH
Apr 30, 2012
  4501
(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

Please login to comment.
Latest blogs
Optimizely Opal: How to Build Effective Workflow Agents

If you're building workflow agents in Optimizely Opal, this post covers how specialized agents pass context to each other, why keeping agents small...

Andre | May 20, 2026

ReviewPR: An Azure Function That Reviews Your Azure DevOps Pull Requests With Claude

A while back I wrote about an  Azure Function App for PDF creation that we use to offload PDF rendering from our Optimizely DXP site. That same...

KennyG | May 19, 2026

Accelerating Optimizely CMS and Commerce upgrades with agentic AI (Part 2 of 2)

The Real Transformation in Optimizely CMS 13: Why the Upgrade Itself Is the Easy Part. A field-tested playbook for enterprise teams moving from...

Hung Le Hoang | May 18, 2026

Is the most powerful AI model really the best value?

Artificial Intelligence is already becoming part of everyday software development. Developers now use AI tools to generate code, write documentatio...

K Khan | May 16, 2026

Optimizely London Dev Meetup 2026

Well, everyone, it's that time of the year again, and we have another London Developer meet up coming for this summer. The date is set for the 2nd ...

Scott Reed | May 15, 2026

Semantic Search - Deep Dive

Deep dive into semantic search with Optimizely Graph

Michał Mitas | May 14, 2026 |