Skip to content

Commit eeb502b

Browse files
authored
Merge pull request #813 from Automattic/feature/709-block-amp-per-page
Add post preview for AMP and allow AMP to be disabled on a per-post basis
2 parents c73f479 + 1b6cc54 commit eeb502b

10 files changed

Lines changed: 831 additions & 61 deletions

File tree

amp.php

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
require_once AMP__DIR__ . '/includes/class-amp-post-type-support.php';
2323
require_once AMP__DIR__ . '/includes/admin/functions.php';
2424
require_once AMP__DIR__ . '/includes/admin/class-amp-customizer.php';
25+
require_once AMP__DIR__ . '/includes/admin/class-amp-post-meta-box.php';
2526
require_once AMP__DIR__ . '/includes/settings/class-amp-customizer-settings.php';
2627
require_once AMP__DIR__ . '/includes/settings/class-amp-customizer-design-settings.php';
2728
require_once AMP__DIR__ . '/includes/actions/class-amp-frontend-actions.php';
@@ -61,6 +62,7 @@ function amp_init() {
6162

6263
load_plugin_textdomain( 'amp', false, plugin_basename( AMP__DIR__ ) . '/languages' );
6364

65+
amp_define_query_var();
6466
add_rewrite_endpoint( AMP_QUERY_VAR, EP_PERMALINK );
6567

6668
add_filter( 'request', 'amp_force_query_var_value' );
@@ -82,7 +84,11 @@ function amp_init() {
8284
*
8385
* @since 0.6
8486
*/
85-
function define_query_var() {
87+
function amp_define_query_var() {
88+
if ( defined( 'AMP_QUERY_VAR' ) ) {
89+
return;
90+
}
91+
8692
/**
8793
* Filter the AMP query variable.
8894
*
@@ -91,7 +97,7 @@ function define_query_var() {
9197
*/
9298
define( 'AMP_QUERY_VAR', apply_filters( 'amp_query_var', 'amp' ) );
9399
}
94-
add_action( 'after_setup_theme', 'define_query_var', 3 );
100+
add_action( 'after_setup_theme', 'amp_define_query_var', 3 );
95101

96102
// Make sure the `amp` query var has an explicit value.
97103
// Avoids issues when filtering the deprecated `query_string` hook.
@@ -147,24 +153,40 @@ function amp_prepare_render() {
147153
add_action( 'template_redirect', 'amp_render' );
148154
}
149155

156+
/**
157+
* Render AMP for queried post.
158+
*
159+
* @since 0.1
160+
*/
150161
function amp_render() {
151-
$post_id = get_queried_object_id();
152-
amp_render_post( $post_id );
162+
163+
// Note that queried object is used instead of the ID so that the_preview for the queried post can apply.
164+
amp_render_post( get_queried_object() );
153165
exit;
154166
}
155167

156-
function amp_render_post( $post_id ) {
157-
$post = get_post( $post_id );
158-
if ( ! $post ) {
159-
return;
168+
/**
169+
* Render AMP post template.
170+
*
171+
* @since 0.5
172+
* @param WP_Post|int $post Post.
173+
*/
174+
function amp_render_post( $post ) {
175+
176+
if ( ! ( $post instanceof WP_Post ) ) {
177+
$post = get_post( $post );
178+
if ( ! $post ) {
179+
return;
180+
}
160181
}
182+
$post_id = $post->ID;
161183

162184
amp_load_classes();
163185

164186
do_action( 'pre_amp_render_post', $post_id );
165187

166188
amp_add_post_template_actions();
167-
$template = new AMP_Post_Template( $post_id );
189+
$template = new AMP_Post_Template( $post );
168190
$template->load();
169191
}
170192

assets/css/amp-post-meta-box.css

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* 1.0 AMP preview.
3+
*
4+
* Submit box preview buttons.
5+
*/
6+
7+
/* Core preview button */
8+
.wp-core-ui #preview-action.has-amp-preview #post-preview {
9+
border-top-right-radius: 0;
10+
border-bottom-right-radius: 0;
11+
float: none;
12+
}
13+
14+
/* AMP preview button */
15+
.wp-core-ui #amp-post-preview.preview {
16+
border-top-left-radius: 0;
17+
border-bottom-left-radius: 0;
18+
text-indent: -9999px;
19+
padding-right: 7px;
20+
padding-left: 7px;
21+
}
22+
23+
.wp-core-ui #amp-post-preview.preview::after {
24+
content: "icon";
25+
width: 14px;
26+
float: left;
27+
background: no-repeat center url( '../images/amp-icon.svg' );
28+
background-size: 14px !important;
29+
}
30+
31+
.wp-core-ui #amp-post-preview.preview.disabled::after {
32+
opacity: 0.6;
33+
}
34+
35+
/* AMP status */
36+
.misc-amp-status .amp-icon {
37+
float: left;
38+
background: transparent url( '../images/amp-icon.svg' ) no-repeat left;
39+
background-size: 17px;
40+
width: 17px;
41+
height: 17px;
42+
margin: 0 8px 0 1px;
43+
}
44+
45+
#amp-status-select {
46+
margin-top: 4px;
47+
}
48+
49+
.amp-status-actions {
50+
margin-top: 10px;
51+
}
52+
53+
@media screen and ( max-width: 782px ) {
54+
#amp-status-select {
55+
line-height: 280%;
56+
}
57+
}

assets/images/amp-icon.svg

Lines changed: 7 additions & 0 deletions
Loading

assets/js/amp-post-meta-box.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/* exported ampPostMetaBox */
2+
3+
/**
4+
* AMP Post Meta Box.
5+
*
6+
* @todo Rename this to be just the ampEditPostScreen?
7+
*
8+
* @since 0.6
9+
*/
10+
var ampPostMetaBox = ( function( $ ) {
11+
'use strict';
12+
13+
var component = {
14+
15+
/**
16+
* Holds data.
17+
*
18+
* @since 0.6
19+
*/
20+
data: {
21+
previewLink: '',
22+
disabled: false,
23+
statusInputName: '',
24+
l10n: {
25+
ampPreviewBtnLabel: ''
26+
}
27+
},
28+
29+
/**
30+
* Toggle animation speed.
31+
*
32+
* @since 0.6
33+
*/
34+
toggleSpeed: 200,
35+
36+
/**
37+
* Core preview button selector.
38+
*
39+
* @since 0.6
40+
*/
41+
previewBtnSelector: '#post-preview',
42+
43+
/**
44+
* AMP preview button selector.
45+
*
46+
* @since 0.6
47+
*/
48+
ampPreviewBtnSelector: '#amp-post-preview'
49+
};
50+
51+
/**
52+
* Boot plugin.
53+
*
54+
* @since 0.6
55+
* @param {Object} data Object data.
56+
* @return {void}
57+
*/
58+
component.boot = function boot( data ) {
59+
component.data = data;
60+
$( document ).ready( function() {
61+
if ( ! component.data.disabled ) {
62+
component.addPreviewButton();
63+
}
64+
component.listen();
65+
} );
66+
};
67+
68+
/**
69+
* Events listener.
70+
*
71+
* @since 0.6
72+
* @return {void}
73+
*/
74+
component.listen = function listen() {
75+
$( component.ampPreviewBtnSelector ).on( 'click.amp-post-preview', function( e ) {
76+
e.preventDefault();
77+
component.onAmpPreviewButtonClick();
78+
} );
79+
80+
$( '.edit-amp-status, [href="#amp_status"]' ).click( function( e ) {
81+
e.preventDefault();
82+
component.toggleAmpStatus( $( e.target ) );
83+
} );
84+
85+
$( '#submitpost input[type="submit"]' ).on( 'click', function() {
86+
$( component.ampPreviewBtnSelector ).addClass( 'disabled' );
87+
} );
88+
};
89+
90+
/**
91+
* Add AMP Preview button.
92+
*
93+
* @since 0.6
94+
* @return {void}
95+
*/
96+
component.addPreviewButton = function addPreviewButton() {
97+
var previewBtn = $( component.previewBtnSelector );
98+
previewBtn
99+
.clone()
100+
.insertAfter( previewBtn )
101+
.prop( {
102+
'href': component.data.previewLink,
103+
'id': component.ampPreviewBtnSelector.replace( '#', '' )
104+
} )
105+
.text( component.data.l10n.ampPreviewBtnLabel )
106+
.parent()
107+
.addClass( 'has-amp-preview' );
108+
};
109+
110+
/**
111+
* AMP Preview button click handler.
112+
*
113+
* We trigger the Core preview link for events propagation purposes.
114+
*
115+
* @since 0.6
116+
* @return {void}
117+
*/
118+
component.onAmpPreviewButtonClick = function onAmpPreviewButtonClick() {
119+
var $input;
120+
121+
// Flag the AMP preview referer.
122+
$input = $( '<input>' )
123+
.prop( {
124+
'type': 'hidden',
125+
'name': 'amp-preview',
126+
'value': 'do-preview'
127+
} )
128+
.insertAfter( component.ampPreviewBtnSelector );
129+
130+
// Trigger Core preview button and remove AMP flag.
131+
$( component.previewBtnSelector ).click();
132+
$input.remove();
133+
};
134+
135+
/**
136+
* Add AMP status toggle.
137+
*
138+
* @since 0.6
139+
* @param {Object} $target Event target.
140+
* @return {void}
141+
*/
142+
component.toggleAmpStatus = function toggleAmpStatus( $target ) {
143+
var $container = $( '#amp-status-select' ),
144+
status = $container.data( 'amp-status' ),
145+
$checked,
146+
editAmpStatus = $( '.edit-amp-status' );
147+
148+
// Don't modify status on cancel button click.
149+
if ( ! $target.hasClass( 'button-cancel' ) ) {
150+
status = $( '[name="' + component.data.statusInputName + '"]:checked' ).val();
151+
}
152+
153+
$checked = $( '#amp-status-' + status );
154+
155+
// Toggle elements.
156+
editAmpStatus.fadeToggle( component.toggleSpeed, function() {
157+
if ( editAmpStatus.is( ':visible' ) ) {
158+
editAmpStatus.focus();
159+
}
160+
} );
161+
$container.slideToggle( component.toggleSpeed );
162+
163+
// Update status.
164+
$container.data( 'amp-status', status );
165+
$checked.prop( 'checked', true );
166+
$( '.amp-status-text' ).text( $checked.next().text() );
167+
};
168+
169+
return component;
170+
})( window.jQuery );

0 commit comments

Comments
 (0)