Version Description
(Feb 18, 2016) =
- Fetch dimensions for hotlinked images.
- Add amp-facebook support.
- Add some new actions and filters (e.g.
amp_init
). - Fix validation errors for [gallery] shortcodes.
- Fix issues with path validation on Windows.
- Fix issues with really squeezed layout.
- Breaking change:
style.css
no longer contains the `
Download this release
Release Info
Developer | batmoo |
Plugin | AMP for WordPress |
Version | 0.3 |
Comparing to | |
See all releases |
Code changes from version 0.2 to 0.3
- amp.php +3 -4
- assets/images/placeholder-icon.png +0 -0
- includes/amp-helper-functions.php +1 -1
- includes/amp-post-template-actions.php +12 -1
- includes/class-amp-post-template.php +21 -5
- includes/embeds/class-amp-facebook-embed.php +55 -0
- includes/embeds/class-amp-gallery-embed.php +6 -1
- includes/lib/class-fastimage.php +253 -0
- includes/sanitizers/class-amp-base-sanitizer.php +0 -4
- includes/sanitizers/class-amp-blacklist-sanitizer.php +13 -4
- includes/sanitizers/class-amp-img-sanitizer.php +1 -1
- includes/utils/class-amp-image-dimension-extractor.php +49 -1
- jetpack-helper.php +6 -1
- readme.md +140 -8
- readme.txt +16 -3
- templates/meta-author.php +2 -0
- templates/single.php +4 -5
- templates/style.php +4 -10
- wpcom-helper.php +43 -42
amp.php
CHANGED
@@ -5,16 +5,13 @@
|
|
5 |
* Plugin URI: https://github.com/automattic/amp-wp
|
6 |
* Author: Automattic
|
7 |
* Author URI: https://automattic.com
|
8 |
-
* Version: 0.
|
9 |
* Text Domain: amp
|
10 |
* Domain Path: /languages/
|
11 |
* License: GPLv2 or later
|
12 |
*/
|
13 |
|
14 |
define( 'AMP_QUERY_VAR', 'amp' );
|
15 |
-
if ( ! defined( 'AMP_DEV_MODE' ) ) {
|
16 |
-
define( 'AMP_DEV_MODE', defined( 'WP_DEBUG' ) && WP_DEBUG );
|
17 |
-
}
|
18 |
|
19 |
define( 'AMP__FILE__', __FILE__ );
|
20 |
define( 'AMP__DIR__', dirname( __FILE__ ) );
|
@@ -38,6 +35,8 @@ function amp_init() {
|
|
38 |
return;
|
39 |
}
|
40 |
|
|
|
|
|
41 |
load_plugin_textdomain( 'amp', false, plugin_basename( AMP__DIR__ ) . '/languages' );
|
42 |
|
43 |
add_rewrite_endpoint( AMP_QUERY_VAR, EP_PERMALINK );
|
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__ ) );
|
35 |
return;
|
36 |
}
|
37 |
|
38 |
+
do_action( 'amp_init' );
|
39 |
+
|
40 |
load_plugin_textdomain( 'amp', false, plugin_basename( AMP__DIR__ ) . '/languages' );
|
41 |
|
42 |
add_rewrite_endpoint( AMP_QUERY_VAR, EP_PERMALINK );
|
assets/images/placeholder-icon.png
CHANGED
Binary file
|
includes/amp-helper-functions.php
CHANGED
@@ -16,7 +16,7 @@ function post_supports_amp( $post ) {
|
|
16 |
return false;
|
17 |
}
|
18 |
|
19 |
-
if ( true === apply_filters( 'amp_skip_post', false, $post->ID ) ) {
|
20 |
return false;
|
21 |
}
|
22 |
|
16 |
return false;
|
17 |
}
|
18 |
|
19 |
+
if ( true === apply_filters( 'amp_skip_post', false, $post->ID, $post ) ) {
|
20 |
return false;
|
21 |
}
|
22 |
|
includes/amp-post-template-actions.php
CHANGED
@@ -25,9 +25,20 @@ function amp_post_template_add_scripts( $amp_template ) {
|
|
25 |
<?php
|
26 |
}
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
add_action( 'amp_post_template_head', 'amp_post_template_add_schemaorg_metadata' );
|
29 |
function amp_post_template_add_schemaorg_metadata( $amp_template ) {
|
|
|
|
|
|
|
|
|
30 |
?>
|
31 |
-
<script type="application/ld+json"><?php echo json_encode( $
|
32 |
<?php
|
33 |
}
|
25 |
<?php
|
26 |
}
|
27 |
|
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 |
+
|
35 |
add_action( 'amp_post_template_head', 'amp_post_template_add_schemaorg_metadata' );
|
36 |
function amp_post_template_add_schemaorg_metadata( $amp_template ) {
|
37 |
+
$metadata = $amp_template->get( 'metadata' );
|
38 |
+
if ( empty( $metadata ) ) {
|
39 |
+
return;
|
40 |
+
}
|
41 |
?>
|
42 |
+
<script type="application/ld+json"><?php echo json_encode( $metadata ); ?></script>
|
43 |
<?php
|
44 |
}
|
includes/class-amp-post-template.php
CHANGED
@@ -13,6 +13,7 @@ require_once( AMP__DIR__ . '/includes/embeds/class-amp-youtube-embed.php' );
|
|
13 |
require_once( AMP__DIR__ . '/includes/embeds/class-amp-gallery-embed.php' );
|
14 |
require_once( AMP__DIR__ . '/includes/embeds/class-amp-instagram-embed.php' );
|
15 |
require_once( AMP__DIR__ . '/includes/embeds/class-amp-vine-embed.php' );
|
|
|
16 |
|
17 |
class AMP_Post_Template {
|
18 |
const SITE_ICON_SIZE = 32;
|
@@ -37,7 +38,7 @@ class AMP_Post_Template {
|
|
37 |
'home_url' => home_url(),
|
38 |
'blog_name' => get_bloginfo( 'name' ),
|
39 |
|
40 |
-
'site_icon_url' => get_site_icon_url( self::SITE_ICON_SIZE ),
|
41 |
'placeholder_image_url' => amp_get_asset_url( 'images/placeholder-icon.png' ),
|
42 |
|
43 |
'amp_runtime_script' => 'https://cdn.ampproject.org/v0.js',
|
@@ -121,7 +122,6 @@ class AMP_Post_Template {
|
|
121 |
'@type' => 'Person',
|
122 |
'name' => $post_author->display_name,
|
123 |
),
|
124 |
-
'image' => $this->get_post_image_metadata(),
|
125 |
);
|
126 |
|
127 |
$site_icon_url = $this->get( 'site_icon_url' );
|
@@ -134,7 +134,12 @@ class AMP_Post_Template {
|
|
134 |
);
|
135 |
}
|
136 |
|
137 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
138 |
}
|
139 |
|
140 |
private function build_post_content() {
|
@@ -144,6 +149,7 @@ class AMP_Post_Template {
|
|
144 |
'AMP_YouTube_Embed_Handler' => array(),
|
145 |
'AMP_Instagram_Embed_Handler' => array(),
|
146 |
'AMP_Vine_Embed_Handler' => array(),
|
|
|
147 |
'AMP_Gallery_Embed_Handler' => array(),
|
148 |
), $this->post ),
|
149 |
apply_filters( 'amp_content_sanitizers', array(
|
@@ -198,7 +204,7 @@ class AMP_Post_Template {
|
|
198 |
|
199 |
$post_image_src = wp_get_attachment_image_src( $post_image_id, 'full' );
|
200 |
|
201 |
-
if ( $post_image_src ) {
|
202 |
$post_image_meta = array(
|
203 |
'@type' => 'ImageObject',
|
204 |
'url' => $post_image_src[0],
|
@@ -232,7 +238,9 @@ class AMP_Post_Template {
|
|
232 |
}
|
233 |
|
234 |
private function is_valid_template( $template ) {
|
235 |
-
|
|
|
|
|
236 |
return false;
|
237 |
}
|
238 |
|
@@ -240,6 +248,14 @@ class AMP_Post_Template {
|
|
240 |
return false;
|
241 |
}
|
242 |
|
|
|
|
|
|
|
|
|
243 |
return true;
|
244 |
}
|
|
|
|
|
|
|
|
|
245 |
}
|
13 |
require_once( AMP__DIR__ . '/includes/embeds/class-amp-gallery-embed.php' );
|
14 |
require_once( AMP__DIR__ . '/includes/embeds/class-amp-instagram-embed.php' );
|
15 |
require_once( AMP__DIR__ . '/includes/embeds/class-amp-vine-embed.php' );
|
16 |
+
require_once( AMP__DIR__ . '/includes/embeds/class-amp-facebook-embed.php' );
|
17 |
|
18 |
class AMP_Post_Template {
|
19 |
const SITE_ICON_SIZE = 32;
|
38 |
'home_url' => home_url(),
|
39 |
'blog_name' => get_bloginfo( 'name' ),
|
40 |
|
41 |
+
'site_icon_url' => apply_filters( 'amp_site_icon_url', function_exists( 'get_site_icon_url' ) ? get_site_icon_url( self::SITE_ICON_SIZE ) : '' ),
|
42 |
'placeholder_image_url' => amp_get_asset_url( 'images/placeholder-icon.png' ),
|
43 |
|
44 |
'amp_runtime_script' => 'https://cdn.ampproject.org/v0.js',
|
122 |
'@type' => 'Person',
|
123 |
'name' => $post_author->display_name,
|
124 |
),
|
|
|
125 |
);
|
126 |
|
127 |
$site_icon_url = $this->get( 'site_icon_url' );
|
134 |
);
|
135 |
}
|
136 |
|
137 |
+
$image_metadata = $this->get_post_image_metadata();
|
138 |
+
if ( $image_metadata ) {
|
139 |
+
$metadata['image'] = $image_metadata;
|
140 |
+
}
|
141 |
+
|
142 |
+
$this->add_data_by_key( 'metadata', apply_filters( 'amp_post_template_metadata', $metadata, $this->post ) );
|
143 |
}
|
144 |
|
145 |
private function build_post_content() {
|
149 |
'AMP_YouTube_Embed_Handler' => array(),
|
150 |
'AMP_Instagram_Embed_Handler' => array(),
|
151 |
'AMP_Vine_Embed_Handler' => array(),
|
152 |
+
'AMP_Facebook_Embed_Handler' => array(),
|
153 |
'AMP_Gallery_Embed_Handler' => array(),
|
154 |
), $this->post ),
|
155 |
apply_filters( 'amp_content_sanitizers', array(
|
204 |
|
205 |
$post_image_src = wp_get_attachment_image_src( $post_image_id, 'full' );
|
206 |
|
207 |
+
if ( is_array( $post_image_src ) ) {
|
208 |
$post_image_meta = array(
|
209 |
'@type' => 'ImageObject',
|
210 |
'url' => $post_image_src[0],
|
238 |
}
|
239 |
|
240 |
private function is_valid_template( $template ) {
|
241 |
+
$template = $this->normalize_path( $template );
|
242 |
+
$content_dir = $this->normalize_path( WP_CONTENT_DIR );
|
243 |
+
if ( 0 !== strpos( $template, $content_dir ) ) {
|
244 |
return false;
|
245 |
}
|
246 |
|
248 |
return false;
|
249 |
}
|
250 |
|
251 |
+
if ( ! file_exists( $template ) ) {
|
252 |
+
return false;
|
253 |
+
}
|
254 |
+
|
255 |
return true;
|
256 |
}
|
257 |
+
|
258 |
+
private function normalize_path( $path ) {
|
259 |
+
return str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, $path );
|
260 |
+
}
|
261 |
}
|
includes/embeds/class-amp-facebook-embed.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once( AMP__DIR__ . '/includes/embeds/class-amp-base-embed-handler.php' );
|
4 |
+
|
5 |
+
class AMP_Facebook_Embed_Handler extends AMP_Base_Embed_Handler {
|
6 |
+
const URL_PATTERN = '#https?://(www\.)?facebook\.com/.*#i';
|
7 |
+
|
8 |
+
protected $DEFAULT_WIDTH = 600;
|
9 |
+
protected $DEFAULT_HEIGHT = 400;
|
10 |
+
|
11 |
+
private static $script_slug = 'amp-facebook';
|
12 |
+
private static $script_src = 'https://cdn.ampproject.org/v0/amp-facebook-0.1.js';
|
13 |
+
|
14 |
+
public function register_embed() {
|
15 |
+
wp_embed_register_handler( 'amp-facebook', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
16 |
+
}
|
17 |
+
|
18 |
+
public function unregister_embed() {
|
19 |
+
wp_embed_unregister_handler( 'amp-facebook', -1 );
|
20 |
+
}
|
21 |
+
|
22 |
+
public function get_scripts() {
|
23 |
+
if ( ! $this->did_convert_elements ) {
|
24 |
+
return array();
|
25 |
+
}
|
26 |
+
|
27 |
+
return array( self::$script_slug => self::$script_src );
|
28 |
+
}
|
29 |
+
|
30 |
+
public function oembed( $matches, $attr, $url, $rawattr ) {
|
31 |
+
return $this->render( array( 'url' => $url ) );
|
32 |
+
}
|
33 |
+
|
34 |
+
public function render( $args ) {
|
35 |
+
$args = wp_parse_args( $args, array(
|
36 |
+
'url' => false,
|
37 |
+
) );
|
38 |
+
|
39 |
+
if ( empty( $args['url'] ) ) {
|
40 |
+
return '';
|
41 |
+
}
|
42 |
+
|
43 |
+
$this->did_convert_elements = true;
|
44 |
+
|
45 |
+
return AMP_HTML_Utils::build_tag(
|
46 |
+
'amp-facebook',
|
47 |
+
array(
|
48 |
+
'data-href' => $args['url'],
|
49 |
+
'layout' => 'responsive',
|
50 |
+
'width' => $this->args['width'],
|
51 |
+
'height' => $this->args['height'],
|
52 |
+
)
|
53 |
+
);
|
54 |
+
}
|
55 |
+
}
|
includes/embeds/class-amp-gallery-embed.php
CHANGED
@@ -126,7 +126,12 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
126 |
|
127 |
return AMP_HTML_Utils::build_tag(
|
128 |
'amp-carousel',
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
130 |
implode( PHP_EOL, $images )
|
131 |
);
|
132 |
}
|
126 |
|
127 |
return AMP_HTML_Utils::build_tag(
|
128 |
'amp-carousel',
|
129 |
+
array(
|
130 |
+
'width' => $this->args['width'],
|
131 |
+
'height' => $this->args['height'],
|
132 |
+
'type' => 'slides',
|
133 |
+
'layout' => 'responsive',
|
134 |
+
),
|
135 |
implode( PHP_EOL, $images )
|
136 |
);
|
137 |
}
|
includes/lib/class-fastimage.php
ADDED
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* FastImage - Because sometimes you just want the size!
|
5 |
+
* Based on the Ruby Implementation by Steven Sykes (https://github.com/sdsykes/fastimage)
|
6 |
+
*
|
7 |
+
* Copyright (c) 2012 Tom Moor
|
8 |
+
* Tom Moor, http://tommoor.com
|
9 |
+
*
|
10 |
+
* MIT Licensed
|
11 |
+
* @version 0.1
|
12 |
+
*/
|
13 |
+
|
14 |
+
class FastImage
|
15 |
+
{
|
16 |
+
private $strpos = 0;
|
17 |
+
private $str;
|
18 |
+
private $type;
|
19 |
+
private $handle;
|
20 |
+
|
21 |
+
public function __construct($uri = null)
|
22 |
+
{
|
23 |
+
if ($uri) $this->load($uri);
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
public function load($uri)
|
28 |
+
{
|
29 |
+
if ($this->handle) $this->close();
|
30 |
+
|
31 |
+
$this->handle = fopen($uri, 'r');
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
public function close()
|
36 |
+
{
|
37 |
+
if ($this->handle)
|
38 |
+
{
|
39 |
+
fclose($this->handle);
|
40 |
+
$this->handle = null;
|
41 |
+
$this->type = null;
|
42 |
+
$this->str = null;
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
public function getSize()
|
48 |
+
{
|
49 |
+
if (!$this->handle)
|
50 |
+
{
|
51 |
+
return false;
|
52 |
+
}
|
53 |
+
|
54 |
+
$this->strpos = 0;
|
55 |
+
if ($this->getType())
|
56 |
+
{
|
57 |
+
return array_values($this->parseSize());
|
58 |
+
}
|
59 |
+
|
60 |
+
return false;
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
public function getType()
|
65 |
+
{
|
66 |
+
if (!$this->handle)
|
67 |
+
{
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
|
71 |
+
$this->strpos = 0;
|
72 |
+
|
73 |
+
if (!$this->type)
|
74 |
+
{
|
75 |
+
switch ($this->getChars(2))
|
76 |
+
{
|
77 |
+
case "BM":
|
78 |
+
return $this->type = 'bmp';
|
79 |
+
case "GI":
|
80 |
+
return $this->type = 'gif';
|
81 |
+
case chr(0xFF).chr(0xd8):
|
82 |
+
return $this->type = 'jpeg';
|
83 |
+
case chr(0x89).'P':
|
84 |
+
return $this->type = 'png';
|
85 |
+
default:
|
86 |
+
return false;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
return $this->type;
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
private function parseSize()
|
95 |
+
{
|
96 |
+
$this->strpos = 0;
|
97 |
+
|
98 |
+
switch ($this->type)
|
99 |
+
{
|
100 |
+
case 'png':
|
101 |
+
return $this->parseSizeForPNG();
|
102 |
+
case 'gif':
|
103 |
+
return $this->parseSizeForGIF();
|
104 |
+
case 'bmp':
|
105 |
+
return $this->parseSizeForBMP();
|
106 |
+
case 'jpeg':
|
107 |
+
return $this->parseSizeForJPEG();
|
108 |
+
}
|
109 |
+
|
110 |
+
return null;
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
private function parseSizeForPNG()
|
115 |
+
{
|
116 |
+
$chars = $this->getChars(25);
|
117 |
+
|
118 |
+
return unpack("N*", substr($chars, 16, 8));
|
119 |
+
}
|
120 |
+
|
121 |
+
|
122 |
+
private function parseSizeForGIF()
|
123 |
+
{
|
124 |
+
$chars = $this->getChars(11);
|
125 |
+
|
126 |
+
return unpack("S*", substr($chars, 6, 4));
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
private function parseSizeForBMP()
|
131 |
+
{
|
132 |
+
$chars = $this->getChars(29);
|
133 |
+
$chars = substr($chars, 14, 14);
|
134 |
+
$type = unpack('C', $chars);
|
135 |
+
|
136 |
+
return (reset($type) == 40) ? unpack('L*', substr($chars, 4)) : unpack('L*', substr($chars, 4, 8));
|
137 |
+
}
|
138 |
+
|
139 |
+
|
140 |
+
private function parseSizeForJPEG()
|
141 |
+
{
|
142 |
+
$state = null;
|
143 |
+
$i = 0;
|
144 |
+
|
145 |
+
while (true)
|
146 |
+
{
|
147 |
+
switch ($state)
|
148 |
+
{
|
149 |
+
default:
|
150 |
+
$this->getChars(2);
|
151 |
+
$state = 'started';
|
152 |
+
break;
|
153 |
+
|
154 |
+
case 'started':
|
155 |
+
$b = $this->getByte();
|
156 |
+
if ($b === false) return false;
|
157 |
+
|
158 |
+
$state = $b == 0xFF ? 'sof' : 'started';
|
159 |
+
break;
|
160 |
+
|
161 |
+
case 'sof':
|
162 |
+
$b = $this->getByte();
|
163 |
+
if (in_array($b, range(0xe0, 0xef)))
|
164 |
+
{
|
165 |
+
$state = 'skipframe';
|
166 |
+
}
|
167 |
+
elseif (in_array($b, array_merge(range(0xC0,0xC3), range(0xC5,0xC7), range(0xC9,0xCB), range(0xCD,0xCF))))
|
168 |
+
{
|
169 |
+
$state = 'readsize';
|
170 |
+
}
|
171 |
+
elseif ($b == 0xFF)
|
172 |
+
{
|
173 |
+
$state = 'sof';
|
174 |
+
}
|
175 |
+
else
|
176 |
+
{
|
177 |
+
$state = 'skipframe';
|
178 |
+
}
|
179 |
+
break;
|
180 |
+
|
181 |
+
case 'skipframe':
|
182 |
+
$skip = $this->readInt($this->getChars(2)) - 2;
|
183 |
+
$state = 'doskip';
|
184 |
+
break;
|
185 |
+
|
186 |
+
case 'doskip':
|
187 |
+
$this->getChars($skip);
|
188 |
+
$state = 'started';
|
189 |
+
break;
|
190 |
+
|
191 |
+
case 'readsize':
|
192 |
+
$c = $this->getChars(7);
|
193 |
+
|
194 |
+
return array($this->readInt(substr($c, 5, 2)), $this->readInt(substr($c, 3, 2)));
|
195 |
+
}
|
196 |
+
}
|
197 |
+
}
|
198 |
+
|
199 |
+
|
200 |
+
private function getChars($n)
|
201 |
+
{
|
202 |
+
$response = null;
|
203 |
+
|
204 |
+
// do we need more data?
|
205 |
+
if ($this->strpos + $n -1 >= strlen($this->str))
|
206 |
+
{
|
207 |
+
$end = ($this->strpos + $n);
|
208 |
+
|
209 |
+
while (strlen($this->str) < $end && $response !== false)
|
210 |
+
{
|
211 |
+
// read more from the file handle
|
212 |
+
$need = $end - ftell($this->handle);
|
213 |
+
|
214 |
+
if ($response = fread($this->handle, $need))
|
215 |
+
{
|
216 |
+
$this->str .= $response;
|
217 |
+
}
|
218 |
+
else
|
219 |
+
{
|
220 |
+
return false;
|
221 |
+
}
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
+
$result = substr($this->str, $this->strpos, $n);
|
226 |
+
$this->strpos += $n;
|
227 |
+
|
228 |
+
return $result;
|
229 |
+
}
|
230 |
+
|
231 |
+
|
232 |
+
private function getByte()
|
233 |
+
{
|
234 |
+
$c = $this->getChars(1);
|
235 |
+
$b = unpack("C", $c);
|
236 |
+
|
237 |
+
return reset($b);
|
238 |
+
}
|
239 |
+
|
240 |
+
|
241 |
+
private function readInt($str)
|
242 |
+
{
|
243 |
+
$size = unpack("C*", $str);
|
244 |
+
|
245 |
+
return ($size[1] << 8) + $size[2];
|
246 |
+
}
|
247 |
+
|
248 |
+
|
249 |
+
public function __destruct()
|
250 |
+
{
|
251 |
+
$this->close();
|
252 |
+
}
|
253 |
+
}
|
includes/sanitizers/class-amp-base-sanitizer.php
CHANGED
@@ -31,10 +31,6 @@ abstract class AMP_Base_Sanitizer {
|
|
31 |
* See https://github.com/Automattic/amp-wp/issues/101
|
32 |
*/
|
33 |
public function enforce_sizes_attribute( $attributes ) {
|
34 |
-
if ( isset( $attributes['sizes'] ) ) {
|
35 |
-
return $attributes;
|
36 |
-
}
|
37 |
-
|
38 |
if ( ! isset( $attributes['width'], $attributes['height'] ) ) {
|
39 |
return $attributes;
|
40 |
}
|
31 |
* See https://github.com/Automattic/amp-wp/issues/101
|
32 |
*/
|
33 |
public function enforce_sizes_attribute( $attributes ) {
|
|
|
|
|
|
|
|
|
34 |
if ( ! isset( $attributes['width'], $attributes['height'] ) ) {
|
35 |
return $attributes;
|
36 |
}
|
includes/sanitizers/class-amp-blacklist-sanitizer.php
CHANGED
@@ -9,6 +9,8 @@ require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-base-sanitizer.php' )
|
|
9 |
* https://github.com/ampproject/amphtml/blob/master/spec/amp-html-format.md#html-tags
|
10 |
*/
|
11 |
class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
|
|
|
12 |
public function sanitize() {
|
13 |
$blacklisted_tags = $this->get_blacklisted_tags();
|
14 |
$blacklisted_attributes = $this->get_blacklisted_attributes();
|
@@ -25,6 +27,7 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
25 |
}
|
26 |
|
27 |
if ( $node->hasAttributes() ) {
|
|
|
28 |
$length = $node->attributes->length;
|
29 |
for ( $i = $length - 1; $i >= 0; $i-- ) {
|
30 |
$attribute = $node->attributes->item( $i );
|
@@ -38,14 +41,21 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
38 |
if ( 0 === stripos( $attribute_name, 'on' ) ) {
|
39 |
$node->removeAttribute( $attribute_name );
|
40 |
continue;
|
41 |
-
}
|
42 |
-
|
43 |
-
if ( 'href' === $attribute_name ) {
|
44 |
$protocol = strtok( $attribute->value, ':' );
|
45 |
if ( in_array( $protocol, $bad_protocols ) ) {
|
46 |
$node->removeAttribute( $attribute_name );
|
47 |
continue;
|
48 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
}
|
51 |
}
|
@@ -93,7 +103,6 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
93 |
'applet',
|
94 |
'form',
|
95 |
'input',
|
96 |
-
'button',
|
97 |
'textarea',
|
98 |
'select',
|
99 |
'option',
|
9 |
* https://github.com/ampproject/amphtml/blob/master/spec/amp-html-format.md#html-tags
|
10 |
*/
|
11 |
class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
12 |
+
const PATTERN_REL_WP_ATTACHMENT = '#wp-att-([\d]+)#';
|
13 |
+
|
14 |
public function sanitize() {
|
15 |
$blacklisted_tags = $this->get_blacklisted_tags();
|
16 |
$blacklisted_attributes = $this->get_blacklisted_attributes();
|
27 |
}
|
28 |
|
29 |
if ( $node->hasAttributes() ) {
|
30 |
+
$node_name = $node->nodeName;
|
31 |
$length = $node->attributes->length;
|
32 |
for ( $i = $length - 1; $i >= 0; $i-- ) {
|
33 |
$attribute = $node->attributes->item( $i );
|
41 |
if ( 0 === stripos( $attribute_name, 'on' ) ) {
|
42 |
$node->removeAttribute( $attribute_name );
|
43 |
continue;
|
44 |
+
} elseif ( 'href' === $attribute_name ) {
|
|
|
|
|
45 |
$protocol = strtok( $attribute->value, ':' );
|
46 |
if ( in_array( $protocol, $bad_protocols ) ) {
|
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 |
}
|
103 |
'applet',
|
104 |
'form',
|
105 |
'input',
|
|
|
106 |
'textarea',
|
107 |
'select',
|
108 |
'option',
|
includes/sanitizers/class-amp-img-sanitizer.php
CHANGED
@@ -33,7 +33,7 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
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 ( $dimensions ) {
|
37 |
$new_attributes['width'] = $dimensions[0];
|
38 |
$new_attributes['height'] = $dimensions[1];
|
39 |
}
|
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 ) ) {
|
37 |
$new_attributes['width'] = $dimensions[0];
|
38 |
$new_attributes['height'] = $dimensions[1];
|
39 |
}
|
includes/utils/class-amp-image-dimension-extractor.php
CHANGED
@@ -15,10 +15,13 @@ class AMP_Image_Dimension_Extractor {
|
|
15 |
self::$callbacks_registered = true;
|
16 |
|
17 |
add_filter( 'amp_extract_image_dimensions', array( __CLASS__, 'extract_from_attachment_metadata' ), 10, 2 );
|
|
|
|
|
|
|
18 |
}
|
19 |
|
20 |
public static function extract_from_attachment_metadata( $dimensions, $url ) {
|
21 |
-
if ( $dimensions ) {
|
22 |
return $dimensions;
|
23 |
}
|
24 |
|
@@ -35,4 +38,49 @@ class AMP_Image_Dimension_Extractor {
|
|
35 |
|
36 |
return array( $metadata['width'], $metadata['height'] );
|
37 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
15 |
self::$callbacks_registered = true;
|
16 |
|
17 |
add_filter( 'amp_extract_image_dimensions', array( __CLASS__, 'extract_from_attachment_metadata' ), 10, 2 );
|
18 |
+
add_filter( 'amp_extract_image_dimensions', array( __CLASS__, 'extract_by_downloading_image' ), 999, 2 ); // Run really late since this is our last resort
|
19 |
+
|
20 |
+
do_action( 'amp_extract_image_dimensions_callbacks_registered' );
|
21 |
}
|
22 |
|
23 |
public static function extract_from_attachment_metadata( $dimensions, $url ) {
|
24 |
+
if ( is_array( $dimensions ) ) {
|
25 |
return $dimensions;
|
26 |
}
|
27 |
|
38 |
|
39 |
return array( $metadata['width'], $metadata['height'] );
|
40 |
}
|
41 |
+
|
42 |
+
public static function extract_by_downloading_image( $dimensions, $url ) {
|
43 |
+
if ( is_array( $dimensions ) ) {
|
44 |
+
return $dimensions;
|
45 |
+
}
|
46 |
+
|
47 |
+
$url_hash = md5( $url );
|
48 |
+
$transient_name = sprintf( 'amp_img_%s', $url_hash );
|
49 |
+
$transient_expiry = 30 * DAY_IN_SECONDS;
|
50 |
+
$transient_fail = 'fail';
|
51 |
+
|
52 |
+
$dimensions = get_transient( $transient_name );
|
53 |
+
|
54 |
+
if ( is_array( $dimensions ) ) {
|
55 |
+
return $dimensions;
|
56 |
+
} elseif ( $transient_fail === $dimensions ) {
|
57 |
+
return false;
|
58 |
+
}
|
59 |
+
|
60 |
+
// Very simple lock to prevent stampedes
|
61 |
+
$transient_lock_name = sprintf( 'amp_lock_%s', $url_hash );
|
62 |
+
if ( false !== get_transient( $transient_lock_name ) ) {
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
set_transient( $transient_lock_name, 1, MINUTE_IN_SECONDS );
|
66 |
+
|
67 |
+
// Note to other developers: please don't use this class directly as it may not stick around forever...
|
68 |
+
if ( ! class_exists( 'FastImage' ) ) {
|
69 |
+
require_once( AMP__DIR__ . '/includes/lib/class-fastimage.php' );
|
70 |
+
}
|
71 |
+
|
72 |
+
// TODO: look into using curl+stream (https://github.com/willwashburn/FasterImage)
|
73 |
+
$image = new FastImage( $url );
|
74 |
+
$dimensions = $image->getSize();
|
75 |
+
|
76 |
+
if ( ! is_array( $dimensions ) ) {
|
77 |
+
set_transient( $transient_name, $transient_fail, $transient_expiry );
|
78 |
+
delete_transient( $transient_lock_name );
|
79 |
+
return false;
|
80 |
+
}
|
81 |
+
|
82 |
+
set_transient( $transient_name, $dimensions, $transient_expiry );
|
83 |
+
delete_transient( $transient_lock_name );
|
84 |
+
return $dimensions;
|
85 |
+
}
|
86 |
}
|
jetpack-helper.php
CHANGED
@@ -2,16 +2,21 @@
|
|
2 |
|
3 |
// Jetpack bits.
|
4 |
|
5 |
-
add_action( '
|
6 |
|
7 |
/**
|
8 |
* Disable Jetpack features that are not compatible with AMP.
|
9 |
*
|
10 |
**/
|
11 |
function amp_jetpack_mods() {
|
|
|
12 |
amp_jetpack_disable_related_posts();
|
13 |
}
|
14 |
|
|
|
|
|
|
|
|
|
15 |
/**
|
16 |
* Remove the Related Posts placeholder and headline that gets hooked into the_content
|
17 |
*
|
2 |
|
3 |
// Jetpack bits.
|
4 |
|
5 |
+
add_action( 'pre_amp_render_post', 'amp_jetpack_mods' );
|
6 |
|
7 |
/**
|
8 |
* Disable Jetpack features that are not compatible with AMP.
|
9 |
*
|
10 |
**/
|
11 |
function amp_jetpack_mods() {
|
12 |
+
amp_jetpack_disable_sharing();
|
13 |
amp_jetpack_disable_related_posts();
|
14 |
}
|
15 |
|
16 |
+
function amp_jetpack_disable_sharing() {
|
17 |
+
add_filter( 'sharing_show', '__return_false', 100 );
|
18 |
+
}
|
19 |
+
|
20 |
/**
|
21 |
* Remove the Related Posts placeholder and headline that gets hooked into the_content
|
22 |
*
|
readme.md
CHANGED
@@ -2,11 +2,13 @@
|
|
2 |
|
3 |
## Overview
|
4 |
|
5 |
-
This plugin adds support for the Accelerated Mobile Pages (AMP) Project, which is an an open source initiative that aims to provide mobile optimized content that can load instantly everywhere.
|
6 |
|
7 |
-
With the plugin active, all
|
8 |
|
9 |
-
|
|
|
|
|
10 |
|
11 |
## Customization / Templating
|
12 |
|
@@ -14,16 +16,69 @@ The plugin ships with a default template that looks nice and clean and we tried
|
|
14 |
|
15 |
You can tweak small pieces of the template or the entire thing depending on your needs.
|
16 |
|
17 |
-
###
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
The default template will attempt to draw from various theme mods, such as site icon and background and header color/image, if supported by the active theme.
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
### Template Tweaks
|
24 |
|
25 |
You can tweak various parts of the template via code.
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
#### Content Width
|
28 |
|
29 |
By default, your theme's `$content_width` value will be used to determine the size of the `amp` content well. You can change this:
|
@@ -51,7 +106,27 @@ function xyz_set_custom_placeholder_image( $data ) {
|
|
51 |
|
52 |
Note: The path must pass the default criteria set out by [`validate_file`](https://developer.wordpress.org/reference/functions/validate_file/) and must be somewhere in a subfolder of `WP_CONTENT_DIR`.
|
53 |
|
54 |
-
####
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
For the meta section of the template (i.e. author, date, taxonomies, etc.), you can override templates for the existing sections, remove them, add new ones.
|
57 |
|
@@ -137,12 +212,34 @@ Then, in `templates/xyz-meta-comment-count.php`:
|
|
137 |
|
138 |
#### Custom CSS
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
If you'd prefer to use your own styles, you can either:
|
141 |
|
142 |
- Create a folder in your theme called `amp` and add a file called `style.php` with your custom CSS.
|
143 |
-
- Specify a custom template using the `amp_post_template_file` filter for `'style' === $type`.
|
144 |
|
145 |
-
|
146 |
|
147 |
#### Head and Footer
|
148 |
|
@@ -199,6 +296,12 @@ do_action( 'amp_post_template_head', $this );
|
|
199 |
do_action( 'amp_post_template_footer', $this );
|
200 |
```
|
201 |
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
* You must include [all required mark-up](https://www.ampproject.org/docs/get_started/create/basic_markup.html) that isn't already output via the `amp_post_template_head` action.
|
203 |
|
204 |
## Handling Media
|
@@ -358,3 +461,32 @@ function xyz_amp_add_ad_sanitizer( $sanitizer_classes, $post ) {
|
|
358 |
return $sanitizer_classes;
|
359 |
}
|
360 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
## Overview
|
4 |
|
5 |
+
This plugin adds support for the [Accelerated Mobile Pages](https://www.ampproject.org) (AMP) Project, which is an an open source initiative that aims to provide mobile optimized content that can load instantly everywhere.
|
6 |
|
7 |
+
With the plugin active, all posts on your site will have dynamically generated AMP-compatible versions, accessible by appending `/amp/` to the end your post URLs. For example, if your post URL is `http://example.com/2016/01/01/amp-on/`, you can access the AMP version at `http://example.com/2016/01/01/amp-on/amp/`. If you do not have [pretty permalinks](https://codex.wordpress.org/Using_Permalinks#mod_rewrite:_.22Pretty_Permalinks.22) enabled, you can do the same thing by appending `?amp=1`, i.e. `http://example.com/2016/01/01/amp-on/?amp=1`
|
8 |
|
9 |
+
Note #1: that Pages and archives are not currently supported.
|
10 |
+
|
11 |
+
Note #2: this plugin only creates AMP content but does not automatically display it to your users when they visit from a mobile device. That is handled by AMP consumers such as Google Search. For more details, see the [AMP Project FAQ](https://www.ampproject.org/docs/support/faqs.html).
|
12 |
|
13 |
## Customization / Templating
|
14 |
|
16 |
|
17 |
You can tweak small pieces of the template or the entire thing depending on your needs.
|
18 |
|
19 |
+
### Where Do I Put My Code?
|
20 |
+
|
21 |
+
The code snippets below and any other code-level customizations should happen in one of the following locations.
|
22 |
+
|
23 |
+
If you're using an off-the-shelf theme (like from the WordPress.org Theme Directory):
|
24 |
+
|
25 |
+
- A [child theme](https://developer.wordpress.org/themes/advanced-topics/child-themes/).
|
26 |
+
- A custom plugin that you activate via the Dashboard.
|
27 |
+
- A [mu-plugin](https://codex.wordpress.org/Must_Use_Plugins).
|
28 |
|
29 |
+
If you're using a custom theme:
|
30 |
+
|
31 |
+
- `functions.php` (or a file `require`-ed by `functions.php`).
|
32 |
+
- Any of the options above.
|
33 |
+
|
34 |
+
### Theme Mods
|
35 |
|
36 |
The default template will attempt to draw from various theme mods, such as site icon and background and header color/image, if supported by the active theme.
|
37 |
|
38 |
+
#### Site Icon
|
39 |
+
|
40 |
+
If you add a site icon, we will automatically replace the WordPress logo in the template.
|
41 |
+
|
42 |
+
If you'd prefer to do it via code:
|
43 |
+
|
44 |
+
```php
|
45 |
+
add_filter( 'amp_post_template_data', 'xyz_amp_set_site_icon_url' );
|
46 |
+
|
47 |
+
function xyz_amp_set_site_icon_url( $data ) {
|
48 |
+
// Ideally a 32x32 image
|
49 |
+
$data[ 'site_icon_url' ] = get_stylesheet_directory_uri() . '/images/amp-site-icon.png';
|
50 |
+
return $data;
|
51 |
+
}
|
52 |
+
```
|
53 |
+
|
54 |
+
#### Custom Header
|
55 |
+
|
56 |
+
This needs to be implemented.
|
57 |
+
|
58 |
### Template Tweaks
|
59 |
|
60 |
You can tweak various parts of the template via code.
|
61 |
|
62 |
+
#### Featured Image
|
63 |
+
|
64 |
+
The default template does not display the featured image currently. There are many ways to add it, such as the snippet below:
|
65 |
+
|
66 |
+
```php
|
67 |
+
add_action( 'pre_amp_render_post', 'xyz_amp_add_custom_actions' );
|
68 |
+
function xyz_amp_add_custom_actions() {
|
69 |
+
add_filter( 'the_content', 'xyz_amp_add_featured_image' );
|
70 |
+
}
|
71 |
+
|
72 |
+
function xyz_amp_add_featured_image( $content ) {
|
73 |
+
if ( has_post_thumbnail() ) {
|
74 |
+
// Just add the raw <img /> tag; our sanitizer will take care of it later.
|
75 |
+
$image = sprintf( '<p class="xyz-featured-image">%s</p>', get_the_post_thumbnail() );
|
76 |
+
$content = $image . $content;
|
77 |
+
}
|
78 |
+
return $content;
|
79 |
+
}
|
80 |
+
```
|
81 |
+
|
82 |
#### Content Width
|
83 |
|
84 |
By default, your theme's `$content_width` value will be used to determine the size of the `amp` content well. You can change this:
|
106 |
|
107 |
Note: The path must pass the default criteria set out by [`validate_file`](https://developer.wordpress.org/reference/functions/validate_file/) and must be somewhere in a subfolder of `WP_CONTENT_DIR`.
|
108 |
|
109 |
+
#### Schema.org (JSON) Metadata
|
110 |
+
|
111 |
+
The plugin adds some default metadata to enable ["Rich Snippet" support](https://developers.google.com/structured-data/rich-snippets/articles). You can modify this using the `amp_post_template_metadata` filter. The following changes the type annotation to `NewsArticle` (from the default `BlogPosting`) and overrides the default Publisher Logo.
|
112 |
+
|
113 |
+
```
|
114 |
+
add_filter( 'amp_post_template_metadata', 'xyz_amp_modify_json_metadata', 10, 2 );
|
115 |
+
|
116 |
+
function xyz_amp_modify_json_metadata( $metadata, $post ) {
|
117 |
+
$metadata['@type'] = 'NewsArticle';
|
118 |
+
|
119 |
+
$metadata['publisher']['logo'] = array(
|
120 |
+
'@type' => 'ImageObject',
|
121 |
+
'url' => get_template_directory_uri() . '/images/my-amp-metadata-logo.png',
|
122 |
+
'height' => 60,
|
123 |
+
'width' => 600,
|
124 |
+
);
|
125 |
+
return $metadata;
|
126 |
+
}
|
127 |
+
```
|
128 |
+
|
129 |
+
#### Template Meta (Author, Date, etc.)
|
130 |
|
131 |
For the meta section of the template (i.e. author, date, taxonomies, etc.), you can override templates for the existing sections, remove them, add new ones.
|
132 |
|
212 |
|
213 |
#### Custom CSS
|
214 |
|
215 |
+
##### Rule Additions
|
216 |
+
|
217 |
+
If you want to append to the existing CSS rules (e.g. styles for a custom embed handler), you can use the `amp_post_template_css` action:
|
218 |
+
|
219 |
+
```php
|
220 |
+
add_action( 'amp_post_template_css', 'xyz_amp_my_additional_css_styles' );
|
221 |
+
|
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 {
|
229 |
+
color: blue;
|
230 |
+
}
|
231 |
+
<?php
|
232 |
+
}
|
233 |
+
```
|
234 |
+
|
235 |
+
##### Completely Override CSS
|
236 |
+
|
237 |
If you'd prefer to use your own styles, you can either:
|
238 |
|
239 |
- Create a folder in your theme called `amp` and add a file called `style.php` with your custom CSS.
|
240 |
+
- Specify a custom template using the `amp_post_template_file` filter for `'style' === $type`. See the "Override" examples in the "Meta" section for examples.
|
241 |
|
242 |
+
Note: the file should only include CSS, not the `<style>` opening and closing tag.
|
243 |
|
244 |
#### Head and Footer
|
245 |
|
296 |
do_action( 'amp_post_template_footer', $this );
|
297 |
```
|
298 |
|
299 |
+
* Within your `amp-custom` `style` tags, you must trigger the `amp_post_template_css` action:
|
300 |
+
|
301 |
+
```php
|
302 |
+
do_action( 'amp_post_template_css', $this );
|
303 |
+
```
|
304 |
+
|
305 |
* You must include [all required mark-up](https://www.ampproject.org/docs/get_started/create/basic_markup.html) that isn't already output via the `amp_post_template_head` action.
|
306 |
|
307 |
## Handling Media
|
461 |
return $sanitizer_classes;
|
462 |
}
|
463 |
```
|
464 |
+
|
465 |
+
## Custom Post Type Support
|
466 |
+
|
467 |
+
By default, the plugin only creates AMP content for posts. You can add support for other post_types like so (assume our post_type slug is `xyz-review`):
|
468 |
+
|
469 |
+
```php
|
470 |
+
add_action( 'amp_init', 'xyz_amp_add_review_cpt' );
|
471 |
+
function xyz_amp_add_review_cpt() {
|
472 |
+
add_post_type_support( 'xyz-review', AMP_QUERY_VAR );
|
473 |
+
}
|
474 |
+
```
|
475 |
+
|
476 |
+
You'll need to flush your rewrite rules after this.
|
477 |
+
|
478 |
+
If you want a custom template for your post type:
|
479 |
+
|
480 |
+
```
|
481 |
+
add_filter( 'amp_post_template_file', 'xyz_amp_set_review_template', 10, 3 );
|
482 |
+
|
483 |
+
function xyz_amp_set_custom_template( $file, $type, $post ) {
|
484 |
+
if ( 'single' === $type && 'xyz-review' === $post->post_type ) {
|
485 |
+
$file = dirname( __FILE__ ) . '/templates/my-amp-review-template.php';
|
486 |
+
}
|
487 |
+
return $file;
|
488 |
+
}
|
489 |
+
|
490 |
+
```
|
491 |
+
|
492 |
+
We may provide better ways to handle this in the future.
|
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.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -13,9 +13,11 @@ Enable Accelerated Mobile Pages (AMP) on your WordPress site.
|
|
13 |
|
14 |
This plugin adds support for the [Accelerated Mobile Pages](https://www.ampproject.org) (AMP) Project, which is an an open source initiative that aims to provide mobile optimized content that can load instantly everywhere.
|
15 |
|
16 |
-
With the plugin active, all posts on your site will have dynamically generated AMP-compatible versions, accessible by appending `/amp/` to the end your
|
17 |
|
18 |
-
Note that Pages and archives are not currently supported.
|
|
|
|
|
19 |
|
20 |
Follow along with or contribute to the development of this plugin at https://github.com/Automattic/amp-wp
|
21 |
|
@@ -32,6 +34,17 @@ You can find details about customization options at https://github.com/Automatti
|
|
32 |
|
33 |
== Changelog ==
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
= 0.2 (Jan 28, 2016) =
|
36 |
|
37 |
* Lots and lots and lots of compatibility and validation fixes
|
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 |
|
13 |
|
14 |
This plugin adds support for the [Accelerated Mobile Pages](https://www.ampproject.org) (AMP) Project, which is an an open source initiative that aims to provide mobile optimized content that can load instantly everywhere.
|
15 |
|
16 |
+
With the plugin active, all posts on your site will have dynamically generated AMP-compatible versions, accessible by appending `/amp/` to the end your post URLs. For example, if your post URL is `http://example.com/2016/01/01/amp-on/`, you can access the AMP version at `http://example.com/2016/01/01/amp-on/amp/`. If you do not have [pretty permalinks](https://codex.wordpress.org/Using_Permalinks#mod_rewrite:_.22Pretty_Permalinks.22) enabled, you can do the same thing by appending `?amp=1`, i.e. `http://example.com/2016/01/01/amp-on/?amp=1`
|
17 |
|
18 |
+
Note #1: that Pages and archives are not currently supported.
|
19 |
+
|
20 |
+
Note #2: this plugin only creates AMP content but does not automatically display it to your users when they visit from a mobile device. That is handled by AMP consumers such as Google Search. For more details, see the [AMP Project FAQ](https://www.ampproject.org/docs/support/faqs.html).
|
21 |
|
22 |
Follow along with or contribute to the development of this plugin at https://github.com/Automattic/amp-wp
|
23 |
|
34 |
|
35 |
== Changelog ==
|
36 |
|
37 |
+
= 0.3 (Feb 18, 2016) =
|
38 |
+
|
39 |
+
* Fetch dimensions for hotlinked images.
|
40 |
+
* Add amp-facebook support.
|
41 |
+
* Add some new actions and filters (e.g. `amp_init`).
|
42 |
+
* Fix validation errors for [gallery] shortcodes.
|
43 |
+
* Fix issues with path validation on Windows.
|
44 |
+
* Fix issues with really squeezed layout.
|
45 |
+
* 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.
|
46 |
+
* 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.
|
47 |
+
|
48 |
= 0.2 (Jan 28, 2016) =
|
49 |
|
50 |
* Lots and lots and lots of compatibility and validation fixes
|
templates/meta-author.php
CHANGED
@@ -1,7 +1,9 @@
|
|
1 |
<?php $post_author = $this->get( 'post_author' ); ?>
|
2 |
<li class="byline">
|
|
|
3 |
<amp-img src="<?php echo esc_url( get_avatar_url( $post_author->user_email, array(
|
4 |
'size' => 24,
|
5 |
) ) ); ?>" width="24" height="24" layout="fixed"></amp-img>
|
|
|
6 |
<span class="author"><?php echo esc_html( $post_author->display_name ); ?></span>
|
7 |
</li>
|
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>
|
templates/single.php
CHANGED
@@ -5,8 +5,11 @@
|
|
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 |
-
|
|
|
9 |
<?php $this->load_parts( array( 'style' ) ); ?>
|
|
|
|
|
10 |
</head>
|
11 |
<body>
|
12 |
<nav class="title-bar">
|
@@ -15,10 +18,6 @@
|
|
15 |
<?php $site_icon_url = $this->get( 'site_icon_url' ); ?>
|
16 |
<?php if ( $site_icon_url ) : ?>
|
17 |
<amp-img src="<?php echo esc_url( $site_icon_url ); ?>" width="32" height="32" class="site-icon"></amp-img>
|
18 |
-
<?php else : ?>
|
19 |
-
<svg x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24">
|
20 |
-
<path class="st0" d="M12,0C5.4,0,0,5.4,0,12c0,6.6,5.4,12,12,12c6.6,0,12-5.4,12-12C24,5.4,18.6,0,12,0z M1.2,12c0-1.6,0.3-3,0.9-4.4l5.1,14.1C3.7,20,1.2,16.3,1.2,12z M12,22.8c-1.1,0-2.1-0.2-3-0.4l3.2-9.4l3.3,9.1c0,0.1,0,0.1,0.1,0.1C14.5,22.6,13.3,22.8,12,22.8z M13.5,6.9c0.6,0,1.2-0.1,1.2-0.1c0.6-0.1,0.5-0.9-0.1-0.9c0,0-1.7,0.1-2.9,0.1c-1.1,0-2.8-0.1-2.8-0.1c-0.6,0-0.7,0.9-0.1,0.9c0,0,0.6,0.1,1.1,0.1l1.7,4.6l-2.4,7.1L5.4,6.9c0.7,0,1.2-0.1,1.2-0.1c0.6-0.1,0.5-0.9-0.1-0.9c0,0-1.7,0.1-2.9,0.1c-0.2,0-0.4,0-0.7,0c1.9-2.9,5.2-4.9,9-4.9c2.8,0,5.4,1.1,7.3,2.8c0,0-0.1,0-0.1,0c-1.1,0-1.8,0.9-1.8,1.9c0,0.9,0.5,1.6,1.1,2.5c0.4,0.7,0.9,1.6,0.9,3c0,0.9-0.3,2.1-0.8,3.5l-1.1,3.6L13.5,6.9z M17.4,21.3l3.3-9.5c0.6-1.5,0.8-2.8,0.8-3.9c0-0.4,0-0.8-0.1-1.1c0.8,1.5,1.3,3.3,1.3,5.2C22.8,16,20.6,19.5,17.4,21.3z"/>
|
21 |
-
</svg>
|
22 |
<?php endif; ?>
|
23 |
<?php echo esc_html( $this->get( 'blog_name' ) ); ?>
|
24 |
</a>
|
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 |
+
|
9 |
+
<style amp-custom>
|
10 |
<?php $this->load_parts( array( 'style' ) ); ?>
|
11 |
+
<?php do_action( 'amp_post_template_css', $this ); ?>
|
12 |
+
</style>
|
13 |
</head>
|
14 |
<body>
|
15 |
<nav class="title-bar">
|
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>
|
templates/style.php
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
<style amp-custom>
|
2 |
/* Generic WP styling */
|
3 |
amp-img.alignright { float: right; margin: 0 0 1em 1em; }
|
4 |
amp-img.alignleft { float: left; margin: 0 1em 1em 0; }
|
@@ -17,8 +16,11 @@ amp-img.aligncenter { display: block; margin-left: auto; margin-right: auto; }
|
|
17 |
|
18 |
/* Generic WP.com reader style */
|
19 |
.content, .title-bar div {
|
20 |
-
|
|
|
|
|
21 |
margin: 0 auto;
|
|
|
22 |
}
|
23 |
|
24 |
body {
|
@@ -151,13 +153,6 @@ nav.title-bar .site-icon {
|
|
151 |
border-radius: 50%;
|
152 |
}
|
153 |
|
154 |
-
nav.title-bar svg {
|
155 |
-
/** svg is 24px **/
|
156 |
-
fill: #fff;
|
157 |
-
float: left;
|
158 |
-
margin: 15px 8px 0 0;
|
159 |
-
}
|
160 |
-
|
161 |
|
162 |
/* Captions */
|
163 |
.wp-caption-text {
|
@@ -196,4 +191,3 @@ amp-vine {
|
|
196 |
background-size: 48px 48px;
|
197 |
min-height: 48px;
|
198 |
}
|
199 |
-
</style>
|
|
|
1 |
/* Generic WP styling */
|
2 |
amp-img.alignright { float: right; margin: 0 0 1em 1em; }
|
3 |
amp-img.alignleft { float: left; margin: 0 1em 1em 0; }
|
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 ); ?>;
|
22 |
margin: 0 auto;
|
23 |
+
<?php endif; ?>
|
24 |
}
|
25 |
|
26 |
body {
|
153 |
border-radius: 50%;
|
154 |
}
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
|
157 |
/* Captions */
|
158 |
.wp-caption-text {
|
191 |
background-size: 48px 48px;
|
192 |
min-height: 48px;
|
193 |
}
|
|
wpcom-helper.php
CHANGED
@@ -2,34 +2,25 @@
|
|
2 |
|
3 |
// WPCOM-specific things
|
4 |
|
5 |
-
define( 'AMP_DEV_MODE', defined( 'WPCOM_SANDBOXED' ) && WPCOM_SANDBOXED );
|
6 |
-
|
7 |
// Add stats pixel
|
8 |
-
add_filter( '
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
);
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
continue;
|
18 |
-
}
|
19 |
-
$content .= sprintf( '<amp-pixel src="%s">', esc_url( $url ) );
|
20 |
-
}
|
21 |
-
|
22 |
-
return $content;
|
23 |
-
}, 10, 2 );
|
24 |
|
25 |
function wpcom_amp_get_pageview_url() {
|
26 |
$stats_info = stats_collect_info();
|
27 |
$a = $stats_info['st_go_args'];
|
28 |
|
29 |
$url = add_query_arg( array(
|
30 |
-
'rand' => '
|
31 |
'host' => rawurlencode( $_SERVER['HTTP_HOST'] ),
|
32 |
-
|
33 |
), 'https://pixel.wp.com/b.gif' );
|
34 |
$url .= '&' . stats_array_string( $a );
|
35 |
return $url;
|
@@ -37,7 +28,7 @@ function wpcom_amp_get_pageview_url() {
|
|
37 |
|
38 |
function wpcom_amp_get_mc_url() {
|
39 |
return add_query_arg( array(
|
40 |
-
'rand' => '
|
41 |
'v' => 'wpcom-no-pv',
|
42 |
'x_amp-views' => 'view',
|
43 |
), 'https://pixel.wp.com/b.gif' );
|
@@ -50,7 +41,7 @@ function wpcom_amp_get_stats_extras_url() {
|
|
50 |
}
|
51 |
|
52 |
$url = add_query_arg( array(
|
53 |
-
'rand' => '
|
54 |
'v' => 'wpcom-no-pv',
|
55 |
), 'https://pixel.wp.com/b.gif' );
|
56 |
|
@@ -67,29 +58,30 @@ function wpcom_amp_get_stats_extras_url() {
|
|
67 |
return $url;
|
68 |
}
|
69 |
|
70 |
-
add_action( '
|
|
|
|
|
71 |
add_filter( 'post_flair_disable', '__return_true', 99 );
|
72 |
remove_filter( 'the_title', 'widont' );
|
73 |
|
74 |
remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
|
75 |
remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'maybe_create_links' ), 100 );
|
76 |
-
}
|
77 |
|
78 |
-
add_action( '
|
79 |
-
add_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
|
80 |
-
add_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'maybe_create_links' ), 100 );
|
81 |
-
} );
|
82 |
|
83 |
-
|
84 |
if ( function_exists( 'jetpack_og_tags' ) ) {
|
85 |
jetpack_og_tags();
|
86 |
}
|
87 |
-
}
|
|
|
|
|
88 |
|
89 |
-
|
90 |
$metadata = wpcom_amp_add_blavatar( $metadata, $post );
|
91 |
return $metadata;
|
92 |
-
}
|
93 |
|
94 |
function wpcom_amp_add_blavatar( $metadata, $post ) {
|
95 |
if ( ! function_exists( 'blavatar_domain' ) ) {
|
@@ -118,9 +110,20 @@ function wpcom_amp_add_blavatar( $metadata, $post ) {
|
|
118 |
return $metadata;
|
119 |
}
|
120 |
|
121 |
-
add_action( '
|
122 |
-
function
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
return $dimensions;
|
125 |
}
|
126 |
|
@@ -140,10 +143,8 @@ function wpcom_amp_extract_image_dimensions( $dimensions, $url ) {
|
|
140 |
return false;
|
141 |
}
|
142 |
|
143 |
-
|
144 |
-
|
145 |
-
function wpcom_amp_extract_image_dimensions_fallback( $dimensions, $url ) {
|
146 |
-
if ( $dimensions ) {
|
147 |
return $dimensions;
|
148 |
}
|
149 |
|
@@ -153,9 +154,9 @@ function wpcom_amp_extract_image_dimensions_fallback( $dimensions, $url ) {
|
|
153 |
|
154 |
require_lib( 'wpcom/imagesize' );
|
155 |
$size = wpcom_getimagesize( $url );
|
156 |
-
if ( $size ) {
|
157 |
-
return
|
158 |
}
|
159 |
|
160 |
-
return
|
161 |
}
|
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;
|
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' );
|
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 |
|
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' ) ) {
|
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 |
|
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 |
|
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 |
}
|