Skip to content

Instantly share code, notes, and snippets.

@westonruter
Last active May 27, 2022 11:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westonruter/900611f075374c5468ea492f23ad4810 to your computer and use it in GitHub Desktop.
Save westonruter/900611f075374c5468ea492f23ad4810 to your computer and use it in GitHub Desktop.
<?php
/**
* Offline template.
*
* @package PWA_Offline_Template
*/
namespace PWA_Offline_Template;
?>
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="profile" href="https://gmpg.org/xfn/11" />
<style>
body {
font-family: sans-serif;
text-align: center;
}
img {
border-radius: 50%;
}
</style>
</head>
<body <?php body_class(); ?>>
<h1><?php esc_html_e( 'Oops! It looks like you&#8217;re offline.', 'pwa' ); ?></h1>
<?php wp_service_worker_error_message_placeholder(); ?>
<p>
<img src="<?php echo esc_url( get_offline_image_url() ); ?>" width="500" height="667" alt="Weston Ruter and Downasaur">
</p>
</body>
</html>
<?php
/**
* Plugin Name: PWA Offline Template
*
* @package PWA_Offline_Template
* @author Weston Ruter, Google
* @license GPL-2.0-or-later
* @copyright 2019 Google Inc.
*
* @wordpress-plugin
* Plugin Name: PWA Offline Template
* Description: Demonstration of how to supply an offline.php template from a plugin. This template is then used by the PWA plugin to serve to users via the service worker when they are offline.
* Plugin URI: https://gist.github.com/westonruter/900611f075374c5468ea492f23ad4810
* Version: 0.1.0
* 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
*/
namespace PWA_Offline_Template;
const OFFLINE_IMAGE_FILENAME = 'downasaur.jpg';
add_filter( 'wp_offline_error_precache_entry', __NAMESPACE__ . '\filter_offline_error_precache_entry' );
add_filter( 'template_include', __NAMESPACE__ . '\filter_template_include_to_override_offline_template', 20 );
add_action( 'wp_front_service_worker', __NAMESPACE__ . '\precache_offline_template_assets' );
/**
* Locate offline template.
*
* @return string
*/
function locate_offline_template_path() {
return __DIR__ . '/offline.php';
}
/**
* Get offline image URL.
*
* @return string
*/
function get_offline_image_url() {
return plugin_dir_url( __FILE__ ) . OFFLINE_IMAGE_FILENAME;
}
/**
* Get the modified time for the offline image.
*
* @return int Modified time.
*/
function get_offline_image_filemtime() {
return filemtime( __DIR__ . '/' . OFFLINE_IMAGE_FILENAME );
}
/**
* Filter the offline error precache entry to ensure revision is bumped when changes are made to the template or its assets.
*
* @param array $entry Entry.
* @return array Entry.
*/
function filter_offline_error_precache_entry( $entry ) {
$entry['revision'] .= ';' . filemtime( locate_offline_template_path() );
$entry['revision'] .= ';' . get_offline_image_url();
return $entry;
}
/**
* Precache assets that are used on the offline template so they are available.
*
* @param \WP_Service_Worker_Scripts $scripts Scripts.
*/
function precache_offline_template_assets( \WP_Service_Worker_Scripts $scripts ) {
$scripts->precaching_routes()->register(
get_offline_image_url(),
array(
'revision' => get_offline_image_filemtime(),
)
);
}
/**
* Filter the template include file to override the offline template.
*
* @param string $include Template include file.
* @return string Filtered template include file.
*/
function filter_template_include_to_override_offline_template( $include ) {
if ( function_exists( 'is_offline' ) && \is_offline() ) {
$include = locate_offline_template_path();
}
return $include;
}
Copy link

ghost commented Feb 20, 2022

@westonruter Placeholder comment inserted by wp_service_worker_error_message_placeholder() get stripped by AMP plugin. Can you please suggest a solution?

@westonruter
Copy link
Author

@stack-exchange Thanks for pointing this out. The quickest solution would be to disable the removal of HTML comments in the Optimizer. This can be done with the following WP PHP plugin code:

add_filter( 'amp_optimizer_config', static function ( $config ) {
	$config['transformers'] = array_diff(
		$config['transformers'],
		[
			\AmpProject\Optimizer\Transformer\MinifyHtml::class,
		]
	);
	return $config;
} );

Or better, to just disable on the offline/500 templates:

add_action(
	'wp',
	static function () {
		if (
			( function_exists( 'is_offline' ) && is_offline() )
			||
			( function_exists( 'is_500' ) && is_500() )
		) {
			add_filter( 'amp_optimizer_config', static function ( $config ) {
				$config['transformers'] = array_diff(
					$config['transformers'],
					[
						\AmpProject\Optimizer\Transformer\MinifyHtml::class,
					]
				);
				return $config;
			} );
		}
	}
);

The better fix would be fore the PWA plugin to output a different token than an HTML comment. I've filed GoogleChromeLabs/pwa-wp#709 for that.

@thelovekesh
Copy link

@westonruter One more idea come up in my mind. What if we disable amp_enable_optimizer at the starting of offline.php template.
Something like this.

<?php
/**
 * Offline template.
 *
 * @package PWA_Offline_Template
 */

if ( function_exists( 'amp_is_request' ) && amp_is_request() ) {
	add_filter( 'amp_enable_optimizer', '__return_false' );
}

...

Let me know your thoughts on it.

@westonruter
Copy link
Author

@thelovekesh That may work, but it would be overkill. The Optimizer has many transformers that are critical to having good performance. In particular, for the offline context it will inline the AMP runtime CSS so that you won't need it cache by the service worker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment