Last active
May 27, 2020 21:04
-
-
Save westonruter/08bea805f2a31e7934dfeeb4e36bb662 to your computer and use it in GitHub Desktop.
WordPress plugin to add AMP compatibility to the Lovecraft theme by Anders Norén. For use with the official AMP plugin in Standard or Transitional template modes: https://wordpress.org/plugins/amp/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* AMP Lovecraft Theme Compat plugin bootstrap. | |
* | |
* @package Google\AMP_Lovecraft_Theme_Compat | |
* @author Weston Ruter, Google | |
* @license GPL-2.0-or-later | |
* @copyright 2020 Google Inc. | |
* | |
* @wordpress-plugin | |
* Plugin Name: AMP Lovecraft Theme Compat | |
* Plugin URI: https://gist.github.com/westonruter/08bea805f2a31e7934dfeeb4e36bb662 | |
* Description: Plugin to add <a href="https://wordpress.org/plugins/amp/">AMP plugin</a> compatibility to the <a href="https://wordpress.org/themes/lovecraft/">Lovecraft</a> theme by Anders Norén. | |
* Version: 0.2 | |
* Author: Weston Ruter, Google | |
* Author URI: https://weston.ruter.net/ | |
* License: GNU General Public License v2 (or later) | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
* Gist Plugin URI: https://gist.github.com/westonruter/08bea805f2a31e7934dfeeb4e36bb662 | |
*/ | |
namespace Google\AMP_Lovecraft_Theme_Compat; | |
/** | |
* Whether the page is AMP. | |
* | |
* @return bool Is AMP. | |
*/ | |
function is_amp() { | |
return function_exists( 'is_amp_endpoint' ) && is_amp_endpoint(); | |
} | |
/** | |
* Remove JS that replaces no-js with js class. | |
* | |
* @see \lovecraft_html_js_class() | |
*/ | |
function add_hooks() { | |
if ( 'lovecraft' === get_template() && is_amp() ) { | |
remove_action( 'wp_head', 'lovecraft_html_js_class', 1 ); | |
add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\override_scripts_and_styles', 11 ); | |
add_filter( 'amp_content_sanitizers', __NAMESPACE__ . '\filter_sanitizers' ); | |
} | |
} | |
add_action( 'wp', __NAMESPACE__ . '\add_hooks' ); | |
/** | |
* Remove enqueued JS. | |
* | |
* @see lovecraft_load_javascript_files() | |
*/ | |
function override_scripts_and_styles() { | |
wp_dequeue_script( 'lovecraft_global' ); | |
wp_add_inline_style( 'lovecraft_style', file_get_contents( __DIR__ . '/style.css' ) ); | |
} | |
/** | |
* Add sanitizer to fix up the markup. | |
* | |
* @param array $sanitizers Sanitizers. | |
* @return array Sanitizers. | |
*/ | |
function filter_sanitizers( $sanitizers ) { | |
require_once __DIR__ . '/class-sanitizer.php'; | |
$sanitizers[ __NAMESPACE__ . '\Sanitizer' ] = []; | |
return $sanitizers; | |
} | |
/** | |
* Bonus improvement: add font-display:swap to the Google Fonts! | |
* | |
* @param string $src Stylesheet URL. | |
* @param string $handle Style handle. | |
* @return string Filtered stylesheet URL. | |
*/ | |
function filter_font_style_loader_src( $src, $handle ) { | |
if ( 'lovecraft_googlefonts' === $handle ) { | |
$src = add_query_arg( 'display', 'swap', $src ); | |
} | |
return $src; | |
} | |
add_filter( 'style_loader_src', __NAMESPACE__ . '\filter_font_style_loader_src', 10, 2 ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Sanitizer | |
* | |
* @package Google\AMP_Lovecraft_Theme_Compat | |
*/ | |
namespace Google\AMP_Lovecraft_Theme_Compat; | |
use AMP_Base_Sanitizer; | |
use DOMElement; | |
use DOMXPath; | |
/** | |
* Class Sanitizer | |
*/ | |
class Sanitizer extends AMP_Base_Sanitizer { | |
/** | |
* Sanitize. | |
*/ | |
public function sanitize() { | |
$xpath = new DOMXPath( $this->dom ); | |
// Set up mobile nav menu. | |
$menu_toggle = $xpath->query( '//button[ @class = "nav-toggle toggle" ]' )->item( 0 ); | |
$mobile_menu = $xpath->query( '//ul[ @class = "mobile-menu" ]' )->item( 0 ); | |
if ( $menu_toggle instanceof DOMElement && $mobile_menu instanceof DOMElement ) { | |
$menu_toggle->parentNode->insertBefore( | |
$this->create_amp_state( 'mobileMenuActive', false ), | |
$menu_toggle | |
); | |
$menu_toggle->setAttribute( 'on', 'tap:AMP.setState( { mobileMenuActive: ! mobileMenuActive, searchActive: false } )' ); | |
$menu_toggle->setAttribute( | |
'data-amp-bind-class', | |
sprintf( '%s + ( mobileMenuActive ? " active" : "" )', wp_json_encode( $menu_toggle->getAttribute( 'class' ) ) ) | |
); | |
$mobile_menu->setAttribute( | |
'data-amp-bind-class', | |
sprintf( '%s + ( mobileMenuActive ? " expanded" : "" )', wp_json_encode( $mobile_menu->getAttribute( 'class' ) ) ) | |
); | |
} | |
// Set up mobile search. | |
$search_toggle = $xpath->query( '//button[ @class = "search-toggle toggle" ]' )->item( 0 ); | |
$mobile_search = $xpath->query( '//div[ @class = "mobile-search" ]' )->item( 0 ); | |
if ( $search_toggle instanceof DOMElement && $mobile_search instanceof DOMElement ) { | |
$search_toggle->parentNode->insertBefore( | |
$this->create_amp_state( 'searchActive', false ), | |
$search_toggle | |
); | |
$search_toggle->setAttribute( 'on', 'tap:AMP.setState( { searchActive: ! searchActive, mobileMenuActive: false } )' ); | |
$search_toggle->setAttribute( | |
'data-amp-bind-class', | |
sprintf( '%s + ( searchActive ? " active" : "" )', wp_json_encode( $search_toggle->getAttribute( 'class' ) ) ) | |
); | |
$mobile_search->setAttribute( | |
'data-amp-bind-class', | |
sprintf( '%s + ( searchActive ? " expanded" : "" )', wp_json_encode( $mobile_search->getAttribute( 'class' ) ) ) | |
); | |
} | |
} | |
/** | |
* Create AMP state. | |
* | |
* @param string $id State ID. | |
* @param mixed $value State value. | |
* @return DOMElement An amp-state element. | |
*/ | |
private function create_amp_state( $id, $value ) { | |
$amp_state = $this->dom->createElement( 'amp-state' ); | |
$amp_state->setAttribute( 'id', $id ); | |
$script = $this->dom->createElement( 'script' ); | |
$script->setAttribute( 'type', 'application/json' ); | |
$script->appendChild( $this->dom->createTextNode( wp_json_encode( $value ) ) ); | |
return $amp_state; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.mobile-menu.expanded, | |
.mobile-search.expanded { | |
display: block; | |
} | |
/* Remove the down arrow that was part of the link */ | |
.main-menu > .menu-item-has-children > a::after { | |
display: none; | |
} | |
/* And instead put it as part of the list item so that it can be tapped */ | |
.main-menu > .menu-item-has-children::after { | |
content: ""; | |
display: block; | |
border: 5px solid transparent; | |
border-top-color: #ca2017; | |
position: absolute; | |
z-index: 1001; | |
right: 0; | |
top: 50%; | |
margin-top: -2px; | |
} | |
.main-menu > li:focus-within > ul { | |
opacity: 1; | |
left: 50%; | |
margin-left: -120px; | |
top: 47px; | |
} | |
.main-menu li > ul > li:focus-within > ul { | |
opacity: 1; | |
top: 0; | |
left: 240px; | |
margin-left: 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Installation instructions: https://gist.github.com/westonruter/6110fbc4bef0c4b8c021a112012f7e9c