22 Comments

  1. OriginalEXE

    It works great, nice idea, my thanks to the author, I imagine this will save me quite some time.

    Report

  2. Dr. J

    Hope they release it for Firefox as well!

    Report

  3. Joan

    Oh, nice little extension, I love it! Thanks so much, Kellen! :)

    Report

  4. Jason Lemieux

    Super cool and nicely done. Thanks, Kellan!

    Report

  5. Mickey Kay

    For those interested in this type of keyboard shortcut timesavers, I definitely recommend checking out Vimium, which provides a TON of useful shortcuts that can be used in tandem with any web app, including WP.

    Report

  6. AdelDima

    It not working with multi website or if you install wordpress in folder : if you have example.com/blog/ it will go back into example.com/wp-admin/.
    I hope they fix it , It’s a great idea.

    Report

    • Kellen Mace

      Hey AdelDima,

      This extension does work for subdirectory multisite installations and when WP is installed in a folder as long as it can tell that that’s the WP root directory. When you hit the keyboard shortcut, it works like this:

      1. Check if the links in the admin bar at the top are present (which are only there when logged in). If so, use those to switch to/from the admin.
      2. If not, search the links in the page source for instances of ‘/wp-content/’ or ‘/wp-includes/’. If at least one URL is found that contains either of those, assume that everything to the left of it is the WP root url, and use that the build the admin URL. So if your site’s URL is example.com/folder/ and you hit the shortcut, you’ll be prompted to login, then redirected to example.com/folder/wp-admin as long as at least one URL on the page contained ‘/wp-content/’ or ‘/wp-includes/’.

      So one example would be an HTML script tag that contains this: src=’http://example.com/folder/wp-includes/js/jquery/jquery.js?ver=1.12.4′

      Until you’re logged in, that’s the only way the extension can tell that the WP install is inside of a folder.

      I hope that helps out. I’m glad you like the idea of the extension :)

      Report

  7. Ahmad Awais

    Awesome Sauce! Loved it!

    Can you also add option to define custom admin urls? E.g. if my admin URI is /login instead of /wp-admin. This extension fails in that scenario!

    Report

    • Kellen Mace

      Ahmad,

      Using custom admin URLs is a bit of an edge case and would require adding more complexity in the form of a settings page where users could enter domains and their corresponding login paths, then checking against those every time a login or admin switch is taking place. Since I’m trying to keep the extension simple and lightweight, I don’t have plans to add that feature at the present.

      However, since it’s open source, you or anyone else can feel free to fork the original and add any custom settings you like – https://github.com/kellenmace/wp-admin-switcher/

      Glad you’re finding it useful! ?

      Report

  8. Luke Cavanagh

    Great idea!

    Report

  9. Thierry Pigot

    I have this functionalities with bookmarks since 2005!

    https://gist.github.com/thierrypigot/3e4e3983739a2dc3a2de1a7062f53d1f

    Report

    • Kellen Mace

      Thierry,

      That’ll do the trick if you’re just interested in switching to the WP admin, but this extension has these additional features:

      1. Switch from the admin back to the front end (to the specific post/page/CPT you were editing, if applicable).
      2. Supports subdirectory multisite installs and WP installs inside of a folder, such as example.com/site-name/wp-admin/.
      3. Sends you to the edit screen for the post/page/CPT you were viewing before you logged in/switched to the admin.
      4. Works via a keyboard shortcut or a click on the extension icon.

      To get all of those features (except #4) in a bookmark, you can use the code below. I think this may be especially handy on mobile devices where users don’t have the option to install Chrome extensions.

      Bookmark code (obfuscated & minified):

      javascript:function b(a){if(Object!=a.constructor||1>Object.keys(a).length)return!1;for(var M in a){var w=document.querySelectorAll(a[M]+" > a.ab-item[href]");if(0<w.length)return w[0].getAttribute("href")}return!1}function c(a){a.endsWith("/")||(a+="/");return a}var d=window.location.pathname;
      if(1<d.indexOf("/wp-admin/")||1<d.indexOf("/wp-login.php")){var e;var f=b({view:"#wp-admin-bar-view",f:"#wp-admin-bar-preview",a:"#wp-admin-bar-site-name"});if(f)e=f;else{b:{var g={j:"/wp-admin/",o:"/wp-login.php"},h;for(h in g){var k=window.location.href.indexOf(g[h]);if(1<k){f=window.location.href.substring(0,k);break b}}f=!1}e=f?f:window.location.origin}window.location=e}else{var l;var m=b({c:"#wp-admin-bar-edit",a:"#wp-admin-bar-site-name"});if(m)l=m;else{var n;c:{var p={i:'link[rel="stylesheet"][href]',
      scripts:"script[src]",g:'link[type="application/rss+xml"][href]',s:'link[rel="pingback"][href]'},q;for(q in p){var r=document.querySelectorAll(p[q]);if(0<r.length)for(var t in r){var u;d:switch(q){case "scripts":u="src";break d;default:u="href"}var v;d:{var x={l:"/wp-content/",m:"/wp-includes/"},y=void 0;for(y in x){var z,A=r[t],B=A[u].indexOf(x[y]);if(z=1<B?A[u].substring(0,B):!1){v=z;break d}}v=!1}if(v){n=v;break c}}}n=!1}var C,D=!1,E={b:"#comment_post_ID[value]",h:'link[rel="shortlink"][href]',
      body:"body[class]"},F;for(F in E){var G=document.querySelectorAll(E[F]);if(0<G.length)switch(F){case "commentsForm":D=G[0].value;break;case "shortlink":c:{var H=G[0].getAttribute("href");if(!(1<H.indexOf("//wp.me/"))){var I=H.indexOf("/?p=");if(1<I){D=H.substring(I+4,H.length);break c}}D=!1}break;case "body":var J=G[0].getAttribute("class"),K=J.indexOf("postid-");if(1<K)var J=J.substring(K+7,J.length),L=J.indexOf(" "),D=1<L?J.substring(0,L):J;else D=!1}}C=D;if(n){var N=c(n)+"wp-admin/";C&&(N=
      N+"post.php?post="+C+"&action=edit");m=N}else m=!1;l=m?m:c(window.location.origin)+"wp-admin/"}window.location=l};

      Full bookmark source code:

      var WordPressAdminSwitcherBookmark = {};
      /**
      * Switch to/from the WordPress Admin.
      */
      WordPressAdminSwitcherBookmark.toggleAdmin = function() {
      if ( WordPressAdminSwitcherBookmark.isWordPressAdmin( window.location.pathname ) ) {
      WordPressAdminSwitcherBookmark.switchToFrontEnd();
      } else {
      WordPressAdminSwitcherBookmark.switchToAdmin();
      }
      };
      /**
      * Is this the WordPress admin?
      *
      * @param {string} url The URL to check.
      * @return {boolean} Whether currently in the WordPress admin.
      */
      WordPressAdminSwitcherBookmark.isWordPressAdmin = function( url ) {
      return ( url.indexOf( '/wp-admin/' ) > 1 ) || ( url.indexOf( '/wp-login.php' ) > 1 );
      };
      /**
      * Switch to the front end.
      */
      WordPressAdminSwitcherBookmark.switchToFrontEnd = function() {
      WordPressAdminSwitcherBookmark.changeWindowLocation( WordPressAdminSwitcherBookmark.getFrontEndUrl() );
      };
      /**
      * Switch to the WP admin.
      */
      WordPressAdminSwitcherBookmark.switchToAdmin = function() {
      WordPressAdminSwitcherBookmark.changeWindowLocation( WordPressAdminSwitcherBookmark.getAdminUrl() );
      };
      /**
      * Get frontend URL.
      *
      * @return {string} The frontend URL.
      */
      WordPressAdminSwitcherBookmark.getFrontEndUrl = function() {
      var url = WordPressAdminSwitcherBookmark.getFrontEndUrlFromAdminBar();
      if ( url ) {
      return url;
      }
      url = WordPressAdminSwitcherBookmark.getFrontEndUrlFromWindowLocation();
      if ( url ) {
      return url;
      }
      // Return WordPressAdminSwitcherBookmark.as a last resort. Has the potential to
      // be incorrect on subdirectory multisite installs.
      return window.location.origin;
      };
      /**
      * Get front end URL from admin bar.
      *
      * Try to get the link to view/preview the post first,
      * then fallback to getting the main front end url.
      *
      * @return {string|boolean} The url or false on failure.
      */
      WordPressAdminSwitcherBookmark.getFrontEndUrlFromAdminBar = function() {
      var adminBarIds = {
      view: '#wp-admin-bar-view',
      preview: '#wp-admin-bar-preview',
      siteName: '#wp-admin-bar-site-name'
      };
      return WordPressAdminSwitcherBookmark.getUrlFromAdminBar( adminBarIds );
      };
      /**
      * Get front end URL from window.location.
      *
      * @return {string|boolean} The url or false on failure.
      */
      WordPressAdminSwitcherBookmark.getFrontEndUrlFromWindowLocation = function() {
      var adminUrlParts = {
      wpAdmin: '/wp-admin/',
      wpLogin: '/wp-login.php'
      };
      for ( var index in adminUrlParts ) {
      var adminUrlPartPosition = WordPressAdminSwitcherBookmark.getPositionOfStringInCurrentUrl( adminUrlParts[ index ] );
      if ( WordPressAdminSwitcherBookmark.doesUrlContainString( adminUrlPartPosition ) ) {
      return WordPressAdminSwitcherBookmark.getPartOfUrlBeforePosition( adminUrlPartPosition );
      }
      }
      return false;
      };
      /**
      * Get the position of a string in the current URL.
      *
      * @param {string} string The string to find within the URL.
      * @return {number} The position of string within the URL.
      */
      WordPressAdminSwitcherBookmark.getPositionOfStringInCurrentUrl = function( string ) {
      return window.location.href.indexOf( string );
      };
      /**
      * Does the URL contain a string?
      *
      * @param {number} stringPosition The position of string within the URL.
      * @return {boolean} Whether the URL contains the string.
      */
      WordPressAdminSwitcherBookmark.doesUrlContainString = function( stringPosition ) {
      return WordPressAdminSwitcherBookmark.doesStringContainSubstring( stringPosition );
      };
      /**
      * Does string contain a substring?
      *
      * @param {number} stringPosition The position of substring within the string.
      * @return {boolean} Whether the substring was found within the string.
      */
      WordPressAdminSwitcherBookmark.doesStringContainSubstring = function( stringPosition ) {
      return stringPosition > 1;
      };
      /**
      * Get part of URL before the provided position.
      *
      * @param {number} stringPosition Exclude the character at WordPressAdminSwitcherBookmark.position and following.
      * @return {string} The part of the URL before stringPosition.
      */
      WordPressAdminSwitcherBookmark.getPartOfUrlBeforePosition = function( stringPosition ) {
      return window.location.href.substring( 0, stringPosition );
      };
      /**
      * Get the admin URL.
      *
      * @return {string} The admin URL.
      */
      WordPressAdminSwitcherBookmark.getAdminUrl = function() {
      var url = WordPressAdminSwitcherBookmark.getAdminUrlFromAdminBar();
      if ( url ) {
      return url;
      }
      url = WordPressAdminSwitcherBookmark.getAdminUrlFromPageSource();
      if ( url ) {
      return url;
      }
      // Return WordPressAdminSwitcherBookmark.as a last resort. Has the potential to
      // be incorrect on subdirectory multisite installs.
      return WordPressAdminSwitcherBookmark.trailingSlashIt( window.location.origin ) + 'wp-admin/';
      };
      /**
      * Get admin URL from page source.
      *
      * @return {string|boolean} The admin URL or false on failure.
      */
      WordPressAdminSwitcherBookmark.getAdminUrlFromPageSource = function() {
      var url = WordPressAdminSwitcherBookmark.inferUrlFromPageLinks(),
      postId = WordPressAdminSwitcherBookmark.inferPostIdFromPageSource();
      if ( url ) {
      var adminUrl = WordPressAdminSwitcherBookmark.getAdminUrlFromSiteUrl( url );
      if ( postId ) {
      adminUrl = WordPressAdminSwitcherBookmark.getPostSpecificAdminUrl( adminUrl, postId );
      }
      return adminUrl;
      }
      return false;
      };
      /**
      * Turn site URL into admin URL.
      *
      * @param {string} url The site URL.
      * @return {string} The admin URL.
      */
      WordPressAdminSwitcherBookmark.getAdminUrlFromSiteUrl = function( url ) {
      return WordPressAdminSwitcherBookmark.trailingSlashIt( url ) + 'wp-admin/';
      };
      /**
      * Turn base admin URL into a post-specific admin URL.
      *
      * @param {string} adminUrl The base admin URL.
      * @param {string} postId The post ID.
      * @return {string} The post-specific admin URL.
      */
      WordPressAdminSwitcherBookmark.getPostSpecificAdminUrl = function( adminUrl, postId ) {
      return adminUrl + 'post.php?post=' + postId + '&action=edit';
      };
      /**
      * Get WP admin URL from the admin bar.
      *
      * @return {string|boolean} The URL or false on failure.
      */
      WordPressAdminSwitcherBookmark.getAdminUrlFromAdminBar = function() {
      var adminBarIds = {
      edit: '#wp-admin-bar-edit',
      siteName: '#wp-admin-bar-site-name'
      };
      return WordPressAdminSwitcherBookmark.getUrlFromAdminBar( adminBarIds );
      };
      /**
      * Get URL from the WP admin bar.
      *
      * @param {Object} adminBarIds The element IDs to use as selectors.
      * @return {string|boolean} The URL or false on failure.
      */
      WordPressAdminSwitcherBookmark.getUrlFromAdminBar = function ( adminBarIds ) {
      if ( WordPressAdminSwitcherBookmark.isEmptyObject( adminBarIds ) ) {
      return false;
      }
      for ( var key in adminBarIds ) {
      var adminBarAnchorHtmlElement = WordPressAdminSwitcherBookmark.getAdminBarAnchorHtmlElement( adminBarIds[ key ] );
      if ( WordPressAdminSwitcherBookmark.wereHtmlElementsFound( adminBarAnchorHtmlElement ) ) {
      return WordPressAdminSwitcherBookmark.getHrefUrlFromHtmlElement( adminBarAnchorHtmlElement );
      }
      }
      return false;
      };
      /**
      * Is WordPressAdminSwitcherBookmark.an empty object?
      *
      * @param {Object} object The object to check.
      * @return {boolean} Whether the object is empty.
      */
      WordPressAdminSwitcherBookmark.isEmptyObject = function( object ) {
      return ( Object != object.constructor ) || ( Object.keys( object ).length < 1 );
      };
      /**
      * Get admin bar anchor HTML element.
      *
      * @param {string} adminBarId The id of the HTML element to get.
      * @return {Object} The matching HTML element NodeList.
      */
      WordPressAdminSwitcherBookmark.getAdminBarAnchorHtmlElement = function( adminBarId ) {
      return document.querySelectorAll( adminBarId + ' > a.ab-item[href]' );
      };
      /**
      * Here any HTML elements found?
      *
      * @param {Object} nodelist The NodeList of HTML elements found.
      * @return {boolean} Whether HTML elements were found.
      */
      WordPressAdminSwitcherBookmark.wereHtmlElementsFound = function( nodelist ) {
      return nodelist.length > 0;
      };
      /**
      * Get the URL from an HTML element's href property.
      *
      * @param {Object} element The HTML element NodeList.
      * @return {string} The URL.
      */
      WordPressAdminSwitcherBookmark.getHrefUrlFromHtmlElement = function( element ) {
      return element[0].getAttribute( 'href' );
      };
      /**
      * Infer the site's URL from links in the page source.
      *
      * We can't simply get the site's URL from window.location
      * because subdomain multisite installs need to have the
      * /site-name/ part of the pathname preserved.
      *
      * @return {string|boolean} The URL or false on failure.
      */
      WordPressAdminSwitcherBookmark.inferUrlFromPageLinks = function() {
      var selectors = {
      stylesheets: 'link[rel="stylesheet"][href]',
      scripts: 'script[src]',
      rss: 'link[type="application/rss+xml"][href]',
      xmlrpc: 'link[rel="pingback"][href]'
      };
      for ( var selectorIndex in selectors ) {
      var elements = document.querySelectorAll( selectors[ selectorIndex ] );
      if ( WordPressAdminSwitcherBookmark.wereHtmlElementsFound( elements ) ) {
      for ( var elementIndex in elements ) {
      var attribute = WordPressAdminSwitcherBookmark.getAttributeForSelector( selectorIndex ),
      url = WordPressAdminSwitcherBookmark.inferUrlFromPageLink( elements[ elementIndex ], attribute );
      if ( url ) {
      return url;
      }
      }
      }
      }
      return false;
      };
      /**
      * Extract the URL from an HTML element.
      *
      * @param {Object} element The HTML element
      * @param {string} attribute The attribute to get the URL from: 'href' or 'src'.
      * @return {string|boolean} The URL or false on failure.
      */
      WordPressAdminSwitcherBookmark.inferUrlFromPageLink = function( element, attribute ) {
      var paths = {
      wpContent: '/wp-content/',
      wpIncludes: '/wp-includes/'
      };
      for ( var index in paths ) {
      var url = WordPressAdminSwitcherBookmark.getUrlSubstringFromHtmlElement( element, attribute, paths[ index ] );
      if ( url ) {
      return url;
      }
      }
      return false;
      };
      /**
      * Get the URL-containing attribute for a selector type.
      *
      * @param {string} selector The selector type.
      * @return {string} The attribute for contains the URL.
      */
      WordPressAdminSwitcherBookmark.getAttributeForSelector = function( selector ) {
      switch ( selector ) {
      case 'scripts':
      return 'src';
      default:
      return 'href';
      }
      };
      /**
      * Extract part of a URL from an HTML element.
      *
      * @param {Object} element The HTML element.
      * @param {string} attribute The attribute to get URL from ('href' or 'src').
      * @param {string} string The text to search for and exclude, along with
      * everything after it.
      * @return {string|boolean} The part of the URL or false on failure.
      */
      WordPressAdminSwitcherBookmark.getUrlSubstringFromHtmlElement = function( element, attribute, string ) {
      var stringPosition = element[ attribute ].indexOf( string );
      if ( WordPressAdminSwitcherBookmark.doesUrlContainString( stringPosition ) ) {
      return element[ attribute ].substring( 0, stringPosition );
      }
      return false;
      };
      /**
      * Infer post ID from the page source.
      *
      * Not all WordPress sites will have WordPressAdminSwitcherBookmark.exposed.
      *
      * @return {string|boolean} The post ID or false on failure.
      */
      WordPressAdminSwitcherBookmark.inferPostIdFromPageSource = function() {
      var postId = false,
      postIdSelectors = {
      commentsForm: '#comment_post_ID[value]',
      shortlink: 'link[rel="shortlink"][href]',
      body: 'body[class]'
      };
      for ( var index in postIdSelectors ) {
      var postIdElement = document.querySelectorAll( postIdSelectors[ index ] );
      if ( ! WordPressAdminSwitcherBookmark.wereHtmlElementsFound( postIdElement ) ) {
      continue;
      }
      switch ( index ) {
      case 'commentsForm':
      postId = WordPressAdminSwitcherBookmark.getPostIdFromCommentsForm( postIdElement );
      break;
      case 'shortlink':
      postId = WordPressAdminSwitcherBookmark.getPostIdFromShortlink( postIdElement );
      break;
      case 'body':
      postId = WordPressAdminSwitcherBookmark.getPostIdFromBodyClass( postIdElement );
      }
      }
      return postId;
      };
      /**
      * Get post ID from comments form.
      *
      * @param {Object} postIdElement The HTML element NodeList containing the post ID.
      * @return {string} The post ID.
      */
      WordPressAdminSwitcherBookmark.getPostIdFromCommentsForm = function( postIdElement ) {
      return postIdElement[0].value;
      };
      /**
      * Get post ID from shortlink.
      *
      * @param {Object} postIdElement The HTML element NodeList containing the post ID.
      * @return {string|boolean} The post ID or false on failure.
      */
      WordPressAdminSwitcherBookmark.getPostIdFromShortlink = function( postIdElement ) {
      var shortlinkUrl = WordPressAdminSwitcherBookmark.getHrefUrlFromHtmlElement( postIdElement );
      if ( ! WordPressAdminSwitcherBookmark.isShortlinkUsingWpMeService( shortlinkUrl ) ) {
      var positionOfUrlTextBeforePostId = WordPressAdminSwitcherBookmark.getPositionOfUrlTextBeforePostId( shortlinkUrl );
      if ( WordPressAdminSwitcherBookmark.doesShortlinkUrlContainPostId( positionOfUrlTextBeforePostId ) ) {
      return WordPressAdminSwitcherBookmark.getPostIdFromShortlinkUrl( shortlinkUrl, positionOfUrlTextBeforePostId );
      }
      }
      return false;
      };
      /**
      * Is shortlink using wp.me service?
      *
      * @param {string} shortlinkUrl The shortlink URL.
      * @return {boolean} Whether shorlinkUrl is using wp.me.
      */
      WordPressAdminSwitcherBookmark.isShortlinkUsingWpMeService = function( shortlinkUrl ) {
      return shortlinkUrl.indexOf( '//wp.me/' ) > 1;
      };
      /**
      * Get the position of the URL before the post ID.
      *
      * @param {string} shortlinkUrl The URL to search.
      * @return {number} The position of the post ID.
      */
      WordPressAdminSwitcherBookmark.getPositionOfUrlTextBeforePostId = function( shortlinkUrl ) {
      return shortlinkUrl.indexOf( '/?p=' );
      };
      /**
      * Does the shortlink URL contain the post ID?
      *
      * @param {number} positionOfUrlTextBeforePostId The position of the URL text before the post ID.
      * @return {boolean} Whether the URL contains the post ID.
      */
      WordPressAdminSwitcherBookmark.doesShortlinkUrlContainPostId = function( positionOfUrlTextBeforePostId ) {
      return WordPressAdminSwitcherBookmark.doesStringContainSubstring( positionOfUrlTextBeforePostId );
      };
      /**
      * Extract the post ID from the shortlink URL.
      *
      * @param {string} shortlinkUrl The shortlink URL.
      * @param {number} positionOfUrlTextBeforePostId The position of URL text before the post ID.
      * @return {string} The post ID.
      */
      WordPressAdminSwitcherBookmark.getPostIdFromShortlinkUrl = function( shortlinkUrl, positionOfUrlTextBeforePostId ) {
      return shortlinkUrl.substring( positionOfUrlTextBeforePostId + 4, shortlinkUrl.length );
      };
      /**
      * Get post ID from body class.
      *
      * @param {Object} postIdElement The HTML element NodeList containing the post ID.
      * @return {string|boolean} The post ID or false on failure.
      */
      WordPressAdminSwitcherBookmark.getPostIdFromBodyClass = function( postIdElement ) {
      var bodyClasses = postIdElement[0].getAttribute( 'class' ),
      postIdPosition = bodyClasses.indexOf( 'postid-' );
      if ( WordPressAdminSwitcherBookmark.doesStringContainSubstring( postIdPosition ) ) {
      bodyClasses = bodyClasses.substring( postIdPosition + 7, bodyClasses.length );
      var firstSpacePosition = bodyClasses.indexOf( ' ' );
      if ( WordPressAdminSwitcherBookmark.doesStringContainSubstring( firstSpacePosition ) ) {
      return bodyClasses.substring( 0, firstSpacePosition );
      }
      return bodyClasses;
      }
      return false;
      };
      /**
      * Add a trailing slash to a URL if it doesn't already have one.
      *
      * @param {string} url The URL.
      * @return {string} url The URL with a trailing slash.
      */
      WordPressAdminSwitcherBookmark.trailingSlashIt = function( url ) {
      if ( ! url.endsWith( '/' ) ) {
      url += '/';
      }
      return url;
      };
      /**
      * Change the window location.
      *
      * @param {string} url The URL to set as the new location.
      */
      WordPressAdminSwitcherBookmark.changeWindowLocation = function( url ) {
      window.location = url;
      };
      WordPressAdminSwitcherBookmark.toggleAdmin();

      Report

  10. Kellen Mace

    Thierry,

    That’ll do the trick if you’re just interested in switching to the WP admin, but this extension has these additional features:

    1. Switch back from the admin to the front end.
    2. Supports subdirectory multisite installs and WP installs inside of a folder, such as example.com/site-name/wp-admin/.
    3. Sends you to the edit screen for the post/page/CPT you were viewing before you logged in/switched to the admin.
    4. Works via a keyboard shortcut or a click on the extension icon.

    To get all of those features (except #4) in a bookmark, you can use the code below. I think this may be especially handy on mobile devices where users don’t have the option to install Chrome extensions.

    Bookmark code (obfuscated & minified):

    javascript:function b(a){if(Object!=a.constructor||1>Object.keys(a).length)return!1;for(var M in a){var w=document.querySelectorAll(a[M]+" > a.ab-item[href]");if(0<w.length)return w[0].getAttribute("href")}return!1}function c(a){a.endsWith("/")||(a+="/");return a}var d=window.location.pathname;
    if(1<d.indexOf("/wp-admin/")||1<d.indexOf("/wp-login.php")){var e;var f=b({view:"#wp-admin-bar-view",f:"#wp-admin-bar-preview",a:"#wp-admin-bar-site-name"});if(f)e=f;else{b:{var g={j:"/wp-admin/",o:"/wp-login.php"},h;for(h in g){var k=window.location.href.indexOf(g[h]);if(1<k){f=window.location.href.substring(0,k);break b}}f=!1}e=f?f:window.location.origin}window.location=e}else{var l;var m=b({c:"#wp-admin-bar-edit",a:"#wp-admin-bar-site-name"});if(m)l=m;else{var n;c:{var p={i:'link[rel="stylesheet"][href]',
    scripts:"script[src]",g:'link[type="application/rss+xml"][href]',s:'link[rel="pingback"][href]'},q;for(q in p){var r=document.querySelectorAll(p[q]);if(0<r.length)for(var t in r){var u;d:switch(q){case "scripts":u="src";break d;default:u="href"}var v;d:{var x={l:"/wp-content/",m:"/wp-includes/"},y=void 0;for(y in x){var z,A=r[t],B=A[u].indexOf(x[y]);if(z=1<B?A[u].substring(0,B):!1){v=z;break d}}v=!1}if(v){n=v;break c}}}n=!1}var C,D=!1,E={b:"#comment_post_ID[value]",h:'link[rel="shortlink"][href]',
    body:"body[class]"},F;for(F in E){var G=document.querySelectorAll(E[F]);if(0<G.length)switch(F){case "commentsForm":D=G[0].value;break;case "shortlink":c:{var H=G[0].getAttribute("href");if(!(1<H.indexOf("//wp.me/"))){var I=H.indexOf("/?p=");if(1<I){D=H.substring(I+4,H.length);break c}}D=!1}break;case "body":var J=G[0].getAttribute("class"),K=J.indexOf("postid-");if(1<K)var J=J.substring(K+7,J.length),L=J.indexOf(" "),D=1<L?J.substring(0,L):J;else D=!1}}C=D;if(n){var N=c(n)+"wp-admin/";C&&(N=
    N+"post.php?post="+C+"&action=edit");m=N}else m=!1;l=m?m:c(window.location.origin)+"wp-admin/"}window.location=l};

    Full bookmark source code:

    var WordPressAdminSwitcherBookmark = {};
    /**
    * Switch to/from the WordPress Admin.
    */
    WordPressAdminSwitcherBookmark.toggleAdmin = function() {
    if ( WordPressAdminSwitcherBookmark.isWordPressAdmin( window.location.pathname ) ) {
    WordPressAdminSwitcherBookmark.switchToFrontEnd();
    } else {
    WordPressAdminSwitcherBookmark.switchToAdmin();
    }
    };
    /**
    * Is this the WordPress admin?
    *
    * @param {string} url The URL to check.
    * @return {boolean} Whether currently in the WordPress admin.
    */
    WordPressAdminSwitcherBookmark.isWordPressAdmin = function( url ) {
    return ( url.indexOf( '/wp-admin/' ) > 1 ) || ( url.indexOf( '/wp-login.php' ) > 1 );
    };
    /**
    * Switch to the front end.
    */
    WordPressAdminSwitcherBookmark.switchToFrontEnd = function() {
    WordPressAdminSwitcherBookmark.changeWindowLocation( WordPressAdminSwitcherBookmark.getFrontEndUrl() );
    };
    /**
    * Switch to the WP admin.
    */
    WordPressAdminSwitcherBookmark.switchToAdmin = function() {
    WordPressAdminSwitcherBookmark.changeWindowLocation( WordPressAdminSwitcherBookmark.getAdminUrl() );
    };
    /**
    * Get frontend URL.
    *
    * @return {string} The frontend URL.
    */
    WordPressAdminSwitcherBookmark.getFrontEndUrl = function() {
    var url = WordPressAdminSwitcherBookmark.getFrontEndUrlFromAdminBar();
    if ( url ) {
    return url;
    }
    url = WordPressAdminSwitcherBookmark.getFrontEndUrlFromWindowLocation();
    if ( url ) {
    return url;
    }
    // Return WordPressAdminSwitcherBookmark.as a last resort. Has the potential to
    // be incorrect on subdirectory multisite installs.
    return window.location.origin;
    };
    /**
    * Get front end URL from admin bar.
    *
    * Try to get the link to view/preview the post first,
    * then fallback to getting the main front end url.
    *
    * @return {string|boolean} The url or false on failure.
    */
    WordPressAdminSwitcherBookmark.getFrontEndUrlFromAdminBar = function() {
    var adminBarIds = {
    view: '#wp-admin-bar-view',
    preview: '#wp-admin-bar-preview',
    siteName: '#wp-admin-bar-site-name'
    };
    return WordPressAdminSwitcherBookmark.getUrlFromAdminBar( adminBarIds );
    };
    /**
    * Get front end URL from window.location.
    *
    * @return {string|boolean} The url or false on failure.
    */
    WordPressAdminSwitcherBookmark.getFrontEndUrlFromWindowLocation = function() {
    var adminUrlParts = {
    wpAdmin: '/wp-admin/',
    wpLogin: '/wp-login.php'
    };
    for ( var index in adminUrlParts ) {
    var adminUrlPartPosition = WordPressAdminSwitcherBookmark.getPositionOfStringInCurrentUrl( adminUrlParts[ index ] );
    if ( WordPressAdminSwitcherBookmark.doesUrlContainString( adminUrlPartPosition ) ) {
    return WordPressAdminSwitcherBookmark.getPartOfUrlBeforePosition( adminUrlPartPosition );
    }
    }
    return false;
    };
    /**
    * Get the position of a string in the current URL.
    *
    * @param {string} string The string to find within the URL.
    * @return {number} The position of string within the URL.
    */
    WordPressAdminSwitcherBookmark.getPositionOfStringInCurrentUrl = function( string ) {
    return window.location.href.indexOf( string );
    };
    /**
    * Does the URL contain a string?
    *
    * @param {number} stringPosition The position of string within the URL.
    * @return {boolean} Whether the URL contains the string.
    */
    WordPressAdminSwitcherBookmark.doesUrlContainString = function( stringPosition ) {
    return WordPressAdminSwitcherBookmark.doesStringContainSubstring( stringPosition );
    };
    /**
    * Does string contain a substring?
    *
    * @param {number} stringPosition The position of substring within the string.
    * @return {boolean} Whether the substring was found within the string.
    */
    WordPressAdminSwitcherBookmark.doesStringContainSubstring = function( stringPosition ) {
    return stringPosition > 1;
    };
    /**
    * Get part of URL before the provided position.
    *
    * @param {number} stringPosition Exclude the character at WordPressAdminSwitcherBookmark.position and following.
    * @return {string} The part of the URL before stringPosition.
    */
    WordPressAdminSwitcherBookmark.getPartOfUrlBeforePosition = function( stringPosition ) {
    return window.location.href.substring( 0, stringPosition );
    };
    /**
    * Get the admin URL.
    *
    * @return {string} The admin URL.
    */
    WordPressAdminSwitcherBookmark.getAdminUrl = function() {
    var url = WordPressAdminSwitcherBookmark.getAdminUrlFromAdminBar();
    if ( url ) {
    return url;
    }
    url = WordPressAdminSwitcherBookmark.getAdminUrlFromPageSource();
    if ( url ) {
    return url;
    }
    // Return WordPressAdminSwitcherBookmark.as a last resort. Has the potential to
    // be incorrect on subdirectory multisite installs.
    return WordPressAdminSwitcherBookmark.trailingSlashIt( window.location.origin ) + 'wp-admin/';
    };
    /**
    * Get admin URL from page source.
    *
    * @return {string|boolean} The admin URL or false on failure.
    */
    WordPressAdminSwitcherBookmark.getAdminUrlFromPageSource = function() {
    var url = WordPressAdminSwitcherBookmark.inferUrlFromPageLinks(),
    postId = WordPressAdminSwitcherBookmark.inferPostIdFromPageSource();
    if ( url ) {
    var adminUrl = WordPressAdminSwitcherBookmark.getAdminUrlFromSiteUrl( url );
    if ( postId ) {
    adminUrl = WordPressAdminSwitcherBookmark.getPostSpecificAdminUrl( adminUrl, postId );
    }
    return adminUrl;
    }
    return false;
    };
    /**
    * Turn site URL into admin URL.
    *
    * @param {string} url The site URL.
    * @return {string} The admin URL.
    */
    WordPressAdminSwitcherBookmark.getAdminUrlFromSiteUrl = function( url ) {
    return WordPressAdminSwitcherBookmark.trailingSlashIt( url ) + 'wp-admin/';
    };
    /**
    * Turn base admin URL into a post-specific admin URL.
    *
    * @param {string} adminUrl The base admin URL.
    * @param {string} postId The post ID.
    * @return {string} The post-specific admin URL.
    */
    WordPressAdminSwitcherBookmark.getPostSpecificAdminUrl = function( adminUrl, postId ) {
    return adminUrl + 'post.php?post=' + postId + '&action=edit';
    };
    /**
    * Get WP admin URL from the admin bar.
    *
    * @return {string|boolean} The URL or false on failure.
    */
    WordPressAdminSwitcherBookmark.getAdminUrlFromAdminBar = function() {
    var adminBarIds = {
    edit: '#wp-admin-bar-edit',
    siteName: '#wp-admin-bar-site-name'
    };
    return WordPressAdminSwitcherBookmark.getUrlFromAdminBar( adminBarIds );
    };
    /**
    * Get URL from the WP admin bar.
    *
    * @param {Object} adminBarIds The element IDs to use as selectors.
    * @return {string|boolean} The URL or false on failure.
    */
    WordPressAdminSwitcherBookmark.getUrlFromAdminBar = function ( adminBarIds ) {
    if ( WordPressAdminSwitcherBookmark.isEmptyObject( adminBarIds ) ) {
    return false;
    }
    for ( var key in adminBarIds ) {
    var adminBarAnchorHtmlElement = WordPressAdminSwitcherBookmark.getAdminBarAnchorHtmlElement( adminBarIds[ key ] );
    if ( WordPressAdminSwitcherBookmark.wereHtmlElementsFound( adminBarAnchorHtmlElement ) ) {
    return WordPressAdminSwitcherBookmark.getHrefUrlFromHtmlElement( adminBarAnchorHtmlElement );
    }
    }
    return false;
    };
    /**
    * Is WordPressAdminSwitcherBookmark.an empty object?
    *
    * @param {Object} object The object to check.
    * @return {boolean} Whether the object is empty.
    */
    WordPressAdminSwitcherBookmark.isEmptyObject = function( object ) {
    return ( Object != object.constructor ) || ( Object.keys( object ).length < 1 );
    };
    /**
    * Get admin bar anchor HTML element.
    *
    * @param {string} adminBarId The id of the HTML element to get.
    * @return {Object} The matching HTML element NodeList.
    */
    WordPressAdminSwitcherBookmark.getAdminBarAnchorHtmlElement = function( adminBarId ) {
    return document.querySelectorAll( adminBarId + ' > a.ab-item[href]' );
    };
    /**
    * Here any HTML elements found?
    *
    * @param {Object} nodelist The NodeList of HTML elements found.
    * @return {boolean} Whether HTML elements were found.
    */
    WordPressAdminSwitcherBookmark.wereHtmlElementsFound = function( nodelist ) {
    return nodelist.length > 0;
    };
    /**
    * Get the URL from an HTML element's href property.
    *
    * @param {Object} element The HTML element NodeList.
    * @return {string} The URL.
    */
    WordPressAdminSwitcherBookmark.getHrefUrlFromHtmlElement = function( element ) {
    return element[0].getAttribute( 'href' );
    };
    /**
    * Infer the site's URL from links in the page source.
    *
    * We can't simply get the site's URL from window.location
    * because subdomain multisite installs need to have the
    * /site-name/ part of the pathname preserved.
    *
    * @return {string|boolean} The URL or false on failure.
    */
    WordPressAdminSwitcherBookmark.inferUrlFromPageLinks = function() {
    var selectors = {
    stylesheets: 'link[rel="stylesheet"][href]',
    scripts: 'script[src]',
    rss: 'link[type="application/rss+xml"][href]',
    xmlrpc: 'link[rel="pingback"][href]'
    };
    for ( var selectorIndex in selectors ) {
    var elements = document.querySelectorAll( selectors[ selectorIndex ] );
    if ( WordPressAdminSwitcherBookmark.wereHtmlElementsFound( elements ) ) {
    for ( var elementIndex in elements ) {
    var attribute = WordPressAdminSwitcherBookmark.getAttributeForSelector( selectorIndex ),
    url = WordPressAdminSwitcherBookmark.inferUrlFromPageLink( elements[ elementIndex ], attribute );
    if ( url ) {
    return url;
    }
    }
    }
    }
    return false;
    };
    /**
    * Extract the URL from an HTML element.
    *
    * @param {Object} element The HTML element
    * @param {string} attribute The attribute to get the URL from: 'href' or 'src'.
    * @return {string|boolean} The URL or false on failure.
    */
    WordPressAdminSwitcherBookmark.inferUrlFromPageLink = function( element, attribute ) {
    var paths = {
    wpContent: '/wp-content/',
    wpIncludes: '/wp-includes/'
    };
    for ( var index in paths ) {
    var url = WordPressAdminSwitcherBookmark.getUrlSubstringFromHtmlElement( element, attribute, paths[ index ] );
    if ( url ) {
    return url;
    }
    }
    return false;
    };
    /**
    * Get the URL-containing attribute for a selector type.
    *
    * @param {string} selector The selector type.
    * @return {string} The attribute for contains the URL.
    */
    WordPressAdminSwitcherBookmark.getAttributeForSelector = function( selector ) {
    switch ( selector ) {
    case 'scripts':
    return 'src';
    default:
    return 'href';
    }
    };
    /**
    * Extract part of a URL from an HTML element.
    *
    * @param {Object} element The HTML element.
    * @param {string} attribute The attribute to get URL from ('href' or 'src').
    * @param {string} string The text to search for and exclude, along with
    * everything after it.
    * @return {string|boolean} The part of the URL or false on failure.
    */
    WordPressAdminSwitcherBookmark.getUrlSubstringFromHtmlElement = function( element, attribute, string ) {
    var stringPosition = element[ attribute ].indexOf( string );
    if ( WordPressAdminSwitcherBookmark.doesUrlContainString( stringPosition ) ) {
    return element[ attribute ].substring( 0, stringPosition );
    }
    return false;
    };
    /**
    * Infer post ID from the page source.
    *
    * Not all WordPress sites will have WordPressAdminSwitcherBookmark.exposed.
    *
    * @return {string|boolean} The post ID or false on failure.
    */
    WordPressAdminSwitcherBookmark.inferPostIdFromPageSource = function() {
    var postId = false,
    postIdSelectors = {
    commentsForm: '#comment_post_ID[value]',
    shortlink: 'link[rel="shortlink"][href]',
    body: 'body[class]'
    };
    for ( var index in postIdSelectors ) {
    var postIdElement = document.querySelectorAll( postIdSelectors[ index ] );
    if ( ! WordPressAdminSwitcherBookmark.wereHtmlElementsFound( postIdElement ) ) {
    continue;
    }
    switch ( index ) {
    case 'commentsForm':
    postId = WordPressAdminSwitcherBookmark.getPostIdFromCommentsForm( postIdElement );
    break;
    case 'shortlink':
    postId = WordPressAdminSwitcherBookmark.getPostIdFromShortlink( postIdElement );
    break;
    case 'body':
    postId = WordPressAdminSwitcherBookmark.getPostIdFromBodyClass( postIdElement );
    }
    }
    return postId;
    };
    /**
    * Get post ID from comments form.
    *
    * @param {Object} postIdElement The HTML element NodeList containing the post ID.
    * @return {string} The post ID.
    */
    WordPressAdminSwitcherBookmark.getPostIdFromCommentsForm = function( postIdElement ) {
    return postIdElement[0].value;
    };
    /**
    * Get post ID from shortlink.
    *
    * @param {Object} postIdElement The HTML element NodeList containing the post ID.
    * @return {string|boolean} The post ID or false on failure.
    */
    WordPressAdminSwitcherBookmark.getPostIdFromShortlink = function( postIdElement ) {
    var shortlinkUrl = WordPressAdminSwitcherBookmark.getHrefUrlFromHtmlElement( postIdElement );
    if ( ! WordPressAdminSwitcherBookmark.isShortlinkUsingWpMeService( shortlinkUrl ) ) {
    var positionOfUrlTextBeforePostId = WordPressAdminSwitcherBookmark.getPositionOfUrlTextBeforePostId( shortlinkUrl );
    if ( WordPressAdminSwitcherBookmark.doesShortlinkUrlContainPostId( positionOfUrlTextBeforePostId ) ) {
    return WordPressAdminSwitcherBookmark.getPostIdFromShortlinkUrl( shortlinkUrl, positionOfUrlTextBeforePostId );
    }
    }
    return false;
    };
    /**
    * Is shortlink using wp.me service?
    *
    * @param {string} shortlinkUrl The shortlink URL.
    * @return {boolean} Whether shorlinkUrl is using wp.me.
    */
    WordPressAdminSwitcherBookmark.isShortlinkUsingWpMeService = function( shortlinkUrl ) {
    return shortlinkUrl.indexOf( '//wp.me/' ) > 1;
    };
    /**
    * Get the position of the URL before the post ID.
    *
    * @param {string} shortlinkUrl The URL to search.
    * @return {number} The position of the post ID.
    */
    WordPressAdminSwitcherBookmark.getPositionOfUrlTextBeforePostId = function( shortlinkUrl ) {
    return shortlinkUrl.indexOf( '/?p=' );
    };
    /**
    * Does the shortlink URL contain the post ID?
    *
    * @param {number} positionOfUrlTextBeforePostId The position of the URL text before the post ID.
    * @return {boolean} Whether the URL contains the post ID.
    */
    WordPressAdminSwitcherBookmark.doesShortlinkUrlContainPostId = function( positionOfUrlTextBeforePostId ) {
    return WordPressAdminSwitcherBookmark.doesStringContainSubstring( positionOfUrlTextBeforePostId );
    };
    /**
    * Extract the post ID from the shortlink URL.
    *
    * @param {string} shortlinkUrl The shortlink URL.
    * @param {number} positionOfUrlTextBeforePostId The position of URL text before the post ID.
    * @return {string} The post ID.
    */
    WordPressAdminSwitcherBookmark.getPostIdFromShortlinkUrl = function( shortlinkUrl, positionOfUrlTextBeforePostId ) {
    return shortlinkUrl.substring( positionOfUrlTextBeforePostId + 4, shortlinkUrl.length );
    };
    /**
    * Get post ID from body class.
    *
    * @param {Object} postIdElement The HTML element NodeList containing the post ID.
    * @return {string|boolean} The post ID or false on failure.
    */
    WordPressAdminSwitcherBookmark.getPostIdFromBodyClass = function( postIdElement ) {
    var bodyClasses = postIdElement[0].getAttribute( 'class' ),
    postIdPosition = bodyClasses.indexOf( 'postid-' );
    if ( WordPressAdminSwitcherBookmark.doesStringContainSubstring( postIdPosition ) ) {
    bodyClasses = bodyClasses.substring( postIdPosition + 7, bodyClasses.length );
    var firstSpacePosition = bodyClasses.indexOf( ' ' );
    if ( WordPressAdminSwitcherBookmark.doesStringContainSubstring( firstSpacePosition ) ) {
    return bodyClasses.substring( 0, firstSpacePosition );
    }
    return bodyClasses;
    }
    return false;
    };
    /**
    * Add a trailing slash to a URL if it doesn't already have one.
    *
    * @param {string} url The URL.
    * @return {string} url The URL with a trailing slash.
    */
    WordPressAdminSwitcherBookmark.trailingSlashIt = function( url ) {
    if ( ! url.endsWith( '/' ) ) {
    url += '/';
    }
    return url;
    };
    /**
    * Change the window location.
    *
    * @param {string} url The URL to set as the new location.
    */
    WordPressAdminSwitcherBookmark.changeWindowLocation = function( url ) {
    window.location = url;
    };
    WordPressAdminSwitcherBookmark.toggleAdmin();

    Report

  11. Kellen Mace

    For anybody following this project, I have implemented two of the features mentioned in the article:

    1. Now after logging in you will be directed to the admin post edit screen for the post/page/custom post type you were viewing before you logged in, if possible, or else the main admin screen.

    2. The cmd/ctrl+shift+A keyboard shortcut now works everywhere, even if the focus is on the omnibar/address bar.

    Report

  12. Mark

    Very cool. Thanks!

    Report

  13. Kellen Mace

    The final feature listed in this article has been added to the extension: the ability to set a custom keyboard shortcut. If you want to switch from using the default cmd/ctrl + shift + A to something else, here’s how you can do that:

    Go to the Chrome menu > More Tools > Extensions and check the “Keyboard shortcuts” link at the bottom. Find WordPress Admin Switcher on the list click the field next to “Switch to/from admin”. Enter your own custom keyboard shortcut.

    Report

Comments are closed.

%d bloggers like this: