Skip to content
This repository has been archived by the owner on Dec 16, 2022. It is now read-only.

Add AMP support (experimental) #379

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "xwp/wp-customize-posts",
"description": "Manage posts and postmeta via the Customizer.",
"version": "0.9.1",
"version": "0.9.2",
"type": "wordpress-plugin",
"keywords": [ "customizer", "customize", "posts", "postmeta", "preview", "featured-image", "page-template" ],
"homepage": "https://github.com/xwp/wp-customize-posts/",
Expand Down
4 changes: 2 additions & 2 deletions css/edit-post-preview-admin.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#preview-action .spinner:not(.is-active-preview) {
visibility: hidden !important;
#preview-action .button.loading {
cursor: progress;
}
2 changes: 1 addition & 1 deletion customize-posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Customize Posts
* Description: Manage posts and postmeta via the Customizer.
* Plugin URI: https://github.com/xwp/wp-customize-posts/
* Version: 0.9.1
* Version: 0.9.2-alpha
* Author: XWP
* Author URI: https://make.xwp.co/
* License: GPLv2+
Expand Down
88 changes: 45 additions & 43 deletions js/edit-post-preview-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ var EditPostPreviewAdmin = (function( $ ) {
var component = {
data: {
customize_url: null,
is_compat: false,
previewed_post: null,
customize_posts_update_changeset_nonce: null
}
Expand All @@ -18,17 +17,23 @@ var EditPostPreviewAdmin = (function( $ ) {
$.extend( component.data, _editPostPreviewAdminExports );
}

/**
* Init.
*
* @returns {void}
*/
component.init = function() {
component.previewButton = $( '#post-preview' );
component.previewButtonSpinner = $( 'span.spinner' ).first().clone();
component.previewButton.after( component.previewButtonSpinner );
component.previewButton
.off( 'click.post-preview' )
.on( 'click.post-preview', component.onClickPreviewBtn );
$( 'form#post' ).on( 'submit', component.onPreviewSubmitPostForm );
};

component.onClickPreviewBtn = function( event ) {
var $btn = $( this ),
/**
* Handle submitting form from preview button.
*
* @param {jQuery.Event} event - Event.
* @returns {void}
*/
component.onPreviewSubmitPostForm = function( event ) {
var $btn,
postId = $( '#post_ID' ).val(),
postType = $( '#post_type' ).val(),
postSettingId,
Expand All @@ -38,14 +43,22 @@ var EditPostPreviewAdmin = (function( $ ) {
wasMobile,
parentId,
menuOrder,
request;
request,
customizeUrl;

$btn = $( document.activeElement );
if ( ! $btn.is( 'a.preview' ) || 'dopreview' !== $( '#wp-preview' ).val() ) {
return;
}

event.preventDefault();

if ( $btn.hasClass( 'disabled' ) ) {
return;
}

customizeUrl = component.data.customize_url + '&url=' + encodeURIComponent( $btn.prop( 'href' ) );

wp.customize.Loader.link = $btn;

// Prevent loader from navigating to new URL.
Expand Down Expand Up @@ -81,41 +94,30 @@ var EditPostPreviewAdmin = (function( $ ) {
// Allow plugins to inject additional settings to preview.
wp.customize.trigger( 'settings-from-edit-post-screen', settings );

// For backward compatibility send the current input fields from the edit post page to the Customizer via sessionStorage.
if ( component.data.is_compat ) {
sessionStorage.setItem( 'previewedCustomizePostSettings[' + postId + ']', JSON.stringify( settings ) );
wp.customize.Loader.open( component.data.customize_url );
$btn.addClass( 'disabled' ).addClass( 'loading' );
request = wp.ajax.post( 'customize_posts_update_changeset', {
customize_posts_update_changeset_nonce: component.data.customize_posts_update_changeset_nonce,
previewed_post: component.data.previewed_post,
input_data: postSettingValue
} );

request.fail( function( resp ) {
var error = JSON.parse( resp.responseText ), errorText;
if ( error.data ) {
errorText = error.data.replace( /_/g, ' ' );
alert( errorText.charAt( 0 ).toUpperCase() + errorText.slice( 1 ) ); // eslint-disable-line no-alert
}
} );

request.done( function( resp ) {
wp.customize.Loader.open( customizeUrl + '&changeset_uuid=' + encodeURIComponent( resp.changeset_uuid ) );
wp.customize.Loader.settings.browser.mobile = wasMobile;
component.bindChangesFromCustomizer( postSettingId, editor );
} else {
$btn.addClass( 'disabled' );
component.previewButtonSpinner.addClass( 'is-active is-active-preview' );
request = wp.ajax.post( 'customize_posts_update_changeset', {
customize_posts_update_changeset_nonce: component.data.customize_posts_update_changeset_nonce,
previewed_post: component.data.previewed_post,
customize_url: component.data.customize_url,
input_data: postSettingValue
} );

request.fail( function( resp ) {
var error = JSON.parse( resp.responseText ), errorText;
if ( error.data ) {
errorText = error.data.replace( /_/g, ' ' );
alert( errorText.charAt( 0 ).toUpperCase() + errorText.slice( 1 ) ); // eslint-disable-line no-alert
}
} );

request.done( function( resp ) {
wp.customize.Loader.open( resp.customize_url );
wp.customize.Loader.settings.browser.mobile = wasMobile;
component.bindChangesFromCustomizer( postSettingId, editor );
} );

request.always( function() {
$btn.removeClass( 'disabled' );
component.previewButtonSpinner.removeClass( 'is-active is-active-preview' );
} );
}
} );

request.always( function() {
$btn.removeClass( 'disabled' ).removeClass( 'loading' );
} );
};

/**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/xwp/wp-customize-posts.git"
},
"version": "0.9.1",
"version": "0.9.2",
"license": "GPL-2.0+",
"private": true,
"devDependencies": {
Expand Down
18 changes: 4 additions & 14 deletions php/class-edit-post-preview.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ public function enqueue_admin_scripts() {

$customize_url = add_query_arg(
array(
'url' => urlencode( self::get_preview_post_link( $post ) ),
'previewed_post' => $post->ID,
'autofocus[section]' => sprintf( 'post[%s][%d]', $post->post_type, $post->ID ),
self::PREVIEW_POST_NONCE_QUERY_VAR => wp_create_nonce( self::PREVIEW_POST_NONCE_ACTION ),
Expand All @@ -146,7 +145,6 @@ public function enqueue_admin_scripts() {
'customize_url' => $customize_url,
self::UPDATE_CHANGESET_NONCE => wp_create_nonce( self::UPDATE_CHANGESET_NONCE_ACTION ),
'previewed_post' => $post->ID,
'is_compat' => version_compare( strtok( get_bloginfo( 'version' ), '-' ), '4.7', '<' ),
);

wp_scripts()->add_data( 'edit-post-preview-admin', 'data', sprintf( 'var _editPostPreviewAdminExports = %s;', wp_json_encode( $data ) ) );
Expand Down Expand Up @@ -224,9 +222,6 @@ public function update_post_changeset() {
} elseif ( ! isset( $_POST['previewed_post'] ) ) {
status_header( 400 );
wp_send_json_error( 'missing_previewed_post' );
} elseif ( empty( $_POST['customize_url'] ) ) {
status_header( 400 );
wp_send_json_error( 'missing_customize_url' );
} elseif ( empty( $_POST['input_data'] ) || ! is_array( $_POST['input_data'] ) ) {
status_header( 400 );
wp_send_json_error( 'missing_input_data' );
Expand All @@ -249,9 +244,9 @@ public function update_post_changeset() {
}

if ( $changeset_uuid ) {
$wp_customize = new \WP_Customize_Manager( array(
$wp_customize = new WP_Customize_Manager( array(
'changeset_uuid' => $changeset_uuid,
) );
) ); // WPCS: override ok.
$changeset_post_id = $wp_customize->changeset_post_id();

if ( $changeset_post_id ) {
Expand All @@ -272,16 +267,11 @@ public function update_post_changeset() {
status_header( 403 );
wp_send_json_error( 'cannot_create_changeset_post' );
}
$wp_customize = new \WP_Customize_Manager();
$wp_customize = new WP_Customize_Manager(); // WPCS: override ok.
$changeset_uuid = $wp_customize->changeset_uuid();
update_post_meta( $previewed_post_id, '_preview_changeset_uuid', $changeset_uuid );
}

$customize_url = add_query_arg(
compact( 'changeset_uuid' ),
wp_unslash( $_POST['customize_url'] )
);

if ( ! isset( $wp_customize->posts ) || ! ( $wp_customize->posts instanceof WP_Customize_Posts ) ) {
wp_send_json_error( 'missing_posts_component' );
}
Expand Down Expand Up @@ -317,6 +307,6 @@ public function update_post_changeset() {
wp_send_json_error( $response->get_error_code() );
}

wp_send_json_success( compact( 'customize_url', 'response' ) );
wp_send_json_success( compact( 'changeset_uuid', 'response' ) );
}
}
112 changes: 110 additions & 2 deletions php/class-wp-customize-posts-preview.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ public function customize_preview_init() {
add_filter( 'customize_render_partials_response', array( $this, 'amend_with_queried_post_ids' ) );
add_filter( 'customize_render_partials_response', array( $this, 'amend_partials_response_with_rest_resources' ), 10, 3 );
remove_filter( 'get_edit_post_link', '__return_empty_string' ); // See <https://core.trac.wordpress.org/ticket/38648>.

// Support for AMP.
add_action( 'amp_customizer_enqueue_preview_scripts', array( $this, 'enqueue_scripts' ) );
if ( false === has_action( 'amp_post_template_footer', array( $this->component->manager->selective_refresh, 'export_preview_data' ) ) ) {
add_action( 'amp_post_template_footer', array( $this->component->manager->selective_refresh, 'export_preview_data' ) );
}
add_filter( 'amp_post_template_data', array( $this, 'filter_amp_post_template_data' ), 10, 2 );
add_filter( 'customize_partial_render', array( $this, 'sanitize_amp_rendered_content_partial' ), 10, 3 );
}

/**
Expand All @@ -126,6 +134,106 @@ public function add_preview_filters() {
return true;
}

/**
* Filter AMP post template data to add body classes.
*
* @param array $data Data.
* @param WP_Post $post Post.
*
* @return array Data.
*/
public function filter_amp_post_template_data( $data, $post ) {
if ( 'page' === $post->post_type ) {
$data['body_class'] .= sprintf( 'page-id-%d', $post->ID );
} else {
$data['body_class'] .= sprintf( 'postid-%d', $post->ID );
}
return $data;
}

/**
* Sanitize rendered content field partial for AMP.
*
* @param string|array|false $rendered The partial value. Default false.
* @param WP_Customize_Partial $partial WP_Customize_Setting instance.
* @return string Rendered partial.
*/
public function sanitize_amp_rendered_content_partial( $rendered, $partial ) {
$should_get_amp_content = (
$partial instanceof WP_Customize_Post_Field_Partial
&&
'post_content' === $partial->field_id
&&
function_exists( 'amp_load_classes' )
&&
function_exists( 'is_amp_endpoint' )
&&
is_amp_endpoint()
);
if ( $should_get_amp_content ) {
$post = get_post( $partial->post_id );

amp_load_classes();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove as of ampproject/amp-wp#819


// The following is copied from AMP_Post_Template::__construct(). See <https://github.com/Automattic/amp-wp/blob/c73f4794b35e410c5c9cb4930c2514575d1bb741/includes/class-amp-post-template.php#L47-L51>.
$content_max_width = AMP_Post_Template::CONTENT_MAX_WIDTH;
if ( isset( $GLOBALS['content_width'] ) && $GLOBALS['content_width'] > 0 ) {
$content_max_width = $GLOBALS['content_width'];
}
$content_max_width = apply_filters( 'amp_content_max_width', $content_max_width );

// The following is adapted from AMP_Post_Template::build_post_content(). See <https://github.com/Automattic/amp-wp/blob/c73f4794b35e410c5c9cb4930c2514575d1bb741/includes/class-amp-post-template.php#L231-L265>.
$amp_content = new AMP_Content( $rendered,
apply_filters(
'amp_content_embed_handlers', array(
'AMP_Twitter_Embed_Handler' => array(),
'AMP_YouTube_Embed_Handler' => array(),
'AMP_DailyMotion_Embed_Handler' => array(),
'AMP_Vimeo_Embed_Handler' => array(),
'AMP_SoundCloud_Embed_Handler' => array(),
'AMP_Instagram_Embed_Handler' => array(),
'AMP_Vine_Embed_Handler' => array(),
'AMP_Facebook_Embed_Handler' => array(),
'AMP_Pinterest_Embed_Handler' => array(),
'AMP_Gallery_Embed_Handler' => array(),
),
$post
),
apply_filters(
'amp_content_sanitizers', array(
'AMP_Style_Sanitizer' => array(),
'AMP_Img_Sanitizer' => array(),
'AMP_Video_Sanitizer' => array(),
'AMP_Audio_Sanitizer' => array(),
'AMP_Playbuzz_Sanitizer' => array(),
'AMP_Iframe_Sanitizer' => array(
'add_placeholder' => true,
),
'AMP_Tag_And_Attribute_Sanitizer' => array(),
),
$post
),
array(
'content_max_width' => $content_max_width,
)
);
$rendered = $amp_content->get_amp_content();
foreach ( $amp_content->get_amp_scripts() as $id => $src ) {
$rendered .= sprintf( '<script async custom-element="%s" src="%s"></script>', esc_attr( $id ), esc_url( $src ) );
}
$styles = $amp_content->get_amp_styles();
if ( ! empty( $styles ) ) {
$rendered .= '<style>';
foreach ( $styles as $selector => $declarations ) {
$declarations = implode( ';', $declarations ) . ';';
$rendered .= sprintf( '%1$s{%2$s}', $selector, $declarations );
}
$rendered .= '</style>';
}
}
return $rendered;
}

/**
* Enqueue scripts for the customizer preview.
*/
Expand Down Expand Up @@ -1310,7 +1418,7 @@ function filter_get_avatar( $avatar, $id_or_email, $size, $default, $alt, $args
public function get_post_field_partial_schema( $field_id = '' ) {
$schema = array(
'post_title' => array(
'selector' => '.entry-title',
'selector' => '.entry-title, .amp-wp-title',
),
'post_name' => array(
'fallback_refresh' => false,
Expand All @@ -1329,7 +1437,7 @@ public function get_post_field_partial_schema( $field_id = '' ) {
'fallback_refresh' => false,
),
'post_content' => array(
'selector' => '.entry-content',
'selector' => '.entry-content, .amp-wp-article-content',
),
'post_excerpt' => array(
'selector' => '.entry-summary',
Expand Down
10 changes: 2 additions & 8 deletions tests/php/test-ajax-class-wp-customize-posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -490,27 +490,21 @@ public function test_update_post_changeset_successes() {
$_POST = wp_slash( array(
'customize_posts_update_changeset_nonce' => wp_create_nonce( 'customize_posts_update_changeset' ),
'previewed_post' => $post_id,
'customize_url' => wp_customize_url(),
'input_data' => $input_data,
) );
$this->make_ajax_call( 'customize_posts_update_changeset' );
$response = json_decode( $this->_last_response, true );

$this->assertTrue( $response['success'] );
$this->assertArrayHasKey( 'customize_url', $response['data'] );
$this->assertArrayHasKey( 'changeset_uuid', $response['data'] );
$this->assertArrayHasKey( 'response', $response['data'] );
$this->assertArrayHasKey( 'setting_validities', $response['data']['response'] );

$setting_key = "post[post][$post_id]";
$this->assertTrue( $response['data']['response']['setting_validities'][ $setting_key ] );

$customize_url_parts = parse_url( $response['data']['customize_url'] );
parse_str( $customize_url_parts['query'], $url_query );
$this->assertNotEmpty( $url_query['changeset_uuid'] );
$this->assertEquals( get_post_meta( $post_id, '_preview_changeset_uuid', true ), $url_query['changeset_uuid'] );

$query = new WP_Query( array(
'post_name' => $url_query['changeset_uuid'],
'post_name' => $response['data']['changeset_uuid'],
'post_type' => 'customize_changeset',
'post_status' => 'auto-draft',
'no_found_rows' => true,
Expand Down