AMP for WordPress - Version 0.3.1

Version Description

  • Breaking change: AMP_QUERY_VAR is now defined right before amp_init.
  • Breaking change: class names for elements in the default template were prefixed with amp-wp-. Any styles targeting these classes should be updated.
Download this release

Release Info

Developer batmoo
Plugin Icon 128x128 AMP for WordPress
Version 0.3.1
Comparing to
See all releases

Code changes from version 0.3 to 0.3.1

amp.php CHANGED
@@ -5,14 +5,12 @@
5
  * Plugin URI: https://github.com/automattic/amp-wp
6
  * Author: Automattic
7
  * Author URI: https://automattic.com
8
- * Version: 0.3
9
  * Text Domain: amp
10
  * Domain Path: /languages/
11
  * License: GPLv2 or later
12
  */
13
 
14
- define( 'AMP_QUERY_VAR', 'amp' );
15
-
16
  define( 'AMP__FILE__', __FILE__ );
17
  define( 'AMP__DIR__', dirname( __FILE__ ) );
18
 
@@ -35,6 +33,8 @@ function amp_init() {
35
  return;
36
  }
37
 
 
 
38
  do_action( 'amp_init' );
39
 
40
  load_plugin_textdomain( 'amp', false, plugin_basename( AMP__DIR__ ) . '/languages' );
5
  * Plugin URI: https://github.com/automattic/amp-wp
6
  * Author: Automattic
7
  * Author URI: https://automattic.com
8
+ * Version: 0.3.1
9
  * Text Domain: amp
10
  * Domain Path: /languages/
11
  * License: GPLv2 or later
12
  */
13
 
 
 
14
  define( 'AMP__FILE__', __FILE__ );
15
  define( 'AMP__DIR__', dirname( __FILE__ ) );
16
 
33
  return;
34
  }
35
 
36
+ define( 'AMP_QUERY_VAR', apply_filters( 'amp_query_var', 'amp' ) );
37
+
38
  do_action( 'amp_init' );
39
 
40
  load_plugin_textdomain( 'amp', false, plugin_basename( AMP__DIR__ ) . '/languages' );
includes/amp-helper-functions.php CHANGED
@@ -4,7 +4,7 @@ function amp_get_permalink( $post_id ) {
4
  if ( '' != get_option( 'permalink_structure' ) ) {
5
  $amp_url = trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( AMP_QUERY_VAR, 'single_amp' );
6
  } else {
7
- $amp_url = add_query_arg( AMP_QUERY_VAR, absint( $post_id ), home_url() );
8
  }
9
 
10
  return apply_filters( 'amp_get_permalink', $amp_url, $post_id );
@@ -16,6 +16,10 @@ function post_supports_amp( $post ) {
16
  return false;
17
  }
18
 
 
 
 
 
19
  if ( true === apply_filters( 'amp_skip_post', false, $post->ID, $post ) ) {
20
  return false;
21
  }
4
  if ( '' != get_option( 'permalink_structure' ) ) {
5
  $amp_url = trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( AMP_QUERY_VAR, 'single_amp' );
6
  } else {
7
+ $amp_url = add_query_arg( AMP_QUERY_VAR, 1, get_permalink( $post_id ) );
8
  }
9
 
10
  return apply_filters( 'amp_get_permalink', $amp_url, $post_id );
16
  return false;
17
  }
18
 
19
+ if ( post_password_required( $post ) ) {
20
+ return false;
21
+ }
22
+
23
  if ( true === apply_filters( 'amp_skip_post', false, $post->ID, $post ) ) {
24
  return false;
25
  }
includes/amp-post-template-actions.php CHANGED
@@ -28,7 +28,7 @@ function amp_post_template_add_scripts( $amp_template ) {
28
  add_action( 'amp_post_template_head', 'amp_post_template_add_boilerplate_css' );
29
  function amp_post_template_add_boilerplate_css( $amp_template ) {
30
  ?>
31
- <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>
32
  <?php
33
  }
34
 
28
  add_action( 'amp_post_template_head', 'amp_post_template_add_boilerplate_css' );
29
  function amp_post_template_add_boilerplate_css( $amp_template ) {
30
  ?>
31
+ <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
32
  <?php
33
  }
34
 
includes/class-amp-post-template.php CHANGED
@@ -17,6 +17,7 @@ require_once( AMP__DIR__ . '/includes/embeds/class-amp-facebook-embed.php' );
17
 
18
  class AMP_Post_Template {
19
  const SITE_ICON_SIZE = 32;
 
20
 
21
  private $template_dir;
22
  private $data;
@@ -27,7 +28,10 @@ class AMP_Post_Template {
27
  $this->ID = $post_id;
28
  $this->post = get_post( $post_id );
29
 
30
- $content_max_width = isset( $GLOBALS['content_width'] ) ? absint( $GLOBALS['content_width'] ) : 600;
 
 
 
31
  $content_max_width = apply_filters( 'amp_content_max_width', $content_max_width );
32
 
33
  $this->data = array(
17
 
18
  class AMP_Post_Template {
19
  const SITE_ICON_SIZE = 32;
20
+ const CONTENT_MAX_WIDTH = 600;
21
 
22
  private $template_dir;
23
  private $data;
28
  $this->ID = $post_id;
29
  $this->post = get_post( $post_id );
30
 
31
+ $content_max_width = self::CONTENT_MAX_WIDTH;
32
+ if ( isset( $GLOBALS['content_width'] ) && $GLOBALS['content_width'] > 0 ) {
33
+ $content_max_width = $GLOBALS['content_width'];
34
+ }
35
  $content_max_width = apply_filters( 'amp_content_max_width', $content_max_width );
36
 
37
  $this->data = array(
includes/sanitizers/class-amp-base-sanitizer.php CHANGED
@@ -42,13 +42,16 @@ abstract class AMP_Base_Sanitizer {
42
 
43
  $attributes['sizes'] = sprintf( '(min-width: %1$dpx) %1$dpx, 100vw', absint( $max_width ) );
44
 
45
- $class = 'amp-wp-enforced-sizes';
46
- if ( isset( $attributes['class'] ) ) {
47
- $attributes['class'] .= ' ' . $class;
48
- } else {
49
- $attributes['class'] = $class;
50
- }
51
 
52
  return $attributes;
53
  }
 
 
 
 
 
 
 
 
54
  }
42
 
43
  $attributes['sizes'] = sprintf( '(min-width: %1$dpx) %1$dpx, 100vw', absint( $max_width ) );
44
 
45
+ $this->add_or_append_attribute( $attributes, 'class', 'amp-wp-enforced-sizes' );
 
 
 
 
 
46
 
47
  return $attributes;
48
  }
49
+
50
+ public function add_or_append_attribute( &$attributes, $key, $value, $separator = ' ' ) {
51
+ if ( isset( $attributes[ $key ] ) ) {
52
+ $attributes[ $key ] .= $separator . $value;
53
+ } else {
54
+ $attributes[ $key ] = $value;
55
+ }
56
+ }
57
  }
includes/sanitizers/class-amp-blacklist-sanitizer.php CHANGED
@@ -38,7 +38,7 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
38
  }
39
 
40
  // on* attributes (like onclick) are a special case
41
- if ( 0 === stripos( $attribute_name, 'on' ) ) {
42
  $node->removeAttribute( $attribute_name );
43
  continue;
44
  } elseif ( 'href' === $attribute_name ) {
@@ -47,15 +47,8 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
47
  $node->removeAttribute( $attribute_name );
48
  continue;
49
  }
50
- } elseif ( 'a' === $node_name && 'rel' === $attribute_name ) {
51
- $old_value = $attribute->value;
52
- $new_value = trim( preg_replace( self::PATTERN_REL_WP_ATTACHMENT, '', $old_value ) );
53
- if ( empty( $new_value ) ) {
54
- $node->removeAttribute( $attribute_name );
55
- } elseif ( $old_value !== $new_value ) {
56
- $node->setAttribute( $attribute_name, $new_value );
57
- }
58
-
59
  }
60
  }
61
  }
@@ -85,6 +78,26 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
85
  }
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  private function get_blacklisted_protocols() {
89
  return array(
90
  'javascript',
@@ -102,12 +115,12 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
102
  'param',
103
  'applet',
104
  'form',
 
105
  'input',
106
  'textarea',
107
  'select',
108
  'option',
109
  'link',
110
- 'meta',
111
 
112
  // These are converted into amp-* versions
113
  //'img',
38
  }
39
 
40
  // on* attributes (like onclick) are a special case
41
+ if ( 0 === stripos( $attribute_name, 'on' ) && $attribute_name != 'on' ) {
42
  $node->removeAttribute( $attribute_name );
43
  continue;
44
  } elseif ( 'href' === $attribute_name ) {
47
  $node->removeAttribute( $attribute_name );
48
  continue;
49
  }
50
+ } elseif ( 'a' === $node_name ) {
51
+ $this->sanitize_a_attribute( $node, $attribute );
 
 
 
 
 
 
 
52
  }
53
  }
54
  }
78
  }
79
  }
80
 
81
+ private function sanitize_a_attribute( $node, $attribute ) {
82
+ $attribute_name = strtolower( $attribute->name );
83
+
84
+ if ( 'rel' === $attribute_name ) {
85
+ $old_value = $attribute->value;
86
+ $new_value = trim( preg_replace( self::PATTERN_REL_WP_ATTACHMENT, '', $old_value ) );
87
+ if ( empty( $new_value ) ) {
88
+ $node->removeAttribute( $attribute_name );
89
+ } elseif ( $old_value !== $new_value ) {
90
+ $node->setAttribute( $attribute_name, $new_value );
91
+ }
92
+ } elseif ( 'rev' === $attribute_name ) {
93
+ // rev removed from HTML5 spec, which was used by Jetpack Markdown.
94
+ $node->removeAttribute( $attribute_name );
95
+ } elseif ( 'target' === $attribute_name && '_new' === $attribute->value ) {
96
+ // _new is not allowed; swap with _blank
97
+ $node->setAttribute( $attribute_name, '_blank' );
98
+ }
99
+ }
100
+
101
  private function get_blacklisted_protocols() {
102
  return array(
103
  'javascript',
115
  'param',
116
  'applet',
117
  'form',
118
+ 'label',
119
  'input',
120
  'textarea',
121
  'select',
122
  'option',
123
  'link',
 
124
 
125
  // These are converted into amp-* versions
126
  //'img',
includes/sanitizers/class-amp-iframe-sanitizer.php CHANGED
@@ -45,8 +45,13 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
45
  $this->did_convert_elements = true;
46
 
47
  $new_attributes = $this->filter_attributes( $old_attributes );
48
- if ( ! isset( $new_attributes['width'], $new_attributes['height'] ) ) {
 
 
49
  $new_attributes['height'] = self::FALLBACK_HEIGHT;
 
 
 
50
  $new_attributes['layout'] = 'fixed-height';
51
  }
52
  $new_attributes = $this->enforce_sizes_attribute( $new_attributes );
@@ -80,14 +85,26 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
80
  switch ( $name ) {
81
  case 'src':
82
  case 'sandbox':
83
- case 'width':
84
  case 'height':
85
- case 'frameborder':
86
  case 'class':
87
  case 'sizes':
88
  $out[ $name ] = $value;
89
  break;
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  case 'allowfullscreen':
92
  case 'allowtransparency':
93
  if ( 'false' !== $value ) {
45
  $this->did_convert_elements = true;
46
 
47
  $new_attributes = $this->filter_attributes( $old_attributes );
48
+
49
+ if ( ! isset( $new_attributes['height'] ) ) {
50
+ unset( $new_attributes['width'] );
51
  $new_attributes['height'] = self::FALLBACK_HEIGHT;
52
+ }
53
+
54
+ if ( ! isset( $new_attributes['width'] ) ) {
55
  $new_attributes['layout'] = 'fixed-height';
56
  }
57
  $new_attributes = $this->enforce_sizes_attribute( $new_attributes );
85
  switch ( $name ) {
86
  case 'src':
87
  case 'sandbox':
 
88
  case 'height':
 
89
  case 'class':
90
  case 'sizes':
91
  $out[ $name ] = $value;
92
  break;
93
 
94
+ case 'width':
95
+ if ( $value === '100%' ) {
96
+ continue;
97
+ }
98
+ $out[ $name ] = $value;
99
+ break;
100
+
101
+ case 'frameborder':
102
+ if ( '0' !== $value && '1' !== $value ) {
103
+ $value = '0';
104
+ }
105
+ $out[ $name ] = $value;
106
+ break;
107
+
108
  case 'allowfullscreen':
109
  case 'allowtransparency':
110
  if ( 'false' !== $value ) {
includes/sanitizers/class-amp-img-sanitizer.php CHANGED
@@ -7,6 +7,9 @@ require_once( AMP__DIR__ . '/includes/utils/class-amp-image-dimension-extractor.
7
  * Converts <img> tags to <amp-img> or <amp-anim>
8
  */
9
  class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
 
 
 
10
  public static $tag = 'img';
11
 
12
  private static $anim_extension = '.gif';
@@ -31,6 +34,8 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
31
  }
32
 
33
  $new_attributes = $this->filter_attributes( $old_attributes );
 
 
34
  if ( ! isset( $new_attributes['width'] ) || ! isset( $new_attributes['height'] ) ) {
35
  $dimensions = AMP_Image_Dimension_Extractor::extract( $new_attributes['src'] );
36
  if ( is_array( $dimensions ) ) {
@@ -39,6 +44,14 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
39
  }
40
  }
41
 
 
 
 
 
 
 
 
 
42
  $new_attributes = $this->enforce_sizes_attribute( $new_attributes );
43
 
44
  if ( $this->is_gif_url( $new_attributes['src'] ) ) {
@@ -73,6 +86,7 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
73
  case 'class':
74
  case 'srcset':
75
  case 'sizes':
 
76
  $out[ $name ] = $value;
77
  break;
78
  default;
7
  * Converts <img> tags to <amp-img> or <amp-anim>
8
  */
9
  class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
10
+ const FALLBACK_WIDTH = 600;
11
+ const FALLBACK_HEIGHT = 400;
12
+
13
  public static $tag = 'img';
14
 
15
  private static $anim_extension = '.gif';
34
  }
35
 
36
  $new_attributes = $this->filter_attributes( $old_attributes );
37
+
38
+ // Try to extract dimensions for the image, if not set.
39
  if ( ! isset( $new_attributes['width'] ) || ! isset( $new_attributes['height'] ) ) {
40
  $dimensions = AMP_Image_Dimension_Extractor::extract( $new_attributes['src'] );
41
  if ( is_array( $dimensions ) ) {
44
  }
45
  }
46
 
47
+ // Final fallback when we have no dimensions.
48
+ if ( ! isset( $new_attributes['width'] ) || ! isset( $new_attributes['height'] ) ) {
49
+ $new_attributes['width'] = isset( $this->args['content_max_width'] ) ? $this->args['content_max_width'] : self::FALLBACK_WIDTH;
50
+ $new_attributes['height'] = self::FALLBACK_HEIGHT;
51
+
52
+ $this->add_or_append_attribute( $new_attributes, 'class', 'amp-wp-unknown-size' );
53
+ }
54
+
55
  $new_attributes = $this->enforce_sizes_attribute( $new_attributes );
56
 
57
  if ( $this->is_gif_url( $new_attributes['src'] ) ) {
86
  case 'class':
87
  case 'srcset':
88
  case 'sizes':
89
+ case 'on':
90
  $out[ $name ] = $value;
91
  break;
92
  default;
includes/utils/class-amp-image-dimension-extractor.php CHANGED
@@ -8,9 +8,42 @@ class AMP_Image_Dimension_Extractor {
8
  self::register_callbacks();
9
  }
10
 
 
 
 
 
 
11
  return apply_filters( 'amp_extract_image_dimensions', false, $url );
12
  }
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  private static function register_callbacks() {
15
  self::$callbacks_registered = true;
16
 
8
  self::register_callbacks();
9
  }
10
 
11
+ $url = self::normalize_url( $url );
12
+ if ( false === $url ) {
13
+ return false;
14
+ }
15
+
16
  return apply_filters( 'amp_extract_image_dimensions', false, $url );
17
  }
18
 
19
+ public static function normalize_url( $url ) {
20
+ if ( empty( $url ) ) {
21
+ return false;
22
+ }
23
+
24
+ if ( 0 === strpos( $url, 'data:' ) ) {
25
+ return false;
26
+ }
27
+
28
+ if ( 0 === strpos( $url, '//' ) ) {
29
+ return set_url_scheme( $url, 'http' );
30
+ }
31
+
32
+ $parsed = parse_url( $url );
33
+ if ( ! isset( $parsed['host'] ) ) {
34
+ $path = '';
35
+ if ( isset( $parsed['path'] ) ) {
36
+ $path .= $parsed['path'];
37
+ }
38
+ if ( isset( $parsed['query'] ) ) {
39
+ $path .= '?' . $parsed['query'];
40
+ }
41
+ $url = site_url( $path );
42
+ }
43
+
44
+ return $url;
45
+ }
46
+
47
  private static function register_callbacks() {
48
  self::$callbacks_registered = true;
49
 
readme.md CHANGED
@@ -55,6 +55,36 @@ function xyz_amp_set_site_icon_url( $data ) {
55
 
56
  This needs to be implemented.
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  ### Template Tweaks
59
 
60
  You can tweak various parts of the template via code.
@@ -135,7 +165,7 @@ For the meta section of the template (i.e. author, date, taxonomies, etc.), you
135
  Create a folder in your theme called `amp` and add a file called `meta-author.php` with the following:
136
 
137
  ```php
138
- <li class="byline">
139
  <span>Anonymous</span>
140
  </li>
141
  ```
@@ -160,7 +190,7 @@ function xyz_amp_set_custom_tax_meta_template( $file, $type, $post ) {
160
  In `t/meta-custom-tax.php`, you can add something like the following to replace the default category and tags with your custom `author` taxonomy:
161
 
162
  ```php
163
- <li class="tax-authors">
164
  <?php echo get_the_term_list( $this->get( 'post_id' ), 'xyz-author', '', ', ' ); ?>
165
  </li>
166
  ```
@@ -222,7 +252,7 @@ add_action( 'amp_post_template_css', 'xyz_amp_my_additional_css_styles' );
222
  function xyz_amp_my_additional_css_styles( $amp_template ) {
223
  // only CSS here please...
224
  ?>
225
- .byline amp-img {
226
  border-radius: 0; /* we don't want round avatars! */
227
  }
228
  .my-custom-class {
@@ -267,6 +297,18 @@ function xyz_amp_add_analytics( $amp_template ) {
267
  }
268
  ```
269
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  ### Custom Template
271
 
272
  If you want complete control over the look and feel of your AMP content, you can override the default template using the `amp_post_template_file` filter and pass it the path to a custom template:
@@ -490,3 +532,9 @@ function xyz_amp_set_custom_template( $file, $type, $post ) {
490
  ```
491
 
492
  We may provide better ways to handle this in the future.
 
 
 
 
 
 
55
 
56
  This needs to be implemented.
57
 
58
+ #### Logo Only
59
+
60
+ If you want to hide the site text and just show a logo, use the `amp_post_template_css` action. The following colours the title bar black, hides the site title, and replaces it with a centered logo:
61
+
62
+ ```
63
+ add_action( 'amp_post_template_css', 'xyz_amp_additional_css_styles' );
64
+
65
+ function discover_fp_amp_additional_css_styles( $amp_template ) {
66
+ // only CSS here please...
67
+ ?>
68
+ nav.amp-wp-title-bar {
69
+ padding: 12px 0;
70
+ background: #000;
71
+ }
72
+ nav.amp-wp-title-bar a {
73
+ background-image: url( 'https://example.com/path/to/logo.png' );
74
+ background-repeat: no-repeat;
75
+ background-size: contain;
76
+ display: block;
77
+ height: 28px;
78
+ width: 94px;
79
+ margin: 0 auto;
80
+ text-indent: -9999px;
81
+ }
82
+ <?php
83
+ }
84
+ ```
85
+
86
+ Note: you will need to adjust the colours and sizes based on your brand.
87
+
88
  ### Template Tweaks
89
 
90
  You can tweak various parts of the template via code.
165
  Create a folder in your theme called `amp` and add a file called `meta-author.php` with the following:
166
 
167
  ```php
168
+ <li class="xyz-byline">
169
  <span>Anonymous</span>
170
  </li>
171
  ```
190
  In `t/meta-custom-tax.php`, you can add something like the following to replace the default category and tags with your custom `author` taxonomy:
191
 
192
  ```php
193
+ <li class="xyz-tax-authors">
194
  <?php echo get_the_term_list( $this->get( 'post_id' ), 'xyz-author', '', ', ' ); ?>
195
  </li>
196
  ```
252
  function xyz_amp_my_additional_css_styles( $amp_template ) {
253
  // only CSS here please...
254
  ?>
255
+ .amp-wp-byline amp-img {
256
  border-radius: 0; /* we don't want round avatars! */
257
  }
258
  .my-custom-class {
297
  }
298
  ```
299
 
300
+ #### AMP Endpoint
301
+
302
+ If you don't want to use the default `/amp` endpoint, use the `amp_query_var` filter to change it to anything else.
303
+
304
+ ```php
305
+ add_filter( 'amp_query_var' , 'xyz_amp_change_endpoint' );
306
+
307
+ function xyz_amp_change_endpoint( $amp_endpoint ) {
308
+ return 'foo';
309
+ }
310
+ ```
311
+
312
  ### Custom Template
313
 
314
  If you want complete control over the look and feel of your AMP content, you can override the default template using the `amp_post_template_file` filter and pass it the path to a custom template:
532
  ```
533
 
534
  We may provide better ways to handle this in the future.
535
+
536
+ ## Plugin integrations
537
+
538
+ ### Yoast SEO
539
+
540
+ If you're using [Yoast SEO](https://wordpress.org/plugins/wordpress-seo/), check out the companion plugin here: https://github.com/Yoast/yoastseo-amp
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: batmoo, joen, automattic
3
  Tags: amp, mobile
4
  Requires at least: 4.4
5
  Tested up to: 4.4
6
- Stable tag: 0.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -34,6 +34,17 @@ You can find details about customization options at https://github.com/Automatti
34
 
35
  == Changelog ==
36
 
 
 
 
 
 
 
 
 
 
 
 
37
  = 0.3 (Feb 18, 2016) =
38
 
39
  * Fetch dimensions for hotlinked images.
@@ -52,3 +63,15 @@ You can find details about customization options at https://github.com/Automatti
52
 
53
  = 0.1 =
54
  * Initial version
 
 
 
 
 
 
 
 
 
 
 
 
3
  Tags: amp, mobile
4
  Requires at least: 4.4
5
  Tested up to: 4.4
6
+ Stable tag: 0.3.1
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
34
 
35
  == Changelog ==
36
 
37
+ = 0.3.1 (Feb 24, 2016) =
38
+
39
+ * Fix AMP URLs for non-pretty permalinks.
40
+ * Fix for password-protected posts.
41
+ * Fix dimension extraction for schema-less or relative image URLs.
42
+ * Better fallback for images with no dimensions.
43
+ * Validation fixes for `a` tags.
44
+ * Updated AMP boilerplate.
45
+ * Allow `on` tags for elements.
46
+ * Prefixed class names.
47
+
48
  = 0.3 (Feb 18, 2016) =
49
 
50
  * Fetch dimensions for hotlinked images.
63
 
64
  = 0.1 =
65
  * Initial version
66
+
67
+ == Upgrade Notice ==
68
+
69
+ = 0.3.1 =
70
+
71
+ * Breaking change: `AMP_QUERY_VAR` is now defined right before `amp_init`.
72
+ * Breaking change: class names for elements in the default template were prefixed with `amp-wp-`. Any styles targeting these classes should be updated.
73
+
74
+ = 0.3 =
75
+
76
+ * Breaking change: `style.css` no longer contains the `<style> tag. If you have a custom stylesheet, you need to update it to remove the tag.
77
+ * Breaking change: `single.php` no longer includes the AMP boilerplate styles. They are instead added via the `amp_post_template_head` hook. If you have a custom template, please remove the boilerplate styles.
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file
templates/meta-author.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php $post_author = $this->get( 'post_author' ); ?>
2
- <li class="byline">
3
  <?php if ( function_exists( 'get_avatar_url' ) ) : ?>
4
  <amp-img src="<?php echo esc_url( get_avatar_url( $post_author->user_email, array(
5
  'size' => 24,
6
  ) ) ); ?>" width="24" height="24" layout="fixed"></amp-img>
7
  <?php endif; ?>
8
- <span class="author"><?php echo esc_html( $post_author->display_name ); ?></span>
9
  </li>
1
  <?php $post_author = $this->get( 'post_author' ); ?>
2
+ <li class="amp-wp-byline">
3
  <?php if ( function_exists( 'get_avatar_url' ) ) : ?>
4
  <amp-img src="<?php echo esc_url( get_avatar_url( $post_author->user_email, array(
5
  'size' => 24,
6
  ) ) ); ?>" width="24" height="24" layout="fixed"></amp-img>
7
  <?php endif; ?>
8
+ <span class="amp-wp-author"><?php echo esc_html( $post_author->display_name ); ?></span>
9
  </li>
templates/meta-taxonomy.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php $categories = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ) ); ?>
2
  <?php if ( $categories ) : ?>
3
- <li class="tax-category">
4
  <span class="screen-reader-text">Categories:</span>
5
  <?php echo $categories; ?>
6
  </li>
@@ -8,7 +8,7 @@
8
 
9
  <?php $tags = get_the_tag_list( '', _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ) ); ?>
10
  <?php if ( $tags ) : ?>
11
- <li class="tax-tag">
12
  <span class="screen-reader-text">Tags:</span>
13
  <?php echo $tags; ?>
14
  </li>
1
  <?php $categories = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ) ); ?>
2
  <?php if ( $categories ) : ?>
3
+ <li class="amp-wp-tax-category">
4
  <span class="screen-reader-text">Categories:</span>
5
  <?php echo $categories; ?>
6
  </li>
8
 
9
  <?php $tags = get_the_tag_list( '', _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ) ); ?>
10
  <?php if ( $tags ) : ?>
11
+ <li class="amp-wp-tax-tag">
12
  <span class="screen-reader-text">Tags:</span>
13
  <?php echo $tags; ?>
14
  </li>
templates/meta-time.php CHANGED
@@ -1,4 +1,4 @@
1
- <li class="posted-on">
2
  <time datetime="<?php echo esc_attr( date( 'c', $this->get( 'post_publish_timestamp' ) ) ); ?>">
3
  <?php
4
  echo esc_html(
1
+ <li class="amp-wp-posted-on">
2
  <time datetime="<?php echo esc_attr( date( 'c', $this->get( 'post_publish_timestamp' ) ) ); ?>">
3
  <?php
4
  echo esc_html(
templates/single.php CHANGED
@@ -2,7 +2,7 @@
2
  <html amp>
3
  <head>
4
  <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui">
6
  <link href="https://fonts.googleapis.com/css?family=Merriweather:400,400italic,700,700italic|Open+Sans:400,700,400italic,700italic" rel="stylesheet" type="text/css">
7
  <?php do_action( 'amp_post_template_head', $this ); ?>
8
 
@@ -12,20 +12,20 @@
12
  </style>
13
  </head>
14
  <body>
15
- <nav class="title-bar">
16
  <div>
17
  <a href="<?php echo esc_url( $this->get( 'home_url' ) ); ?>">
18
  <?php $site_icon_url = $this->get( 'site_icon_url' ); ?>
19
  <?php if ( $site_icon_url ) : ?>
20
- <amp-img src="<?php echo esc_url( $site_icon_url ); ?>" width="32" height="32" class="site-icon"></amp-img>
21
  <?php endif; ?>
22
  <?php echo esc_html( $this->get( 'blog_name' ) ); ?>
23
  </a>
24
  </div>
25
  </nav>
26
- <div class="content">
27
- <h1 class="title"><?php echo esc_html( $this->get( 'post_title' ) ); ?></h1>
28
- <ul class="meta">
29
  <?php $this->load_parts( apply_filters( 'amp_post_template_meta_parts', array( 'meta-author', 'meta-time', 'meta-taxonomy' ) ) ); ?>
30
  </ul>
31
  <?php echo $this->get( 'post_amp_content' ); // amphtml content; no kses ?>
2
  <html amp>
3
  <head>
4
  <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
6
  <link href="https://fonts.googleapis.com/css?family=Merriweather:400,400italic,700,700italic|Open+Sans:400,700,400italic,700italic" rel="stylesheet" type="text/css">
7
  <?php do_action( 'amp_post_template_head', $this ); ?>
8
 
12
  </style>
13
  </head>
14
  <body>
15
+ <nav class="amp-wp-title-bar">
16
  <div>
17
  <a href="<?php echo esc_url( $this->get( 'home_url' ) ); ?>">
18
  <?php $site_icon_url = $this->get( 'site_icon_url' ); ?>
19
  <?php if ( $site_icon_url ) : ?>
20
+ <amp-img src="<?php echo esc_url( $site_icon_url ); ?>" width="32" height="32" class="amp-wp-site-icon"></amp-img>
21
  <?php endif; ?>
22
  <?php echo esc_html( $this->get( 'blog_name' ) ); ?>
23
  </a>
24
  </div>
25
  </nav>
26
+ <div class="amp-wp-content">
27
+ <h1 class="amp-wp-title"><?php echo esc_html( $this->get( 'post_title' ) ); ?></h1>
28
+ <ul class="amp-wp-meta">
29
  <?php $this->load_parts( apply_filters( 'amp_post_template_meta_parts', array( 'meta-author', 'meta-time', 'meta-taxonomy' ) ) ); ?>
30
  </ul>
31
  <?php echo $this->get( 'post_amp_content' ); // amphtml content; no kses ?>
templates/style.php CHANGED
@@ -14,8 +14,14 @@ amp-img.aligncenter { display: block; margin-left: auto; margin-right: auto; }
14
  max-width: 100%;
15
  }
16
 
17
- /* Generic WP.com reader style */
18
- .content, .title-bar div {
 
 
 
 
 
 
19
  <?php $content_max_width = absint( $this->get( 'content_max_width' ) ); ?>
20
  <?php if ( $content_max_width > 0 ) : ?>
21
  max-width: <?php echo sprintf( '%dpx', $content_max_width ); ?>;
@@ -32,7 +38,7 @@ body {
32
  padding-bottom: 100px;
33
  }
34
 
35
- .content {
36
  padding: 16px;
37
  overflow-wrap: break-word;
38
  word-wrap: break-word;
@@ -40,7 +46,7 @@ body {
40
  color: #3d596d;
41
  }
42
 
43
- .title {
44
  margin: 36px 0 0 0;
45
  font-size: 36px;
46
  line-height: 1.258;
@@ -48,7 +54,7 @@ body {
48
  color: #2e4453;
49
  }
50
 
51
- .meta {
52
  margin-bottom: 16px;
53
  }
54
 
@@ -72,8 +78,8 @@ a:focus {
72
 
73
 
74
  /* Open Sans */
75
- .meta,
76
- nav.title-bar,
77
  .wp-caption-text {
78
  font-family: "Open Sans", sans-serif;
79
  font-size: 15px;
@@ -81,12 +87,12 @@ nav.title-bar,
81
 
82
 
83
  /* Meta */
84
- ul.meta {
85
  padding: 24px 0 0 0;
86
  margin: 0 0 24px 0;
87
  }
88
 
89
- ul.meta li {
90
  list-style: none;
91
  display: inline-block;
92
  margin: 0;
@@ -97,21 +103,21 @@ ul.meta li {
97
  max-width: 300px;
98
  }
99
 
100
- ul.meta li:before {
101
  content: "\2022";
102
  margin: 0 8px;
103
  }
104
 
105
- ul.meta li:first-child:before {
106
  display: none;
107
  }
108
 
109
- .meta,
110
- .meta a {
111
  color: #4f748e;
112
  }
113
 
114
- .meta .screen-reader-text {
115
  /* from twentyfifteen */
116
  clip: rect(1px, 1px, 1px, 1px);
117
  height: 1px;
@@ -120,7 +126,7 @@ ul.meta li:first-child:before {
120
  width: 1px;
121
  }
122
 
123
- .byline amp-img {
124
  border-radius: 50%;
125
  border: 0;
126
  background: #f3f6f8;
@@ -131,22 +137,22 @@ ul.meta li:first-child:before {
131
 
132
 
133
  /* Titlebar */
134
- nav.title-bar {
135
  background: #0a89c0;
136
  padding: 0 16px;
137
  }
138
 
139
- nav.title-bar div {
140
  line-height: 54px;
141
  color: #fff;
142
  }
143
 
144
- nav.title-bar a {
145
  color: #fff;
146
  text-decoration: none;
147
  }
148
 
149
- nav.title-bar .site-icon {
150
  /** site icon is 32px **/
151
  float: left;
152
  margin: 11px 8px 0 0;
14
  max-width: 100%;
15
  }
16
 
17
+ .amp-wp-unknown-size img {
18
+ /** Worst case scenario when we can't figure out dimensions for an image. **/
19
+ /** Force the image into a box of fixed dimensions and use object-fit to scale. **/
20
+ object-fit: contain;
21
+ }
22
+
23
+ /* Template Styles */
24
+ .amp-wp-content, .amp-wp-title-bar div {
25
  <?php $content_max_width = absint( $this->get( 'content_max_width' ) ); ?>
26
  <?php if ( $content_max_width > 0 ) : ?>
27
  max-width: <?php echo sprintf( '%dpx', $content_max_width ); ?>;
38
  padding-bottom: 100px;
39
  }
40
 
41
+ .amp-wp-content {
42
  padding: 16px;
43
  overflow-wrap: break-word;
44
  word-wrap: break-word;
46
  color: #3d596d;
47
  }
48
 
49
+ .amp-wp-title {
50
  margin: 36px 0 0 0;
51
  font-size: 36px;
52
  line-height: 1.258;
54
  color: #2e4453;
55
  }
56
 
57
+ .amp-wp-meta {
58
  margin-bottom: 16px;
59
  }
60
 
78
 
79
 
80
  /* Open Sans */
81
+ .amp-wp-meta,
82
+ nav.amp-wp-title-bar,
83
  .wp-caption-text {
84
  font-family: "Open Sans", sans-serif;
85
  font-size: 15px;
87
 
88
 
89
  /* Meta */
90
+ ul.amp-wp-meta {
91
  padding: 24px 0 0 0;
92
  margin: 0 0 24px 0;
93
  }
94
 
95
+ ul.amp-wp-meta li {
96
  list-style: none;
97
  display: inline-block;
98
  margin: 0;
103
  max-width: 300px;
104
  }
105
 
106
+ ul.amp-wp-meta li:before {
107
  content: "\2022";
108
  margin: 0 8px;
109
  }
110
 
111
+ ul.amp-wp-meta li:first-child:before {
112
  display: none;
113
  }
114
 
115
+ .amp-wp-meta,
116
+ .amp-wp-meta a {
117
  color: #4f748e;
118
  }
119
 
120
+ .amp-wp-meta .screen-reader-text {
121
  /* from twentyfifteen */
122
  clip: rect(1px, 1px, 1px, 1px);
123
  height: 1px;
126
  width: 1px;
127
  }
128
 
129
+ .amp-wp-byline amp-img {
130
  border-radius: 50%;
131
  border: 0;
132
  background: #f3f6f8;
137
 
138
 
139
  /* Titlebar */
140
+ nav.amp-wp-title-bar {
141
  background: #0a89c0;
142
  padding: 0 16px;
143
  }
144
 
145
+ nav.amp-wp-title-bar div {
146
  line-height: 54px;
147
  color: #fff;
148
  }
149
 
150
+ nav.amp-wp-title-bar a {
151
  color: #fff;
152
  text-decoration: none;
153
  }
154
 
155
+ nav.amp-wp-title-bar .amp-wp-site-icon {
156
  /** site icon is 32px **/
157
  float: left;
158
  margin: 11px 8px 0 0;
wpcom-helper.php DELETED
@@ -1,162 +0,0 @@
1
- <?php
2
-
3
- // WPCOM-specific things
4
-
5
- // Add stats pixel
6
- add_filter( 'amp_post_template_footer', 'jetpack_amp_add_stats_pixel' );
7
-
8
- function jetpack_amp_add_stats_pixel( $amp_template ) {
9
- ?>
10
- <amp-pixel src="<?php echo esc_url( wpcom_amp_get_pageview_url() ); ?>"></amp-pixel>
11
- <amp-pixel src="<?php echo esc_url( wpcom_amp_get_mc_url() ); ?>"></amp-pixel>
12
- <amp-pixel src="<?php echo esc_url( wpcom_amp_get_stats_extras_url() ); ?>"></amp-pixel>
13
- <?php
14
- }
15
-
16
- function wpcom_amp_get_pageview_url() {
17
- $stats_info = stats_collect_info();
18
- $a = $stats_info['st_go_args'];
19
-
20
- $url = add_query_arg( array(
21
- 'rand' => 'RANDOM', // AMP placeholder
22
- 'host' => rawurlencode( $_SERVER['HTTP_HOST'] ),
23
- 'ref' => 'DOCUMENT_REFERRER', // AMP placeholder
24
- ), 'https://pixel.wp.com/b.gif' );
25
- $url .= '&' . stats_array_string( $a );
26
- return $url;
27
- }
28
-
29
- function wpcom_amp_get_mc_url() {
30
- return add_query_arg( array(
31
- 'rand' => 'RANDOM', // special amp placeholder
32
- 'v' => 'wpcom-no-pv',
33
- 'x_amp-views' => 'view',
34
- ), 'https://pixel.wp.com/b.gif' );
35
- }
36
-
37
- function wpcom_amp_get_stats_extras_url() {
38
- $stats_extras = stats_extras();
39
- if ( ! $stats_extras ) {
40
- return false;
41
- }
42
-
43
- $url = add_query_arg( array(
44
- 'rand' => 'RANDOM', // special amp placeholder
45
- 'v' => 'wpcom-no-pv',
46
- ), 'https://pixel.wp.com/b.gif' );
47
-
48
- $url .= '&' . stats_array_string( array(
49
- 'crypt' => base64_encode(
50
- wp_encrypt_plus(
51
- ltrim(
52
- add_query_arg( $stats_extras, ''),
53
- '?'),
54
- 8, 'url')
55
- )
56
- ) );
57
-
58
- return $url;
59
- }
60
-
61
- add_action( 'pre_amp_render_post', 'jetpack_amp_disable_the_content_filters' );
62
-
63
- function jetpack_amp_disable_the_content_filters( $post_id ) {
64
- add_filter( 'post_flair_disable', '__return_true', 99 );
65
- remove_filter( 'the_title', 'widont' );
66
-
67
- remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
68
- remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'maybe_create_links' ), 100 );
69
- }
70
-
71
- add_action( 'amp_post_template_head', 'jetpack_amp_add_og_tags' );
72
-
73
- function jetpack_amp_add_og_tags( $amp_template ) {
74
- if ( function_exists( 'jetpack_og_tags' ) ) {
75
- jetpack_og_tags();
76
- }
77
- }
78
-
79
- add_filter( 'amp_post_template_metadata', 'jetpack_amp_post_template_metadata', 10, 2 );
80
-
81
- function jetpack_amp_post_template_metadata( $metadata, $post ) {
82
- $metadata = wpcom_amp_add_blavatar( $metadata, $post );
83
- return $metadata;
84
- }
85
-
86
- function wpcom_amp_add_blavatar( $metadata, $post ) {
87
- if ( ! function_exists( 'blavatar_domain' ) ) {
88
- return $metadata;
89
- }
90
-
91
- if ( ! isset( $metadata['publisher'] ) ) {
92
- return $metadata;
93
- }
94
-
95
- if ( isset( $metadata['publisher']['logo'] ) ) {
96
- return $metadata;
97
- }
98
-
99
- $size = 60;
100
- $blavatar_domain = blavatar_domain( site_url() );
101
- if ( blavatar_exists( $blavatar_domain ) ) {
102
- $metadata['publisher']['logo'] = array(
103
- '@type' => 'ImageObject',
104
- 'url' => blavatar_url( $blavatar_domain, 'img', $size, false, true ),
105
- 'width' => $size,
106
- 'height' => $size,
107
- );
108
- }
109
-
110
- return $metadata;
111
- }
112
-
113
- add_action( 'amp_extract_image_dimensions_callbacks_registered', 'wpcom_amp_extract_image_dimensions_add_custom_callbacks' );
114
- function wpcom_amp_extract_image_dimensions_add_custom_callbacks() {
115
- // If images are being served from Photon or WP.com files, try extracting the size using querystring.
116
- add_action( 'amp_extract_image_dimensions', 'wpcom_amp_extract_image_dimensions_from_querystring', 9, 2 ); // Hook in before the default extractors
117
-
118
- // Uses a special wpcom lib (wpcom_getimagesize) to extract dimensions as a last resort if we weren't able to figure them out.
119
- add_action( 'amp_extract_image_dimensions', 'wpcom_amp_extract_image_dimensions_from_getimagesize', 99, 2 ); // Our last resort, so run late
120
-
121
- // The wpcom override obviates this one, so take it out.
122
- remove_action( 'amp_extract_image_dimensions', array( 'AMP_Image_Dimension_Extractor', 'extract_by_downloading_image' ), 100 );
123
- }
124
-
125
- function wpcom_amp_extract_image_dimensions_from_querystring( $dimensions, $url ) {
126
- if ( is_array( $dimensions ) ) {
127
- return $dimensions;
128
- }
129
-
130
- $host = parse_url( $url, PHP_URL_HOST );
131
- if ( ! wp_endswith( $host, '.wp.com' ) || ! wp_endswith( $host, '.files.wordpress.com' ) ) {
132
- return false;
133
- }
134
-
135
- $query = parse_url( $url, PHP_URL_QUERY );
136
- $w = isset( $query['w'] ) ? absint( $query['w'] ) : false;
137
- $h = isset( $query['h'] ) ? absint( $query['h'] ) : false;
138
-
139
- if ( false !== $w && false !== $h ) {
140
- return array( $w, $h );
141
- }
142
-
143
- return false;
144
- }
145
-
146
- function wpcom_amp_extract_image_dimensions_from_getimagesize( $dimensions, $url ) {
147
- if ( is_array( $dimensions ) ) {
148
- return $dimensions;
149
- }
150
-
151
- if ( ! function_exists( 'require_lib' ) ) {
152
- return false;
153
- }
154
-
155
- require_lib( 'wpcom/imagesize' );
156
- $size = wpcom_getimagesize( $url );
157
- if ( ! is_array( $size ) ) {
158
- return false;
159
- }
160
-
161
- return array( $size[0], $size[1] );
162
- }