diff --git a/amp.php b/amp.php index f854b6caea3..3bbb9ac540f 100644 --- a/amp.php +++ b/amp.php @@ -127,7 +127,20 @@ function amp_force_query_var_value( $query_vars ) { * @return void */ function amp_maybe_add_actions() { - if ( amp_is_canonical() || ! is_singular() || is_feed() ) { + + // Add hooks for when a themes that support AMP. + if ( current_theme_supports( 'amp' ) ) { + if ( amp_is_canonical() ) { + AMP_Canonical_Mode_Actions::register_hooks(); + } elseif ( is_amp_endpoint() ) { + AMP_Paired_Mode_Actions::register_hooks(); + } else { + AMP_Frontend_Actions::register_hooks(); + } + return; + } + + if ( ! is_singular() || is_feed() ) { return; } diff --git a/includes/actions/class-amp-canonical-mode-actions.php b/includes/actions/class-amp-canonical-mode-actions.php new file mode 100644 index 00000000000..952da21096e --- /dev/null +++ b/includes/actions/class-amp-canonical-mode-actions.php @@ -0,0 +1,191 @@ +. + add_action( 'wp_head', array( __CLASS__, 'print_meta_charset' ), 0 ); + add_action( 'wp_head', array( __CLASS__, 'print_meta_viewport' ), 2 ); + add_action( 'wp_head', array( __CLASS__, 'print_amp_boilerplate_code' ), 3 ); + add_action( 'wp_head', array( __CLASS__, 'print_amp_scripts' ), 4 ); + add_action( 'wp_head', array( __CLASS__, 'print_amp_custom_style' ), 5 ); + + add_action( 'admin_bar_init', array( __CLASS__, 'admin_bar_init' ) ); + add_theme_support( 'admin-bar', array( 'callback' => '__return_false' ) ); + + // @todo Add output buffering. + // @todo Add character conversion. + } + + /** + * Print meta charset tag. + * + * @link https://www.ampproject.org/docs/reference/spec#chrs + */ + public static function print_meta_charset() { + echo ''; + } + + /** + * Print meta charset tag. + * + * @link https://www.ampproject.org/docs/reference/spec#vprt + */ + public static function print_meta_viewport() { + echo ''; + } + + /** + * Print AMP boilerplate code. + * + * @link https://www.ampproject.org/docs/reference/spec#boilerplate + */ + public static function print_amp_boilerplate_code() { + echo ''; + echo ''; + } + + /** + * Print AMP script and placeholder for others. + * + * @link https://www.ampproject.org/docs/reference/spec#scrpt + */ + public static function print_amp_scripts() { + echo ''; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript + echo ''; // Replaced after output buffering with all AMP component scripts. + } + + /** + * Add canonical link. + * + * Replaces `rel_canonical()` which only outputs canonical URLs for singular posts and pages. + * This can be removed once WP Core #18660 lands. + * + * @link https://www.ampproject.org/docs/reference/spec#canon. + * @link https://core.trac.wordpress.org/ticket/18660 + * + * @see rel_canonical() + * @global WP $wp + * @global WP_Rewrite $wp_rewrite + */ + public static function rel_canonical() { + global $wp, $wp_rewrite; + + $url = null; + if ( is_singular() ) { + $url = wp_get_canonical_url(); + } + + // For non-singular queries, make use of the request URI and public query vars to determine canonical URL. + if ( empty( $url ) ) { + $added_query_vars = $wp->query_vars; + if ( ! $wp_rewrite->permalink_structure || empty( $wp->request ) ) { + $url = home_url( '/' ); + } else { + $url = home_url( user_trailingslashit( $wp->request ) ); + parse_str( $wp->matched_query, $matched_query_vars ); + foreach ( $wp->query_vars as $key => $value ) { + + // Remove query vars that were matched in the rewrite rules for the request. + if ( isset( $matched_query_vars[ $key ] ) ) { + unset( $added_query_vars[ $key ] ); + } + } + } + } + + if ( ! empty( $added_query_vars ) ) { + $url = add_query_arg( $added_query_vars, $url ); + } + + echo '' . "\n"; + } + + /** + * Print Custom AMP styles. + * + * @see wp_custom_css_cb() + */ + public static function print_amp_custom_style() { + echo ''; + } + + /** + * Fix up admin bar. + */ + public static function admin_bar_init() { + remove_action( 'wp_head', 'wp_admin_bar_header' ); + add_action( 'admin_bar_menu', array( __CLASS__, 'remove_customize_support_script' ), 100 ); // See WP_Admin_Bar::add_menus(). + add_filter( 'body_class', array( __CLASS__, array( __CLASS__, 'filter_body_class_to_force_customize_support' ) ) ); + } + + /** + * Let the body class include customize-support by default since support script won't be able to dynamically add it. + * + * @see wp_customize_support_script() + * + * @param array $classes Body classes. + * @return array Classes. + */ + public static function filter_body_class_to_force_customize_support( $classes ) { + $i = array_search( 'no-customize-support', $classes, true ); + if ( false !== $i ) { + array_splice( $classes, $i, 1 ); + } + $classes[] = 'customize-support'; + return $classes; + } + + /** + * Remove Customizer support script. + * + * @see WP_Admin_Bar::add_menus() + * @see wp_customize_support_script() + */ + public static function remove_customize_support_script() { + remove_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' ); + } +} diff --git a/includes/actions/class-amp-paired-mode-actions.php b/includes/actions/class-amp-paired-mode-actions.php new file mode 100644 index 00000000000..8e3531936b1 --- /dev/null +++ b/includes/actions/class-amp-paired-mode-actions.php @@ -0,0 +1,21 @@ + 'includes/actions/class-amp-actions', 'AMP_Frontend_Actions' => 'includes/actions/class-amp-frontend-actions', 'AMP_Paired_Post_Actions' => 'includes/actions/class-amp-paired-post-actions', + 'AMP_Paired_Mode_Actions' => 'includes/actions/class-amp-paired-mode-actions', + 'AMP_Canonical_Mode_Actions' => 'includes/actions/class-amp-canonical-mode-actions', 'AMP_Template_Customizer' => 'includes/admin/class-amp-customizer', 'AMP_Post_Meta_Box' => 'includes/admin/class-amp-post-meta-box', 'AMP_Post_Type_Support' => 'includes/class-amp-post-type-support',