Version Description
- Breaking change: The new template has changes to markup, class names, and styles that may not work with existing customizations. If you want to stay on the old template for now, you can use the following code snippet:
if ( function_exists( 'amp_backcompat_use_v03_templates' ) ) {
amp_backcompat_use_v03_templates();
}
For more details, please see https://wordpress.org/support/topic/v0-4-whats-new-and-possible-breaking-changes/
Download this release
Release Info
Developer | batmoo |
Plugin | AMP for WordPress |
Version | 0.4 |
Comparing to | |
See all releases |
Code changes from version 0.3.3 to 0.4
- amp.php +44 -2
- assets/images/placeholder-icon.png +0 -0
- assets/js/amp-customizer-design-preview.js +40 -0
- assets/js/amp-customizer-preview.js +15 -0
- back-compat/back-compat.php +12 -0
- back-compat/templates-v0-3/header-bar.php +13 -0
- back-compat/templates-v0-3/meta-author.php +9 -0
- back-compat/templates-v0-3/meta-taxonomy.php +15 -0
- back-compat/templates-v0-3/meta-time.php +12 -0
- back-compat/templates-v0-3/single.php +24 -0
- back-compat/templates-v0-3/style.php +242 -0
- includes/admin/class-amp-customizer.php +170 -0
- includes/admin/functions.php +71 -0
- includes/amp-helper-functions.php +6 -0
- includes/amp-post-template-actions.php +20 -0
- includes/class-amp-content.php +10 -0
- includes/class-amp-post-template.php +110 -1
- includes/embeds/class-amp-youtube-embed.php +12 -2
- includes/sanitizers/class-amp-base-sanitizer.php +4 -0
- includes/sanitizers/class-amp-blacklist-sanitizer.php +19 -4
- includes/sanitizers/class-amp-img-sanitizer.php +1 -1
- includes/sanitizers/class-amp-style-sanitizer.php +103 -0
- includes/settings/class-amp-customizer-design-settings.php +156 -0
- includes/settings/class-amp-customizer-settings.php +13 -0
- includes/utils/class-amp-dom-utils.php +45 -2
- readme.md +5 -0
- readme.txt +44 -6
- screenshot-1.png +0 -0
- screenshot-2.png +0 -0
- templates/featured-image.php +18 -0
- templates/footer.php +9 -0
- templates/header-bar.php +4 -4
- templates/meta-author.php +9 -8
- templates/meta-comments-link.php +11 -0
- templates/meta-taxonomy.php +15 -11
- templates/meta-time.php +2 -2
- templates/single.php +29 -12
- templates/style.php +280 -145
amp.php
CHANGED
@@ -5,7 +5,7 @@
|
|
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
|
@@ -13,17 +13,33 @@
|
|
13 |
|
14 |
define( 'AMP__FILE__', __FILE__ );
|
15 |
define( 'AMP__DIR__', dirname( __FILE__ ) );
|
|
|
16 |
|
|
|
17 |
require_once( AMP__DIR__ . '/includes/amp-helper-functions.php' );
|
|
|
|
|
|
|
18 |
|
19 |
register_activation_hook( __FILE__, 'amp_activate' );
|
20 |
function amp_activate() {
|
21 |
-
amp_init
|
|
|
|
|
22 |
flush_rewrite_rules();
|
23 |
}
|
24 |
|
25 |
register_deactivation_hook( __FILE__, 'amp_deactivate' );
|
26 |
function amp_deactivate() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
flush_rewrite_rules();
|
28 |
}
|
29 |
|
@@ -114,3 +130,29 @@ function amp_render() {
|
|
114 |
$template->load();
|
115 |
exit;
|
116 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Plugin URI: https://github.com/automattic/amp-wp
|
6 |
* Author: Automattic
|
7 |
* Author URI: https://automattic.com
|
8 |
+
* Version: 0.4
|
9 |
* Text Domain: amp
|
10 |
* Domain Path: /languages/
|
11 |
* License: GPLv2 or later
|
13 |
|
14 |
define( 'AMP__FILE__', __FILE__ );
|
15 |
define( 'AMP__DIR__', dirname( __FILE__ ) );
|
16 |
+
define( 'AMP__VERSION', '0.4' );
|
17 |
|
18 |
+
require_once( AMP__DIR__ . '/back-compat/back-compat.php' );
|
19 |
require_once( AMP__DIR__ . '/includes/amp-helper-functions.php' );
|
20 |
+
require_once( AMP__DIR__ . '/includes/admin/functions.php' );
|
21 |
+
require_once( AMP__DIR__ . '/includes/settings/class-amp-customizer-settings.php' );
|
22 |
+
require_once( AMP__DIR__ . '/includes/settings/class-amp-customizer-design-settings.php' );
|
23 |
|
24 |
register_activation_hook( __FILE__, 'amp_activate' );
|
25 |
function amp_activate() {
|
26 |
+
if ( ! did_action( 'amp_init' ) ) {
|
27 |
+
amp_init();
|
28 |
+
}
|
29 |
flush_rewrite_rules();
|
30 |
}
|
31 |
|
32 |
register_deactivation_hook( __FILE__, 'amp_deactivate' );
|
33 |
function amp_deactivate() {
|
34 |
+
// We need to manually remove the amp endpoint
|
35 |
+
global $wp_rewrite;
|
36 |
+
foreach ( $wp_rewrite->endpoints as $index => $endpoint ) {
|
37 |
+
if ( AMP_QUERY_VAR === $endpoint[1] ) {
|
38 |
+
unset( $wp_rewrite->endpoints[ $index ] );
|
39 |
+
break;
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
flush_rewrite_rules();
|
44 |
}
|
45 |
|
130 |
$template->load();
|
131 |
exit;
|
132 |
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Bootstraps the AMP customizer.
|
136 |
+
*
|
137 |
+
* If the AMP customizer is enabled, initially drop the core widgets and menus panels. If the current
|
138 |
+
* preview page isn't flagged as an AMP template, the core panels will be re-added and the AMP panel
|
139 |
+
* hidden.
|
140 |
+
*
|
141 |
+
* @internal This callback must be hooked before priority 10 on 'plugins_loaded' to properly unhook
|
142 |
+
* the core panels.
|
143 |
+
*
|
144 |
+
* @since 0.4
|
145 |
+
*/
|
146 |
+
function _amp_bootstrap_customizer() {
|
147 |
+
/**
|
148 |
+
* Filter whether to enable the AMP template customizer functionality.
|
149 |
+
*
|
150 |
+
* @param bool $enable Whether to enable the AMP customizer. Default true.
|
151 |
+
*/
|
152 |
+
$amp_customizer_enabled = apply_filters( 'amp_customizer_is_enabled', true );
|
153 |
+
|
154 |
+
if ( true === $amp_customizer_enabled ) {
|
155 |
+
amp_init_customizer();
|
156 |
+
}
|
157 |
+
}
|
158 |
+
add_action( 'plugins_loaded', '_amp_bootstrap_customizer', 9 );
|
assets/images/placeholder-icon.png
CHANGED
Binary file
|
assets/js/amp-customizer-design-preview.js
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
( function( $ ) {
|
2 |
+
'use strict';
|
3 |
+
|
4 |
+
// Nav bar text color.
|
5 |
+
wp.customize( 'amp_customizer[header_color]', function( value ) {
|
6 |
+
value.bind( function( to ) {
|
7 |
+
$( '.amp-wp-header a' ).css( 'color', to );
|
8 |
+
$( '.amp-wp-header div' ).css( 'color', to );
|
9 |
+
$( '.amp-wp-header .amp-wp-site-icon' ).css( 'border-color', to ).css( 'background-color', to );
|
10 |
+
} );
|
11 |
+
} );
|
12 |
+
|
13 |
+
// Nav bar background color.
|
14 |
+
wp.customize( 'amp_customizer[header_background_color]', function( value ) {
|
15 |
+
value.bind( function( to ) {
|
16 |
+
$( 'html, .amp-wp-header' ).css( 'background-color', to );
|
17 |
+
$( '.amp-wp-article a, .amp-wp-article a:visited, .amp-wp-footer a, .amp-wp-footer a:visited' ).css( 'color', to );
|
18 |
+
$( 'blockquote, .amp-wp-byline amp-img' ).css( 'border-color', to );
|
19 |
+
} );
|
20 |
+
} );
|
21 |
+
|
22 |
+
// AMP background color scheme.
|
23 |
+
wp.customize( 'amp_customizer[color_scheme]', function( value ) {
|
24 |
+
value.bind( function( to ) {
|
25 |
+
var colors = amp_customizer_design.color_schemes[ to ];
|
26 |
+
|
27 |
+
if ( ! colors ) {
|
28 |
+
console.error( 'Selected color scheme "%s" not registered.', to );
|
29 |
+
return;
|
30 |
+
}
|
31 |
+
|
32 |
+
$( 'body' ).css( 'background-color', colors.theme_color );
|
33 |
+
$( 'body, a:hover, a:active, a:focus, blockquote, .amp-wp-article, .amp-wp-title' ).css( 'color', colors.text_color );
|
34 |
+
$( '.amp-wp-meta, .wp-caption .wp-caption-text, .amp-wp-tax-category, .amp-wp-tax-tag, .amp-wp-footer p' ).css( 'color', colors.muted_text_color );
|
35 |
+
$( '.wp-caption .wp-caption-text, .amp-wp-comments-link a, .amp-wp-footer' ).css( 'border-color', colors.border_color );
|
36 |
+
$( '.amp-wp-iframe-placeholder, amp-carousel, amp-iframe, amp-youtube, amp-instagram, amp-vine' ).css( 'background-color', colors.border_color );
|
37 |
+
} );
|
38 |
+
} );
|
39 |
+
|
40 |
+
} )( jQuery );
|
assets/js/amp-customizer-preview.js
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
( function( $ ) {
|
2 |
+
'use strict';
|
3 |
+
|
4 |
+
// Don't allow navigation away from the AMP page in the preview.
|
5 |
+
// The Customizer breaks pretty spectacularly when that happens as it's only meant to work for AMP pages.
|
6 |
+
$( 'a' ).click( function( e ) {
|
7 |
+
var href = this.getAttribute( 'href' );
|
8 |
+
if ( href && href.indexOf( '#' ) === 0 ) {
|
9 |
+
return true;
|
10 |
+
}
|
11 |
+
|
12 |
+
return false;
|
13 |
+
} );
|
14 |
+
|
15 |
+
} )( jQuery );
|
back-compat/back-compat.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// If you want to use the template that shipped with v0.3 and earlier, you can use this to force that.
|
4 |
+
// Note that this may not stick around forever, so use caution and `function_exists`.
|
5 |
+
function amp_backcompat_use_v03_templates() {
|
6 |
+
add_filter( 'amp_customizer_is_enabled', '__return_false' );
|
7 |
+
add_filter( 'amp_post_template_dir', '_amp_backcompat_use_v03_templates_callback', 0 ); // early in case there are other overrides
|
8 |
+
}
|
9 |
+
|
10 |
+
function _amp_backcompat_use_v03_templates_callback( $templates ) {
|
11 |
+
return AMP__DIR__ . '/back-compat/templates-v0-3';
|
12 |
+
}
|
back-compat/templates-v0-3/header-bar.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $site_icon_url = $this->get( 'site_icon_url' ); ?>
|
2 |
+
|
3 |
+
<nav class="amp-wp-title-bar">
|
4 |
+
<div>
|
5 |
+
<a href="<?php echo esc_url( $this->get( 'home_url' ) ); ?>">
|
6 |
+
<?php if ( $site_icon_url ) : ?>
|
7 |
+
<amp-img src="<?php echo esc_url( $site_icon_url ); ?>" width="32" height="32" class="amp-wp-site-icon"></amp-img>
|
8 |
+
<?php endif; ?>
|
9 |
+
|
10 |
+
<?php echo esc_html( $this->get( 'blog_name' ) ); ?>
|
11 |
+
</a>
|
12 |
+
</div>
|
13 |
+
</nav>
|
back-compat/templates-v0-3/meta-author.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $post_author = $this->get( 'post_author' ); ?>
|
2 |
+
<li class="amp-wp-byline">
|
3 |
+
<?php if ( function_exists( 'get_avatar_url' ) ) : ?>
|
4 |
+
<amp-img src="<?php echo esc_url( get_avatar_url( $post_author->user_email, array(
|
5 |
+
'size' => 24,
|
6 |
+
) ) ); ?>" width="24" height="24" layout="fixed"></amp-img>
|
7 |
+
<?php endif; ?>
|
8 |
+
<span class="amp-wp-author"><?php echo esc_html( $post_author->display_name ); ?></span>
|
9 |
+
</li>
|
back-compat/templates-v0-3/meta-taxonomy.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $categories = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ) ); ?>
|
2 |
+
<?php if ( $categories ) : ?>
|
3 |
+
<li class="amp-wp-tax-category">
|
4 |
+
<span class="screen-reader-text">Categories:</span>
|
5 |
+
<?php echo $categories; ?>
|
6 |
+
</li>
|
7 |
+
<?php endif; ?>
|
8 |
+
|
9 |
+
<?php $tags = get_the_tag_list( '', _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ) ); ?>
|
10 |
+
<?php if ( $tags && ! is_wp_error( $tags ) ) : ?>
|
11 |
+
<li class="amp-wp-tax-tag">
|
12 |
+
<span class="screen-reader-text">Tags:</span>
|
13 |
+
<?php echo $tags; ?>
|
14 |
+
</li>
|
15 |
+
<?php endif; ?>
|
back-compat/templates-v0-3/meta-time.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<li class="amp-wp-posted-on">
|
2 |
+
<time datetime="<?php echo esc_attr( date( 'c', $this->get( 'post_publish_timestamp' ) ) ); ?>">
|
3 |
+
<?php
|
4 |
+
echo esc_html(
|
5 |
+
sprintf(
|
6 |
+
_x( '%s ago', '%s = human-readable time difference', 'amp' ),
|
7 |
+
human_time_diff( $this->get( 'post_publish_timestamp' ), current_time( 'timestamp' ) )
|
8 |
+
)
|
9 |
+
);
|
10 |
+
?>
|
11 |
+
</time>
|
12 |
+
</li>
|
back-compat/templates-v0-3/single.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html amp <?php language_attributes(); ?>>
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8">
|
5 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
|
6 |
+
<?php do_action( 'amp_post_template_head', $this ); ?>
|
7 |
+
|
8 |
+
<style amp-custom>
|
9 |
+
<?php $this->load_parts( array( 'style' ) ); ?>
|
10 |
+
<?php do_action( 'amp_post_template_css', $this ); ?>
|
11 |
+
</style>
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<?php $this->load_parts( array( 'header-bar' ) ); ?>
|
15 |
+
<div class="amp-wp-content">
|
16 |
+
<h1 class="amp-wp-title"><?php echo wp_kses_data( $this->get( 'post_title' ) ); ?></h1>
|
17 |
+
<ul class="amp-wp-meta">
|
18 |
+
<?php $this->load_parts( apply_filters( 'amp_post_template_meta_parts', array( 'meta-author', 'meta-time', 'meta-taxonomy' ) ) ); ?>
|
19 |
+
</ul>
|
20 |
+
<?php echo $this->get( 'post_amp_content' ); // amphtml content; no kses ?>
|
21 |
+
</div>
|
22 |
+
<?php do_action( 'amp_post_template_footer', $this ); ?>
|
23 |
+
</body>
|
24 |
+
</html>
|
back-compat/templates-v0-3/style.php
ADDED
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Merriweather fonts */
|
2 |
+
@font-face {
|
3 |
+
font-family:'Merriweather';
|
4 |
+
src:url('https://s1.wp.com/i/fonts/merriweather/merriweather-regular-webfont.woff2') format('woff2'),
|
5 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-regular-webfont.woff') format('woff'),
|
6 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-regular-webfont.ttf') format('truetype'),
|
7 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-regular-webfont.svg#merriweatherregular') format('svg');
|
8 |
+
font-weight:400;
|
9 |
+
font-style:normal;
|
10 |
+
}
|
11 |
+
|
12 |
+
@font-face {
|
13 |
+
font-family:'Merriweather';
|
14 |
+
src:url('https://s1.wp.com/i/fonts/merriweather/merriweather-italic-webfont.woff2') format('woff2'),
|
15 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-italic-webfont.woff') format('woff'),
|
16 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-italic-webfont.ttf') format('truetype'),
|
17 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-italic-webfont.svg#merriweatheritalic') format('svg');
|
18 |
+
font-weight:400;
|
19 |
+
font-style:italic;
|
20 |
+
}
|
21 |
+
|
22 |
+
@font-face {
|
23 |
+
font-family:'Merriweather';
|
24 |
+
src:url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.woff2') format('woff2'),
|
25 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.woff') format('woff'),
|
26 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.ttf') format('truetype'),
|
27 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.svg#merriweatherbold') format('svg');
|
28 |
+
font-weight:700;
|
29 |
+
font-style:normal;
|
30 |
+
}
|
31 |
+
|
32 |
+
@font-face {
|
33 |
+
font-family:'Merriweather';
|
34 |
+
src:url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.woff2') format('woff2'),
|
35 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.woff') format('woff'),
|
36 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.ttf') format('truetype'),
|
37 |
+
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.svg#merriweatherbold_italic') format('svg');
|
38 |
+
font-weight:700;
|
39 |
+
font-style:italic;
|
40 |
+
}
|
41 |
+
|
42 |
+
/* Generic WP styling */
|
43 |
+
amp-img.alignright { float: right; margin: 0 0 1em 1em; }
|
44 |
+
amp-img.alignleft { float: left; margin: 0 1em 1em 0; }
|
45 |
+
amp-img.aligncenter { display: block; margin-left: auto; margin-right: auto; }
|
46 |
+
.alignright { float: right; }
|
47 |
+
.alignleft { float: left; }
|
48 |
+
.aligncenter { display: block; margin-left: auto; margin-right: auto; }
|
49 |
+
|
50 |
+
.wp-caption.alignleft { margin-right: 1em; }
|
51 |
+
.wp-caption.alignright { margin-left: 1em; }
|
52 |
+
|
53 |
+
.amp-wp-enforced-sizes {
|
54 |
+
/** Our sizes fallback is 100vw, and we have a padding on the container; the max-width here prevents the element from overflowing. **/
|
55 |
+
max-width: 100%;
|
56 |
+
}
|
57 |
+
|
58 |
+
.amp-wp-unknown-size img {
|
59 |
+
/** Worst case scenario when we can't figure out dimensions for an image. **/
|
60 |
+
/** Force the image into a box of fixed dimensions and use object-fit to scale. **/
|
61 |
+
object-fit: contain;
|
62 |
+
}
|
63 |
+
|
64 |
+
/* Template Styles */
|
65 |
+
.amp-wp-content, .amp-wp-title-bar div {
|
66 |
+
<?php $content_max_width = absint( $this->get( 'content_max_width' ) ); ?>
|
67 |
+
<?php if ( $content_max_width > 0 ) : ?>
|
68 |
+
max-width: <?php echo sprintf( '%dpx', $content_max_width ); ?>;
|
69 |
+
margin: 0 auto;
|
70 |
+
<?php endif; ?>
|
71 |
+
}
|
72 |
+
|
73 |
+
body {
|
74 |
+
font-family: 'Merriweather', Serif;
|
75 |
+
font-size: 16px;
|
76 |
+
line-height: 1.8;
|
77 |
+
background: #fff;
|
78 |
+
color: #3d596d;
|
79 |
+
padding-bottom: 100px;
|
80 |
+
}
|
81 |
+
|
82 |
+
.amp-wp-content {
|
83 |
+
padding: 16px;
|
84 |
+
overflow-wrap: break-word;
|
85 |
+
word-wrap: break-word;
|
86 |
+
font-weight: 400;
|
87 |
+
color: #3d596d;
|
88 |
+
}
|
89 |
+
|
90 |
+
.amp-wp-title {
|
91 |
+
margin: 36px 0 0 0;
|
92 |
+
font-size: 36px;
|
93 |
+
line-height: 1.258;
|
94 |
+
font-weight: 700;
|
95 |
+
color: #2e4453;
|
96 |
+
}
|
97 |
+
|
98 |
+
.amp-wp-meta {
|
99 |
+
margin-bottom: 16px;
|
100 |
+
}
|
101 |
+
|
102 |
+
p,
|
103 |
+
ol,
|
104 |
+
ul,
|
105 |
+
figure {
|
106 |
+
margin: 0 0 24px 0;
|
107 |
+
}
|
108 |
+
|
109 |
+
a,
|
110 |
+
a:visited {
|
111 |
+
color: #0087be;
|
112 |
+
}
|
113 |
+
|
114 |
+
a:hover,
|
115 |
+
a:active,
|
116 |
+
a:focus {
|
117 |
+
color: #33bbe3;
|
118 |
+
}
|
119 |
+
|
120 |
+
|
121 |
+
/* UI Fonts */
|
122 |
+
.amp-wp-meta,
|
123 |
+
nav.amp-wp-title-bar,
|
124 |
+
.wp-caption-text {
|
125 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif;
|
126 |
+
font-size: 15px;
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
/* Meta */
|
131 |
+
ul.amp-wp-meta {
|
132 |
+
padding: 24px 0 0 0;
|
133 |
+
margin: 0 0 24px 0;
|
134 |
+
}
|
135 |
+
|
136 |
+
ul.amp-wp-meta li {
|
137 |
+
list-style: none;
|
138 |
+
display: inline-block;
|
139 |
+
margin: 0;
|
140 |
+
line-height: 24px;
|
141 |
+
white-space: nowrap;
|
142 |
+
overflow: hidden;
|
143 |
+
text-overflow: ellipsis;
|
144 |
+
max-width: 300px;
|
145 |
+
}
|
146 |
+
|
147 |
+
ul.amp-wp-meta li:before {
|
148 |
+
content: "\2022";
|
149 |
+
margin: 0 8px;
|
150 |
+
}
|
151 |
+
|
152 |
+
ul.amp-wp-meta li:first-child:before {
|
153 |
+
display: none;
|
154 |
+
}
|
155 |
+
|
156 |
+
.amp-wp-meta,
|
157 |
+
.amp-wp-meta a {
|
158 |
+
color: #4f748e;
|
159 |
+
}
|
160 |
+
|
161 |
+
.amp-wp-meta .screen-reader-text {
|
162 |
+
/* from twentyfifteen */
|
163 |
+
clip: rect(1px, 1px, 1px, 1px);
|
164 |
+
height: 1px;
|
165 |
+
overflow: hidden;
|
166 |
+
position: absolute;
|
167 |
+
width: 1px;
|
168 |
+
}
|
169 |
+
|
170 |
+
.amp-wp-byline amp-img {
|
171 |
+
border-radius: 50%;
|
172 |
+
border: 0;
|
173 |
+
background: #f3f6f8;
|
174 |
+
position: relative;
|
175 |
+
top: 6px;
|
176 |
+
margin-right: 6px;
|
177 |
+
}
|
178 |
+
|
179 |
+
/* Titlebar */
|
180 |
+
nav.amp-wp-title-bar {
|
181 |
+
background: <?php echo esc_html( $this->get_customizer_setting( 'navbar_background', self::DEFAULT_NAVBAR_BACKGROUND ) ); // not ideal for escaping here, but better than nothing? ?>;
|
182 |
+
padding: 0 16px;
|
183 |
+
}
|
184 |
+
|
185 |
+
nav.amp-wp-title-bar div {
|
186 |
+
line-height: 54px;
|
187 |
+
color: <?php echo esc_html( $this->get_customizer_setting( 'navbar_color', self::DEFAULT_NAVBAR_COLOR ) ); ?>;
|
188 |
+
}
|
189 |
+
|
190 |
+
nav.amp-wp-title-bar a {
|
191 |
+
color: <?php echo esc_html( $this->get_customizer_setting( 'navbar_color', self::DEFAULT_NAVBAR_COLOR ) ); ?>;
|
192 |
+
text-decoration: none;
|
193 |
+
}
|
194 |
+
|
195 |
+
nav.amp-wp-title-bar .amp-wp-site-icon {
|
196 |
+
/** site icon is 32px **/
|
197 |
+
float: left;
|
198 |
+
margin: 11px 8px 0 0;
|
199 |
+
border-radius: 50%;
|
200 |
+
}
|
201 |
+
|
202 |
+
/* Captions */
|
203 |
+
.wp-caption-text {
|
204 |
+
padding: 8px 16px;
|
205 |
+
font-style: italic;
|
206 |
+
}
|
207 |
+
|
208 |
+
|
209 |
+
/* Quotes */
|
210 |
+
blockquote {
|
211 |
+
padding: 16px;
|
212 |
+
margin: 8px 0 24px 0;
|
213 |
+
border-left: 2px solid #87a6bc;
|
214 |
+
color: #4f748e;
|
215 |
+
background: #e9eff3;
|
216 |
+
}
|
217 |
+
|
218 |
+
blockquote p:last-child {
|
219 |
+
margin-bottom: 0;
|
220 |
+
}
|
221 |
+
|
222 |
+
/* Other Elements */
|
223 |
+
amp-carousel {
|
224 |
+
background: #000;
|
225 |
+
}
|
226 |
+
|
227 |
+
amp-iframe,
|
228 |
+
amp-youtube,
|
229 |
+
amp-instagram,
|
230 |
+
amp-vine {
|
231 |
+
background: #f3f6f8;
|
232 |
+
}
|
233 |
+
|
234 |
+
amp-carousel > amp-img > img {
|
235 |
+
object-fit: contain;
|
236 |
+
}
|
237 |
+
|
238 |
+
.amp-wp-iframe-placeholder {
|
239 |
+
background: #f3f6f8 url( <?php echo esc_url( $this->get( 'placeholder_image_url' ) ); ?> ) no-repeat center 40%;
|
240 |
+
background-size: 48px 48px;
|
241 |
+
min-height: 48px;
|
242 |
+
}
|
includes/admin/class-amp-customizer.php
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* AMP class that implements a template style editor in the Customizer.
|
4 |
+
*
|
5 |
+
* A direct, formed link to the AMP editor in the Customizer is added via
|
6 |
+
* {@see amp_customizer_editor_link()} as a submenu to the Appearance menu.
|
7 |
+
*
|
8 |
+
* @since 0.4
|
9 |
+
*/
|
10 |
+
class AMP_Template_Customizer {
|
11 |
+
/**
|
12 |
+
* AMP template editor panel ID.
|
13 |
+
*
|
14 |
+
* @since 0.4
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
const PANEL_ID = 'amp_panel';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Customizer instance.
|
21 |
+
*
|
22 |
+
* @since 0.4
|
23 |
+
* @access protected
|
24 |
+
* @var WP_Customize_Manager $wp_customize
|
25 |
+
*/
|
26 |
+
protected $wp_customize;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Initialize the template Customizer feature class.
|
30 |
+
*
|
31 |
+
* @static
|
32 |
+
* @since 0.4
|
33 |
+
* @access public
|
34 |
+
*
|
35 |
+
* @param WP_Customize_Manager $wp_customize Customizer instance.
|
36 |
+
*/
|
37 |
+
public static function init( $wp_customize ) {
|
38 |
+
$self = new self();
|
39 |
+
|
40 |
+
$self->wp_customize = $wp_customize;
|
41 |
+
|
42 |
+
do_action( 'amp_customizer_init', $self );
|
43 |
+
|
44 |
+
// Settings need to be registered for regular customize requests as well (since save is handled there)
|
45 |
+
$self->register_settings();
|
46 |
+
|
47 |
+
// Our custom panels only need to go for AMP Customizer requests though
|
48 |
+
if ( self::is_amp_customizer() ) {
|
49 |
+
if ( empty( $_GET['url'] ) ) {
|
50 |
+
$wp_customize->set_preview_url( amp_admin_get_preview_permalink() );
|
51 |
+
}
|
52 |
+
|
53 |
+
$self->_unregister_core_ui();
|
54 |
+
$self->register_ui();
|
55 |
+
} elseif ( is_customize_preview() ) {
|
56 |
+
// Delay preview-specific actions until we're sure we're rendering an AMP page, since it's too early for `is_amp_endpoint()` here.
|
57 |
+
add_action( 'pre_amp_render_post', array( $self, 'init_preview' ) );
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Filters the core components to unhook the nav_menus and widgets panels.
|
63 |
+
*
|
64 |
+
* @since 0.4
|
65 |
+
* @access private
|
66 |
+
*
|
67 |
+
* @return array Array of core Customizer components to keep active.
|
68 |
+
*/
|
69 |
+
public static function _unregister_core_panels( $panels ) {
|
70 |
+
if ( self::is_amp_customizer() ) {
|
71 |
+
$panels = array();
|
72 |
+
}
|
73 |
+
return $panels;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Removes all non-AMP sections and panels.
|
78 |
+
*
|
79 |
+
* Provides a clean, standalone instance-like experience by removing all non-AMP registered panels and sections.
|
80 |
+
*
|
81 |
+
* @since 0.4
|
82 |
+
* @access private
|
83 |
+
*/
|
84 |
+
private function _unregister_core_ui() {
|
85 |
+
$panels = $this->wp_customize->panels();
|
86 |
+
$sections = $this->wp_customize->sections();
|
87 |
+
|
88 |
+
foreach ( $panels as $panel_id => $object ) {
|
89 |
+
$this->wp_customize->remove_panel( $panel_id );
|
90 |
+
}
|
91 |
+
|
92 |
+
foreach ( $sections as $section_id => $object ) {
|
93 |
+
$this->wp_customize->remove_section( $section_id );
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
public function init_preview() {
|
98 |
+
// Preview needs controls registered too for postMessage communication.
|
99 |
+
$this->register_ui();
|
100 |
+
|
101 |
+
add_action( 'amp_post_template_footer', array( $this, 'add_preview_scripts' ) );
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Sets up the AMP Customizer preview.
|
106 |
+
*/
|
107 |
+
public function register_ui() {
|
108 |
+
add_action( 'customize_controls_enqueue_scripts', array( $this, 'add_customizer_scripts' ) );
|
109 |
+
add_filter( 'customize_previewable_devices', array( $this, 'force_mobile_preview' ) );
|
110 |
+
|
111 |
+
$this->wp_customize->add_panel( self::PANEL_ID, array(
|
112 |
+
'type' => 'amp',
|
113 |
+
'title' => __( 'AMP', 'amp' ),
|
114 |
+
'description' => sprintf( __( '<a href="%s" target="_blank">The AMP Project</a> is a Google-led initiative that dramatically improves loading speeds on phones and tablets. You can use the Customizer to preview changes to your AMP template before publishing them.', 'amp' ), 'https://ampproject.org' ),
|
115 |
+
) );
|
116 |
+
|
117 |
+
do_action( 'amp_customizer_register_ui', $this->wp_customize );
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Registers settings for customizing AMP templates.
|
122 |
+
*
|
123 |
+
* @since 0.4
|
124 |
+
* @access public
|
125 |
+
*/
|
126 |
+
public function register_settings() {
|
127 |
+
do_action( 'amp_customizer_register_settings', $this->wp_customize );
|
128 |
+
}
|
129 |
+
|
130 |
+
public function add_customizer_scripts() {
|
131 |
+
wp_enqueue_script( 'wp-util' ); // fix `wp.template is not a function`
|
132 |
+
do_action( 'amp_customizer_enqueue_scripts' );
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Enqueues scripts and fires the 'wp_footer' action so we can output customizer scripts.
|
137 |
+
*
|
138 |
+
* This breaks AMP validation in the customizer but is necessary for the live preview.
|
139 |
+
*
|
140 |
+
* @since 0.4
|
141 |
+
* @access public
|
142 |
+
*/
|
143 |
+
public function add_preview_scripts() {
|
144 |
+
wp_enqueue_script(
|
145 |
+
'amp-customizer',
|
146 |
+
amp_get_asset_url( 'js/amp-customizer-preview.js' ),
|
147 |
+
array( 'jquery', 'customize-preview', 'wp-util' ),
|
148 |
+
$version = false,
|
149 |
+
$footer = true
|
150 |
+
);
|
151 |
+
|
152 |
+
do_action( 'amp_customizer_enqueue_preview_scripts', $this->wp_customize );
|
153 |
+
|
154 |
+
/** This action is documented in wp-includes/general-template.php */
|
155 |
+
do_action( 'wp_footer' );
|
156 |
+
}
|
157 |
+
|
158 |
+
public function force_mobile_preview( $devices ) {
|
159 |
+
if ( isset( $devices[ 'mobile' ] ) ) {
|
160 |
+
$devices['mobile']['default'] = true;
|
161 |
+
unset( $devices['desktop']['default'] );
|
162 |
+
}
|
163 |
+
|
164 |
+
return $devices;
|
165 |
+
}
|
166 |
+
|
167 |
+
public static function is_amp_customizer() {
|
168 |
+
return ! empty( $_REQUEST[ AMP_CUSTOMIZER_QUERY_VAR ] );
|
169 |
+
}
|
170 |
+
}
|
includes/admin/functions.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Callbacks for adding AMP-related things to the admin.
|
3 |
+
|
4 |
+
define( 'AMP_CUSTOMIZER_QUERY_VAR', 'customize_amp' );
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Sets up the AMP template editor for the Customizer.
|
8 |
+
*/
|
9 |
+
function amp_init_customizer() {
|
10 |
+
require_once( AMP__DIR__ . '/includes/admin/class-amp-customizer.php' );
|
11 |
+
|
12 |
+
// Drop core panels (menus, widgets) from the AMP customizer
|
13 |
+
add_filter( 'customize_loaded_components', array( 'AMP_Template_Customizer', '_unregister_core_panels' ) );
|
14 |
+
|
15 |
+
// Fire up the AMP Customizer
|
16 |
+
add_action( 'customize_register', array( 'AMP_Template_Customizer', 'init' ), 500 );
|
17 |
+
|
18 |
+
// Add some basic design settings + controls to the Customizer
|
19 |
+
add_action( 'amp_init', array( 'AMP_Customizer_Design_Settings', 'init' ) );
|
20 |
+
|
21 |
+
// Add a link to the Customizer
|
22 |
+
add_action( 'admin_menu', 'amp_add_customizer_link' );
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Registers a submenu page to access the AMP template editor panel in the Customizer.
|
27 |
+
*/
|
28 |
+
function amp_add_customizer_link() {
|
29 |
+
// Teensy little hack on menu_slug, but it works. No redirect!
|
30 |
+
$menu_slug = add_query_arg( array(
|
31 |
+
'autofocus[panel]' => AMP_Template_Customizer::PANEL_ID,
|
32 |
+
'return' => rawurlencode( admin_url() ),
|
33 |
+
AMP_CUSTOMIZER_QUERY_VAR => true,
|
34 |
+
), 'customize.php' );
|
35 |
+
|
36 |
+
// Add the theme page.
|
37 |
+
$page = add_theme_page(
|
38 |
+
__( 'AMP', 'amp' ),
|
39 |
+
__( 'AMP', 'amp' ),
|
40 |
+
'edit_theme_options',
|
41 |
+
$menu_slug
|
42 |
+
);
|
43 |
+
}
|
44 |
+
|
45 |
+
function amp_admin_get_preview_permalink() {
|
46 |
+
/**
|
47 |
+
* Filter the post type to retrieve the latest of for use in the AMP template customizer.
|
48 |
+
*
|
49 |
+
* @param string $post_type Post type slug. Default 'post'.
|
50 |
+
*/
|
51 |
+
$post_type = (string) apply_filters( 'amp_customizer_post_type', 'post' );
|
52 |
+
|
53 |
+
if ( ! post_type_supports( $post_type, 'amp' ) ) {
|
54 |
+
return;
|
55 |
+
}
|
56 |
+
|
57 |
+
$post_ids = get_posts( array(
|
58 |
+
'post_status' => 'publish',
|
59 |
+
'post_type' => $post_type,
|
60 |
+
'posts_per_page' => 1,
|
61 |
+
'fields' => 'ids',
|
62 |
+
) );
|
63 |
+
|
64 |
+
if ( empty( $post_ids ) ) {
|
65 |
+
return false;
|
66 |
+
}
|
67 |
+
|
68 |
+
$post_id = $post_ids[0];
|
69 |
+
|
70 |
+
return amp_get_permalink( $post_id );
|
71 |
+
}
|
includes/amp-helper-functions.php
CHANGED
@@ -1,6 +1,12 @@
|
|
1 |
<?php
|
2 |
|
3 |
function amp_get_permalink( $post_id ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
if ( '' != get_option( 'permalink_structure' ) ) {
|
5 |
$amp_url = trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( AMP_QUERY_VAR, 'single_amp' );
|
6 |
} else {
|
1 |
<?php
|
2 |
|
3 |
function amp_get_permalink( $post_id ) {
|
4 |
+
$pre_url = apply_filters( 'amp_pre_get_permalink', false, $post_id );
|
5 |
+
|
6 |
+
if ( false !== $pre_url ) {
|
7 |
+
return $pre_url;
|
8 |
+
}
|
9 |
+
|
10 |
if ( '' != get_option( 'permalink_structure' ) ) {
|
11 |
$amp_url = trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( AMP_QUERY_VAR, 'single_amp' );
|
12 |
} else {
|
includes/amp-post-template-actions.php
CHANGED
@@ -25,6 +25,14 @@ function amp_post_template_add_scripts( $amp_template ) {
|
|
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 |
?>
|
@@ -43,6 +51,18 @@ function amp_post_template_add_schemaorg_metadata( $amp_template ) {
|
|
43 |
<?php
|
44 |
}
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
add_action( 'amp_post_template_data', 'amp_post_template_add_analytics_script' );
|
47 |
function amp_post_template_add_analytics_script( $data ) {
|
48 |
if ( ! empty( $data['amp_analytics'] ) ) {
|
25 |
<?php
|
26 |
}
|
27 |
|
28 |
+
add_action( 'amp_post_template_head', 'amp_post_template_add_fonts' );
|
29 |
+
function amp_post_template_add_fonts( $amp_template ) {
|
30 |
+
$font_urls = $amp_template->get( 'font_urls', array() );
|
31 |
+
foreach( $font_urls as $slug => $url ) : ?>
|
32 |
+
<link rel="stylesheet" href="<?php echo esc_url( $url ); ?>">
|
33 |
+
<?php endforeach;
|
34 |
+
}
|
35 |
+
|
36 |
add_action( 'amp_post_template_head', 'amp_post_template_add_boilerplate_css' );
|
37 |
function amp_post_template_add_boilerplate_css( $amp_template ) {
|
38 |
?>
|
51 |
<?php
|
52 |
}
|
53 |
|
54 |
+
add_action( 'amp_post_template_css', 'amp_post_template_add_styles', 99 );
|
55 |
+
function amp_post_template_add_styles( $amp_template ) {
|
56 |
+
$styles = $amp_template->get( 'post_amp_styles' );
|
57 |
+
if ( ! empty( $styles ) ) {
|
58 |
+
echo '/* Inline styles */' . PHP_EOL;
|
59 |
+
foreach ( $styles as $selector => $declarations ) {
|
60 |
+
$declarations = implode( ";", $declarations ) . ";";
|
61 |
+
printf( '%1$s{%2$s}', $selector, $declarations );
|
62 |
+
}
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
add_action( 'amp_post_template_data', 'amp_post_template_add_analytics_script' );
|
67 |
function amp_post_template_add_analytics_script( $data ) {
|
68 |
if ( ! empty( $data['amp_analytics'] ) ) {
|
includes/class-amp-content.php
CHANGED
@@ -8,6 +8,7 @@ class AMP_Content {
|
|
8 |
private $content;
|
9 |
private $amp_content = '';
|
10 |
private $amp_scripts = array();
|
|
|
11 |
private $args = array();
|
12 |
private $embed_handler_classes = array();
|
13 |
private $sanitizer_classes = array();
|
@@ -29,6 +30,10 @@ class AMP_Content {
|
|
29 |
return $this->amp_scripts;
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
32 |
private function transform() {
|
33 |
$content = $this->content;
|
34 |
|
@@ -47,6 +52,10 @@ class AMP_Content {
|
|
47 |
$this->amp_scripts = array_merge( $this->amp_scripts, $scripts );
|
48 |
}
|
49 |
|
|
|
|
|
|
|
|
|
50 |
private function register_embed_handlers() {
|
51 |
$embed_handlers = array();
|
52 |
|
@@ -85,6 +94,7 @@ class AMP_Content {
|
|
85 |
|
86 |
$sanitizer->sanitize();
|
87 |
$this->add_scripts( $sanitizer->get_scripts() );
|
|
|
88 |
}
|
89 |
|
90 |
return AMP_DOM_Utils::get_content_from_dom( $dom );
|
8 |
private $content;
|
9 |
private $amp_content = '';
|
10 |
private $amp_scripts = array();
|
11 |
+
private $amp_styles = array();
|
12 |
private $args = array();
|
13 |
private $embed_handler_classes = array();
|
14 |
private $sanitizer_classes = array();
|
30 |
return $this->amp_scripts;
|
31 |
}
|
32 |
|
33 |
+
public function get_amp_styles() {
|
34 |
+
return $this->amp_styles;
|
35 |
+
}
|
36 |
+
|
37 |
private function transform() {
|
38 |
$content = $this->content;
|
39 |
|
52 |
$this->amp_scripts = array_merge( $this->amp_scripts, $scripts );
|
53 |
}
|
54 |
|
55 |
+
private function add_styles( $styles ) {
|
56 |
+
$this->amp_styles = array_merge( $this->amp_styles, $styles );
|
57 |
+
}
|
58 |
+
|
59 |
private function register_embed_handlers() {
|
60 |
$embed_handlers = array();
|
61 |
|
94 |
|
95 |
$sanitizer->sanitize();
|
96 |
$this->add_scripts( $sanitizer->get_scripts() );
|
97 |
+
$this->add_styles( $sanitizer->get_styles() );
|
98 |
}
|
99 |
|
100 |
return AMP_DOM_Utils::get_content_from_dom( $dom );
|
includes/class-amp-post-template.php
CHANGED
@@ -6,6 +6,7 @@ require_once( AMP__DIR__ . '/includes/utils/class-amp-string-utils.php' );
|
|
6 |
|
7 |
require_once( AMP__DIR__ . '/includes/class-amp-content.php' );
|
8 |
|
|
|
9 |
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-blacklist-sanitizer.php' );
|
10 |
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-img-sanitizer.php' );
|
11 |
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-video-sanitizer.php' );
|
@@ -23,6 +24,10 @@ class AMP_Post_Template {
|
|
23 |
const SITE_ICON_SIZE = 32;
|
24 |
const CONTENT_MAX_WIDTH = 600;
|
25 |
|
|
|
|
|
|
|
|
|
26 |
private $template_dir;
|
27 |
private $data;
|
28 |
|
@@ -45,13 +50,24 @@ class AMP_Post_Template {
|
|
45 |
'canonical_url' => get_permalink( $post_id ),
|
46 |
'home_url' => home_url(),
|
47 |
'blog_name' => get_bloginfo( 'name' ),
|
|
|
48 |
|
49 |
'site_icon_url' => apply_filters( 'amp_site_icon_url', function_exists( 'get_site_icon_url' ) ? get_site_icon_url( self::SITE_ICON_SIZE ) : '' ),
|
50 |
'placeholder_image_url' => amp_get_asset_url( 'images/placeholder-icon.png' ),
|
51 |
|
|
|
|
|
|
|
|
|
52 |
'amp_runtime_script' => 'https://cdn.ampproject.org/v0.js',
|
53 |
'amp_component_scripts' => array(),
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
/**
|
56 |
* Add amp-analytics tags.
|
57 |
*
|
@@ -63,10 +79,11 @@ class AMP_Post_Template {
|
|
63 |
* @param object $post The current post.
|
64 |
*/
|
65 |
'amp_analytics' => apply_filters( 'amp_post_template_analytics', array(), $this->post ),
|
66 |
-
|
67 |
|
68 |
$this->build_post_content();
|
69 |
$this->build_post_data();
|
|
|
70 |
|
71 |
$this->data = apply_filters( 'amp_post_template_data', $this->data, $this->post );
|
72 |
}
|
@@ -81,6 +98,15 @@ class AMP_Post_Template {
|
|
81 |
return $default;
|
82 |
}
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
public function load() {
|
85 |
$this->load_parts( array( 'single' ) );
|
86 |
}
|
@@ -160,6 +186,25 @@ class AMP_Post_Template {
|
|
160 |
}
|
161 |
|
162 |
$this->add_data_by_key( 'metadata', apply_filters( 'amp_post_template_metadata', $metadata, $this->post ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
}
|
164 |
|
165 |
private function build_post_content() {
|
@@ -173,6 +218,7 @@ class AMP_Post_Template {
|
|
173 |
'AMP_Gallery_Embed_Handler' => array(),
|
174 |
), $this->post ),
|
175 |
apply_filters( 'amp_content_sanitizers', array(
|
|
|
176 |
'AMP_Blacklist_Sanitizer' => array(),
|
177 |
'AMP_Img_Sanitizer' => array(),
|
178 |
'AMP_Video_Sanitizer' => array(),
|
@@ -188,6 +234,68 @@ class AMP_Post_Template {
|
|
188 |
|
189 |
$this->add_data_by_key( 'post_amp_content', $amp_content->get_amp_content() );
|
190 |
$this->merge_data_for_key( 'amp_component_scripts', $amp_content->get_amp_scripts() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
}
|
192 |
|
193 |
/**
|
@@ -248,6 +356,7 @@ class AMP_Post_Template {
|
|
248 |
return;
|
249 |
}
|
250 |
|
|
|
251 |
include( $file );
|
252 |
}
|
253 |
|
6 |
|
7 |
require_once( AMP__DIR__ . '/includes/class-amp-content.php' );
|
8 |
|
9 |
+
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-style-sanitizer.php' );
|
10 |
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-blacklist-sanitizer.php' );
|
11 |
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-img-sanitizer.php' );
|
12 |
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-video-sanitizer.php' );
|
24 |
const SITE_ICON_SIZE = 32;
|
25 |
const CONTENT_MAX_WIDTH = 600;
|
26 |
|
27 |
+
// Needed for 0.3 back-compat
|
28 |
+
const DEFAULT_NAVBAR_BACKGROUND = '#0a89c0';
|
29 |
+
const DEFAULT_NAVBAR_COLOR = '#fff';
|
30 |
+
|
31 |
private $template_dir;
|
32 |
private $data;
|
33 |
|
50 |
'canonical_url' => get_permalink( $post_id ),
|
51 |
'home_url' => home_url(),
|
52 |
'blog_name' => get_bloginfo( 'name' ),
|
53 |
+
'body_class' => '',
|
54 |
|
55 |
'site_icon_url' => apply_filters( 'amp_site_icon_url', function_exists( 'get_site_icon_url' ) ? get_site_icon_url( self::SITE_ICON_SIZE ) : '' ),
|
56 |
'placeholder_image_url' => amp_get_asset_url( 'images/placeholder-icon.png' ),
|
57 |
|
58 |
+
'featured_image' => false,
|
59 |
+
'comments_link_url' => false,
|
60 |
+
'comments_link_text' => false,
|
61 |
+
|
62 |
'amp_runtime_script' => 'https://cdn.ampproject.org/v0.js',
|
63 |
'amp_component_scripts' => array(),
|
64 |
|
65 |
+
'customizer_settings' => array(),
|
66 |
+
|
67 |
+
'font_urls' => array(
|
68 |
+
'merriweather' => 'https://fonts.googleapis.com/css?family=Merriweather:400,400italic,700,700italic',
|
69 |
+
),
|
70 |
+
|
71 |
/**
|
72 |
* Add amp-analytics tags.
|
73 |
*
|
79 |
* @param object $post The current post.
|
80 |
*/
|
81 |
'amp_analytics' => apply_filters( 'amp_post_template_analytics', array(), $this->post ),
|
82 |
+
);
|
83 |
|
84 |
$this->build_post_content();
|
85 |
$this->build_post_data();
|
86 |
+
$this->build_customizer_settings();
|
87 |
|
88 |
$this->data = apply_filters( 'amp_post_template_data', $this->data, $this->post );
|
89 |
}
|
98 |
return $default;
|
99 |
}
|
100 |
|
101 |
+
public function get_customizer_setting( $name, $default = null ) {
|
102 |
+
$settings = $this->get( 'customizer_settings' );
|
103 |
+
if ( ! empty( $settings[ $name ] ) ) {
|
104 |
+
return $settings[ $name ];
|
105 |
+
}
|
106 |
+
|
107 |
+
return $default;
|
108 |
+
}
|
109 |
+
|
110 |
public function load() {
|
111 |
$this->load_parts( array( 'single' ) );
|
112 |
}
|
186 |
}
|
187 |
|
188 |
$this->add_data_by_key( 'metadata', apply_filters( 'amp_post_template_metadata', $metadata, $this->post ) );
|
189 |
+
|
190 |
+
$this->build_post_featured_image();
|
191 |
+
$this->build_post_commments_data();
|
192 |
+
}
|
193 |
+
|
194 |
+
private function build_post_commments_data() {
|
195 |
+
if ( ! post_type_supports( $this->post->post_type, 'comments' ) ) {
|
196 |
+
return;
|
197 |
+
}
|
198 |
+
|
199 |
+
$comments_link_url = get_comments_link( $this->ID );
|
200 |
+
$comments_link_text = comments_open( $this->ID )
|
201 |
+
? __( 'Leave a Comment', 'amp' )
|
202 |
+
: __( 'View Comments', 'amp' );
|
203 |
+
|
204 |
+
$this->add_data( array(
|
205 |
+
'comments_link_url' => $comments_link_url,
|
206 |
+
'comments_link_text' => $comments_link_text,
|
207 |
+
) );
|
208 |
}
|
209 |
|
210 |
private function build_post_content() {
|
218 |
'AMP_Gallery_Embed_Handler' => array(),
|
219 |
), $this->post ),
|
220 |
apply_filters( 'amp_content_sanitizers', array(
|
221 |
+
'AMP_Style_Sanitizer' => array(),
|
222 |
'AMP_Blacklist_Sanitizer' => array(),
|
223 |
'AMP_Img_Sanitizer' => array(),
|
224 |
'AMP_Video_Sanitizer' => array(),
|
234 |
|
235 |
$this->add_data_by_key( 'post_amp_content', $amp_content->get_amp_content() );
|
236 |
$this->merge_data_for_key( 'amp_component_scripts', $amp_content->get_amp_scripts() );
|
237 |
+
$this->add_data_by_key( 'post_amp_styles', $amp_content->get_amp_styles() );
|
238 |
+
}
|
239 |
+
|
240 |
+
private function build_post_featured_image() {
|
241 |
+
$post_id = $this->ID;
|
242 |
+
$featured_html = get_the_post_thumbnail( $post_id, 'large' );
|
243 |
+
|
244 |
+
// Skip featured image if no featured image is available.
|
245 |
+
if ( ! $featured_html ) {
|
246 |
+
return;
|
247 |
+
}
|
248 |
+
|
249 |
+
$featured_id = get_post_thumbnail_id( $post_id );
|
250 |
+
|
251 |
+
// If an image with the same ID as the featured image exists in the content, skip the featured image markup.
|
252 |
+
// Prevents duplicate images, which is especially problematic for photo blogs.
|
253 |
+
// A bit crude but it's fast and should cover most cases.
|
254 |
+
$post_content = $this->post->post_content;
|
255 |
+
if ( false !== strpos( $post_content, 'wp-image-' . $featured_id )
|
256 |
+
|| false !== strpos( $post_content, 'attachment_' . $featured_id ) ) {
|
257 |
+
return;
|
258 |
+
}
|
259 |
+
|
260 |
+
$featured_image = get_post( $featured_id );
|
261 |
+
|
262 |
+
remove_filter( 'the_content', 'wpautop' ); // We don't want our image wrapped in a <p>
|
263 |
+
$featured_amp_content = new AMP_Content(
|
264 |
+
$featured_html,
|
265 |
+
array(),
|
266 |
+
array(
|
267 |
+
'AMP_Img_Sanitizer' => array(),
|
268 |
+
),
|
269 |
+
array(
|
270 |
+
'content_max_width' => $this->get( 'content_max_width' ),
|
271 |
+
)
|
272 |
+
);
|
273 |
+
add_filter( 'the_content', 'wpautop' );
|
274 |
+
|
275 |
+
$this->add_data_by_key( 'featured_image', array(
|
276 |
+
'amp_html' => $featured_amp_content->get_amp_content(),
|
277 |
+
'caption' => $featured_image->post_excerpt,
|
278 |
+
) );
|
279 |
+
}
|
280 |
+
|
281 |
+
private function build_customizer_settings() {
|
282 |
+
$settings = AMP_Customizer_Settings::get_settings();
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Filter AMP Customizer settings.
|
286 |
+
*
|
287 |
+
* Inject your Customizer settings here to make them accessible via the getter in your custom style.php template.
|
288 |
+
*
|
289 |
+
* Example:
|
290 |
+
*
|
291 |
+
* echo esc_html( $this->get_customizer_setting( 'your_setting_key', 'your_default_value' ) );
|
292 |
+
*
|
293 |
+
* @since 0.4
|
294 |
+
*
|
295 |
+
* @param array $settings Array of AMP Customizer settings.
|
296 |
+
* @param WP_Post $post Current post object.
|
297 |
+
*/
|
298 |
+
$this->add_data_by_key( 'customizer_settings', apply_filters( 'amp_post_template_customizer_settings', $settings, $this->post ) );
|
299 |
}
|
300 |
|
301 |
/**
|
356 |
return;
|
357 |
}
|
358 |
|
359 |
+
do_action( 'amp_post_template_include_' . $template_type, $this );
|
360 |
include( $file );
|
361 |
}
|
362 |
|
includes/embeds/class-amp-youtube-embed.php
CHANGED
@@ -5,7 +5,8 @@ require_once( AMP__DIR__ . '/includes/embeds/class-amp-base-embed-handler.php' )
|
|
5 |
// Much of this class is borrowed from Jetpack embeds
|
6 |
class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
7 |
const SHORT_URL_HOST = 'youtu.be';
|
8 |
-
|
|
|
9 |
const RATIO = 0.5625;
|
10 |
|
11 |
protected $DEFAULT_WIDTH = 600;
|
@@ -104,7 +105,7 @@ class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
104 |
parse_str( $parsed_url['query'], $query_args );
|
105 |
|
106 |
if ( isset( $query_args['v'] ) ) {
|
107 |
-
$video_id = $query_args['v'];
|
108 |
}
|
109 |
}
|
110 |
|
@@ -119,4 +120,13 @@ class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
119 |
|
120 |
return $video_id;
|
121 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
}
|
5 |
// Much of this class is borrowed from Jetpack embeds
|
6 |
class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
7 |
const SHORT_URL_HOST = 'youtu.be';
|
8 |
+
// Only handling single videos. Playlists are handled elsewhere.
|
9 |
+
const URL_PATTERN = '#https?://(?:www\.)?(?:youtube.com/(?:v/|e/|embed/|watch[/\#?])|youtu\.be/).*#i';
|
10 |
const RATIO = 0.5625;
|
11 |
|
12 |
protected $DEFAULT_WIDTH = 600;
|
105 |
parse_str( $parsed_url['query'], $query_args );
|
106 |
|
107 |
if ( isset( $query_args['v'] ) ) {
|
108 |
+
$video_id = $this->sanitize_v_arg( $query_args['v'] );
|
109 |
}
|
110 |
}
|
111 |
|
120 |
|
121 |
return $video_id;
|
122 |
}
|
123 |
+
|
124 |
+
private function sanitize_v_arg( $value ) {
|
125 |
+
// Deal with broken params like `?v=123?rel=0`
|
126 |
+
if ( false !== strpos( $value, '?' ) ) {
|
127 |
+
$value = strtok( $value, '?' );
|
128 |
+
}
|
129 |
+
|
130 |
+
return $value;
|
131 |
+
}
|
132 |
}
|
includes/sanitizers/class-amp-base-sanitizer.php
CHANGED
@@ -20,6 +20,10 @@ abstract class AMP_Base_Sanitizer {
|
|
20 |
return array();
|
21 |
}
|
22 |
|
|
|
|
|
|
|
|
|
23 |
protected function get_body_node() {
|
24 |
return $this->dom->getElementsByTagName( 'body' )->item( 0 );
|
25 |
}
|
20 |
return array();
|
21 |
}
|
22 |
|
23 |
+
public function get_styles() {
|
24 |
+
return array();
|
25 |
+
}
|
26 |
+
|
27 |
protected function get_body_node() {
|
28 |
return $this->dom->getElementsByTagName( 'body' )->item( 0 );
|
29 |
}
|
includes/sanitizers/class-amp-blacklist-sanitizer.php
CHANGED
@@ -37,9 +37,11 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
37 |
// Some nodes may contain valid content but are themselves invalid.
|
38 |
// Remove the node but preserve the children.
|
39 |
if ( 'font' === $node_name ) {
|
40 |
-
$this->replace_node_with_children( $node );
|
|
|
41 |
} elseif ( 'a' === $node_name && false === $this->validate_a_node( $node ) ) {
|
42 |
-
$this->replace_node_with_children( $node );
|
|
|
43 |
}
|
44 |
|
45 |
if ( $node->hasAttributes() ) {
|
@@ -144,21 +146,28 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
144 |
}
|
145 |
|
146 |
$valid_protocols = array( 'http', 'https', 'mailto', 'sms', 'tel', 'viber', 'whatsapp' );
|
|
|
147 |
$protocol = strtok( $href, ':' );
|
|
|
148 |
if ( false === filter_var( $href, FILTER_VALIDATE_URL )
|
149 |
-
|
|
|
|
|
|
|
|
|
150 |
return false;
|
151 |
}
|
152 |
|
153 |
return true;
|
154 |
}
|
155 |
|
156 |
-
private function replace_node_with_children( $node ) {
|
157 |
// If the node has children and also has a parent node,
|
158 |
// clone and re-add all the children just before current node.
|
159 |
if ( $node->hasChildNodes() && $node->parentNode ) {
|
160 |
foreach ( $node->childNodes as $child_node ) {
|
161 |
$new_child = $child_node->cloneNode( true );
|
|
|
162 |
$node->parentNode->insertBefore( $new_child, $node );
|
163 |
}
|
164 |
}
|
@@ -208,6 +217,9 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
208 |
'embed',
|
209 |
'embedvideo',
|
210 |
|
|
|
|
|
|
|
211 |
// These are converted into amp-* versions
|
212 |
//'img',
|
213 |
//'video',
|
@@ -220,6 +232,9 @@ class AMP_Blacklist_Sanitizer extends AMP_Base_Sanitizer {
|
|
220 |
return $this->merge_defaults_with_args( 'add_blacklisted_attributes', array(
|
221 |
'style',
|
222 |
'size',
|
|
|
|
|
|
|
223 |
) );
|
224 |
}
|
225 |
}
|
37 |
// Some nodes may contain valid content but are themselves invalid.
|
38 |
// Remove the node but preserve the children.
|
39 |
if ( 'font' === $node_name ) {
|
40 |
+
$this->replace_node_with_children( $node, $bad_attributes, $bad_protocols );
|
41 |
+
return;
|
42 |
} elseif ( 'a' === $node_name && false === $this->validate_a_node( $node ) ) {
|
43 |
+
$this->replace_node_with_children( $node, $bad_attributes, $bad_protocols );
|
44 |
+
return;
|
45 |
}
|
46 |
|
47 |
if ( $node->hasAttributes() ) {
|
146 |
}
|
147 |
|
148 |
$valid_protocols = array( 'http', 'https', 'mailto', 'sms', 'tel', 'viber', 'whatsapp' );
|
149 |
+
$special_protocols = array( 'tel', 'sms' ); // these ones don't valid with `filter_var+FILTER_VALIDATE_URL`
|
150 |
$protocol = strtok( $href, ':' );
|
151 |
+
|
152 |
if ( false === filter_var( $href, FILTER_VALIDATE_URL )
|
153 |
+
&& ! in_array( $protocol, $special_protocols ) ) {
|
154 |
+
return false;
|
155 |
+
}
|
156 |
+
|
157 |
+
if ( ! in_array( $protocol, $valid_protocols ) ) {
|
158 |
return false;
|
159 |
}
|
160 |
|
161 |
return true;
|
162 |
}
|
163 |
|
164 |
+
private function replace_node_with_children( $node, $bad_attributes, $bad_protocols ) {
|
165 |
// If the node has children and also has a parent node,
|
166 |
// clone and re-add all the children just before current node.
|
167 |
if ( $node->hasChildNodes() && $node->parentNode ) {
|
168 |
foreach ( $node->childNodes as $child_node ) {
|
169 |
$new_child = $child_node->cloneNode( true );
|
170 |
+
$this->strip_attributes_recursive( $new_child, $bad_attributes, $bad_protocols );
|
171 |
$node->parentNode->insertBefore( $new_child, $node );
|
172 |
}
|
173 |
}
|
217 |
'embed',
|
218 |
'embedvideo',
|
219 |
|
220 |
+
// Other weird ones
|
221 |
+
'comments-count',
|
222 |
+
|
223 |
// These are converted into amp-* versions
|
224 |
//'img',
|
225 |
//'video',
|
232 |
return $this->merge_defaults_with_args( 'add_blacklisted_attributes', array(
|
233 |
'style',
|
234 |
'size',
|
235 |
+
'clear',
|
236 |
+
'align',
|
237 |
+
'valign',
|
238 |
) );
|
239 |
}
|
240 |
}
|
includes/sanitizers/class-amp-img-sanitizer.php
CHANGED
@@ -28,7 +28,7 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
28 |
$node = $nodes->item( $i );
|
29 |
$old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
30 |
|
31 |
-
if (
|
32 |
$node->parentNode->removeChild( $node );
|
33 |
continue;
|
34 |
}
|
28 |
$node = $nodes->item( $i );
|
29 |
$old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
30 |
|
31 |
+
if ( empty( $old_attributes['src'] ) ) {
|
32 |
$node->parentNode->removeChild( $node );
|
33 |
continue;
|
34 |
}
|
includes/sanitizers/class-amp-style-sanitizer.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once( AMP__DIR__ . '/includes/sanitizers/class-amp-base-sanitizer.php' );
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Collects inline styles and outputs them in the amp-custom stylesheet.
|
7 |
+
*/
|
8 |
+
class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
9 |
+
private $styles = array();
|
10 |
+
|
11 |
+
public function get_styles() {
|
12 |
+
return $this->styles;
|
13 |
+
}
|
14 |
+
|
15 |
+
public function sanitize() {
|
16 |
+
$body = $this->get_body_node();
|
17 |
+
$this->collect_styles_recursive( $body );
|
18 |
+
}
|
19 |
+
|
20 |
+
private function collect_styles_recursive( $node ) {
|
21 |
+
if ( $node->nodeType !== XML_ELEMENT_NODE ) {
|
22 |
+
return;
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( $node->hasAttributes() && $node instanceof DOMElement ) {
|
26 |
+
$style = $node->getAttribute( 'style' );
|
27 |
+
$class = $node->getAttribute( 'class' );
|
28 |
+
|
29 |
+
if ( $style ) {
|
30 |
+
$style = $this->process_style( $style );
|
31 |
+
if ( ! empty( $style ) ) {
|
32 |
+
$class_name = $this->generate_class_name( $style );
|
33 |
+
$new_class = trim( $class . ' ' . $class_name );
|
34 |
+
|
35 |
+
$node->setAttribute( 'class', $new_class );
|
36 |
+
$this->styles[ '.' . $class_name ] = $style;
|
37 |
+
}
|
38 |
+
|
39 |
+
$node->removeAttribute( 'style' );
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
$length = $node->childNodes->length;
|
44 |
+
for ( $i = $length - 1; $i >= 0; $i -- ) {
|
45 |
+
$child_node = $node->childNodes->item( $i );
|
46 |
+
|
47 |
+
$this->collect_styles_recursive( $child_node );
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
private function process_style( $string ) {
|
52 |
+
// Filter properties
|
53 |
+
$string = safecss_filter_attr( esc_html( $string ) );
|
54 |
+
|
55 |
+
if ( ! $string ) {
|
56 |
+
return array();
|
57 |
+
}
|
58 |
+
|
59 |
+
// Normalize order
|
60 |
+
$styles = array_map( 'trim', explode( ';', $string ) );
|
61 |
+
sort( $styles );
|
62 |
+
|
63 |
+
$processed_styles = array();
|
64 |
+
|
65 |
+
// Normalize whitespace and filter rules
|
66 |
+
foreach ( $styles as $index => $rule ) {
|
67 |
+
$arr2 = array_map( 'trim', explode( ':', $rule, 2 ) );
|
68 |
+
if ( 2 !== count( $arr2 ) ) {
|
69 |
+
continue;
|
70 |
+
}
|
71 |
+
|
72 |
+
list( $property, $value ) = $this->filter_style( $arr2[0], $arr2[1] );
|
73 |
+
if ( empty( $property ) || empty( $value ) ) {
|
74 |
+
continue;
|
75 |
+
}
|
76 |
+
|
77 |
+
$processed_styles[ $index ] = $property . ':' . $value;
|
78 |
+
}
|
79 |
+
|
80 |
+
return $processed_styles;
|
81 |
+
}
|
82 |
+
|
83 |
+
private function filter_style( $property, $value ) {
|
84 |
+
// Handle overflow rule
|
85 |
+
// https://www.ampproject.org/docs/reference/spec.html#properties
|
86 |
+
if ( 0 === strpos( $property, 'overflow' )
|
87 |
+
&& ( false !== strpos( $value, 'auto' ) || false !== strpos( $value, 'scroll' ) )
|
88 |
+
) {
|
89 |
+
return false;
|
90 |
+
}
|
91 |
+
|
92 |
+
if ( 'width' === $property ) {
|
93 |
+
$property = 'max-width';
|
94 |
+
}
|
95 |
+
|
96 |
+
return array( $property, $value );
|
97 |
+
}
|
98 |
+
|
99 |
+
private function generate_class_name( $data ) {
|
100 |
+
$string = maybe_serialize( $data );
|
101 |
+
return 'amp-wp-inline-' . md5( $string );
|
102 |
+
}
|
103 |
+
}
|
includes/settings/class-amp-customizer-design-settings.php
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class AMP_Customizer_Design_Settings {
|
4 |
+
const DEFAULT_HEADER_COLOR = '#fff';
|
5 |
+
const DEFAULT_HEADER_BACKGROUND_COLOR = '#0a89c0';
|
6 |
+
const DEFAULT_COLOR_SCHEME = 'light';
|
7 |
+
|
8 |
+
public static function init() {
|
9 |
+
add_action( 'amp_customizer_init', array( __CLASS__, 'init_customizer' ) );
|
10 |
+
|
11 |
+
add_filter( 'amp_customizer_get_settings', array( __CLASS__, 'append_settings' ) );
|
12 |
+
}
|
13 |
+
|
14 |
+
public static function init_customizer() {
|
15 |
+
add_action( 'amp_customizer_register_settings', array( __CLASS__, 'register_customizer_settings' ) );
|
16 |
+
add_action( 'amp_customizer_register_ui', array( __CLASS__, 'register_customizer_ui' ) );
|
17 |
+
add_action( 'amp_customizer_enqueue_preview_scripts', array( __CLASS__, 'enqueue_customizer_preview_scripts' ) );
|
18 |
+
}
|
19 |
+
|
20 |
+
public static function register_customizer_settings( $wp_customize ) {
|
21 |
+
// Header text color setting
|
22 |
+
$wp_customize->add_setting( 'amp_customizer[header_color]', array(
|
23 |
+
'type' => 'option',
|
24 |
+
'default' => self::DEFAULT_HEADER_COLOR,
|
25 |
+
'sanitize_callback' => 'sanitize_hex_color',
|
26 |
+
'transport' => 'postMessage'
|
27 |
+
) );
|
28 |
+
|
29 |
+
// Header background color
|
30 |
+
$wp_customize->add_setting( 'amp_customizer[header_background_color]', array(
|
31 |
+
'type' => 'option',
|
32 |
+
'default' => self::DEFAULT_HEADER_BACKGROUND_COLOR,
|
33 |
+
'sanitize_callback' => 'sanitize_hex_color',
|
34 |
+
'transport' => 'postMessage'
|
35 |
+
) );
|
36 |
+
|
37 |
+
// Background color scheme
|
38 |
+
$wp_customize->add_setting( 'amp_customizer[color_scheme]', array(
|
39 |
+
'type' => 'option',
|
40 |
+
'default' => self::DEFAULT_COLOR_SCHEME,
|
41 |
+
'sanitize_callback' => array( __CLASS__ , 'sanitize_color_scheme' ),
|
42 |
+
'transport' => 'postMessage'
|
43 |
+
) );
|
44 |
+
}
|
45 |
+
|
46 |
+
public function register_customizer_ui( $wp_customize ) {
|
47 |
+
$wp_customize->add_section( 'amp_design', array(
|
48 |
+
'title' => __( 'Design', 'amp' ),
|
49 |
+
'panel' => AMP_Template_Customizer::PANEL_ID,
|
50 |
+
) );
|
51 |
+
|
52 |
+
// Header text color control.
|
53 |
+
$wp_customize->add_control(
|
54 |
+
new WP_Customize_Color_Control( $wp_customize, 'amp_header_color', array(
|
55 |
+
'settings' => 'amp_customizer[header_color]',
|
56 |
+
'label' => __( 'Header Text Color', 'amp' ),
|
57 |
+
'section' => 'amp_design',
|
58 |
+
'priority' => 10
|
59 |
+
) )
|
60 |
+
);
|
61 |
+
|
62 |
+
// Header background color control.
|
63 |
+
$wp_customize->add_control(
|
64 |
+
new WP_Customize_Color_Control( $wp_customize, 'amp_header_background_color', array(
|
65 |
+
'settings' => 'amp_customizer[header_background_color]',
|
66 |
+
'label' => __( 'Header Background & Link Color', 'amp' ),
|
67 |
+
'section' => 'amp_design',
|
68 |
+
'priority' => 20
|
69 |
+
) )
|
70 |
+
);
|
71 |
+
|
72 |
+
// Background color scheme
|
73 |
+
$wp_customize->add_control( 'amp_color_scheme', array(
|
74 |
+
'settings' => 'amp_customizer[color_scheme]',
|
75 |
+
'label' => __( 'Color Scheme', 'amp' ),
|
76 |
+
'section' => 'amp_design',
|
77 |
+
'type' => 'radio',
|
78 |
+
'priority' => 30,
|
79 |
+
'choices' => self::get_color_scheme_names(),
|
80 |
+
));
|
81 |
+
}
|
82 |
+
|
83 |
+
public static function enqueue_customizer_preview_scripts() {
|
84 |
+
wp_enqueue_script(
|
85 |
+
'amp-customizer-design-preview',
|
86 |
+
amp_get_asset_url( 'js/amp-customizer-design-preview.js' ),
|
87 |
+
array( 'amp-customizer' ),
|
88 |
+
false,
|
89 |
+
true
|
90 |
+
);
|
91 |
+
wp_localize_script( 'amp-customizer-design-preview', 'amp_customizer_design', array(
|
92 |
+
'color_schemes' => self::get_color_schemes(),
|
93 |
+
) );
|
94 |
+
}
|
95 |
+
|
96 |
+
public static function append_settings( $settings ) {
|
97 |
+
$settings = wp_parse_args( $settings, array(
|
98 |
+
'header_color' => self::DEFAULT_HEADER_COLOR,
|
99 |
+
'header_background_color' => self::DEFAULT_HEADER_BACKGROUND_COLOR,
|
100 |
+
'color_scheme' => self::DEFAULT_COLOR_SCHEME,
|
101 |
+
) );
|
102 |
+
|
103 |
+
$theme_colors = self::get_colors_for_color_scheme( $settings['color_scheme'] );
|
104 |
+
|
105 |
+
return array_merge( $settings, $theme_colors, array(
|
106 |
+
'link_color' => $settings['header_background_color'],
|
107 |
+
) );
|
108 |
+
}
|
109 |
+
|
110 |
+
protected static function get_color_scheme_names() {
|
111 |
+
return array(
|
112 |
+
'light' => __( 'Light', 'amp'),
|
113 |
+
'dark' => __( 'Dark', 'amp' ),
|
114 |
+
);
|
115 |
+
}
|
116 |
+
|
117 |
+
protected static function get_color_schemes() {
|
118 |
+
return array(
|
119 |
+
'light' => array(
|
120 |
+
// Convert colors to greyscale for light theme color; see http://goo.gl/2gDLsp
|
121 |
+
'theme_color' => '#fff',
|
122 |
+
'text_color' => '#353535',
|
123 |
+
'muted_text_color' => '#696969',
|
124 |
+
'border_color' => '#c2c2c2',
|
125 |
+
),
|
126 |
+
'dark' => array(
|
127 |
+
// Convert and invert colors to greyscale for dark theme color; see http://goo.gl/uVB2cO
|
128 |
+
'theme_color' => '#0a0a0a',
|
129 |
+
'text_color' => '#dedede',
|
130 |
+
'muted_text_color' => '#b1b1b1',
|
131 |
+
'border_color' => '#707070',
|
132 |
+
)
|
133 |
+
);
|
134 |
+
}
|
135 |
+
|
136 |
+
protected static function get_colors_for_color_scheme( $scheme ) {
|
137 |
+
$color_schemes = self::get_color_schemes();
|
138 |
+
|
139 |
+
if ( isset( $color_schemes[ $scheme ] ) ) {
|
140 |
+
return $color_schemes[ $scheme ];
|
141 |
+
}
|
142 |
+
|
143 |
+
return $color_schemes[ self::DEFAULT_COLOR_SCHEME ];
|
144 |
+
}
|
145 |
+
|
146 |
+
public static function sanitize_color_scheme( $value ) {
|
147 |
+
$schemes = self::get_color_scheme_names();
|
148 |
+
$scheme_slugs = array_keys( $schemes );
|
149 |
+
|
150 |
+
if ( ! in_array( $value, $scheme_slugs ) ) {
|
151 |
+
$value = self::DEFAULT_COLOR_SCHEME;
|
152 |
+
}
|
153 |
+
|
154 |
+
return $value;
|
155 |
+
}
|
156 |
+
}
|
includes/settings/class-amp-customizer-settings.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class AMP_Customizer_Settings {
|
4 |
+
private static function get_stored_options() {
|
5 |
+
return get_option( 'amp_customizer', array() );
|
6 |
+
}
|
7 |
+
|
8 |
+
public static function get_settings() {
|
9 |
+
$settings = self::get_stored_options();
|
10 |
+
|
11 |
+
return apply_filters( 'amp_customizer_get_settings', $settings );
|
12 |
+
}
|
13 |
+
}
|
includes/utils/class-amp-dom-utils.php
CHANGED
@@ -25,8 +25,14 @@ class AMP_DOM_Utils {
|
|
25 |
// Only want children of the body tag, since we have a subset of HTML.
|
26 |
$out = '';
|
27 |
$body = $dom->getElementsByTagName( 'body' )->item( 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
foreach ( $body->childNodes as $node ) {
|
29 |
-
$out .= $dom->saveXML( $node
|
30 |
}
|
31 |
return $out;
|
32 |
}
|
@@ -52,6 +58,43 @@ class AMP_DOM_Utils {
|
|
52 |
}
|
53 |
|
54 |
public static function is_node_empty( $node ) {
|
55 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
57 |
}
|
25 |
// Only want children of the body tag, since we have a subset of HTML.
|
26 |
$out = '';
|
27 |
$body = $dom->getElementsByTagName( 'body' )->item( 0 );
|
28 |
+
|
29 |
+
// AMP elements always need closing tags.
|
30 |
+
// To force them, we can't use saveHTML (node support is 5.3+) and LIBXML_NOEMPTYTAG results in issues with self-closing tags like `br` and `hr`.
|
31 |
+
// So, we're manually forcing closing tags.
|
32 |
+
self::recursive_force_closing_tags( $dom, $body );
|
33 |
+
|
34 |
foreach ( $body->childNodes as $node ) {
|
35 |
+
$out .= $dom->saveXML( $node );
|
36 |
}
|
37 |
return $out;
|
38 |
}
|
58 |
}
|
59 |
|
60 |
public static function is_node_empty( $node ) {
|
61 |
+
return false === $node->hasChildNodes()
|
62 |
+
&& empty( $node->textContent );
|
63 |
+
}
|
64 |
+
|
65 |
+
public static function recursive_force_closing_tags( $dom, $node ) {
|
66 |
+
if ( XML_ELEMENT_NODE !== $node->nodeType ) {
|
67 |
+
return;
|
68 |
+
}
|
69 |
+
|
70 |
+
if ( self::is_self_closing_tag( $node->nodeName ) ) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
+
if ( self::is_node_empty( $node ) ) {
|
75 |
+
$text_node = $dom->createTextNode( '' );
|
76 |
+
$node->appendChild( $text_node );
|
77 |
+
return;
|
78 |
+
}
|
79 |
+
|
80 |
+
$num_children = $node->childNodes->length;
|
81 |
+
for ( $i = $num_children - 1; $i >= 0; $i-- ) {
|
82 |
+
$child = $node->childNodes->item( $i );
|
83 |
+
self::recursive_force_closing_tags( $dom, $child );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
private static function is_self_closing_tag( $tag ) {
|
88 |
+
// This function is called a lot; the static var prevents having to re-create the array every time.
|
89 |
+
static $self_closing_tags;
|
90 |
+
if ( ! isset( $self_closing_tags ) ) {
|
91 |
+
// https://www.w3.org/TR/html5/syntax.html#serializing-html-fragments
|
92 |
+
// Not all are valid AMP, but we include them for completeness.
|
93 |
+
$self_closing_tags = array(
|
94 |
+
'area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr',
|
95 |
+
);
|
96 |
+
}
|
97 |
+
|
98 |
+
return in_array( $tag, $self_closing_tags );
|
99 |
}
|
100 |
}
|
readme.md
CHANGED
@@ -575,6 +575,11 @@ We may provide better ways to handle this in the future.
|
|
575 |
|
576 |
Jetpack integration is baked in. More support for things like Related Posts to come.
|
577 |
|
|
|
|
|
|
|
|
|
|
|
578 |
### Yoast SEO
|
579 |
|
580 |
If you're using [Yoast SEO](https://wordpress.org/plugins/wordpress-seo/), check out the companion plugin here: https://github.com/Yoast/yoastseo-amp
|
575 |
|
576 |
Jetpack integration is baked in. More support for things like Related Posts to come.
|
577 |
|
578 |
+
### Parse.ly
|
579 |
+
|
580 |
+
[Parse.ly's WordPress plugin](https://wordpress.org/plugins/wp-parsely/) automatically tracks AMP pages when enabled along with this plugin.
|
581 |
+
|
582 |
+
|
583 |
### Yoast SEO
|
584 |
|
585 |
If you're using [Yoast SEO](https://wordpress.org/plugins/wordpress-seo/), check out the companion plugin here: https://github.com/Yoast/yoastseo-amp
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: batmoo, joen, automattic, potatomaster
|
|
3 |
Tags: amp, mobile
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 4.6
|
6 |
-
Stable tag: 0.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -25,20 +25,46 @@ Follow along with or contribute to the development of this plugin at https://git
|
|
25 |
|
26 |
1. Upload the folder to the `/wp-content/plugins/` directory
|
27 |
1. Activate the plugin through the 'Plugins' menu in WordPress
|
|
|
28 |
|
29 |
== Frequently Asked Questions ==
|
30 |
|
31 |
= How do I customize the AMP output for my site? =
|
32 |
|
33 |
-
You can
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
== Changelog ==
|
36 |
|
37 |
-
= 0.4 (
|
38 |
|
39 |
-
-
|
40 |
-
- Customizer
|
41 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
= 0.3.3 (Aug 18, 2016) =
|
44 |
|
@@ -100,6 +126,18 @@ You can find details about customization options at https://github.com/Automatti
|
|
100 |
|
101 |
== Upgrade Notice ==
|
102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
= 0.3.1 =
|
104 |
|
105 |
* Breaking change: `AMP_QUERY_VAR` is now defined right before `amp_init`.
|
3 |
Tags: amp, mobile
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 4.6
|
6 |
+
Stable tag: 0.4
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
25 |
|
26 |
1. Upload the folder to the `/wp-content/plugins/` directory
|
27 |
1. Activate the plugin through the 'Plugins' menu in WordPress
|
28 |
+
1. You may need to refresh your permalinks by going to `Settings > Permalinks` and tapping the `Save` button.
|
29 |
|
30 |
== Frequently Asked Questions ==
|
31 |
|
32 |
= How do I customize the AMP output for my site? =
|
33 |
|
34 |
+
You can tweak a few things like colours from the AMP Customizer. From the Dashboard, go to `Appearance > AMP`.
|
35 |
+
|
36 |
+
For deeper level customizations, please see the readme at https://github.com/Automattic/amp-wp/blob/master/readme.md
|
37 |
+
|
38 |
+
= What about ads and shortcodes and such? =
|
39 |
+
|
40 |
+
Check out https://github.com/Automattic/amp-wp/blob/master/readme.md#handling-media
|
41 |
+
|
42 |
+
= What about analytics? =
|
43 |
+
|
44 |
+
Many plugins are adding AMP support already. If you handling analytics yourself, please see https://github.com/Automattic/amp-wp/blob/master/readme.md#analytics
|
45 |
+
|
46 |
+
= Google Webmaster Tools is reporting validation errors for my site. How do I fix them? =
|
47 |
+
|
48 |
+
The best place to start is to open a new discussion in the [support forum](https://wordpress.org/support/plugin/amp) with details on what the specific validation error is.
|
49 |
+
|
50 |
+
= Why aren't Pages supported yet =
|
51 |
+
|
52 |
+
A wise green Yoda once said, "Patience you must have, my young padawan." We're working on it :)
|
53 |
|
54 |
== Changelog ==
|
55 |
|
56 |
+
= 0.4 (2016-10-06) =
|
57 |
|
58 |
+
- New template: spiffy, shiny, and has the fresh theme smell (props allancole and the Automattic Theme Team).
|
59 |
+
- AMP Customizer: Pick your colours and make the template your own (props DrewAPicture and 10up)
|
60 |
+
- Fix: support for inline styles (props coreymckrill).
|
61 |
+
- Fix: no more fatal errors when tags not supported by post type (props david-binda)
|
62 |
+
- Fix: no more unnecessary `<br>` tags.
|
63 |
+
- Fix: sanitize children of removed nodes (like empty `<a>` tags) (props Maxime2).
|
64 |
+
- Fix: no more broken YouTube URLs with multiple ?s.
|
65 |
+
- Fix: properly handle tel and sms schemes (h/t soundstrategies).
|
66 |
+
- Fix: remove amp endpoint on deactivate.
|
67 |
+
- New filter: `amp_pre_get_permalink` if you want a completely custom AMP permalink.
|
68 |
|
69 |
= 0.3.3 (Aug 18, 2016) =
|
70 |
|
126 |
|
127 |
== Upgrade Notice ==
|
128 |
|
129 |
+
= 0.4 =
|
130 |
+
|
131 |
+
* Breaking change: The new template has changes to markup, class names, and styles that may not work with existing customizations. If you want to stay on the old template for now, you can use the following code snippet:
|
132 |
+
|
133 |
+
```
|
134 |
+
if ( function_exists( 'amp_backcompat_use_v03_templates' ) ) {
|
135 |
+
amp_backcompat_use_v03_templates();
|
136 |
+
}
|
137 |
+
```
|
138 |
+
|
139 |
+
For more details, please see https://wordpress.org/support/topic/v0-4-whats-new-and-possible-breaking-changes/
|
140 |
+
|
141 |
= 0.3.1 =
|
142 |
|
143 |
* Breaking change: `AMP_QUERY_VAR` is now defined right before `amp_init`.
|
screenshot-1.png
CHANGED
Binary file
|
screenshot-2.png
CHANGED
Binary file
|
templates/featured-image.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$featured_image = $this->get( 'featured_image' );
|
3 |
+
|
4 |
+
if ( empty( $featured_image ) ) {
|
5 |
+
return;
|
6 |
+
}
|
7 |
+
|
8 |
+
$amp_html = $featured_image['amp_html'];
|
9 |
+
$caption = $featured_image['caption'];
|
10 |
+
?>
|
11 |
+
<figure class="amp-wp-article-featured-image wp-caption">
|
12 |
+
<?php echo $amp_html; // amphtml content; no kses ?>
|
13 |
+
<?php if ( $caption ) : ?>
|
14 |
+
<p class="wp-caption-text">
|
15 |
+
<?php echo wp_kses_data( $caption ); ?>
|
16 |
+
</p>
|
17 |
+
<?php endif; ?>
|
18 |
+
</figure>
|
templates/footer.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<footer class="amp-wp-footer">
|
2 |
+
<div>
|
3 |
+
<h2><?php echo esc_html( $this->get( 'blog_name' ) ); ?></h2>
|
4 |
+
<p>
|
5 |
+
<a href="<?php echo esc_url( __( 'https://wordpress.org/', 'amp' ) ); ?>"><?php printf( __( 'Powered by %s', 'amp' ), 'WordPress' ); ?></a>
|
6 |
+
</p>
|
7 |
+
<a href="#top" class="back-to-top"><?php _e( 'Back to top', 'amp' ); ?></a>
|
8 |
+
</div>
|
9 |
+
</footer>
|
templates/header-bar.php
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
<
|
2 |
<div>
|
3 |
<a href="<?php echo esc_url( $this->get( 'home_url' ) ); ?>">
|
4 |
-
<?php $site_icon_url = $this->get( 'site_icon_url' );
|
5 |
-
|
6 |
<amp-img src="<?php echo esc_url( $site_icon_url ); ?>" width="32" height="32" class="amp-wp-site-icon"></amp-img>
|
7 |
<?php endif; ?>
|
8 |
<?php echo esc_html( $this->get( 'blog_name' ) ); ?>
|
9 |
</a>
|
10 |
</div>
|
11 |
-
</
|
1 |
+
<header id="#top" class="amp-wp-header">
|
2 |
<div>
|
3 |
<a href="<?php echo esc_url( $this->get( 'home_url' ) ); ?>">
|
4 |
+
<?php $site_icon_url = $this->get( 'site_icon_url' );
|
5 |
+
if ( $site_icon_url ) : ?>
|
6 |
<amp-img src="<?php echo esc_url( $site_icon_url ); ?>" width="32" height="32" class="amp-wp-site-icon"></amp-img>
|
7 |
<?php endif; ?>
|
8 |
<?php echo esc_html( $this->get( 'blog_name' ) ); ?>
|
9 |
</a>
|
10 |
</div>
|
11 |
+
</header>
|
templates/meta-author.php
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
<?php $post_author = $this->get( 'post_author' ); ?>
|
2 |
-
|
3 |
-
<?php
|
4 |
-
<amp-
|
5 |
-
'
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
</
|
|
1 |
<?php $post_author = $this->get( 'post_author' ); ?>
|
2 |
+
<?php if ( $post_author ) : ?>
|
3 |
+
<?php $author_avatar_url = get_avatar_url( $post_author->user_email, array( 'size' => 24 ) ); ?>
|
4 |
+
<div class="amp-wp-meta amp-wp-byline">
|
5 |
+
<?php if ( function_exists( 'get_avatar_url' ) ) : ?>
|
6 |
+
<amp-img src="<?php echo esc_url( $author_avatar_url ); ?>" width="24" height="24" layout="fixed"></amp-img>
|
7 |
+
<?php endif; ?>
|
8 |
+
<span class="amp-wp-author author vcard"><?php echo esc_html( $post_author->display_name ); ?></span>
|
9 |
+
</div>
|
10 |
+
<?php endif; ?>
|
templates/meta-comments-link.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$comments_link_url = $this->get( 'comments_link_url' );
|
3 |
+
?>
|
4 |
+
<?php if ( $comments_link_url ) : ?>
|
5 |
+
<?php $comments_link_text = $this->get( 'comments_link_text' ); ?>
|
6 |
+
<div class="amp-wp-meta amp-wp-comments-link">
|
7 |
+
<a href="<?php echo esc_url( $comments_link_url ); ?>">
|
8 |
+
<?php echo esc_html( $comments_link_text ); ?>
|
9 |
+
</a>
|
10 |
+
</div>
|
11 |
+
<?php endif; ?>
|
templates/meta-taxonomy.php
CHANGED
@@ -1,15 +1,19 @@
|
|
1 |
-
<?php $categories = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ) ); ?>
|
2 |
<?php if ( $categories ) : ?>
|
3 |
-
<
|
4 |
-
|
5 |
-
|
6 |
-
</li>
|
7 |
<?php endif; ?>
|
8 |
|
9 |
-
<?php
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
15 |
<?php endif; ?>
|
1 |
+
<?php $categories = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ), '', $this->ID ); ?>
|
2 |
<?php if ( $categories ) : ?>
|
3 |
+
<div class="amp-wp-meta amp-wp-tax-category">
|
4 |
+
<?php printf( esc_html__( 'Categories: %s', 'amp' ), $categories ); ?>
|
5 |
+
</div>
|
|
|
6 |
<?php endif; ?>
|
7 |
|
8 |
+
<?php
|
9 |
+
$tags = get_the_tag_list(
|
10 |
+
'',
|
11 |
+
_x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ),
|
12 |
+
'',
|
13 |
+
$this->ID
|
14 |
+
); ?>
|
15 |
+
<?php if ( $tags && ! is_wp_error( $tags ) ) : ?>
|
16 |
+
<div class="amp-wp-meta amp-wp-tax-tag">
|
17 |
+
<?php printf( esc_html__( 'Tags: %s', 'amp' ), $tags ); ?>
|
18 |
+
</div>
|
19 |
<?php endif; ?>
|
templates/meta-time.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<
|
2 |
<time datetime="<?php echo esc_attr( date( 'c', $this->get( 'post_publish_timestamp' ) ) ); ?>">
|
3 |
<?php
|
4 |
echo esc_html(
|
@@ -9,4 +9,4 @@
|
|
9 |
);
|
10 |
?>
|
11 |
</time>
|
12 |
-
</
|
1 |
+
<div class="amp-wp-meta amp-wp-posted-on">
|
2 |
<time datetime="<?php echo esc_attr( date( 'c', $this->get( 'post_publish_timestamp' ) ) ); ?>">
|
3 |
<?php
|
4 |
echo esc_html(
|
9 |
);
|
10 |
?>
|
11 |
</time>
|
12 |
+
</div>
|
templates/single.php
CHANGED
@@ -1,24 +1,41 @@
|
|
1 |
<!doctype html>
|
2 |
-
<html amp
|
3 |
<head>
|
4 |
<meta charset="utf-8">
|
5 |
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
|
6 |
<?php do_action( 'amp_post_template_head', $this ); ?>
|
7 |
-
|
8 |
<style amp-custom>
|
9 |
-
|
10 |
-
|
11 |
</style>
|
12 |
</head>
|
13 |
-
|
|
|
|
|
14 |
<?php $this->load_parts( array( 'header-bar' ) ); ?>
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
<?php do_action( 'amp_post_template_footer', $this ); ?>
|
|
|
23 |
</body>
|
24 |
</html>
|
1 |
<!doctype html>
|
2 |
+
<html amp <?php language_attributes(); ?>>
|
3 |
<head>
|
4 |
<meta charset="utf-8">
|
5 |
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
|
6 |
<?php do_action( 'amp_post_template_head', $this ); ?>
|
|
|
7 |
<style amp-custom>
|
8 |
+
<?php $this->load_parts( array( 'style' ) ); ?>
|
9 |
+
<?php do_action( 'amp_post_template_css', $this ); ?>
|
10 |
</style>
|
11 |
</head>
|
12 |
+
|
13 |
+
<body class="<?php echo esc_attr( $this->get( 'body_class' ) ); ?>">
|
14 |
+
|
15 |
<?php $this->load_parts( array( 'header-bar' ) ); ?>
|
16 |
+
|
17 |
+
<article class="amp-wp-article">
|
18 |
+
|
19 |
+
<header class="amp-wp-article-header">
|
20 |
+
<h1 class="amp-wp-title"><?php echo wp_kses_data( $this->get( 'post_title' ) ); ?></h1>
|
21 |
+
<?php $this->load_parts( apply_filters( 'amp_post_article_header_meta', array( 'meta-author', 'meta-time' ) ) ); ?>
|
22 |
+
</header>
|
23 |
+
|
24 |
+
<?php $this->load_parts( array( 'featured-image' ) ); ?>
|
25 |
+
|
26 |
+
<div class="amp-wp-article-content">
|
27 |
+
<?php echo $this->get( 'post_amp_content' ); // amphtml content; no kses ?>
|
28 |
+
</div>
|
29 |
+
|
30 |
+
<footer class="amp-wp-article-footer">
|
31 |
+
<?php $this->load_parts( apply_filters( 'amp_post_article_footer_meta', array( 'meta-taxonomy', 'meta-comments-link' ) ) ); ?>
|
32 |
+
</footer>
|
33 |
+
|
34 |
+
</article>
|
35 |
+
|
36 |
+
<?php $this->load_parts( array( 'footer' ) ); ?>
|
37 |
+
|
38 |
<?php do_action( 'amp_post_template_footer', $this ); ?>
|
39 |
+
|
40 |
</body>
|
41 |
</html>
|
templates/style.php
CHANGED
@@ -1,58 +1,36 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
font-weight:400;
|
19 |
-
font-style:italic;
|
20 |
-
}
|
21 |
-
|
22 |
-
@font-face {
|
23 |
-
font-family:'Merriweather';
|
24 |
-
src:url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.woff2') format('woff2'),
|
25 |
-
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.woff') format('woff'),
|
26 |
-
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.ttf') format('truetype'),
|
27 |
-
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bold-webfont.svg#merriweatherbold') format('svg');
|
28 |
-
font-weight:700;
|
29 |
-
font-style:normal;
|
30 |
-
}
|
31 |
-
|
32 |
-
@font-face {
|
33 |
-
font-family:'Merriweather';
|
34 |
-
src:url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.woff2') format('woff2'),
|
35 |
-
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.woff') format('woff'),
|
36 |
-
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.ttf') format('truetype'),
|
37 |
-
url('https://s1.wp.com/i/fonts/merriweather/merriweather-bolditalic-webfont.svg#merriweatherbold_italic') format('svg');
|
38 |
-
font-weight:700;
|
39 |
-
font-style:italic;
|
40 |
}
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
amp-img.aligncenter { display: block; margin-left: auto; margin-right: auto; }
|
46 |
-
.alignright { float: right; }
|
47 |
-
.alignleft { float: left; }
|
48 |
-
.aligncenter { display: block; margin-left: auto; margin-right: auto; }
|
49 |
|
50 |
-
.
|
51 |
-
|
|
|
|
|
|
|
52 |
|
53 |
.amp-wp-enforced-sizes {
|
54 |
/** Our sizes fallback is 100vw, and we have a padding on the container; the max-width here prevents the element from overflowing. **/
|
55 |
max-width: 100%;
|
|
|
56 |
}
|
57 |
|
58 |
.amp-wp-unknown-size img {
|
@@ -62,175 +40,249 @@ amp-img.aligncenter { display: block; margin-left: auto; margin-right: auto; }
|
|
62 |
}
|
63 |
|
64 |
/* Template Styles */
|
65 |
-
|
66 |
-
|
|
|
67 |
<?php if ( $content_max_width > 0 ) : ?>
|
68 |
-
max-width: <?php echo sprintf( '%dpx', $content_max_width ); ?>;
|
69 |
margin: 0 auto;
|
|
|
70 |
<?php endif; ?>
|
71 |
}
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
font-size: 16px;
|
76 |
-
line-height: 1.8;
|
77 |
-
background: #fff;
|
78 |
-
color: #3d596d;
|
79 |
-
padding-bottom: 100px;
|
80 |
}
|
81 |
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
font-weight:
|
87 |
-
|
88 |
-
}
|
89 |
-
|
90 |
-
.amp-wp-title {
|
91 |
-
margin: 36px 0 0 0;
|
92 |
-
font-size: 36px;
|
93 |
-
line-height: 1.258;
|
94 |
-
font-weight: 700;
|
95 |
-
color: #2e4453;
|
96 |
-
}
|
97 |
-
|
98 |
-
.amp-wp-meta {
|
99 |
-
margin-bottom: 16px;
|
100 |
}
|
101 |
|
102 |
p,
|
103 |
ol,
|
104 |
ul,
|
105 |
figure {
|
106 |
-
margin: 0 0
|
|
|
107 |
}
|
108 |
|
109 |
a,
|
110 |
a:visited {
|
111 |
-
color:
|
112 |
}
|
113 |
|
114 |
a:hover,
|
115 |
a:active,
|
116 |
a:focus {
|
117 |
-
color:
|
118 |
}
|
119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
/* UI Fonts */
|
|
|
122 |
.amp-wp-meta,
|
123 |
-
|
124 |
-
.wp-
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif;
|
126 |
-
font-size: 15px;
|
127 |
}
|
128 |
|
|
|
129 |
|
130 |
-
|
131 |
-
|
132 |
-
padding: 24px 0 0 0;
|
133 |
-
margin: 0 0 24px 0;
|
134 |
}
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
max-width: 300px;
|
145 |
}
|
146 |
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
}
|
151 |
|
152 |
-
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
}
|
155 |
|
156 |
-
|
157 |
-
|
158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
}
|
160 |
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
169 |
|
170 |
.amp-wp-byline amp-img {
|
|
|
171 |
border-radius: 50%;
|
172 |
-
border: 0;
|
173 |
-
background: #f3f6f8;
|
174 |
position: relative;
|
175 |
-
top: 6px;
|
176 |
margin-right: 6px;
|
177 |
}
|
178 |
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
|
|
|
|
|
|
|
|
184 |
}
|
185 |
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
189 |
}
|
190 |
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
}
|
195 |
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
201 |
}
|
202 |
|
|
|
|
|
|
|
203 |
|
204 |
/* Captions */
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
}
|
209 |
|
|
|
|
|
|
|
210 |
|
211 |
-
|
212 |
-
|
213 |
-
padding: 16px;
|
214 |
-
margin: 8px 0 24px 0;
|
215 |
-
border-left: 2px solid #87a6bc;
|
216 |
-
color: #4f748e;
|
217 |
-
background: #e9eff3;
|
218 |
}
|
219 |
|
220 |
-
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
222 |
}
|
223 |
|
224 |
-
/*
|
|
|
225 |
amp-carousel {
|
226 |
-
background:
|
|
|
227 |
}
|
228 |
-
|
229 |
amp-iframe,
|
230 |
amp-youtube,
|
231 |
amp-instagram,
|
232 |
amp-vine {
|
233 |
-
background:
|
|
|
|
|
|
|
|
|
|
|
234 |
}
|
235 |
|
236 |
amp-carousel > amp-img > img {
|
@@ -238,7 +290,90 @@ amp-carousel > amp-img > img {
|
|
238 |
}
|
239 |
|
240 |
.amp-wp-iframe-placeholder {
|
241 |
-
background:
|
242 |
background-size: 48px 48px;
|
243 |
min-height: 48px;
|
244 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Get content width
|
3 |
+
$content_max_width = absint( $this->get( 'content_max_width' ) );
|
4 |
+
|
5 |
+
// Get template colors
|
6 |
+
$theme_color = $this->get_customizer_setting( 'theme_color' );
|
7 |
+
$text_color = $this->get_customizer_setting( 'text_color' );
|
8 |
+
$muted_text_color = $this->get_customizer_setting( 'muted_text_color' );
|
9 |
+
$border_color = $this->get_customizer_setting( 'border_color' );
|
10 |
+
$link_color = $this->get_customizer_setting( 'link_color' );
|
11 |
+
$header_background_color = $this->get_customizer_setting( 'header_background_color' );
|
12 |
+
$header_color = $this->get_customizer_setting( 'header_color' );
|
13 |
+
?>
|
14 |
+
/* Generic WP styling */
|
15 |
+
|
16 |
+
.alignright {
|
17 |
+
float: right;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
}
|
19 |
|
20 |
+
.alignleft {
|
21 |
+
float: left;
|
22 |
+
}
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
.aligncenter {
|
25 |
+
display: block;
|
26 |
+
margin-left: auto;
|
27 |
+
margin-right: auto;
|
28 |
+
}
|
29 |
|
30 |
.amp-wp-enforced-sizes {
|
31 |
/** Our sizes fallback is 100vw, and we have a padding on the container; the max-width here prevents the element from overflowing. **/
|
32 |
max-width: 100%;
|
33 |
+
margin: 0 auto;
|
34 |
}
|
35 |
|
36 |
.amp-wp-unknown-size img {
|
40 |
}
|
41 |
|
42 |
/* Template Styles */
|
43 |
+
|
44 |
+
.amp-wp-content,
|
45 |
+
.amp-wp-title-bar div {
|
46 |
<?php if ( $content_max_width > 0 ) : ?>
|
|
|
47 |
margin: 0 auto;
|
48 |
+
max-width: <?php echo sprintf( '%dpx', $content_max_width ); ?>;
|
49 |
<?php endif; ?>
|
50 |
}
|
51 |
|
52 |
+
html {
|
53 |
+
background: <?php echo sanitize_hex_color( $header_background_color ); ?>;
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
|
56 |
+
body {
|
57 |
+
background: <?php echo sanitize_hex_color( $theme_color ); ?>;
|
58 |
+
color: <?php echo sanitize_hex_color( $text_color ); ?>;
|
59 |
+
font-family: 'Merriweather', 'Times New Roman', Times, Serif;
|
60 |
+
font-weight: 300;
|
61 |
+
line-height: 1.75em;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
}
|
63 |
|
64 |
p,
|
65 |
ol,
|
66 |
ul,
|
67 |
figure {
|
68 |
+
margin: 0 0 1em;
|
69 |
+
padding: 0;
|
70 |
}
|
71 |
|
72 |
a,
|
73 |
a:visited {
|
74 |
+
color: <?php echo sanitize_hex_color( $link_color ); ?>;
|
75 |
}
|
76 |
|
77 |
a:hover,
|
78 |
a:active,
|
79 |
a:focus {
|
80 |
+
color: <?php echo sanitize_hex_color( $text_color ); ?>;
|
81 |
}
|
82 |
|
83 |
+
/* Quotes */
|
84 |
+
|
85 |
+
blockquote {
|
86 |
+
color: <?php echo sanitize_hex_color( $text_color ); ?>;
|
87 |
+
background: rgba(127,127,127,.125);
|
88 |
+
border-left: 2px solid <?php echo sanitize_hex_color( $link_color ); ?>;
|
89 |
+
margin: 8px 0 24px 0;
|
90 |
+
padding: 16px;
|
91 |
+
}
|
92 |
+
|
93 |
+
blockquote p:last-child {
|
94 |
+
margin-bottom: 0;
|
95 |
+
}
|
96 |
|
97 |
/* UI Fonts */
|
98 |
+
|
99 |
.amp-wp-meta,
|
100 |
+
.amp-wp-header div,
|
101 |
+
.amp-wp-title,
|
102 |
+
.wp-caption-text,
|
103 |
+
.amp-wp-tax-category,
|
104 |
+
.amp-wp-tax-tag,
|
105 |
+
.amp-wp-comments-link,
|
106 |
+
.amp-wp-footer p,
|
107 |
+
.back-to-top {
|
108 |
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif;
|
|
|
109 |
}
|
110 |
|
111 |
+
/* Header */
|
112 |
|
113 |
+
.amp-wp-header {
|
114 |
+
background-color: <?php echo sanitize_hex_color( $header_background_color ); ?>;
|
|
|
|
|
115 |
}
|
116 |
|
117 |
+
.amp-wp-header div {
|
118 |
+
color: <?php echo sanitize_hex_color( $header_color ); ?>;
|
119 |
+
font-size: 1em;
|
120 |
+
font-weight: 400;
|
121 |
+
margin: 0 auto;
|
122 |
+
max-width: calc(840px - 32px);
|
123 |
+
padding: .875em 16px;
|
124 |
+
position: relative;
|
|
|
125 |
}
|
126 |
|
127 |
+
.amp-wp-header a {
|
128 |
+
color: <?php echo sanitize_hex_color( $header_color ); ?>;
|
129 |
+
text-decoration: none;
|
130 |
}
|
131 |
|
132 |
+
/* Site Icon */
|
133 |
+
|
134 |
+
.amp-wp-header .amp-wp-site-icon {
|
135 |
+
/** site icon is 32px **/
|
136 |
+
background-color: <?php echo sanitize_hex_color( $header_color ); ?>;
|
137 |
+
border: 1px solid <?php echo sanitize_hex_color( $header_color ); ?>;
|
138 |
+
border-radius: 50%;
|
139 |
+
position: absolute;
|
140 |
+
right: 18px;
|
141 |
+
top: 10px;
|
142 |
}
|
143 |
|
144 |
+
/* Article */
|
145 |
+
|
146 |
+
.amp-wp-article {
|
147 |
+
color: <?php echo sanitize_hex_color( $text_color ); ?>;
|
148 |
+
font-weight: 400;
|
149 |
+
margin: 1.5em auto;
|
150 |
+
max-width: 840px;
|
151 |
+
overflow-wrap: break-word;
|
152 |
+
word-wrap: break-word;
|
153 |
}
|
154 |
|
155 |
+
/* Article Header */
|
156 |
+
|
157 |
+
.amp-wp-article-header {
|
158 |
+
align-items: center;
|
159 |
+
align-content: stretch;
|
160 |
+
display: flex;
|
161 |
+
flex-wrap: wrap;
|
162 |
+
justify-content: space-between;
|
163 |
+
margin: 1.5em 16px 1.5em;
|
164 |
+
}
|
165 |
+
|
166 |
+
.amp-wp-title {
|
167 |
+
color: <?php echo sanitize_hex_color( $text_color ); ?>;
|
168 |
+
display: block;
|
169 |
+
flex: 1 0 100%;
|
170 |
+
font-weight: 900;
|
171 |
+
margin: 0 0 .625em;
|
172 |
+
width: 100%;
|
173 |
+
}
|
174 |
+
|
175 |
+
/* Article Meta */
|
176 |
+
|
177 |
+
.amp-wp-meta {
|
178 |
+
color: <?php echo sanitize_hex_color( $muted_text_color ); ?>;
|
179 |
+
display: inline-block;
|
180 |
+
flex: 2 1 50%;
|
181 |
+
font-size: .875em;
|
182 |
+
line-height: 1.5em;
|
183 |
+
margin: 0;
|
184 |
+
padding: 0;
|
185 |
+
}
|
186 |
+
|
187 |
+
.amp-wp-article-header .amp-wp-meta:last-of-type {
|
188 |
+
text-align: right;
|
189 |
+
}
|
190 |
+
|
191 |
+
.amp-wp-article-header .amp-wp-meta:first-of-type {
|
192 |
+
text-align: left;
|
193 |
+
}
|
194 |
+
|
195 |
+
.amp-wp-byline amp-img,
|
196 |
+
.amp-wp-byline .amp-wp-author {
|
197 |
+
display: inline-block;
|
198 |
+
vertical-align: middle;
|
199 |
}
|
200 |
|
201 |
.amp-wp-byline amp-img {
|
202 |
+
border: 1px solid <?php echo sanitize_hex_color( $link_color ); ?>;
|
203 |
border-radius: 50%;
|
|
|
|
|
204 |
position: relative;
|
|
|
205 |
margin-right: 6px;
|
206 |
}
|
207 |
|
208 |
+
.amp-wp-posted-on {
|
209 |
+
text-align: right;
|
210 |
+
}
|
211 |
+
|
212 |
+
/* Featured image */
|
213 |
|
214 |
+
.amp-wp-article-featured-image {
|
215 |
+
margin: 0 0 1em;
|
216 |
+
}
|
217 |
+
.amp-wp-article-featured-image amp-img {
|
218 |
+
margin: 0 auto;
|
219 |
+
}
|
220 |
+
.amp-wp-article-featured-image.wp-caption .wp-caption-text {
|
221 |
+
margin: 0 18px;
|
222 |
}
|
223 |
|
224 |
+
/* Article Content */
|
225 |
+
|
226 |
+
.amp-wp-article-content {
|
227 |
+
margin: 0 16px;
|
228 |
}
|
229 |
|
230 |
+
.amp-wp-article-content ul,
|
231 |
+
.amp-wp-article-content ol {
|
232 |
+
margin-left: 1em;
|
233 |
}
|
234 |
|
235 |
+
.amp-wp-article-content amp-img {
|
236 |
+
margin: 0 auto;
|
237 |
+
}
|
238 |
+
|
239 |
+
.amp-wp-article-content amp-img.alignright {
|
240 |
+
margin: 0 0 1em 16px;
|
241 |
}
|
242 |
|
243 |
+
.amp-wp-article-content amp-img.alignleft {
|
244 |
+
margin: 0 16px 1em 0;
|
245 |
+
}
|
246 |
|
247 |
/* Captions */
|
248 |
+
|
249 |
+
.wp-caption {
|
250 |
+
padding: 0;
|
251 |
}
|
252 |
|
253 |
+
.wp-caption.alignleft {
|
254 |
+
margin-right: 16px;
|
255 |
+
}
|
256 |
|
257 |
+
.wp-caption.alignright {
|
258 |
+
margin-left: 16px;
|
|
|
|
|
|
|
|
|
|
|
259 |
}
|
260 |
|
261 |
+
.wp-caption .wp-caption-text {
|
262 |
+
border-bottom: 1px solid <?php echo sanitize_hex_color( $border_color ); ?>;
|
263 |
+
color: <?php echo sanitize_hex_color( $muted_text_color ); ?>;
|
264 |
+
font-size: .875em;
|
265 |
+
line-height: 1.5em;
|
266 |
+
margin: 0;
|
267 |
+
padding: .66em 10px .75em;
|
268 |
}
|
269 |
|
270 |
+
/* AMP Media */
|
271 |
+
|
272 |
amp-carousel {
|
273 |
+
background: <?php echo sanitize_hex_color( $border_color ); ?>;
|
274 |
+
margin: 0 -16px 1.5em;
|
275 |
}
|
|
|
276 |
amp-iframe,
|
277 |
amp-youtube,
|
278 |
amp-instagram,
|
279 |
amp-vine {
|
280 |
+
background: <?php echo sanitize_hex_color( $border_color ); ?>;
|
281 |
+
margin: 0 -16px 1.5em;
|
282 |
+
}
|
283 |
+
|
284 |
+
.amp-wp-article-content amp-carousel amp-img {
|
285 |
+
border: none;
|
286 |
}
|
287 |
|
288 |
amp-carousel > amp-img > img {
|
290 |
}
|
291 |
|
292 |
.amp-wp-iframe-placeholder {
|
293 |
+
background: <?php echo sanitize_hex_color( $border_color ); ?> url( <?php echo esc_url( $this->get( 'placeholder_image_url' ) ); ?> ) no-repeat center 40%;
|
294 |
background-size: 48px 48px;
|
295 |
min-height: 48px;
|
296 |
}
|
297 |
+
|
298 |
+
/* Article Footer Meta */
|
299 |
+
|
300 |
+
.amp-wp-article-footer .amp-wp-meta {
|
301 |
+
display: block;
|
302 |
+
}
|
303 |
+
|
304 |
+
.amp-wp-tax-category,
|
305 |
+
.amp-wp-tax-tag {
|
306 |
+
color: <?php echo sanitize_hex_color( $muted_text_color ); ?>;
|
307 |
+
font-size: .875em;
|
308 |
+
line-height: 1.5em;
|
309 |
+
margin: 1.5em 16px;
|
310 |
+
}
|
311 |
+
|
312 |
+
.amp-wp-comments-link {
|
313 |
+
color: <?php echo sanitize_hex_color( $muted_text_color ); ?>;
|
314 |
+
font-size: .875em;
|
315 |
+
line-height: 1.5em;
|
316 |
+
text-align: center;
|
317 |
+
margin: 2.25em 0 1.5em;
|
318 |
+
}
|
319 |
+
|
320 |
+
.amp-wp-comments-link a {
|
321 |
+
border-style: solid;
|
322 |
+
border-color: <?php echo sanitize_hex_color( $border_color ); ?>;
|
323 |
+
border-width: 1px 1px 2px;
|
324 |
+
border-radius: 4px;
|
325 |
+
background-color: transparent;
|
326 |
+
color: <?php echo sanitize_hex_color( $link_color ); ?>;
|
327 |
+
cursor: pointer;
|
328 |
+
display: block;
|
329 |
+
font-size: 14px;
|
330 |
+
font-weight: 600;
|
331 |
+
line-height: 18px;
|
332 |
+
margin: 0 auto;
|
333 |
+
max-width: 200px;
|
334 |
+
padding: 11px 16px;
|
335 |
+
text-decoration: none;
|
336 |
+
width: 50%;
|
337 |
+
-webkit-transition: background-color 0.2s ease;
|
338 |
+
transition: background-color 0.2s ease;
|
339 |
+
}
|
340 |
+
|
341 |
+
/* AMP Footer */
|
342 |
+
|
343 |
+
.amp-wp-footer {
|
344 |
+
border-top: 1px solid <?php echo sanitize_hex_color( $border_color ); ?>;
|
345 |
+
margin: calc(1.5em - 1px) 0 0;
|
346 |
+
}
|
347 |
+
|
348 |
+
.amp-wp-footer div {
|
349 |
+
margin: 0 auto;
|
350 |
+
max-width: calc(840px - 32px);
|
351 |
+
padding: 1.25em 16px 1.25em;
|
352 |
+
position: relative;
|
353 |
+
}
|
354 |
+
|
355 |
+
.amp-wp-footer h2 {
|
356 |
+
font-size: 1em;
|
357 |
+
line-height: 1.375em;
|
358 |
+
margin: 0 0 .5em;
|
359 |
+
}
|
360 |
+
|
361 |
+
.amp-wp-footer p {
|
362 |
+
color: <?php echo sanitize_hex_color( $muted_text_color ); ?>;
|
363 |
+
font-size: .8em;
|
364 |
+
line-height: 1.5em;
|
365 |
+
margin: 0 85px 0 0;
|
366 |
+
}
|
367 |
+
|
368 |
+
.amp-wp-footer a {
|
369 |
+
text-decoration: none;
|
370 |
+
}
|
371 |
+
|
372 |
+
.back-to-top {
|
373 |
+
bottom: 1.275em;
|
374 |
+
font-size: .8em;
|
375 |
+
font-weight: 600;
|
376 |
+
line-height: 2em;
|
377 |
+
position: absolute;
|
378 |
+
right: 16px;
|
379 |
+
}
|