From 143cd2a21b547b0f92f5ebb4816ffdd8d9ba0fa9 Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Thu, 21 Jun 2018 17:12:35 -0700
Subject: [PATCH 01/34] WIP
---
amp.php | 50 ++++++++++++++++---
includes/class-amp-theme-support.php | 49 +++++++++++++-----
.../options/class-amp-options-manager.php | 20 ++++----
includes/options/class-amp-options-menu.php | 36 ++++++++++---
tests/test-class-amp-theme-support.php | 14 +++---
5 files changed, 124 insertions(+), 45 deletions(-)
diff --git a/amp.php b/amp.php
index ef419328c96..43542fb3669 100644
--- a/amp.php
+++ b/amp.php
@@ -272,15 +272,36 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
}
/**
- * Whether this is in 'canonical mode.'
+ * Whether this is in 'canonical mode'.
*
- * Themes can register support for this with `add_theme_support( 'amp' )`.
- * Then, this will change the plugin from 'paired mode,' and it won't use its own templates.
- * Nor output frontend markup like the 'rel' link. If the theme registers support for AMP with:
- * `add_theme_support( 'amp', array( 'template_dir' => 'my-amp-templates' ) )`
- * it will retain 'paired mode.
+ * Themes can register support for this with `add_theme_support( 'amp' )`, or via the
+ * following so that only so that single blog posts will be native/canonical, pages are paired,
+ * and everything else has AMP unavailable:
*
- * @return boolean Whether this is in AMP 'canonical mode'.
+ * 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;
+ * }
+ * },
+ * ) );
+ *
+ * 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.
+ *
+ * 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(
+ * 'template_dir' => 'my-amp-templates',
+ * ) );
+ *
+ * @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() {
$support = get_theme_support( 'amp' );
@@ -289,9 +310,22 @@ function amp_is_canonical() {
}
if ( is_array( $support ) ) {
$args = array_shift( $support );
- if ( empty( $args['template_dir'] ) ) {
+
+ $is_native = (
+ isset( $args['available_callback'] )
+ &&
+ is_callable( $args['available_callback'] )
+ &&
+ 'native' === call_user_func( $args['available_callback'] )
+ );
+ if ( $is_native ) {
return true;
}
+
+ // 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'] ) ) {
+ return false;
+ }
}
return false;
}
diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php
index 7389490b2bb..a43189097ab 100644
--- a/includes/class-amp-theme-support.php
+++ b/includes/class-amp-theme-support.php
@@ -24,7 +24,7 @@ class AMP_Theme_Support {
*
* @var string
*/
- const RESPONSE_CACHE_GROUP = 'amp-reponse';
+ const RESPONSE_CACHE_GROUP = 'amp-response';
/**
* Sanitizer classes.
@@ -148,8 +148,24 @@ public static function apply_options() {
$args = array(
'__added_via_option' => true,
);
- if ( 'paired' === $theme_support_option ) {
- $args['template_dir'] = './';
+ if ( 'native' === $theme_support_option ) {
+ $args['available_callback'] = function() {
+ /**
+ * Queried object.
+ *
+ * @var WP_Post $queried_object
+ */
+ $queried_object = get_queried_object();
+ if ( is_singular() && post_supports_amp( $queried_object ) ) {
+ return 'native';
+ }
+
+ if ( AMP_Options_Manager::get_option( 'non_singular_supported' ) ) {
+ return 'native';
+ }
+
+ return false;
+ };
}
add_theme_support( 'amp', $args );
}
@@ -168,8 +184,9 @@ public static function finish_init() {
self::ensure_proper_amp_location();
- if ( ! amp_is_canonical() ) {
- self::register_paired_hooks();
+ $theme_support = get_theme_support( 'amp' );
+ if ( ! empty( $theme_support[0]['template_dir'] ) ) {
+ self::add_amp_template_filters();
}
self::add_hooks();
@@ -285,8 +302,14 @@ public static function is_paired_available() {
$args = array_shift( $support );
if ( isset( $args['available_callback'] ) && is_callable( $args['available_callback'] ) ) {
- return call_user_func( $args['available_callback'] );
+ /*
+ * The available_callback here will return a bool or the string 'paired'.
+ * If it returns 'native' then `amp_is_canonical()` above would have short-circuited.
+ */
+ return (bool) call_user_func( $args['available_callback'] );
}
+
+ // This is the same as if there is a template_dir defined with no available_callback.
return true;
}
@@ -303,13 +326,13 @@ public static function is_customize_preview_iframe() {
}
/**
- * Register hooks for paired mode.
+ * Register filters for loading AMP-specific templates.
*/
- public static function register_paired_hooks() {
+ public static function add_amp_template_filters() {
foreach ( self::$template_types as $template_type ) {
- add_filter( "{$template_type}_template_hierarchy", array( __CLASS__, 'filter_paired_template_hierarchy' ) );
+ add_filter( "{$template_type}_template_hierarchy", array( __CLASS__, 'filter_amp_template_hierarchy' ) );
}
- add_filter( 'template_include', array( __CLASS__, 'filter_paired_template_include' ), 100 );
+ add_filter( 'template_include', array( __CLASS__, 'filter_amp_template_include' ), 100 );
}
/**
@@ -727,7 +750,7 @@ public static function amend_comment_form() {
* @param array $templates Template hierarchy.
* @return array Templates.
*/
- public static function filter_paired_template_hierarchy( $templates ) {
+ public static function filter_amp_template_hierarchy( $templates ) {
$support = get_theme_support( 'amp' );
$args = array_shift( $support );
if ( isset( $args['template_dir'] ) ) {
@@ -749,8 +772,8 @@ public static function filter_paired_template_hierarchy( $templates ) {
* @param string $template Template to include.
* @return string Template to include.
*/
- public static function filter_paired_template_include( $template ) {
- if ( empty( $template ) || ! self::is_paired_available() ) {
+ public static function filter_amp_template_include( $template ) {
+ if ( empty( $template ) ) {
wp_safe_redirect( self::get_current_canonical_url(), 302 ); // Temporary redirect because support may come later.
exit;
}
diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php
index 7e0fbf4018e..c41ce3acdc7 100644
--- a/includes/options/class-amp-options-manager.php
+++ b/includes/options/class-amp-options-manager.php
@@ -23,12 +23,13 @@ class AMP_Options_Manager {
* @var array
*/
protected static $defaults = array(
- 'theme_support' => 'disabled',
- 'supported_post_types' => array(),
- 'analytics' => array(),
- 'force_sanitization' => false,
- 'accept_tree_shaking' => false,
- 'disable_admin_bar' => false,
+ 'theme_support' => 'disabled',
+ 'supported_post_types' => array(),
+ 'analytics' => array(),
+ 'force_sanitization' => false,
+ 'accept_tree_shaking' => false,
+ 'disable_admin_bar' => false,
+ 'non_singular_supported' => true,
);
/**
@@ -116,9 +117,10 @@ public static function validate_options( $new_options ) {
$options['theme_support'] = $new_options['theme_support'];
}
- $options['force_sanitization'] = ! empty( $new_options['force_sanitization'] );
- $options['accept_tree_shaking'] = ! empty( $new_options['accept_tree_shaking'] );
- $options['disable_admin_bar'] = ! empty( $new_options['disable_admin_bar'] );
+ $options['force_sanitization'] = ! empty( $new_options['force_sanitization'] );
+ $options['accept_tree_shaking'] = ! empty( $new_options['accept_tree_shaking'] );
+ $options['disable_admin_bar'] = ! empty( $new_options['disable_admin_bar'] );
+ $options['non_singular_supported'] = ! empty( $new_options['non_singular_supported'] );
// Validate post type support.
if ( isset( $new_options['supported_post_types'] ) ) {
diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php
index f3e51f34f7b..2c5eb81f3fc 100644
--- a/includes/options/class-amp-options-menu.php
+++ b/includes/options/class-amp-options-menu.php
@@ -99,9 +99,9 @@ public function add_menu_items() {
);
add_settings_field(
- 'supported_post_types',
- __( 'Post Type Support', 'amp' ),
- array( $this, 'render_post_types_support' ),
+ 'supported_queries',
+ __( 'Supported Queries', 'amp' ),
+ array( $this, 'render_supported_queries' ),
AMP_Options_Manager::OPTION_NAME,
'general',
array(
@@ -276,16 +276,36 @@ public function render_validation_handling() {
*
* @since 0.6
*/
- public function render_post_types_support() {
- $builtin_support = AMP_Post_Type_Support::get_builtin_supported_post_types();
- $element_name = AMP_Options_Manager::OPTION_NAME . '[supported_post_types][]';
+ public function render_supported_queries() {
?>
+
+
+
-
+
@@ -302,7 +302,7 @@ public function render_supported_templates() {
$element_name = AMP_Options_Manager::OPTION_NAME . '[supported_post_types][]';
?>
@@ -333,19 +333,38 @@ public function render_supported_templates() {
array(
- 'front' => array(),
- 'posts' => array(),
- 'date' => array(),
- ),
- 'author' => array(
+ 'author' => array(
'' => __( 'All author pages', 'amp' ),
),
- 'category' => array(
- '' => __( 'All category pages', 'amp' ),
- )
+ 'category' => array_merge(
+ array(
+ '' => __( 'All category pages', 'amp' ),
+ )
+ ),
+ 'tag' => array_merge(
+ array(
+ '' => __( 'All tag pages', 'amp' ),
+ )
+ ),
+ 'date' => array(
+ '' => __( 'All date archives', 'amp' ),
+ 'day' => __( 'Daily archives', 'amp' ),
+ 'month' => __( 'Monthly archives', 'amp' ),
+ 'year' => __( 'Yearly archives', 'amp' ),
+ ),
+ 'page' => array(
+ 'front' => __( 'Front page', 'amp' ),
+ 'posts' => __( 'Posts page', 'amp' ),
+ 'archive' => __( 'Archive page', 'amp' ),
+ '404' => __( '404 error page', 'amp' ),
+ 'search' => __( 'Search results', 'amp' ),
+ ),
+ // @todo Post type archives.
+ // @todo Custom taxonomies.
);
+
?>
From 1d2053c85aff75b8f7814f63fbdbe7cf16a2bb98 Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Wed, 27 Jun 2018 16:42:27 -0700
Subject: [PATCH 05/34] WIP5
---
includes/class-amp-post-type-support.php | 2 +-
includes/class-amp-theme-support.php | 85 +++++++++++
.../options/class-amp-options-manager.php | 8 +-
includes/options/class-amp-options-menu.php | 133 ++++++++----------
4 files changed, 152 insertions(+), 76 deletions(-)
diff --git a/includes/class-amp-post-type-support.php b/includes/class-amp-post-type-support.php
index 22a1bef580b..24ca1b074b0 100644
--- a/includes/class-amp-post-type-support.php
+++ b/includes/class-amp-post-type-support.php
@@ -29,7 +29,7 @@ public static function get_builtin_supported_post_types() {
public static function get_eligible_post_types() {
return array_merge(
self::get_builtin_supported_post_types(),
- array( 'page' ),
+ array( 'page', 'attachment' ),
array_values( get_post_types(
array(
'public' => true,
diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php
index 57644ce47a8..4a4752799e6 100644
--- a/includes/class-amp-theme-support.php
+++ b/includes/class-amp-theme-support.php
@@ -449,6 +449,91 @@ public static function get_template_availability( $query = null ) {
return true;
}
+ /**
+ * Get conditionals which are used for determining availability.
+ *
+ * @return array Selections.
+ */
+ public static function get_template_conditional_options() {
+ $templates = array(
+ 'home' => array(
+ 'label' => __( 'Homepage', 'amp' ),
+ 'callback' => 'is_front_page',
+ ),
+ 'blog' => array(
+ 'label' => __( 'Blog', 'amp' ),
+ 'callback' => 'is_home',
+ ),
+ 'archives' => array(
+ 'label' => __( 'Archives', 'amp' ),
+ 'description' => __( 'Including index pages for categories, tags, authors, and dates.', 'amp' ),
+ 'callback' => 'is_archive',
+ 'children' => array(
+ 'author' => array(
+ 'label' => __( 'Author', 'amp' ),
+ 'callback' => 'is_author',
+ ),
+ 'date' => array(
+ 'label' => __( 'Date', 'amp' ),
+ 'callback' => 'is_date',
+ ),
+ ),
+ ),
+ 'search' => array(
+ 'label' => __( 'Search', 'amp' ),
+ 'callback' => 'is_search',
+ ),
+ '404' => array(
+ 'label' => __( 'Not Found (404)', 'amp' ),
+ 'callback' => 'is_404',
+ ),
+ 'other' => array(
+ 'label' => __( 'Other', 'amp' ),
+ 'callback' => '__return_true',
+ ),
+ );
+
+ if ( taxonomy_exists( 'category' ) ) {
+ $templates['archives']['children']['category'] = array(
+ 'label' => get_taxonomy( 'category' )->labels->name,
+ 'callback' => 'is_category',
+ );
+ }
+ if ( taxonomy_exists( 'post_tag' ) ) {
+ $templates['archives']['children']['tag'] = array(
+ 'label' => get_taxonomy( 'post_tag' )->labels->name,
+ 'callback' => 'is_tag',
+ );
+ }
+ $taxonomy_args = array(
+ '_builtin' => false,
+ 'publicly_queryable' => true,
+ );
+ foreach ( get_taxonomies( $taxonomy_args, 'objects' ) as $taxonomy ) {
+ $templates['archives']['children'][ 'tax_' . $taxonomy->name ] = array(
+ 'label' => $taxonomy->labels->name,
+ 'callback' => function ( WP_Query $query ) use ( $taxonomy ) {
+ return $query->is_tax( $taxonomy->name );
+ },
+ );
+ }
+
+ $post_type_args = array(
+ 'has_archive' => true,
+ 'publicly_queryable' => true,
+ );
+ foreach ( get_post_types( $post_type_args, 'objects' ) as $post_type ) {
+ $templates['archives']['children'][ 'post_type_archive_' . $post_type->name ] = array(
+ 'label' => $post_type->labels->archives,
+ 'callback' => function ( WP_Query $query ) use ( $post_type ) {
+ return $query->is_post_type_archive( $post_type->name );
+ },
+ );
+ }
+
+ return $templates;
+ }
+
/**
* Register hooks.
*/
diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php
index 099975b8cc0..d24ba94f226 100644
--- a/includes/options/class-amp-options-manager.php
+++ b/includes/options/class-amp-options-manager.php
@@ -120,10 +120,10 @@ public static function validate_options( $new_options ) {
$options['theme_support'] = $new_options['theme_support'];
}
- $options['force_sanitization'] = ! empty( $new_options['force_sanitization'] );
- $options['accept_tree_shaking'] = ! empty( $new_options['accept_tree_shaking'] );
- $options['disable_admin_bar'] = ! empty( $new_options['disable_admin_bar'] );
- $options['non_singular_supported'] = ! empty( $new_options['non_singular_supported'] );
+ $options['force_sanitization'] = ! empty( $new_options['force_sanitization'] );
+ $options['accept_tree_shaking'] = ! empty( $new_options['accept_tree_shaking'] );
+ $options['disable_admin_bar'] = ! empty( $new_options['disable_admin_bar'] );
+ $options['all_templates_supported'] = ! empty( $new_options['all_templates_supported'] );
// Validate post type support.
if ( isset( $new_options['supported_post_types'] ) ) {
diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php
index a0c5e20a1cb..048b2b2c23b 100644
--- a/includes/options/class-amp-options-menu.php
+++ b/includes/options/class-amp-options-menu.php
@@ -278,13 +278,7 @@ public function render_validation_handling() {
*/
public function render_supported_templates() {
?>
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
array(
- '' => __( 'All author pages', 'amp' ),
- ),
- 'category' => array_merge(
- array(
- '' => __( 'All category pages', 'amp' ),
- )
- ),
- 'tag' => array_merge(
- array(
- '' => __( 'All tag pages', 'amp' ),
- )
- ),
- 'date' => array(
- '' => __( 'All date archives', 'amp' ),
- 'day' => __( 'Daily archives', 'amp' ),
- 'month' => __( 'Monthly archives', 'amp' ),
- 'year' => __( 'Yearly archives', 'amp' ),
- ),
- 'page' => array(
- 'front' => __( 'Front page', 'amp' ),
- 'posts' => __( 'Posts page', 'amp' ),
- 'archive' => __( 'Archive page', 'amp' ),
- '404' => __( '404 error page', 'amp' ),
- 'search' => __( 'Search results', 'amp' ),
- ),
- // @todo Post type archives.
- // @todo Custom taxonomies.
- );
+ }
+ /**
+ * @param array $options Options.
+ * @param bool $parent_checked
+ */
+ private function list_template_conditional_options( $options, $parent_checked = false ) {
+ $element_name = AMP_Options_Manager::OPTION_NAME . '[supported_templates][]';
?>
+
Date: Wed, 27 Jun 2018 21:46:34 -0700
Subject: [PATCH 06/34] WIP6
---
includes/class-amp-post-type-support.php | 31 +++++++++----------
.../options/class-amp-options-manager.php | 7 ++---
includes/options/class-amp-options-menu.php | 28 ++++++++++++++---
tests/test-class-amp-post-type-support.php | 12 ++-----
4 files changed, 43 insertions(+), 35 deletions(-)
diff --git a/includes/class-amp-post-type-support.php b/includes/class-amp-post-type-support.php
index 24ca1b074b0..31270d540bf 100644
--- a/includes/class-amp-post-type-support.php
+++ b/includes/class-amp-post-type-support.php
@@ -14,9 +14,11 @@ class AMP_Post_Type_Support {
/**
* Get post types that plugin supports out of the box (which cannot be disabled).
*
+ * @deprecated
* @return string[] Post types.
*/
public static function get_builtin_supported_post_types() {
+ _deprecated_function( __METHOD__, '1.0' );
return array_filter( array( 'post' ), 'post_type_exists' );
}
@@ -27,17 +29,12 @@ public static function get_builtin_supported_post_types() {
* @return string[] Post types eligible for AMP.
*/
public static function get_eligible_post_types() {
- return array_merge(
- self::get_builtin_supported_post_types(),
- array( 'page', 'attachment' ),
- array_values( get_post_types(
- array(
- 'public' => true,
- '_builtin' => false,
- ),
- 'names'
- ) )
- );
+ return array_values( get_post_types(
+ array(
+ 'public' => true,
+ ),
+ 'names'
+ ) );
}
/**
@@ -49,10 +46,11 @@ public static function get_eligible_post_types() {
* @since 0.6
*/
public static function add_post_type_support() {
- $post_types = array_merge(
- self::get_builtin_supported_post_types(),
- AMP_Options_Manager::get_option( 'supported_post_types', array() )
- );
+ if ( current_theme_supports( 'amp' ) && AMP_Options_Manager::get_option( 'all_templates_supported' ) ) {
+ $post_types = self::get_eligible_post_types();
+ } else {
+ $post_types = AMP_Options_Manager::get_option( 'supported_post_types', array() );
+ }
foreach ( $post_types as $post_type ) {
add_post_type_support( $post_type, amp_get_slug() );
}
@@ -72,8 +70,7 @@ public static function get_support_errors( $post ) {
}
$errors = array();
- // Because `add_rewrite_endpoint` doesn't let us target specific post_types.
- if ( isset( $post->post_type ) && ! post_type_supports( $post->post_type, amp_get_slug() ) ) {
+ if ( ! post_type_supports( $post->post_type, amp_get_slug() ) ) {
$errors[] = 'post-type-support';
}
diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php
index d24ba94f226..f87f89b6a54 100644
--- a/includes/options/class-amp-options-manager.php
+++ b/includes/options/class-amp-options-manager.php
@@ -24,7 +24,7 @@ class AMP_Options_Manager {
*/
protected static $defaults = array(
'theme_support' => 'disabled',
- 'supported_post_types' => array(),
+ 'supported_post_types' => array( 'post' ),
'analytics' => array(),
'force_sanitization' => false,
'accept_tree_shaking' => false,
@@ -126,8 +126,8 @@ public static function validate_options( $new_options ) {
$options['all_templates_supported'] = ! empty( $new_options['all_templates_supported'] );
// Validate post type support.
+ $options['supported_post_types'] = array();
if ( isset( $new_options['supported_post_types'] ) ) {
- $options['supported_post_types'] = array();
foreach ( $new_options['supported_post_types'] as $post_type ) {
if ( ! post_type_exists( $post_type ) ) {
add_settings_error( self::OPTION_NAME, 'unknown_post_type', __( 'Unrecognized post type.', 'amp' ) );
@@ -192,11 +192,10 @@ public static function validate_options( $new_options ) {
* @see add_settings_error()
*/
public static function check_supported_post_type_update_errors() {
- $builtin_support = AMP_Post_Type_Support::get_builtin_supported_post_types();
$supported_types = self::get_option( 'supported_post_types', array() );
foreach ( AMP_Post_Type_Support::get_eligible_post_types() as $name ) {
$post_type = get_post_type_object( $name );
- if ( empty( $post_type ) || in_array( $post_type->name, $builtin_support, true ) ) {
+ if ( empty( $post_type ) ) {
continue;
}
diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php
index 048b2b2c23b..5664a06f01a 100644
--- a/includes/options/class-amp-options-menu.php
+++ b/includes/options/class-amp-options-menu.php
@@ -293,6 +293,9 @@ public function render_supported_templates() {
+
+
+
-
@@ -304,7 +307,6 @@ public function render_supported_templates() {
value="name ); ?>"
name, amp_get_slug() ) ); ?>
>
-
@@ -321,9 +323,18 @@ public function render_supported_templates() {
+
', $sanitized_html ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
}
+ /**
+ * Test get_template_availability.
+ *
+ * @covers AMP_Theme_Support::get_template_availability()
+ */
+ public function test_get_template_availability() {
+ $this->markTestIncomplete();
+ // @todo Test nested.
+ // @todo Test callback vs ID.
+ // @todo Test with query, post, or page.
+ // @todo Test without availability of WP_Query (no_query_available).
+ // @todo Test without theme support (no_theme_support).
+ // @todo Test unrecognized by theme support arg.
+ // @todo Test unrecognized.
+ }
+
+ /**
+ * Test get_supportable_templates.
+ *
+ * @covers AMP_Theme_Support::get_supportable_templates()
+ */
+ public function test_get_supportable_templates() {
+ $this->markTestIncomplete();
+ // @todo Register custom taxonomy.
+ // @todo Set static front page
+ // @todo Add custom post types.
+ }
+
/**
* Test add_hooks.
*
@@ -812,11 +844,11 @@ public function test_amend_comment_form() {
}
/**
- * Test filter_paired_template_hierarchy.
+ * Test filter_amp_template_hierarchy.
*
* @covers AMP_Theme_Support::filter_amp_template_hierarchy()
*/
- public function test_filter_paired_template_hierarchy() {
+ public function test_filter_amp_template_hierarchy() {
$template_dir = 'amp-templates';
add_theme_support( 'amp', array(
'template_dir' => $template_dir,
@@ -950,6 +982,15 @@ public function test_filter_cancel_comment_reply_link() {
$this->assertContains( 'Click here to cancel reply.', $filtered_link_no_text_passed );
}
+ /**
+ * Test init_admin_bar.
+ *
+ * @covers \AMP_Theme_Support::init_admin_bar()
+ */
+ public function test_init_admin_bar() {
+ $this->markTestIncomplete();
+ }
+
/**
* Test print_amp_styles.
*
From 3d07eac72467132c99c20b0db85115080e0293fc Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Sun, 1 Jul 2018 20:49:53 -0700
Subject: [PATCH 25/34] Discard matching is_home when there are other matching
templates
---
includes/class-amp-theme-support.php | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php
index 65665ade482..18a8f0e593c 100644
--- a/includes/class-amp-theme-support.php
+++ b/includes/class-amp-theme-support.php
@@ -489,7 +489,7 @@ public static function get_template_availability( $query = null ) {
if ( is_string( $callback ) && 'is_' === substr( $callback, 0, 3 ) && method_exists( $query, $callback ) ) {
$is_match = call_user_func( array( $query, $callback ) );
} elseif ( is_callable( $callback ) ) {
- $is_match = call_user_func( $callback );
+ $is_match = call_user_func( $callback, $query );
} else {
/* translators: %s is the supportable template ID. */
_doing_it_wrong( __FUNCTION__, esc_html__( 'Supportable template "%s" does not have a callable callback.', 'amp' ), '1.0' );
@@ -535,6 +535,15 @@ public static function get_template_availability( $query = null ) {
}
}
+ // The is_home() condition is the default so discard it if there are other matching templates.
+ if ( count( $matching_templates ) > 1 && isset( $matching_templates['is_home'] ) ) {
+ unset( $matching_templates['is_home'] );
+ }
+
+ /*
+ * If there are more than one matching templates, then something is probably not right.
+ * Template conditions need to be set up properly to prevent this from happening.
+ */
if ( count( $matching_templates ) > 1 ) {
_doing_it_wrong( __FUNCTION__, esc_html__( 'Did not expect there to be more than one matching template. Did you filter amp_supportable_templates to not honor the template hierarchy?', 'amp' ), '1.0' );
}
From c32d76b62e3322974fffb7936f75b69faaaca106 Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Sun, 1 Jul 2018 21:03:53 -0700
Subject: [PATCH 26/34] Elimiante Other/unrecognized template option since
indistinguishable from is_home
* Devs should use filter to add support for custom templates
* When a custom template is added via amp_supportable_templates filter then is_home will be discarded if there is another match
---
includes/class-amp-theme-support.php | 5 +----
.../options/class-amp-options-manager.php | 20 ++++++++-----------
includes/options/class-amp-options-menu.php | 10 ----------
tests/test-class-amp-meta-box.php | 1 -
tests/test-class-amp-options-manager.php | 17 ++++++++--------
tests/test-class-amp-theme-support.php | 2 --
6 files changed, 17 insertions(+), 38 deletions(-)
diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php
index 18a8f0e593c..3f06cc24455 100644
--- a/includes/class-amp-theme-support.php
+++ b/includes/class-amp-theme-support.php
@@ -468,9 +468,6 @@ public static function get_template_availability( $query = null ) {
$all_templates_supported = (
$all_templates_supported_by_theme_support || AMP_Options_Manager::get_option( 'all_templates_supported' )
);
- $unrecognized_templates_supported = ( // @todo Get this from $supportable_templates.
- isset( $theme_templates_supported['unrecognized'] ) ? true === $theme_templates_supported['unrecognized'] : AMP_Options_Manager::get_option( 'unrecognized_templates_supported' )
- );
// Make sure global $wp_query is set in case of conditionals that unfortunately look at global scope.
$prev_query = $wp_query;
@@ -552,7 +549,7 @@ public static function get_template_availability( $query = null ) {
// If there aren't any matching templates left that are supported, then we consider it to not be available.
if ( ! $matching_template ) {
- if ( $all_templates_supported || $unrecognized_templates_supported ) {
+ if ( $all_templates_supported ) {
return array_merge(
$default_response,
array(
diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php
index a4f82af1620..40eb41f85ee 100644
--- a/includes/options/class-amp-options-manager.php
+++ b/includes/options/class-amp-options-manager.php
@@ -23,15 +23,14 @@ class AMP_Options_Manager {
* @var array
*/
protected static $defaults = array(
- 'theme_support' => 'disabled',
- 'supported_post_types' => array( 'post' ),
- 'analytics' => array(),
- 'force_sanitization' => false,
- 'accept_tree_shaking' => false,
- 'disable_admin_bar' => false,
- 'all_templates_supported' => true,
- 'unrecognized_templates_supported' => false,
- 'supported_templates' => array( 'is_singular' ),
+ 'theme_support' => 'disabled',
+ 'supported_post_types' => array( 'post' ),
+ 'analytics' => array(),
+ 'force_sanitization' => false,
+ 'accept_tree_shaking' => false,
+ 'disable_admin_bar' => false,
+ 'all_templates_supported' => true,
+ 'supported_templates' => array( 'is_singular' ),
);
/**
@@ -128,9 +127,6 @@ public static function validate_options( $new_options ) {
$is_template_support_required = ( isset( $theme_support_args['templates_supported'] ) && 'all' === $theme_support_args['templates_supported'] );
if ( ! $is_template_support_required ) {
$options['all_templates_supported'] = ! empty( $new_options['all_templates_supported'] );
- if ( ! isset( $theme_support_args['templates_supported']['unrecognized'] ) ) {
- $options['unrecognized_templates_supported'] = ! empty( $new_options['unrecognized_templates_supported'] );
- }
// Validate post type support.
$options['supported_post_types'] = array();
diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php
index f30b611637e..207cdfd2733 100644
--- a/includes/options/class-amp-options-menu.php
+++ b/includes/options/class-amp-options-menu.php
@@ -344,16 +344,6 @@ public function render_supported_templates() {
-
-
-
-
', $sanitized_html ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
}
+ /**
+ * Test incorrect usage for get_template_availability.
+ *
+ * @expectedIncorrectUsage AMP_Theme_Support::get_template_availability
+ * @covers AMP_Theme_Support::get_template_availability()
+ */
+ public function test_incorrect_usage_get_template_availability() {
+ global $wp_query;
+
+ // Test no query available.
+ $wp_query = null; // WPCS: override ok.
+ $availability = AMP_Theme_Support::get_template_availability();
+ $this->assertInternalType( 'array', $availability );
+ $this->assertEquals( array( 'no_query_available' ), $availability['errors'] );
+ $this->assertFalse( $availability['supported'] );
+ $this->assertNull( $availability['immutable'] );
+ $this->assertNull( $availability['template'] );
+
+ // Test no theme support.
+ remove_theme_support( 'amp' );
+ $this->go_to( get_permalink( $this->factory()->post->create() ) );
+ $availability = AMP_Theme_Support::get_template_availability();
+ $this->assertEquals( array( 'no_theme_support' ), $availability['errors'] );
+ $this->assertFalse( $availability['supported'] );
+ $this->assertNull( $availability['immutable'] );
+ $this->assertNull( $availability['template'] );
+ }
+
/**
* Test get_template_availability.
*
* @covers AMP_Theme_Support::get_template_availability()
*/
public function test_get_template_availability() {
- $this->markTestIncomplete();
- // @todo Test nested.
- // @todo Test callback vs ID.
- // @todo Test with query, post, or page.
- // @todo Test without availability of WP_Query (no_query_available).
- // @todo Test without theme support (no_theme_support).
+ global $wp_query;
+ $post_id = $this->factory()->post->create();
+ query_posts( array( 'p' => $post_id ) ); // phpcs:ignore
+
+ // Test successful match of singular template.
+ $this->assertTrue( is_singular() );
+ AMP_Options_Manager::update_option( 'all_templates_supported', false );
+ add_theme_support( 'amp' );
+ $availability = AMP_Theme_Support::get_template_availability();
+ $this->assertEmpty( $availability['errors'] );
+ $this->assertTrue( $availability['supported'] );
+ $this->assertFalse( $availability['immutable'] );
+ $this->assertEquals( 'is_singular', $availability['template'] );
+
+ // Test successful match when passing WP_Query and WP_Post into method.
+ $query = $wp_query;
+ $wp_query = null; // WPCS: override ok.
+ $availability = AMP_Theme_Support::get_template_availability( $query );
+ $this->assertTrue( $availability['supported'] );
+ $this->assertEquals( 'is_singular', $availability['template'] );
+ $availability = AMP_Theme_Support::get_template_availability( get_post( $post_id ) );
+ $this->assertTrue( $availability['supported'] );
+ $this->assertEquals( 'is_singular', $availability['template'] );
+ $this->assertNull( $wp_query ); // Make sure it is reset.
+
+ // Test nested hierarchy.
+ AMP_Options_Manager::update_option( 'supported_templates', array( 'is_special' ) );
+ add_filter( 'amp_supportable_templates', function( $templates ) {
+ $templates['is_single'] = array(
+ 'label' => 'Single post',
+ 'supported' => false,
+ 'parent' => 'is_singular',
+ );
+ $templates['is_special'] = array(
+ 'label' => 'Special post',
+ 'parent' => 'is_single',
+ 'callback' => function( WP_Query $query ) {
+ return $query->is_singular() && 'special' === get_post( $query->get_queried_object_id() )->post_name;
+ },
+ );
+ $templates['is_page'] = array(
+ 'label' => 'Page',
+ 'supported' => true,
+ 'parent' => 'is_singular',
+ );
+ return $templates;
+ } );
+
+ $availability = AMP_Theme_Support::get_template_availability( get_post( $post_id ) );
+ $this->assertFalse( $availability['supported'] );
+ $this->assertTrue( $availability['immutable'] );
+ $this->assertEquals( 'is_single', $availability['template'] );
+
+ $special_id = $this->factory()->post->create( array(
+ 'post_type' => 'post',
+ 'post_name' => 'special',
+ ) );
+ $availability = AMP_Theme_Support::get_template_availability( get_post( $special_id ) );
+ $this->assertTrue( $availability['supported'] );
+ $this->assertEquals( 'is_special', $availability['template'] );
+ $this->assertFalse( $availability['immutable'] );
+
+ $availability = AMP_Theme_Support::get_template_availability( $this->factory()->post->create_and_get( array( 'post_type' => 'page' ) ) );
+ $this->assertFalse( $availability['supported'] );
+ $this->assertEquals( array( 'post-type-support' ), $availability['errors'] );
+ $this->assertEquals( 'is_page', $availability['template'] );
+ add_post_type_support( 'page', 'amp' );
+ $availability = AMP_Theme_Support::get_template_availability( $this->factory()->post->create_and_get( array( 'post_type' => 'page' ) ) );
+ $this->assertTrue( $availability['supported'] );
}
/**
From 38b5546fc1a34c387f9b698ead370845ab775d58 Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Mon, 2 Jul 2018 00:47:50 -0700
Subject: [PATCH 31/34] Add test for custom template
---
tests/test-class-amp-theme-support.php | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/tests/test-class-amp-theme-support.php b/tests/test-class-amp-theme-support.php
index 99084230af3..13ce040fa90 100644
--- a/tests/test-class-amp-theme-support.php
+++ b/tests/test-class-amp-theme-support.php
@@ -473,7 +473,7 @@ public function test_get_template_availability() {
$this->assertNull( $wp_query ); // Make sure it is reset.
// Test nested hierarchy.
- AMP_Options_Manager::update_option( 'supported_templates', array( 'is_special' ) );
+ AMP_Options_Manager::update_option( 'supported_templates', array( 'is_special', 'is_custom' ) );
add_filter( 'amp_supportable_templates', function( $templates ) {
$templates['is_single'] = array(
'label' => 'Single post',
@@ -492,8 +492,18 @@ public function test_get_template_availability() {
'supported' => true,
'parent' => 'is_singular',
);
+ $templates['is_custom'] = array(
+ 'label' => 'Custom',
+ 'callback' => function( WP_Query $query ) {
+ return false !== $query->get( 'custom', false );
+ },
+ );
return $templates;
} );
+ add_filter( 'query_vars', function( $vars ) {
+ $vars[] = 'custom';
+ return $vars;
+ } );
$availability = AMP_Theme_Support::get_template_availability( get_post( $post_id ) );
$this->assertFalse( $availability['supported'] );
@@ -516,6 +526,12 @@ public function test_get_template_availability() {
add_post_type_support( 'page', 'amp' );
$availability = AMP_Theme_Support::get_template_availability( $this->factory()->post->create_and_get( array( 'post_type' => 'page' ) ) );
$this->assertTrue( $availability['supported'] );
+
+ // Test custom.
+ $this->go_to( '/?custom=1' );
+ $availability = AMP_Theme_Support::get_template_availability();
+ $this->assertTrue( $availability['supported'] );
+ $this->assertEquals( 'is_custom', $availability['template'] );
}
/**
From acf9849ef0b3094dfb18b4c15a0980f22d8b9b15 Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Mon, 2 Jul 2018 11:31:22 -0700
Subject: [PATCH 32/34] Restore available_callback but mark as deprecated
Use _doing_it_wrong() instead of trigger_error()
---
includes/admin/class-amp-post-meta-box.php | 5 +
includes/class-amp-theme-support.php | 63 ++++++---
.../options/class-amp-options-manager.php | 26 ++--
includes/options/class-amp-options-menu.php | 132 ++++++++++--------
tests/test-class-amp-theme-support.php | 100 ++++++++++---
5 files changed, 216 insertions(+), 110 deletions(-)
diff --git a/includes/admin/class-amp-post-meta-box.php b/includes/admin/class-amp-post-meta-box.php
index 58c14246363..325e81e7b9d 100644
--- a/includes/admin/class-amp-post-meta-box.php
+++ b/includes/admin/class-amp-post-meta-box.php
@@ -184,6 +184,11 @@ public function render_status( $post ) {
return;
}
+ /*
+ * When theme support is present then theme templates can be served in AMP and we check first if the template is available.
+ * Checking for template availability will include a check for get_support_errors. Otherwise, if theme support is not present
+ * then we just check get_support_errors.
+ */
if ( current_theme_supports( 'amp' ) ) {
$availability = AMP_Theme_Support::get_template_availability( $post );
$status = $availability['supported'] ? self::ENABLED_STATUS : self::DISABLED_STATUS;
diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php
index f373a004724..fbc25ba3050 100644
--- a/includes/class-amp-theme-support.php
+++ b/includes/class-amp-theme-support.php
@@ -157,10 +157,8 @@ public static function is_support_added_via_option() {
* Read theme support and apply options from admin for whether theme support is enabled and via what template is enabled.
*
* @see AMP_Post_Type_Support::add_post_type_support() For where post type support is added, since it is irrespective of theme support.
- *
- * @param bool $check_args Whether the theme support args should be checked.
*/
- public static function read_theme_support( $check_args = WP_DEBUG ) {
+ public static function read_theme_support() {
self::$support_added_via_option = false;
self::$initial_theme_support_args = false;
@@ -172,18 +170,20 @@ public static function read_theme_support( $check_args = WP_DEBUG ) {
self::$initial_theme_support_args = array_shift( $support );
// Validate theme support usage.
- if ( $check_args ) {
- $keys = array( 'template_dir', 'comments_live_list', 'mode', 'optional', 'templates_supported' );
- if ( ! is_array( self::$initial_theme_support_args ) ) {
- trigger_error( esc_html__( 'Expected AMP theme support arg to be array.', 'amp' ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
- } elseif ( count( array_diff( array_keys( self::$initial_theme_support_args ), $keys ) ) !== 0 ) {
- trigger_error( esc_html( sprintf( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
- /* translators: %1$s is expected keys and %2$s is actual keys */
- __( 'Expected AMP theme support to keys (%1$s) but saw (%2$s)', 'amp' ),
- join( ', ', $keys ),
- join( ', ', array_keys( self::$initial_theme_support_args ) )
- ) ) );
- }
+ $keys = array( 'template_dir', 'comments_live_list', 'mode', 'optional', 'templates_supported', 'available_callback' );
+ if ( ! is_array( self::$initial_theme_support_args ) ) {
+ _doing_it_wrong( 'add_theme_support', esc_html__( 'Expected AMP theme support arg to be array.', 'amp' ), '1.0' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
+ } elseif ( count( array_diff( array_keys( self::$initial_theme_support_args ), $keys ) ) !== 0 ) {
+ _doing_it_wrong( 'add_theme_support', esc_html( sprintf( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
+ /* translators: %1$s is expected keys and %2$s is actual keys */
+ __( 'Expected AMP theme support to keys (%1$s) but saw (%2$s)', 'amp' ),
+ join( ', ', $keys ),
+ join( ', ', array_keys( self::$initial_theme_support_args ) )
+ ) ), '1.0' );
+ }
+
+ if ( isset( self::$initial_theme_support_args['available_callback'] ) ) {
+ _doing_it_wrong( 'add_theme_support', esc_html__( 'The available_callback is deprecated when adding amp theme support in favor of declaratively setting the supported_templates.', 'amp' ), '1.0' );
}
}
}
@@ -359,7 +359,6 @@ public static function redirect_ampless_url( $exit = true ) {
* When 'amp' theme support has not been added or canonical mode is enabled, then this returns false.
*
* @since 0.7
- * @since 1.0 This no longer looks at the available_callback bit instead calls get_template_availability.
*
* @see amp_is_canonical()
* @return bool Whether available.
@@ -457,6 +456,38 @@ public static function get_template_availability( $query = null ) {
);
}
+ // Support available_callback from 0.7, though it is deprecated.
+ if ( isset( $theme_support_args['available_callback'] ) && is_callable( $theme_support_args['available_callback'] ) ) {
+ /**
+ * Queried object.
+ *
+ * @var WP_Post $queried_object
+ */
+ $queried_object = $query->get_queried_object();
+ if ( ( is_singular() || $query->is_posts_page ) && ! post_supports_amp( $queried_object ) ) {
+ return array_merge(
+ $default_response,
+ array(
+ 'errors' => array( 'no-post-support' ),
+ 'supported' => false,
+ 'immutable' => true,
+ )
+ );
+ }
+
+ $response = array_merge(
+ $default_response,
+ array(
+ 'supported' => call_user_func( $theme_support_args['available_callback'] ),
+ 'immutable' => true,
+ )
+ );
+ if ( ! $response['supported'] ) {
+ $response['errors'][] = 'available_callback';
+ }
+ return $response;
+ }
+
$all_templates_supported_by_theme_support = false;
if ( isset( $theme_support_args['templates_supported'] ) ) {
$all_templates_supported_by_theme_support = 'all' === $theme_support_args['templates_supported'];
diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php
index 40eb41f85ee..e18bdbc1bad 100644
--- a/includes/options/class-amp-options-manager.php
+++ b/includes/options/class-amp-options-manager.php
@@ -122,24 +122,24 @@ public static function validate_options( $new_options ) {
$options['accept_tree_shaking'] = ! empty( $new_options['accept_tree_shaking'] );
$options['disable_admin_bar'] = ! empty( $new_options['disable_admin_bar'] );
+ // Validate post type support.
+ $options['supported_post_types'] = array();
+ if ( isset( $new_options['supported_post_types'] ) ) {
+ foreach ( $new_options['supported_post_types'] as $post_type ) {
+ if ( ! post_type_exists( $post_type ) ) {
+ add_settings_error( self::OPTION_NAME, 'unknown_post_type', __( 'Unrecognized post type.', 'amp' ) );
+ } else {
+ $options['supported_post_types'][] = $post_type;
+ }
+ }
+ }
+
$theme_support_args = AMP_Theme_Support::get_theme_support_args( array( 'initial' => true ) );
$is_template_support_required = ( isset( $theme_support_args['templates_supported'] ) && 'all' === $theme_support_args['templates_supported'] );
- if ( ! $is_template_support_required ) {
+ if ( ! $is_template_support_required && ! isset( $theme_support_args['available_callback'] ) ) {
$options['all_templates_supported'] = ! empty( $new_options['all_templates_supported'] );
- // Validate post type support.
- $options['supported_post_types'] = array();
- if ( isset( $new_options['supported_post_types'] ) ) {
- foreach ( $new_options['supported_post_types'] as $post_type ) {
- if ( ! post_type_exists( $post_type ) ) {
- add_settings_error( self::OPTION_NAME, 'unknown_post_type', __( 'Unrecognized post type.', 'amp' ) );
- } else {
- $options['supported_post_types'][] = $post_type;
- }
- }
- }
-
// Validate supported templates.
$options['supported_templates'] = array();
if ( isset( $new_options['supported_templates'] ) ) {
diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php
index 207cdfd2733..82672bc1df6 100644
--- a/includes/options/class-amp-options-menu.php
+++ b/includes/options/class-amp-options-menu.php
@@ -287,27 +287,35 @@ public function render_validation_handling() {
*/
public function render_supported_templates() {
$theme_support_args = AMP_Theme_Support::get_theme_support_args( array( 'initial' => true ) ); // Initial so we can get before removed if optional.
-
?>
-
-
-
-
+
+
+
+
+
+
+
+
@@ -334,55 +342,57 @@ public function render_supported_templates() {
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
assertInstanceOf( 'PHPUnit_Framework_Error_Notice', $e );
- $this->assertEquals( 'Expected AMP theme support arg to be array.', $e->getMessage() );
+ AMP_Theme_Support::read_theme_support();
$this->assertTrue( current_theme_supports( 'amp' ) );
+ }
- // Test invalid args for theme support.
+ /**
+ * Test add_theme_support(amp) with invalid args.
+ *
+ * @expectedIncorrectUsage add_theme_support
+ * @covers \AMP_Theme_Support::read_theme_support()
+ * @covers \AMP_Theme_Support::get_theme_support_args()
+ */
+ public function test_read_theme_support_bad_args_array() {
$args = array(
'mode' => 'native',
'invalid_param_key' => array(),
);
add_theme_support( 'amp', $args );
- try {
- AMP_Theme_Support::read_theme_support( true );
- } catch ( Exception $exception ) {
- $e = $exception;
- }
- $this->assertStringStartsWith( 'Expected AMP theme support to keys', $e->getMessage() );
+ AMP_Theme_Support::read_theme_support();
+ $this->assertTrue( current_theme_supports( 'amp' ) );
$this->assertEquals( $args, AMP_Theme_Support::get_theme_support_args() );
$this->assertEquals( $args, AMP_Theme_Support::get_theme_support_args( array( 'initial' => true ) ) );
$this->assertTrue( current_theme_supports( 'amp' ) );
+ }
+
+ /**
+ * Test add_theme_support(amp) with invalid args.
+ *
+ * @expectedIncorrectUsage add_theme_support
+ * @covers \AMP_Theme_Support::read_theme_support()
+ */
+ public function test_read_theme_support_bad_available_callback() {
+ add_theme_support( 'amp', array(
+ 'available_callback' => function() {
+ return (bool) wp_rand( 0, 1 );
+ },
+ ) );
+ AMP_Theme_Support::read_theme_support();
+ $this->assertTrue( current_theme_supports( 'amp' ) );
+ }
+
+ /**
+ * Test read_theme_support, get_theme_support_args, and is_support_added_via_option.
+ *
+ * @covers \AMP_Theme_Support::read_theme_support()
+ * @covers \AMP_Theme_Support::is_support_added_via_option()
+ * @covers \AMP_Theme_Support::get_theme_support_args()
+ */
+ public function test_read_theme_support_and_support_args() {
// Test behavior of optional flag, that AMP is not enabled if the DB option is not set.
$args = array(
@@ -441,6 +462,45 @@ public function test_incorrect_usage_get_template_availability() {
$this->assertNull( $availability['template'] );
}
+ /**
+ * Test get_template_availability with available_callback.
+ *
+ * @expectedIncorrectUsage add_theme_support
+ * @covers AMP_Theme_Support::get_template_availability()
+ */
+ public function test_get_template_availability_with_available_callback() {
+ $this->go_to( get_permalink( $this->factory()->post->create() ) );
+ add_theme_support( 'amp', array(
+ 'available_callback' => '__return_true',
+ ) );
+ AMP_Theme_Support::init();
+ $availability = AMP_Theme_Support::get_template_availability();
+ $this->assertEquals(
+ $availability,
+ array(
+ 'supported' => true,
+ 'immutable' => true,
+ 'template' => null,
+ 'errors' => array(),
+ )
+ );
+
+ add_theme_support( 'amp', array(
+ 'available_callback' => '__return_false',
+ ) );
+ AMP_Theme_Support::init();
+ $availability = AMP_Theme_Support::get_template_availability();
+ $this->assertEquals(
+ $availability,
+ array(
+ 'supported' => false,
+ 'immutable' => true,
+ 'template' => null,
+ 'errors' => array( 'available_callback' ),
+ )
+ );
+ }
+
/**
* Test get_template_availability.
*
From 7091b35ec7f316680cf5d1c6cf77a66dd6aa47b8 Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Mon, 2 Jul 2018 11:44:37 -0700
Subject: [PATCH 33/34] Fix generation of AMP permalink for attachments
---
includes/amp-helper-functions.php | 3 +++
includes/class-amp-theme-support.php | 1 +
2 files changed, 4 insertions(+)
diff --git a/includes/amp-helper-functions.php b/includes/amp-helper-functions.php
index 964a563ce94..aa2d825554d 100644
--- a/includes/amp-helper-functions.php
+++ b/includes/amp-helper-functions.php
@@ -123,6 +123,9 @@ function amp_get_permalink( $post_id ) {
||
// If the post type is hierarchical then the /amp/ endpoint isn't available.
is_post_type_hierarchical( get_post_type( $post_id ) )
+ ||
+ // Attachment pages don't accept the /amp/ endpoint.
+ 'attachment' === get_post_type( $post_id )
);
if ( $use_query_var ) {
$amp_url = add_query_arg( amp_get_slug(), '', $permalink );
diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php
index fbc25ba3050..709d1082208 100644
--- a/includes/class-amp-theme-support.php
+++ b/includes/class-amp-theme-support.php
@@ -172,6 +172,7 @@ public static function read_theme_support() {
// Validate theme support usage.
$keys = array( 'template_dir', 'comments_live_list', 'mode', 'optional', 'templates_supported', 'available_callback' );
if ( ! is_array( self::$initial_theme_support_args ) ) {
+ self::$initial_theme_support_args = array();
_doing_it_wrong( 'add_theme_support', esc_html__( 'Expected AMP theme support arg to be array.', 'amp' ), '1.0' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
} elseif ( count( array_diff( array_keys( self::$initial_theme_support_args ), $keys ) ) !== 0 ) {
_doing_it_wrong( 'add_theme_support', esc_html( sprintf( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
From b54fcc0e9278eecebf91bb104e4ee23881cc1019 Mon Sep 17 00:00:00 2001
From: Weston Ruter
Date: Mon, 2 Jul 2018 12:32:53 -0700
Subject: [PATCH 34/34] Fix initialization of paried mode and Customizer, and
fix support options on admin screen
---
amp.php | 16 +++++++++++++++-
includes/options/class-amp-options-menu.php | 14 ++++----------
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/amp.php b/amp.php
index 09fa1402bd7..18baaf95225 100644
--- a/amp.php
+++ b/amp.php
@@ -301,6 +301,7 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
* 'templates_supported' => 'all',
* ) );
*
+ * @see AMP_Theme_Support::read_theme_support()
* @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() {
@@ -311,9 +312,22 @@ function amp_is_canonical() {
$mode = 'native';
$support = get_theme_support( 'amp' );
if ( is_array( $support ) ) {
- $args = array_shift( $support );
+ $args = array_shift( $support );
+ $support = AMP_Options_Manager::get_option( 'theme_support' );
+
+ // If support is optional, look at DB option if mode is not explicitly set in theme support.
+ if ( ! empty( $args['optional'] ) ) {
+ if ( 'disabled' === $support ) {
+ return false;
+ } elseif ( ! isset( $args['mode'] ) ) {
+ return 'native' === $support;
+ }
+ }
+
if ( isset( $args['mode'] ) ) {
$mode = $args['mode'];
+ } elseif ( 'disabled' !== $support ) {
+ $mode = $support; // Supplied via admin screen.
} elseif ( ! empty( $args['template_dir'] ) ) {
$mode = 'paired'; // If there is a template_dir, then paired mode is implied.
}
diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php
index 82672bc1df6..4ce89cf0958 100644
--- a/includes/options/class-amp-options-menu.php
+++ b/includes/options/class-amp-options-menu.php
@@ -129,21 +129,15 @@ public function render_theme_support() {
$support_args = AMP_Theme_Support::get_theme_support_args( array( 'initial' => true ) );
$theme_support_mutable = (
- empty( $support_args )
- ||
! empty( $support_args['optional'] )
||
AMP_Theme_Support::is_support_added_via_option()
);
- $mode_mutable = ! ( is_array( $support_args ) && isset( $support_args['mode'] ) );
+ $mode_mutable = ! isset( $support_args['mode'] );
if ( ! $theme_support_mutable || ( ! $mode_mutable && 'disabled' !== $theme_support ) ) {
- if ( amp_is_canonical() ) {
- $theme_support = 'native';
- } else {
- $theme_support = 'paired';
- }
+ $theme_support = isset( $support_args['mode'] ) ? $support_args['mode'] : 'native';
}
$should_have_theme_support = in_array( get_template(), array( 'twentyfifteen', 'twentysixteen', 'twentyseventeen' ), true );
@@ -168,7 +162,7 @@ public function render_theme_support() {
-
+
>