-
-
Save westonruter/5f4f27ed3bdd676e3f08524b9bab8bb4 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* AMP Mobile JS Redirection plugin initialization file. | |
* | |
* @package AMP_Mobile_JS_Redirection | |
* @author Weston Ruter, Google | |
* @link https://gist.github.com/westonruter/5f4f27ed3bdd676e3f08524b9bab8bb4 | |
* @license GPL-2.0-or-later | |
* @copyright 2019 Google Inc. | |
* | |
* @wordpress-plugin | |
* Plugin Name: AMP Mobile JS Redirection | |
* Plugin URI: https://gist.github.com/westonruter/5f4f27ed3bdd676e3f08524b9bab8bb4 | |
* Description: Automatically redirect mobile visitors to the AMP version when the AMP plugin is in a paired mode (Reader/Transitional). This plugin depends on AMP plugin v1.5-alpha. Reader more in <a href="https://github.com/ampproject/amp-wp/issues/2044">amp-wp#2044</a>. | |
* Version: 0.2 | |
* Author: Weston Ruter, Google | |
* Author URI: https://weston.ruter.net/ | |
* License: GNU General Public License v2 (or later) | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
* Gist Plugin URI: https://gist.github.com/westonruter/5f4f27ed3bdd676e3f08524b9bab8bb4 | |
*/ | |
namespace AMP_Mobile_JS_Redirection; | |
use WP_Post; | |
use WP_Query; | |
const DISABLE_MOBILE_REDIRECT_KEY = 'disable_mobile_redirect'; | |
/** | |
* Initialize. | |
*/ | |
function init() { | |
// Abort if the AMP plugin is is not active. | |
if ( ! function_exists( 'is_amp_endpoint' ) ) { | |
return; | |
} | |
if ( version_compare( AMP__VERSION, '1.5', '<' ) ) { | |
trigger_error( 'Plugin depends on AMP plugin v1.5', E_USER_NOTICE ); | |
return; | |
} | |
// Abort if in Standard mode (AMP-first) since redirecting to the AMP version only makes sense in a paired AMP context. | |
if ( amp_is_canonical() ) { | |
return; | |
} | |
// Prevent needless redirects to mobile version after on a mobile page by forcing AMP-to-AMP linking to be enabled. | |
add_filter( 'amp_to_amp_linking_enabled', '__return_true' ); | |
if ( is_amp() ) { | |
add_action( 'wp_footer', __NAMESPACE__ . '\add_version_switcher_link' ); | |
add_action( 'amp_post_template_footer', __NAMESPACE__ . '\add_version_switcher_link' ); | |
} elseif ( has_amp_version_available() ) { | |
add_action( | |
'wp_head', | |
__NAMESPACE__ . '\add_redirect_script', | |
~PHP_INT_MAX // Run the absolutely earliest as possible. | |
); | |
add_action( 'wp_footer', __NAMESPACE__ . '\add_version_switcher_link' ); | |
} | |
} | |
add_action( 'wp', __NAMESPACE__ . '\init' ); | |
/** | |
* Determine whether it is an AMP response. | |
* | |
* @return bool | |
*/ | |
function is_amp() { | |
return function_exists( 'is_amp_endpoint' ) && is_amp_endpoint(); | |
} | |
/** | |
* Determine whether there is an AMP version available for this URL. | |
* | |
* @return bool | |
* @global WP_Query $wp_query | |
*/ | |
function has_amp_version_available() { | |
global $wp_query; | |
$queried_object = get_queried_object(); | |
if ( current_theme_supports( \AMP_Theme_Support::SLUG ) ) { | |
// Abort if in Transitional mode and AMP is not available for the URL. | |
if ( ! \AMP_Theme_Support::is_paired_available() ) { | |
return false; | |
} | |
} elseif ( ! ( $queried_object instanceof WP_Post && $wp_query instanceof WP_Query && ( $wp_query->is_singular() || $wp_query->is_posts_page ) && post_supports_amp( $queried_object ) ) ) { | |
// Abort if in Reader mode and the post doesn't support AMP. | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Add script as early to the page as possible to detect mobile visitors and redirect to the AMP version unless they have opted-out. | |
* | |
* This function is only called in a non-AMP context, that is in the context of the "desktop" site (non-AMP). | |
* Again, this assumes Reader/Transitional mode. AMP is fully capable of creating desktop experiences, | |
* and this is what the AMP plugin's Standard mode enables: AMP-first. | |
* | |
* @todo Need to handle the case where the AMP version redirected to the non-AMP version due to validation errors. | |
*/ | |
function add_redirect_script() { | |
?> | |
<script> | |
(function( disableMobileRedirectKey, ampQueryParam ) { | |
var isMobile = /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi/.test( navigator.userAgent ); // See wp_is_mobile(). | |
if ( isMobile ) { | |
document.addEventListener( 'DOMContentLoaded', function() { | |
var versionSwitchLink = document.getElementById( 'site-version-switcher' ); | |
if ( versionSwitchLink ) { | |
versionSwitchLink.hidden = false; | |
} | |
} ); | |
} | |
// Short-circuit if mobile redirection is disabled. | |
if ( '1' === sessionStorage.getItem( disableMobileRedirectKey ) ) { | |
return; | |
} | |
// Handle request that disables mobile redirect by storing the preference and scrubbing the URL of the param. | |
var url = new URL( location.href ); | |
if ( url.searchParams.has( disableMobileRedirectKey ) ) { | |
url.searchParams.delete( disableMobileRedirectKey ); | |
sessionStorage.setItem( disableMobileRedirectKey, '1' ); | |
history.replaceState( {}, '', url.href ); | |
return; | |
} | |
// Otherwise, if the user agent is mobile, we need to redirect them. | |
if ( isMobile && ! url.searchParams.has( ampQueryParam ) ) { | |
window.stop(); // Stop loading the page! This should cancel all loading resources. | |
// Replace the current page with the AMP version. | |
url.searchParams.append( ampQueryParam, '1' ); | |
location.replace( url.href ); | |
} | |
})( | |
<?php echo wp_json_encode( DISABLE_MOBILE_REDIRECT_KEY ); ?>, | |
<?php echo wp_json_encode( amp_get_slug() ); ?> | |
); | |
</script> | |
<?php | |
} | |
/** | |
* Add version switcher link. | |
*/ | |
function add_version_switcher_link() { | |
global $wp_query; | |
$is_amp = is_amp(); | |
if ( $is_amp ) { | |
$url = add_query_arg( | |
DISABLE_MOBILE_REDIRECT_KEY, | |
'1', | |
amp_remove_endpoint( amp_get_current_url() ) | |
); | |
} else { | |
if ( current_theme_supports( \AMP_Theme_Support::SLUG ) ) { | |
if ( \AMP_Theme_Support::is_paired_available() ) { | |
$url = add_query_arg( amp_get_slug(), '', amp_get_current_url() ); | |
} | |
} elseif ( $wp_query instanceof WP_Query && ( $wp_query->is_singular() || $wp_query->is_posts_page ) && post_supports_amp( get_post( get_queried_object_id() ) ) ) { | |
$url = amp_get_permalink( get_queried_object_id() ); | |
} | |
} | |
if ( ! isset( $url ) ) { | |
return; | |
} | |
?> | |
<div | |
id="site-version-switcher" | |
<?php if ( ! $is_amp ) : ?> | |
hidden | |
<?php endif; ?> | |
> | |
<style> | |
#version-switch-link { | |
display: block; | |
width: 100%; | |
padding: 15px 0; | |
font-size: 16px; | |
font-weight: 600; | |
color: #eaeaea; | |
text-align: center; | |
background-color: #444; | |
border: 0; | |
} | |
</style> | |
<?php if ( $is_amp ) : ?> | |
<a | |
id="version-switch-link" | |
rel="noamphtml" | |
href="<?php echo esc_url( $url ); ?>" | |
> | |
<?php esc_html_e( 'Leave mobile version', 'amp' ); ?> | |
</a> | |
<?php else : ?> | |
<a | |
id="version-switch-link" | |
rel="amphtml" | |
href="<?php echo esc_url( $url ); ?>" | |
onclick="<?php echo esc_attr( sprintf( 'sessionStorage.removeItem( %s );', wp_json_encode( DISABLE_MOBILE_REDIRECT_KEY ) ) ); ?>" | |
> | |
<?php esc_html_e( 'Return to mobile version', 'amp' ); ?> | |
</a> | |
<?php endif; ?> | |
</div> | |
<?php | |
} |
Installation instructions: https://gist.github.com/westonruter/6110fbc4bef0c4b8c021a112012f7e9c
Hello,
I've just installed the plugin and met with a few issues:
The desktop link seems to link to the wrong root of my site.
e.g. site.com/extension instead of site.com/blog/extension
Also, certain posts go into a redirection loop
e.g. site.com/blog/extension/?amp=1&=1&=1&=1&=1.......
Is this a known issue? Let me know if I can furnish more information. Thanks!
Warm Regards
The desktop link is obtained via amp_get_current_url()
which is currently:
function amp_get_current_url() {
$url = preg_replace( '#(^https?://[^/]+)/.*#', '$1', home_url( '/' ) );
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
$url = esc_url_raw( $url . wp_unslash( $_SERVER['REQUEST_URI'] ) );
} else {
$url .= '/';
}
return $url;
}
Is there a bug in there?
What if add_desktop_link()
here was changed to define $non_amp_url
as:
$non_amp_url = add_query_arg(
DISABLE_MOBILE_REDIRECT_KEY,
'1',
amp_remove_endpoint( wp_unslash( $_SERVER['REQUEST_URI'] ) )
);
I've just pushed an update that should fix the issue with the infinite redirect issue and also improve detection for whether redirection should happen in the first place.
It seems that my REQUEST_URI is returning a different root, I'll have to look into that.
The infinite redirect issue was fixed. Thanks!
Why would the url have two amp's after installing it? e.g example.net/post-abc/amp/?amp
@faheem864 Are you in Transitional mode or Reader mode?
The functionality in this plugin is now part of the AMP plugin as of v2.0. Please deactivate this plugin and upgrade the AMP plugin.
In addition to using
window.stop()
, another option could be todocument.write('<plaintext>')
, althoughplaintext
is obsolete: “Do not use this element.”