WordPress Admin Switcher: A New Google Chrome Extension for Switching Between Admin and Frontend

photo credit: Ilya Pavlov
photo credit: Ilya Pavlov

If your job involves working with WordPress, you probably switch between front and backend countless times every day while getting things done. Kellen Mace, a developer at WebDevStudios, has just released a handy Google Chrome Extension that will save you a few clicks while switching back and forth.

WordPress Admin Switcher offers a keyboard shortcut that will zip you from frontend to admin without having to reach for your mouse/trackpad: cmd + shift + A (Mac) or ctrl + shift + A (Windows/Linux).

The keyboard shortcut works on any WordPress-powered site to do the following:

  • Sends a logged-out user to the admin login
  • Sends a logged-in user on the frontend to the post edit screen for the for the post/page/custom post type currently being viewed
  • Sends a logged-in user from the admin to the corresponding frontend for the post/page/custom post type being edited (or else the main site URL)

The extension also supports switching to/from the admin on a subdirectory multisite install with URLs like domain.com/site-name/. It works on WordPress.com VIP sites and any WordPress-powered website. Clicking the extension icon also performs the same behavior as the keyboard shortcut. This chart on the extension’s GitHub page shows how many clicks users can save with the extension:

wordpress-admin-switcher-chrome-extension

“I was envisioning this extension being most useful for experienced people who frequently work with WordPress sites and have a desire to speed up their workflow when logging into them and switching to/from the admin,” Mace said. However, the extension can also be useful for novice users who perpetually forget the URL for accessing their site’s admin.

In the future, Mace plans to add more features, including the ability to navigate to a specific post/page on any WordPress site, hit the shortcut to log in and then be taken back to the edit screen for the post you were viewing before logging in.

“That functionality depends on knowing the post ID, however, which not all WordPress sites expose on the front end,” he said. “So essentially the extension would try to infer the post ID from the page source. If found, it would send the user to its edit screen after login. If not found, it would just fall back to sending them to the main /wp-admin/ dashboard page.”

The keyboard shortcut doesn’t currently switch you to/from the admin if the focus is on Chrome’s omnibar, so Mace wants to update the extension to be able to listen for the keyboard shortcut and act on it even when in the omnibar. He also said he hopes to allow users the option to assign their own keyboard shortcuts if the default doesn’t seem natural for them.

If you work in WordPress and Chrome all day, this extension could boost your efficiency and productivity. I tested it and the current features work as expected. Install the extension directly from the Chrome web store or check out the project on GitHub.

22

22 responses to “WordPress Admin Switcher: A New Google Chrome Extension for Switching Between Admin and Frontend”

    • 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 :)

    • 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! ?

  1. I have this functionalities with bookmarks since 2005!



    This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
    Learn more about bidirectional Unicode characters

    javascript:( function(){ with(window.open('http://'+window.location.host+'/wp-admin','_blank')){ document.close(); } })()
    view raw

    WP admin

    hosted with ❤ by GitHub
    • 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):



      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters

      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:



      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters

      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();
  2. 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):



    This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
    Learn more about bidirectional Unicode characters

    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:



    This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
    Learn more about bidirectional Unicode characters

    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();
  3. 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.

  4. 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.

Newsletter

Subscribe Via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

%d bloggers like this: