Skip to content

Commit

Permalink
Refactor AMP modes (#2550)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
westonruter authored and swissspidy committed Jun 11, 2019
1 parent 875c6ee commit bbecffc
Show file tree
Hide file tree
Showing 32 changed files with 1,041 additions and 447 deletions.
56 changes: 30 additions & 26 deletions amp.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ function amp_deactivate() {
}
}

flush_rewrite_rules();
flush_rewrite_rules( false );
}

/*
Expand Down Expand Up @@ -333,38 +333,42 @@ function amp_init() {
*/
do_action( 'amp_init' );

add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK );

add_filter( 'allowed_redirect_hosts', array( 'AMP_HTTP', 'filter_allowed_redirect_hosts' ) );
AMP_HTTP::purge_amp_query_vars();
AMP_HTTP::send_cors_headers();
AMP_HTTP::handle_xhr_request();
AMP_Theme_Support::init();
AMP_Validation_Manager::init();
AMP_Post_Type_Support::add_post_type_support();
AMP_Story_Post_Type::register();
AMP_Service_Worker::init();
add_action( 'init', array( 'AMP_Post_Type_Support', 'add_post_type_support' ), 1000 ); // After post types have been defined.

if ( defined( 'WP_CLI' ) && WP_CLI ) {
WP_CLI::add_command( 'amp', new AMP_CLI() );
}

add_filter( 'request', 'amp_force_query_var_value' );
add_action( 'admin_init', 'AMP_Options_Manager::register_settings' );
add_action( 'wp_loaded', 'amp_editor_core_blocks' );
add_action( 'wp_loaded', 'amp_post_meta_box' );
add_action( 'wp_loaded', 'amp_story_templates' );
add_action( 'wp_loaded', 'amp_add_options_menu' );
add_action( 'wp_loaded', 'amp_admin_pointer' );
add_action( 'parse_query', 'amp_correct_query_when_is_front_page' );
add_action( 'admin_bar_menu', 'amp_add_admin_bar_view_link', 100 );
add_action( 'wp_loaded', 'amp_post_meta_box' ); // Used in both Website and Stories experiences.

if ( AMP_Options_Manager::is_website_experience_enabled() ) {
add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK );
AMP_Post_Type_Support::add_post_type_support();
add_action( 'init', array( 'AMP_Post_Type_Support', 'add_post_type_support' ), 1000 ); // After post types have been defined.
add_action( 'parse_query', 'amp_correct_query_when_is_front_page' );
add_action( 'admin_bar_menu', 'amp_add_admin_bar_view_link', 100 );
add_action( 'wp_loaded', 'amp_editor_core_blocks' );
add_filter( 'request', 'amp_force_query_var_value' );

// Add actions for reader mode templates.
add_action( 'wp', 'amp_maybe_add_actions' );

// Redirect the old url of amp page to the updated url.
add_filter( 'old_slug_redirect_url', 'amp_redirect_old_slug_to_new_url' );
}

// Redirect the old url of amp page to the updated url.
add_filter( 'old_slug_redirect_url', 'amp_redirect_old_slug_to_new_url' );
if ( AMP_Options_Manager::is_stories_experience_enabled() ) {
AMP_Story_Post_Type::register();
add_action( 'wp_loaded', 'amp_story_templates' );
}

// Add actions for legacy post templates.
add_action( 'wp', 'amp_maybe_add_actions' );
if ( defined( 'WP_CLI' ) && WP_CLI ) {
WP_CLI::add_command( 'amp', new AMP_CLI() );
}

/*
* Broadcast plugin updates.
Expand Down Expand Up @@ -513,7 +517,7 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
*
* add_theme_support( AMP_Theme_Support::SLUG );
*
* This will serve templates in native AMP, allowing you to use AMP components in your theme templates.
* This will serve templates in AMP-first, allowing you to use AMP components in your theme templates.
* If you want to make available in transitional mode, where templates are served in AMP or non-AMP documents, do:
*
* add_theme_support( AMP_Theme_Support::SLUG, array(
Expand All @@ -526,7 +530,7 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
* 'template_dir' => 'amp',
* ) );
*
* If you want to have AMP-specific templates in addition to serving native AMP, do:
* If you want to have AMP-specific templates in addition to serving AMP-first, do:
*
* add_theme_support( AMP_Theme_Support::SLUG, array(
* 'paired' => false,
Expand All @@ -549,16 +553,16 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
* ) );
*
* @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.
* @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.
*/
function amp_is_canonical() {
if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) {
return false;
}

$args = AMP_Theme_Support::get_theme_support_args();
if ( isset( $args['paired'] ) ) {
return empty( $args['paired'] );
if ( isset( $args[ AMP_Theme_Support::PAIRED_FLAG ] ) ) {
return empty( $args[ AMP_Theme_Support::PAIRED_FLAG ] );
}

// If there is a template_dir, then transitional mode is implied.
Expand Down
47 changes: 30 additions & 17 deletions assets/src/block-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,31 @@ import { addAMPAttributes, addAMPExtraProps, filterBlocksEdit, filterBlocksSave
import { getMinimumFeaturedImageDimensions } from '../common/helpers';
import './store';

const {
isWebsiteEnabled,
isStoriesEnabled,
isStandardMode,
} = select( 'amp/block-editor' );

const { ampLatestStoriesBlockData } = window;

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

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

plugins.keys().forEach( ( modulePath ) => {
const { name, render, icon } = plugins( modulePath );
registerPlugin( name, { icon, render } );
} );

registerPlugin( name, { icon, render } );
} );
addFilter( 'blocks.registerBlockType', 'ampEditorBlocks/addAttributes', addAMPAttributes );
addFilter( 'blocks.getSaveElement', 'ampEditorBlocks/filterSave', filterBlocksSave );
addFilter( 'editor.BlockEdit', 'ampEditorBlocks/filterEdit', filterBlocksEdit, 20 );
addFilter( 'blocks.getSaveContent.extraProps', 'ampEditorBlocks/addExtraAttributes', addAMPExtraProps );
addFilter( 'editor.PostFeaturedImage', 'ampEditorBlocks/withFeaturedImageNotice', withFeaturedImageNotice );
addFilter( 'editor.MediaUpload', 'ampEditorBlocks/addCroppedFeaturedImage', ( InitialMediaUpload ) => withCroppedFeaturedImage( InitialMediaUpload, getMinimumFeaturedImageDimensions() ) );
}

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

// Prevent registering latest-stories block if not enabled.
if ( 'amp/amp-latest-stories' === name && typeof ampLatestStoriesBlockData === 'undefined' ) {
return;
}
const isLatestStoriesBlock = 'amp/amp-latest-stories' === name;

const blockRequiresAmp = AMP_DEPENDENT_BLOCKS.includes( name );
const shouldRegister = (
(
isWebsiteEnabled() && isStandardMode() && AMP_DEPENDENT_BLOCKS.includes( name )
) ||
(
isStoriesEnabled() && isLatestStoriesBlock && typeof ampLatestStoriesBlockData !== 'undefined'
)
);

if ( ! blockRequiresAmp || select( 'amp/block-editor' ).isNativeAMP() ) {
if ( shouldRegister ) {
registerBlockType( name, settings );
}
} );
52 changes: 38 additions & 14 deletions assets/src/block-editor/store/selectors.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,65 @@
/**
* Returns the block validation errors for a given clientId.
* Returns whether the current theme has AMP support.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
* @param {Object} state Editor state.
*
* @return {Array} Block validation errors.
* @return {boolean} Whether the current theme has AMP support.
*/
export function getBlockValidationErrors( state, clientId ) {
return state.errorsByClientId[ clientId ] || [];
export function hasThemeSupport( state ) {
return Boolean( state.hasThemeSupport );
}

/**
* Returns whether the current theme has AMP support.
* Returns whether the current site is in Standard mode (AMP-first) as opposed to Transitional (paired).
*
* @param {Object} state Editor state.
*
* @return {boolean} Whether the current theme has AMP support.
* @return {boolean} Whether the current site is AMP-first.
*/
export function hasThemeSupport( state ) {
return Boolean( state.hasThemeSupport );
export function isStandardMode( state ) {
return Boolean( state.isStandardMode );
}

/**
* Returns whether the website experience is enabled.
*
* @param {Object} state Editor state.
*
* @return {boolean} Whether website experienced enabled.
*/
export function isWebsiteEnabled( state ) {
return Boolean( state.isWebsiteEnabled );
}

/**
* Returns whether the current site uses native AMP.
* Returns whether the stories experience is enabled.
*
* @param {Object} state Editor state.
*
* @return {boolean} Whether the current site uses native AMP.
* @return {boolean} Whether stories experienced enabled.
*/
export function isNativeAMP( state ) {
return Boolean( state.isNativeAMP );
export function isStoriesEnabled( state ) {
return Boolean( state.isStoriesEnabled );
}

/**
* Returns the default AMP status.
*
* @param {Object} state Editor state.
*
* @return {string} The default AMP status.
*/
export function getDefaultStatus( state ) {
return state.defaultStatus;
}

/**
* Returns the possible AMP statuses.
*
* @param {Object} state Editor state.
*
* @return {string[]} The possible AMP statuses, 'enabled' and 'disabled'.
*/
export function getPossibleStatuses( state ) {
return state.possibleStatuses;
}
36 changes: 36 additions & 0 deletions assets/src/block-editor/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,47 @@
* Internal dependencies
*/
import {
hasThemeSupport,
isStandardMode,
isWebsiteEnabled,
isStoriesEnabled,
getDefaultStatus,
getPossibleStatuses,
} from '../selectors';

describe( 'selectors', () => {
describe( 'hasThemeSupport', () => {
it( 'should return whether the theme has AMP support', () => {
const state = { hasThemeSupport: false };

expect( hasThemeSupport( state ) ).toBe( false );
} );
} );

describe( 'isStandardMode', () => {
it( 'should return whether standard mode is enabled', () => {
const state = { isStandardMode: true };

expect( isStandardMode( state ) ).toBe( true );
} );
} );

describe( 'isWebsiteEnabled', () => {
it( 'should return whether the website format is enabled', () => {
const state = { isWebsiteEnabled: false };

expect( isWebsiteEnabled( state ) ).toBe( false );
} );
} );

describe( 'isStoriesEnabled', () => {
it( 'should return whether the stories format is enabled', () => {
const state = { isStoriesEnabled: false };

expect( isStoriesEnabled( state ) ).toBe( false );
} );
} );

describe( 'getDefaultStatus', () => {
it( 'should return the default AMP status', () => {
const state = { defaultStatus: 'enabled' };
Expand Down
Loading

0 comments on commit bbecffc

Please sign in to comment.