6

We have a case where we need to notify approvers when a page is sent for approval.

In the notification email, I want to include a link so that the approvers can go directly to the page in the Sitecore Experience Editor (version 8.1-Update 1). If they are not logged in, they should naturally get the login form and then be redirect the the requested page.

We have done something similar before with the Content Editor using a URL on the format:
{cmsHost}/sitecore/shell/Applications/Content%20Editor.aspx?id={itemID}&fo={itemID}&la={itemLanguage}

If the user is not logged in, they are redirected to /sitecore/login with a returnUrl parameter that points to my link. After logging in, the user is automatically redirected to the correct page in the Content Editor.

For the Experience Editor, I tried to use the URL format:
{cmsHost}/?sc_itemid={itemID}&sc_lang={itemLanguage}&sc_version={itemVersion}&sc_mode={mode}

This works fine when the user is logged in, but when the user is not logged in, the request is simply redirected to /sitecore/login without the returnUrl parameter.

After some digging it looks like the returnUrl is added specifically in the Content Editor code (and a few other applications), but there is no such logic in the Experience Editor.

I did find a configuration setting called Authentication.SaveRawUrl that felt promising:

Specifies whether the original request URL is passed to the login page (saved in 'url' query string parameter).

Setting this to true did indeed add a url parameter when Sitecore redirects the user to the login page. However, there are a few issues:

  • There is no built-in support for actually redirecting the user after logging in (like for the returnUrl parameter).
  • Linking to the Content Editor will redirect to the login form with both the returnUrl and the url parameters.
  • The url is also encoded twice for some reason (I'm guessing this is a bug?).

I can see a few different possible work-arounds, but non is very appealing:

  • Write another processor for redirecting after login (using the url parameter)
  • Patching or rewriting the SaveRawUrl functionality to set the returnUrl
  • Linking to a custom handler that checks if the user is logged in and redirects accordingly

Quite frankly this feels like a fairly standard feature that should work uniformly out-of-the-box?

Is there a preferred way of doing this sort of external deep links to the Experience Editor?

2 Answers 2

10

Instead of linking to an item with an id parameter, instead link to the full item URL with sc_mode=edit parameter set, e.g.

{cmsHost}/path/to/item-page?sc_lang={itemLanguage}&sc_version={itemVersion}&sc_mode=edit

The user will be redirected to the login page with the correct returnUrl parameter and then correctly redirected back to the item in Experience Editor mode after successfully logging in.

0
0

If you need some special handling on where to go after signing in you can always inject the pipeline getStartUrl.

Configuration patch

    <?xml version="1.0"?>
    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
      <sitecore>
        <pipelines role:require="Standalone or ContentManagement">
          <getStartUrl>
            <processor patch:before="*[@type='Sitecore.Pipelines.GetStartUrl.GetStartUrlFromQueryString, Sitecore.Kernel']"
                       type="OurCustomPackage.Pipelines.GetStartUrlFromCustomCode, OurCustomPackage" />
          </getStartUrl>
        </pipelines>
      </sitecore>
    </configuration>

Class to do the redirection. In our case get a cookie with a path use in editor mode

using System;
using System.Web;
using Sitecore.Diagnostics;
using Sitecore.Pipelines.GetStartUrl;
using Sitecore.StringExtensions;
using Sitecore.Web;

namespace OurCustomPackage.Pipelines
{
    /// <summary>
    /// Redirect user to a suitable page after logging in
    /// </summary>
    public class GetStartUrlFromCustomCode : Sitecore.Pipelines.GetStartUrl.GetStartUrlProcessor
    {
        public GetStartUrlFromCustomCode()
        {
        }

        public override void Process(GetStartUrlArgs args)
        {
            try // try/catch around it all to avoid not being able to log in!
            {
                string value = WebUtil.GetCookieValue(Constants.StartUrlCookie);
                if (!value.IsNullOrEmpty() && value.StartsWith("/"))
                {
                    // Select edit mode
                    value += value.Contains("?") ? "&" : "?";
                    value += "sc_mode=edit";
                    // Build a complete uri
                    string uri = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + value;
                    // Note: If port ever becomes a problem use Request.Url.Authority instead of Request.Url.Host

                    args.Result = new Uri(uri);
                }
            } catch (Exception e)
            {
                Log.Error("While trying to redirect user to the correct page", e, this);
            }
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.