Skip to content

Instantly share code, notes, and snippets.

@joemaller
Last active December 1, 2020 17:29
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 joemaller/06bd67b8386711ee2e783e0840286e68 to your computer and use it in GitHub Desktop.
Save joemaller/06bd67b8386711ee2e783e0840286e68 to your computer and use it in GitHub Desktop.
A class for creating a WordPress rewrite rule to serve a stylesheet from a persistent top-level url
<?php
namespace IdeasOnPurpose;
/**
* This class created a nice little persistent endpoint for an
* externally referenced stylesheet. This was necessary because
* our themes are versioned with each release living in a different-
* named directory. All assets are also generated by Webpack and
* have hashed filenames.
*
* Two filter-functions are included for removing the trailing slash
* from requests so the content is served at /wufoo.css and not
* /wufoo.css/
*
* This was substantially pared back because WP Engine intercepts
* all requests for *.css files, so the rewrite rule never got to
* WordPress.
*/
class WufooEndpoint
{
public function __construct()
{
if ($this->manifest()) {
add_action('init', [$this, 'register']);
add_filter('query_vars', [$this, 'var']);
add_filter('template_redirect', [$this, 'slashRedirect']);
add_filter('redirect_canonical', [$this, 'noSlash']);
add_filter('template_include', [$this, 'styles']);
}
}
/**
* Checks that there's a wufoo stylesheet in the dependency manifest
* and return that value if found.
*/
public function manifest()
{
$manifest_file = get_template_directory() . '/dist/dependency-manifest.json';
$manifest = json_decode(file_get_contents($manifest_file), true);
$this->stylesheet = false;
// TODO: This will be problematic if there's more than one CSS file.
foreach ($manifest['wufoo']['files'] as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'css') {
$this->stylesheet = $file;
}
}
return $this->stylesheet;
}
/**
* Register the rewrite rule
*/
public function register()
{
add_rewrite_rule('wufoo\.css/?$', 'index.php?wufoo_styles=true', 'top');
}
/**
* Register the wufoo_styles query_var
*/
public function var($vars)
{
$vars[] = 'wufoo_styles';
return $vars;
}
/**
* Redirect requests for /wufoo.css/ to a slash-free url instead
*/
public function slashRedirect()
{
if (preg_match('%wufoo\.css/$%', $_SERVER['REQUEST_URI'])) {
wp_redirect(home_url('wufoo.css', 'relative'), 301);
exit();
}
}
/**
* Don't add a trailing slash to /wufoo.css requests
* Without this, $this->slashRedirect will cause a redirect loop
*/
public function noSlash($url)
{
return preg_replace('%wufoo\.css/?$%', 'wufoo.css', $url);
}
/**
* Returns a CSS Content-type header and the stylesheet when the wufoo_styles query_var is set
*/
public function styles($template)
{
if (get_query_var('wufoo_styles')) {
header('Content-type: text/css', true);
return ABSPATH . $this->stylesheet;
}
return $template;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment