Skip to content

Commit bbecffc

Browse files
westonruterswissspidy
authored andcommitted
Refactor AMP modes (#2550)
* Always allow switching from Transitional to Native on sites that are defined with `add_theme_support('amp', ['paired' => true])`. Fixes #2312. * Restore suppression of validation error warnings appearing in Reader mode. Fixes #2311 * Add functionality for users to chose AMP + Stories, AMP-only, Stories-only. Fixes #2470 * Phase out “Native” terminology in favor of “AMP-first”. Fixes #2507.
1 parent 875c6ee commit bbecffc

32 files changed

+1041
-447
lines changed

amp.php

+30-26
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ function amp_deactivate() {
278278
}
279279
}
280280

281-
flush_rewrite_rules();
281+
flush_rewrite_rules( false );
282282
}
283283

284284
/*
@@ -333,38 +333,42 @@ function amp_init() {
333333
*/
334334
do_action( 'amp_init' );
335335

336-
add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK );
337-
338336
add_filter( 'allowed_redirect_hosts', array( 'AMP_HTTP', 'filter_allowed_redirect_hosts' ) );
339337
AMP_HTTP::purge_amp_query_vars();
340338
AMP_HTTP::send_cors_headers();
341339
AMP_HTTP::handle_xhr_request();
342340
AMP_Theme_Support::init();
343341
AMP_Validation_Manager::init();
344-
AMP_Post_Type_Support::add_post_type_support();
345-
AMP_Story_Post_Type::register();
346342
AMP_Service_Worker::init();
347-
add_action( 'init', array( 'AMP_Post_Type_Support', 'add_post_type_support' ), 1000 ); // After post types have been defined.
348-
349-
if ( defined( 'WP_CLI' ) && WP_CLI ) {
350-
WP_CLI::add_command( 'amp', new AMP_CLI() );
351-
}
352-
353-
add_filter( 'request', 'amp_force_query_var_value' );
354343
add_action( 'admin_init', 'AMP_Options_Manager::register_settings' );
355-
add_action( 'wp_loaded', 'amp_editor_core_blocks' );
356-
add_action( 'wp_loaded', 'amp_post_meta_box' );
357-
add_action( 'wp_loaded', 'amp_story_templates' );
358344
add_action( 'wp_loaded', 'amp_add_options_menu' );
359345
add_action( 'wp_loaded', 'amp_admin_pointer' );
360-
add_action( 'parse_query', 'amp_correct_query_when_is_front_page' );
361-
add_action( 'admin_bar_menu', 'amp_add_admin_bar_view_link', 100 );
346+
add_action( 'wp_loaded', 'amp_post_meta_box' ); // Used in both Website and Stories experiences.
347+
348+
if ( AMP_Options_Manager::is_website_experience_enabled() ) {
349+
add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK );
350+
AMP_Post_Type_Support::add_post_type_support();
351+
add_action( 'init', array( 'AMP_Post_Type_Support', 'add_post_type_support' ), 1000 ); // After post types have been defined.
352+
add_action( 'parse_query', 'amp_correct_query_when_is_front_page' );
353+
add_action( 'admin_bar_menu', 'amp_add_admin_bar_view_link', 100 );
354+
add_action( 'wp_loaded', 'amp_editor_core_blocks' );
355+
add_filter( 'request', 'amp_force_query_var_value' );
356+
357+
// Add actions for reader mode templates.
358+
add_action( 'wp', 'amp_maybe_add_actions' );
359+
360+
// Redirect the old url of amp page to the updated url.
361+
add_filter( 'old_slug_redirect_url', 'amp_redirect_old_slug_to_new_url' );
362+
}
362363

363-
// Redirect the old url of amp page to the updated url.
364-
add_filter( 'old_slug_redirect_url', 'amp_redirect_old_slug_to_new_url' );
364+
if ( AMP_Options_Manager::is_stories_experience_enabled() ) {
365+
AMP_Story_Post_Type::register();
366+
add_action( 'wp_loaded', 'amp_story_templates' );
367+
}
365368

366-
// Add actions for legacy post templates.
367-
add_action( 'wp', 'amp_maybe_add_actions' );
369+
if ( defined( 'WP_CLI' ) && WP_CLI ) {
370+
WP_CLI::add_command( 'amp', new AMP_CLI() );
371+
}
368372

369373
/*
370374
* Broadcast plugin updates.
@@ -513,7 +517,7 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
513517
*
514518
* add_theme_support( AMP_Theme_Support::SLUG );
515519
*
516-
* This will serve templates in native AMP, allowing you to use AMP components in your theme templates.
520+
* This will serve templates in AMP-first, allowing you to use AMP components in your theme templates.
517521
* If you want to make available in transitional mode, where templates are served in AMP or non-AMP documents, do:
518522
*
519523
* add_theme_support( AMP_Theme_Support::SLUG, array(
@@ -526,7 +530,7 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
526530
* 'template_dir' => 'amp',
527531
* ) );
528532
*
529-
* If you want to have AMP-specific templates in addition to serving native AMP, do:
533+
* If you want to have AMP-specific templates in addition to serving AMP-first, do:
530534
*
531535
* add_theme_support( AMP_Theme_Support::SLUG, array(
532536
* 'paired' => false,
@@ -549,16 +553,16 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
549553
* ) );
550554
*
551555
* @see AMP_Theme_Support::read_theme_support()
552-
* @return boolean Whether this is in AMP 'canonical' mode, that is whether it is native and there is not separate AMP URL current URL.
556+
* @return boolean Whether this is in AMP 'canonical' mode, that is whether it is AMP-first and there is not a separate (paired) AMP URL.
553557
*/
554558
function amp_is_canonical() {
555559
if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) {
556560
return false;
557561
}
558562

559563
$args = AMP_Theme_Support::get_theme_support_args();
560-
if ( isset( $args['paired'] ) ) {
561-
return empty( $args['paired'] );
564+
if ( isset( $args[ AMP_Theme_Support::PAIRED_FLAG ] ) ) {
565+
return empty( $args[ AMP_Theme_Support::PAIRED_FLAG ] );
562566
}
563567

564568
// If there is a template_dir, then transitional mode is implied.

assets/src/block-editor/index.js

+30-17
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,31 @@ import { addAMPAttributes, addAMPExtraProps, filterBlocksEdit, filterBlocksSave
1414
import { getMinimumFeaturedImageDimensions } from '../common/helpers';
1515
import './store';
1616

17+
const {
18+
isWebsiteEnabled,
19+
isStoriesEnabled,
20+
isStandardMode,
21+
} = select( 'amp/block-editor' );
22+
1723
const { ampLatestStoriesBlockData } = window;
1824

19-
addFilter( 'blocks.registerBlockType', 'ampEditorBlocks/addAttributes', addAMPAttributes );
20-
addFilter( 'blocks.getSaveElement', 'ampEditorBlocks/filterSave', filterBlocksSave );
21-
addFilter( 'editor.BlockEdit', 'ampEditorBlocks/filterEdit', filterBlocksEdit, 20 );
22-
addFilter( 'blocks.getSaveContent.extraProps', 'ampEditorBlocks/addExtraAttributes', addAMPExtraProps );
23-
addFilter( 'editor.PostFeaturedImage', 'ampEditorBlocks/withFeaturedImageNotice', withFeaturedImageNotice );
24-
addFilter( 'editor.MediaUpload', 'ampEditorBlocks/addCroppedFeaturedImage', ( InitialMediaUpload ) => withCroppedFeaturedImage( InitialMediaUpload, getMinimumFeaturedImageDimensions() ) );
25+
// Add filters if AMP for Website experience is enabled.
26+
if ( isWebsiteEnabled() ) {
27+
const plugins = require.context( './plugins', true, /.*\.js$/ );
2528

26-
const plugins = require.context( './plugins', true, /.*\.js$/ );
29+
plugins.keys().forEach( ( modulePath ) => {
30+
const { name, render, icon } = plugins( modulePath );
2731

28-
plugins.keys().forEach( ( modulePath ) => {
29-
const { name, render, icon } = plugins( modulePath );
32+
registerPlugin( name, { icon, render } );
33+
} );
3034

31-
registerPlugin( name, { icon, render } );
32-
} );
35+
addFilter( 'blocks.registerBlockType', 'ampEditorBlocks/addAttributes', addAMPAttributes );
36+
addFilter( 'blocks.getSaveElement', 'ampEditorBlocks/filterSave', filterBlocksSave );
37+
addFilter( 'editor.BlockEdit', 'ampEditorBlocks/filterEdit', filterBlocksEdit, 20 );
38+
addFilter( 'blocks.getSaveContent.extraProps', 'ampEditorBlocks/addExtraAttributes', addAMPExtraProps );
39+
addFilter( 'editor.PostFeaturedImage', 'ampEditorBlocks/withFeaturedImageNotice', withFeaturedImageNotice );
40+
addFilter( 'editor.MediaUpload', 'ampEditorBlocks/addCroppedFeaturedImage', ( InitialMediaUpload ) => withCroppedFeaturedImage( InitialMediaUpload, getMinimumFeaturedImageDimensions() ) );
41+
}
3342

3443
/*
3544
* If there's no theme support, unregister blocks that are only meant for AMP.
@@ -52,14 +61,18 @@ const blocks = require.context( './blocks', true, /(?<!test\/)index\.js$/ );
5261
blocks.keys().forEach( ( modulePath ) => {
5362
const { name, settings } = blocks( modulePath );
5463

55-
// Prevent registering latest-stories block if not enabled.
56-
if ( 'amp/amp-latest-stories' === name && typeof ampLatestStoriesBlockData === 'undefined' ) {
57-
return;
58-
}
64+
const isLatestStoriesBlock = 'amp/amp-latest-stories' === name;
5965

60-
const blockRequiresAmp = AMP_DEPENDENT_BLOCKS.includes( name );
66+
const shouldRegister = (
67+
(
68+
isWebsiteEnabled() && isStandardMode() && AMP_DEPENDENT_BLOCKS.includes( name )
69+
) ||
70+
(
71+
isStoriesEnabled() && isLatestStoriesBlock && typeof ampLatestStoriesBlockData !== 'undefined'
72+
)
73+
);
6174

62-
if ( ! blockRequiresAmp || select( 'amp/block-editor' ).isNativeAMP() ) {
75+
if ( shouldRegister ) {
6376
registerBlockType( name, settings );
6477
}
6578
} );
+38-14
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,65 @@
11
/**
2-
* Returns the block validation errors for a given clientId.
2+
* Returns whether the current theme has AMP support.
33
*
4-
* @param {Object} state Editor state.
5-
* @param {string} clientId Block client ID.
4+
* @param {Object} state Editor state.
65
*
7-
* @return {Array} Block validation errors.
6+
* @return {boolean} Whether the current theme has AMP support.
87
*/
9-
export function getBlockValidationErrors( state, clientId ) {
10-
return state.errorsByClientId[ clientId ] || [];
8+
export function hasThemeSupport( state ) {
9+
return Boolean( state.hasThemeSupport );
1110
}
1211

1312
/**
14-
* Returns whether the current theme has AMP support.
13+
* Returns whether the current site is in Standard mode (AMP-first) as opposed to Transitional (paired).
1514
*
1615
* @param {Object} state Editor state.
1716
*
18-
* @return {boolean} Whether the current theme has AMP support.
17+
* @return {boolean} Whether the current site is AMP-first.
1918
*/
20-
export function hasThemeSupport( state ) {
21-
return Boolean( state.hasThemeSupport );
19+
export function isStandardMode( state ) {
20+
return Boolean( state.isStandardMode );
21+
}
22+
23+
/**
24+
* Returns whether the website experience is enabled.
25+
*
26+
* @param {Object} state Editor state.
27+
*
28+
* @return {boolean} Whether website experienced enabled.
29+
*/
30+
export function isWebsiteEnabled( state ) {
31+
return Boolean( state.isWebsiteEnabled );
2232
}
2333

2434
/**
25-
* Returns whether the current site uses native AMP.
35+
* Returns whether the stories experience is enabled.
2636
*
2737
* @param {Object} state Editor state.
2838
*
29-
* @return {boolean} Whether the current site uses native AMP.
39+
* @return {boolean} Whether stories experienced enabled.
3040
*/
31-
export function isNativeAMP( state ) {
32-
return Boolean( state.isNativeAMP );
41+
export function isStoriesEnabled( state ) {
42+
return Boolean( state.isStoriesEnabled );
3343
}
3444

45+
/**
46+
* Returns the default AMP status.
47+
*
48+
* @param {Object} state Editor state.
49+
*
50+
* @return {string} The default AMP status.
51+
*/
3552
export function getDefaultStatus( state ) {
3653
return state.defaultStatus;
3754
}
3855

56+
/**
57+
* Returns the possible AMP statuses.
58+
*
59+
* @param {Object} state Editor state.
60+
*
61+
* @return {string[]} The possible AMP statuses, 'enabled' and 'disabled'.
62+
*/
3963
export function getPossibleStatuses( state ) {
4064
return state.possibleStatuses;
4165
}

assets/src/block-editor/store/test/selectors.js

+36
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,47 @@
22
* Internal dependencies
33
*/
44
import {
5+
hasThemeSupport,
6+
isStandardMode,
7+
isWebsiteEnabled,
8+
isStoriesEnabled,
59
getDefaultStatus,
610
getPossibleStatuses,
711
} from '../selectors';
812

913
describe( 'selectors', () => {
14+
describe( 'hasThemeSupport', () => {
15+
it( 'should return whether the theme has AMP support', () => {
16+
const state = { hasThemeSupport: false };
17+
18+
expect( hasThemeSupport( state ) ).toBe( false );
19+
} );
20+
} );
21+
22+
describe( 'isStandardMode', () => {
23+
it( 'should return whether standard mode is enabled', () => {
24+
const state = { isStandardMode: true };
25+
26+
expect( isStandardMode( state ) ).toBe( true );
27+
} );
28+
} );
29+
30+
describe( 'isWebsiteEnabled', () => {
31+
it( 'should return whether the website format is enabled', () => {
32+
const state = { isWebsiteEnabled: false };
33+
34+
expect( isWebsiteEnabled( state ) ).toBe( false );
35+
} );
36+
} );
37+
38+
describe( 'isStoriesEnabled', () => {
39+
it( 'should return whether the stories format is enabled', () => {
40+
const state = { isStoriesEnabled: false };
41+
42+
expect( isStoriesEnabled( state ) ).toBe( false );
43+
} );
44+
} );
45+
1046
describe( 'getDefaultStatus', () => {
1147
it( 'should return the default AMP status', () => {
1248
const state = { defaultStatus: 'enabled' };

0 commit comments

Comments
 (0)