diff --git a/amp.php b/amp.php index 43542fb3669..8090d1e422d 100644 --- a/amp.php +++ b/amp.php @@ -279,28 +279,26 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) { * and everything else has AMP unavailable: * * add_theme_support( 'amp', array( - * 'template_dir' => 'amp-templates/', // Optional. In case you need to override the template as a whole. - * 'available_callback' => function() { - * // @todo Warning: If a plugin or theme calls is_amp_endpoint() before parse_query() then the conditionals will not work! - * if ( is_single() ) { - * return 'native'; - * } elseif ( is_page() ) { - * return 'paired'; // Or 'true'. - * } else { - * return false; - * } - * }, + * 'available_callback' => 'is_single', * ) ); * * Then, this will change the plugin so that it won't run in 'paired mode' with separate URLs. - * Neither will it output the rel=amphtml link on the frontend. + * Neither will it output the rel=amphtml link on the frontend. To serve a site in paired mode, add the paired arg: * - * Paired mode will be retained if the theme registers support for AMP with just a template_dir and no available_callback: + * add_theme_support( 'amp', array( + * 'paired' => true, + * 'available_callback' => 'is_single', + * ) ); + * + * Paired mode will also be retained if the theme registers support for AMP with just a template_dir and no available_callback: * * add_theme_support( 'amp', array( * 'template_dir' => 'my-amp-templates', * ) ); * + * @todo Why do we even need this function? + * @see \AMP_Theme_Support::is_paired_available() + * * @return boolean Whether this is in AMP 'canonical' mode, that is whether it is native and there is not separate AMP URL current URL. */ function amp_is_canonical() { @@ -308,27 +306,31 @@ function amp_is_canonical() { if ( true === $support ) { return true; } + if ( is_array( $support ) ) { $args = array_shift( $support ); - $is_native = ( - isset( $args['available_callback'] ) - && - is_callable( $args['available_callback'] ) - && - 'native' === call_user_func( $args['available_callback'] ) - ); - if ( $is_native ) { - return true; + // If paired arg is supplied, then it is never canonical. + if ( ! empty( $args['paired'] ) ) { + return false; } - // If there is no available_callback and yet there is a template_dir, then paired mode is implied. - if ( empty( $args['available_callback'] ) && ! empty( $args['template_dir'] ) ) { + // If there is a template_dir, then paired mode is implied. + if ( ! empty( $args['template_dir'] ) ) { return false; } +// +// // Otherwise, the available_callback dictates whether AMP is available. +// if ( isset( $args['available_callback'] ) && is_callable( $args['available_callback'] ) ) { +// return call_user_func( $args['available_callback'] ); +// } } - return false; + return true; } +// +//function amp_is_available() { +// +//} /** * Load classes. @@ -460,6 +462,7 @@ function _amp_bootstrap_customizer() { /** * Redirects the old AMP URL to the new AMP URL. + * * If post slug is updated the amp page with old post slug will be redirected to the updated url. * * @since 0.5 diff --git a/includes/amp-helper-functions.php b/includes/amp-helper-functions.php index a5cc1e25626..254c264f993 100644 --- a/includes/amp-helper-functions.php +++ b/includes/amp-helper-functions.php @@ -243,10 +243,6 @@ function amp_add_amphtml_link() { * @return bool Whether the post supports AMP. */ function post_supports_amp( $post ) { - if ( amp_is_canonical() ) { - return true; - } - $errors = AMP_Post_Type_Support::get_support_errors( $post ); // Return false if an error is found. @@ -261,9 +257,9 @@ function post_supports_amp( $post ) { case AMP_Post_Meta_Box::DISABLED_STATUS: return false; - // Disabled by default for custom page templates, page on front and page for posts. + // Disabled by default for custom page templates, page on front and page for posts, unless 'amp' theme support is present. default: - $enabled = ( + $enabled = current_theme_supports( 'amp' ) || ( ! (bool) get_page_template_slug( $post ) && ! ( @@ -291,10 +287,12 @@ function post_supports_amp( $post ) { } /** - * Are we currently on an AMP URL? + * Determine whether the current response being served as AMP. * - * @since 1.0 This function can be called before the `parse_query` action because the 'amp' query var is specifically and exclusively used when 'amp' theme support is added. + * This function cannot be called before the parse_query action because it needs to be able + * to determine the queried object is able to be served as AMP. * + * @see is_header_video_active() * @return bool Whether it is the AMP endpoint. */ function is_amp_endpoint() { @@ -302,17 +300,47 @@ function is_amp_endpoint() { return false; } - // When 'amp' theme support is (or will be added) then these are the conditions that are key to be checked. - if ( amp_is_canonical() || isset( $_GET[ amp_get_slug() ] ) ) { // WPCS: CSRF OK. - return true; + $did_parse_query = did_action( 'parse_query' ); + + if ( ! $did_parse_query ) { + _doing_it_wrong( __FUNCTION__, sprintf( esc_html__( "is_amp_endpoint() was called before the 'parse_query' hook was called. This function will always return 'false' before the 'parse_query' hook is called.", 'amp' ) ), '0.4.2' ); + } + + $has_amp_query_var = ( + isset( $_GET[ amp_get_slug() ] ) // WPCS: CSRF OK. + || + false !== get_query_var( amp_get_slug(), false ) + ); + + // When there is no query var and AMP is not canonical/native, then this is definitely not an AMP endpoint. + if ( ! $has_amp_query_var && ! amp_is_canonical() ) { + return false; } - // Condition for non-theme support when /amp/ endpoint is used. - if ( false !== get_query_var( amp_get_slug(), false ) ) { - return true; + /* + * If theme suport is present and there is available_callback, it is what determines whether this is + * an AMP endpoint. The available_callback is is presumed to check post_supports_amp(). + * @todo Should available_callback take a WP_Query as its arg? We need to be able to determine whether AMP is supported for another URL. + * @todo Should this not be a filter? + */ + if ( current_theme_supports( 'amp' ) ) { + $args = get_theme_support( 'amp' ); + if ( isset( $args[0]['available_callback'] ) && is_callable( $args[0]['available_callback'] ) ) { + return call_user_func( $args[0]['available_callback'] ); + } + } + + // When there is no theme support, then + if ( $did_parse_query ) { + $queried_object = get_queried_object(); + return ( + is_singular() && $queried_object instanceof WP_Post && post_supports_amp( $queried_object ) + || + ! is_singular() && AMP_Options_Manager::get_option( 'non_singular_supported' ) + ); } - return false; + return true; } /** diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php index a43189097ab..36cec33def1 100644 --- a/includes/class-amp-theme-support.php +++ b/includes/class-amp-theme-support.php @@ -281,6 +281,7 @@ public static function redirect_ampless_url( $exit = true ) { * Returns true when there is a template_dir defined in theme support, and if a defined available_callback * returns true. * + * @see amp_is_canonical() * @return bool Whether available. */ public static function is_paired_available() { @@ -299,6 +300,10 @@ public static function is_paired_available() { return false; } + if ( ! is_singular() && ! AMP_Options_Manager::get_option( 'non_singular_supported' ) ) { + return false; + } + $args = array_shift( $support ); if ( isset( $args['available_callback'] ) && is_callable( $args['available_callback'] ) ) {