Skip to content

Instantly share code, notes, and snippets.

@westonruter
Last active April 5, 2024 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westonruter/67487d199f4cbc1968a30c60de121893 to your computer and use it in GitHub Desktop.
Save westonruter/67487d199f4cbc1968a30c60de121893 to your computer and use it in GitHub Desktop.
<?php
/**
* AMP Subdomain Paired URLs plugin file.
*
* @package Google\AMP_Subdomain_Paired_URLs
* @author Weston Ruter, Google
* @license GPL-2.0-or-later
* @copyright 2020 Google Inc.
*
* @wordpress-plugin
* Plugin Name: AMP Subdomain Paired URLs
* Plugin URI: https://gist.github.com/westonruter/67487d199f4cbc1968a30c60de121893
* Description: Demonstration of how to configure AMP plugin v2.1 to use an "amp" subdomain for paired AMP URLs (in Transitional mode or Reader mode). Depends on <a href="https://github.com/ampproject/amp-wp/pull/5558">amp-wp#5558</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/67487d199f4cbc1968a30c60de121893
*/
namespace AMP_Subdomain_Paired_URLs;
add_filter(
'amp_custom_paired_url_structure',
function () {
require_once __DIR__ . '/SubdomainUrlStructure.php';
return SubdomainUrlStructure::class;
}
);
/*
* In order for this to work properly, you must define the necessary cookie constants in the wp-config.php to include
* subdomains. For example, if your site is located at https://wordpressdev.lndo.site then you may need to add this to
* add this your wp-config.php:
*
* define( 'COOKIE_DOMAIN', '.wordpressdev.lndo.site' );
* define( 'COOKIEHASH', md5( 'wordpressdev.lndo.site' ) );
* define( 'COOKIEPATH', '/' );
*
* If you do not do this, then you will not be able to preview AMP post changes or do paired browsing.
*/
/**
* Check whether the current request is for an AMP page.
*
* @return bool Is an AMP request.
*/
function is_amp_request() {
return function_exists( 'amp_is_request' ) && amp_is_request();
}
/**
* Determine whether a URL is for AMP.
*
* @param string $url URL.
* @return bool Whether the URL has the AMP subdomain.
*/
function has_amp_subdomain( $url ) {
return (bool) preg_match(
'/^amp\./',
wp_parse_url( $url, PHP_URL_HOST )
);
}
/**
* Add amp subdomain to a URL.
*
* @param string $url URL.
* @return string URL with amp subdomain.
*/
function add_amp_subdomain( $url ) {
return preg_replace( '#(?<=://)(?!amp\.)#', 'amp.', $url );
}
/**
* Remove amp subdomain from a URL.
*
* @param string $url URL which may have an amp subdomain.
* @return string URL without amp subdomain.
*/
function remove_amp_subdomain( $url ) {
return preg_replace( '#(?<=://)amp\.#', '', $url );
}
// Since the WP_HOME may have been modified so that the amp subdomain is an alias, make sure that the post canonical
// links get the subdomain removed on AMP pages.
add_filter(
'get_canonical_url',
function ( $canonical_url ) {
if ( is_amp_request() ) {
$canonical_url = remove_amp_subdomain( $canonical_url );
}
return $canonical_url;
}
);
// Make sure that validation requests to the amp subdomain are allowed.
add_filter(
'allowed_redirect_hosts',
function ( $hosts ) {
$hosts[] = wp_parse_url( add_amp_subdomain( home_url() ), PHP_URL_HOST );
return $hosts;
}
);
<?php
/**
* Class SubdomainUrlStructure.
*
* @package Google\AMP_Path_Prefix_Paired_URLs
*/
namespace AMP_Subdomain_Paired_URLs;
use AmpProject\AmpWP\PairedUrlStructure;
/**
* Descriptor for paired URL structures that use an AMP subdomain.
*/
class SubdomainUrlStructure extends PairedUrlStructure {
/**
* Add amp subdomain to a URL.
*
* @param string $url URL (or path).
* @return string URL with amp subdomain.
*/
public function add_endpoint( $url ) {
return add_amp_subdomain( $url );
}
/**
* Remove AMP path prefix from a URL.
*
* @param string $url URL (or path).
* @return string URL without amp subdomain.
*/
public function remove_endpoint( $url ) {
return remove_amp_subdomain( $url );
}
}
@sudarsha
Copy link

sudarsha commented Jan 5, 2021

Thanks. This does work more or less fine. The only thing is, since we're adding both the amp subdomain and qeury_var to the paired url, it doesn't look very nice.
The amphtml link is in this format https://amp.xxxx.yyy/jgakjgajkldfjakfjadkl?amp=1
While that works fine, it doesn't look terribly aesthetic.
If I remove add_query_var from return $this->paired_url->add_query_var( add_amp_subdomain( $url ) ); , would it work? I'm not a coder, as you might have guessed.
Also, would I then have to do the same with in the remove_endpoint function as well?

@sudarsha
Copy link

sudarsha commented Jan 5, 2021

It does seem to me that I can remove add_query_var function from add_endpoint function, as that functionality is anyway being done by the subdomain server when it cannot find a readymade file (cached file) to supply to the requester?
It also seems to be that I should maintain the >remove_query_var function in the remove_endpoint( $url ) as, by this point, the amp=1 query string has been attached to the url by the subdomain server, in place of the amp subdomain, as part of its 302 redirection. Therefore, perhaps, when it comes to the remove_endpoint( $url ) function, I should get replace remove_query_var( remove_amp_subdomain( $url ) ) with remove_query_var($url) ????

I've removed the problem of amp being attached to both sides of the url by NOT MAKING the following change:

-		return add_amp_subdomain( $url );
+		return $this->paired_url->add_query_var( add_amp_subdomain( $url ) );

I've also changed
return $this->paired_url->remove_query_var( remove_amp_subdomain( $url ) );
to
return $this->paired_url->remove_query_var( $url );
given that there will be no subdomain when the request hits this [origin] server. The subdomain will be stripped out by the proxy during redirection.
Things seem to be working. I hope the code is fine?

@westonruter
Copy link
Author

westonruter commented Jan 5, 2021

Thanks. This does work more or less fine. The only thing is, since we're adding both the amp subdomain and qeury_var to the paired url, it doesn't look very nice.

The appearance of the AMP URL should be irrelevant.

Things seem to be working. I hope the code is fine?

It is expected that add_endpoint and remove_endpoint should do exactly the opposite operations. So if that's not done then I can't say that it will always work as intended. But if the reverse operation for you is being handled somehow elsewhere in your server stack, then good for you. The point of the custom paired URL structures is to give you the flexibility to do what you need for your particular use case. That being said, I can't get too far into the particulars of your setup.

@sudarsha
Copy link

sudarsha commented Jan 6, 2021

I've monitored the set up for more than 24 hours now. Everything is working very well. Thanks a lot for your help.

@pierlon
Copy link

pierlon commented Jan 21, 2021

Admin URLs will need to be filtered to remove the AMP subdomain as well. Some items in the AMP admin bar menu may not resolve correctly, for example.

@Wesley-Carnicle
Copy link

What if the subdomain doesn't have Wordpress installed does it still work with the main site. I know CNN did amp.cnn.com I would like to do amp.mydomain.com

@westonruter
Copy link
Author

westonruter commented Apr 5, 2024

@Wesley-Carnicle Unsure. This is only relevant when WordPress is installed on the subdomain and specifically when the subdomain is an alias of the main domain, and where the same WordPress install with the AMP plugin is on both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment