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.cssno longer contains the `
Download this release
Release Info
| Developer | batmoo |
| Plugin | |
| 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 |
}
|
