Skip to content

Soil

Version 4.1.1 • Updated August 1st, 2022

Soil is no longer in active development — see our announcement for Acorn Prettify

A WordPress plugin which contains a collection of modules to apply theme-agnostic front-end modifications.

<?php

add_action('after_setup_theme', function () {
    /**
     * Enable features from the Soil plugin if activated.
     */
    add_theme_support('soil', [
        'clean-up', // Cleaner WordPress markup
        'disable-rest-api', // Disable REST API
        'disable-asset-versioning', // Remove asset versioning
        'disable-trackbacks', // Disable trackbacks
        'google-analytics' => 'UA-XXXXX-Y', // Google Analytics
        'js-to-footer', // Move JS to footer
        'nav-walker', // Clean up nav menu markup
        'nice-search', // Redirect /?s=query to /search/query
        'relative-urls', // Convert absolute URLs to relative URLs
    ]);
});

Soil is compatible with all WordPress themes and plugins and doesn’t have any requirements

You don’t need to use any other Roots projects to use the features from Soil.

Features

Cleaner WordPress markup

  • Clean up wp_head()
    • Remove unnecessary <link> ’s
    • Remove inline CSS and JS from WP emoji support
    • Remove inline CSS used by Recent Comments widget
    • Remove inline CSS used by posts with galleries
  • Remove the WordPress version from RSS feeds
  • Clean up language_attributes() used in <html> tag
  • Clean up output of stylesheet <link> tags, remove unncessary type='text/css' , only display media if it is meaningful
  • Clean up output of <script> tags, remove unnecessary type='text=javascript'
  • Add and remove body_class() classes
    • Add post/page slug if not present and template slug
    • Remove unnecessary classes
  • Remove unnecessary self-closing tags (/> )
  • Don’t return the default description in the RSS feed ("Just another WordPress site")

Soil’s clean up reduces the amount of front-end requests on your site:

WordPress 5.5, Twenty Twenty theme with Soil activated

Requests Total Page Size
9 272 KB

WordPress 5.5, Twenty Twenty theme without Soil

Requests Total Page Size
12 288 KB

Cleaner walker for navigation menus

Walker_Nav_Menu (WordPress default) example output:

<li id="menu-item-8" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-8"><a href="/">Home</a></li>
<li id="menu-item-9" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-9"><a href="/sample-page/">Sample Page</a></li>

Soil’s NavWalker example output:

<li class="menu-home"><a href="/">Home</a></li>
<li class="menu-sample-page"><a href="/sample-page/">Sample Page</a></li>

Nice search

Redirect search results from /?s=query to /search/query/ .

Root relative URLs

Replace many of the absolute URLs that WordPress outputs with root relative URLs.

Google Analytics

Lightweight method of adding support for HTML5 Boilerplate’s Google Analytics snippet to your site.

Move all JS to the footer

Force all WordPress enqueued JavaScript to the footer.

Disable trackbacks

Globally disable trackbacks and pingbacks.

Disable asset versioning

Remove the version query string from all styles and scripts.

WordPress markup with Soil’s clean up module

<!DOCTYPE html>
<html class="no-js" lang="en-US">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" >
    <link rel="profile" href="https://gmpg.org/xfn/11">
    <title>Site Name &#8211; Just another WordPress site</title>
    <link rel="alternate" type="application/rss+xml" title="Site Name &raquo; Feed" href="http://example.test/feed/" />
    <link rel="stylesheet" href="//cdn.roots.io/wp/wp-content/themes/twentytwenty/style.css">
    <style id='twentytwenty-style-inline-css'>
      .color-accent,.color-accent-hover:hover,.color-accent-hover:focus,:root .has-accent-color,.has-drop-cap:not(:focus):first-letter,.wp-block-button.is-style-outline,a { color: #cd2653; }blockquote,.border-color-accent,.border-color-accent-hover:hover,.border-color-accent-hover:focus { border-color: #cd2653; }button:not(.toggle),.button,.faux-button,.wp-block-button__link,.wp-block-file .wp-block-file__button,input[type="button"],input[type="reset"],input[type="submit"],.bg-accent,.bg-accent-hover:hover,.bg-accent-hover:focus,:root .has-accent-background-color,.comment-reply-link { background-color: #cd2653; }.fill-children-accent,.fill-children-accent * { fill: #cd2653; }body,.entry-title a,:root .has-primary-color { color: #000000; }:root .has-primary-background-color { background-color: #000000; }cite,figcaption,.wp-caption-text,.post-meta,.entry-content .wp-block-archives li,.entry-content .wp-block-categories li,.entry-content .wp-block-latest-posts li,.wp-block-latest-comments__comment-date,.wp-block-latest-posts__post-date,.wp-block-embed figcaption,.wp-block-image figcaption,.wp-block-pullquote cite,.comment-metadata,.comment-respond .comment-notes,.comment-respond .logged-in-as,.pagination .dots,.entry-content hr:not(.has-background),hr.styled-separator,:root .has-secondary-color { color: #6d6d6d; }:root .has-secondary-background-color { background-color: #6d6d6d; }pre,fieldset,input,textarea,table,table *,hr { border-color: #dcd7ca; }caption,code,code,kbd,samp,.wp-block-table.is-style-stripes tbody tr:nth-child(odd),:root .has-subtle-background-background-color { background-color: #dcd7ca; }.wp-block-table.is-style-stripes { border-bottom-color: #dcd7ca; }.wp-block-latest-posts.is-grid li { border-top-color: #dcd7ca; }:root .has-subtle-background-color { color: #dcd7ca; }body:not(.overlay-header) .primary-menu > li > a,body:not(.overlay-header) .primary-menu > li > .icon,.modal-menu a,.footer-menu a, .footer-widgets a,#site-footer .wp-block-button.is-style-outline,.wp-block-pullquote:before,.singular:not(.overlay-header) .entry-header a,.archive-header a,.header-footer-group .color-accent,.header-footer-group .color-accent-hover:hover { color: #cd2653; }.social-icons a,#site-footer button:not(.toggle),#site-footer .button,#site-footer .faux-button,#site-footer .wp-block-button__link,#site-footer .wp-block-file__button,#site-footer input[type="button"],#site-footer input[type="reset"],#site-footer input[type="submit"] { background-color: #cd2653; }.header-footer-group,body:not(.overlay-header) #site-header .toggle,.menu-modal .toggle { color: #000000; }body:not(.overlay-header) .primary-menu ul { background-color: #000000; }body:not(.overlay-header) .primary-menu > li > ul:after { border-bottom-color: #000000; }body:not(.overlay-header) .primary-menu ul ul:after { border-left-color: #000000; }.site-description,body:not(.overlay-header) .toggle-inner .toggle-text,.widget .post-date,.widget .rss-date,.widget_archive li,.widget_categories li,.widget cite,.widget_pages li,.widget_meta li,.widget_nav_menu li,.powered-by-wordpress,.to-the-top,.singular .entry-header .post-meta,.singular:not(.overlay-header) .entry-header .post-meta a { color: #6d6d6d; }.header-footer-group pre,.header-footer-group fieldset,.header-footer-group input,.header-footer-group textarea,.header-footer-group table,.header-footer-group table *,.footer-nav-widgets-wrapper,#site-footer,.menu-modal nav *,.footer-widgets-outer-wrapper,.footer-top { border-color: #dcd7ca; }.header-footer-group table caption,body:not(.overlay-header) .header-inner .toggle-wrapper::before { background-color: #dcd7ca; }
    </style>
    <link rel="stylesheet" href="//cdn.roots.io/wp/wp-content/themes/twentytwenty/print.css" media="print">
    <link rel="canonical" href="http://example.test/" />
    <script>document.documentElement.className = document.documentElement.className.replace( 'no-js', 'js' );</script>
    <style id="custom-background-css">
      body.custom-background { background-color: #fff; }
    </style>
  </head>
  <body class="home page custom-background wp-embed-responsive singular enable-search-modal missing-post-thumbnail has-no-pagination not-showing-comments show-avatars footer-top-visible">

Default WordPress markup without Soil

<!DOCTYPE html>
<html class="no-js" lang="en-US">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" >
    <link rel="profile" href="https://gmpg.org/xfn/11">
    <title>Site Name &#8211; Just another WordPress site</title>
    <link rel='dns-prefetch' href='//s.w.org' />
    <link rel="alternate" type="application/rss+xml" title="Site Name &raquo; Feed" href="http://example.test/feed/" />
    <link rel="alternate" type="application/rss+xml" title="Site Name &raquo; Comments Feed" href="http://example.test/comments/feed/" />
    <script>
      window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/13.0.0\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/13.0.0\/svg\/","svgExt":".svg","source":{"concatemoji":"http:\/\/example.test\/wp\/wp-includes\/js\/wp-emoji-release.min.js?ver=5.5"}};
      !function(e,a,t){var r,n,o,i,p=a.createElement("canvas"),s=p.getContext&&p.getContext("2d");function c(e,t){var a=String.fromCharCode;s.clearRect(0,0,p.width,p.height),s.fillText(a.apply(this,e),0,0);var r=p.toDataURL();return s.clearRect(0,0,p.width,p.height),s.fillText(a.apply(this,t),0,0),r===p.toDataURL()}function l(e){if(!s||!s.fillText)return!1;switch(s.textBaseline="top",s.font="600 32px Arial",e){case"flag":return!c([127987,65039,8205,9895,65039],[127987,65039,8203,9895,65039])&&(!c([55356,56826,55356,56819],[55356,56826,8203,55356,56819])&&!c([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]));case"emoji":return!c([55357,56424,8205,55356,57212],[55357,56424,8203,55356,57212])}return!1}function d(e){var t=a.createElement("script");t.src=e,t.defer=t.type="text/javascript",a.getElementsByTagName("head")[0].appendChild(t)}for(i=Array("flag","emoji"),t.supports={everything:!0,everythingExceptFlag:!0},o=0;o<i.length;o++)t.supports[i[o]]=l(i[o]),t.supports.everything=t.supports.everything&&t.supports[i[o]],"flag"!==i[o]&&(t.supports.everythingExceptFlag=t.supports.everythingExceptFlag&&t.supports[i[o]]);t.supports.everythingExceptFlag=t.supports.everythingExceptFlag&&!t.supports.flag,t.DOMReady=!1,t.readyCallback=function(){t.DOMReady=!0},t.supports.everything||(n=function(){t.readyCallback()},a.addEventListener?(a.addEventListener("DOMContentLoaded",n,!1),e.addEventListener("load",n,!1)):(e.attachEvent("onload",n),a.attachEvent("onreadystatechange",function(){"complete"===a.readyState&&t.readyCallback()})),(r=t.source||{}).concatemoji?d(r.concatemoji):r.wpemoji&&r.twemoji&&(d(r.twemoji),d(r.wpemoji)))}(window,document,window._wpemojiSettings);
    </script>
    <style>
      img.wp-smiley,
      img.emoji {
      display: inline !important;
      border: none !important;
      box-shadow: none !important;
      height: 1em !important;
      width: 1em !important;
      margin: 0 .07em !important;
      vertical-align: -0.1em !important;
      background: none !important;
      padding: 0 !important;
      }
    </style>
    <link rel='stylesheet' id='wp-block-library-css'  href='http://example.test/wp/wp-includes/css/dist/block-library/style.min.css?ver=5.5' media='all' />
    <link rel='stylesheet' id='twentytwenty-style-css'  href='http://example.test/wp/wp-content/themes/twentytwenty/style.css?ver=1.3' media='all' />
    <style id='twentytwenty-style-inline-css'>
      .color-accent,.color-accent-hover:hover,.color-accent-hover:focus,:root .has-accent-color,.has-drop-cap:not(:focus):first-letter,.wp-block-button.is-style-outline,a { color: #cd2653; }blockquote,.border-color-accent,.border-color-accent-hover:hover,.border-color-accent-hover:focus { border-color: #cd2653; }button:not(.toggle),.button,.faux-button,.wp-block-button__link,.wp-block-file .wp-block-file__button,input[type="button"],input[type="reset"],input[type="submit"],.bg-accent,.bg-accent-hover:hover,.bg-accent-hover:focus,:root .has-accent-background-color,.comment-reply-link { background-color: #cd2653; }.fill-children-accent,.fill-children-accent * { fill: #cd2653; }body,.entry-title a,:root .has-primary-color { color: #000000; }:root .has-primary-background-color { background-color: #000000; }cite,figcaption,.wp-caption-text,.post-meta,.entry-content .wp-block-archives li,.entry-content .wp-block-categories li,.entry-content .wp-block-latest-posts li,.wp-block-latest-comments__comment-date,.wp-block-latest-posts__post-date,.wp-block-embed figcaption,.wp-block-image figcaption,.wp-block-pullquote cite,.comment-metadata,.comment-respond .comment-notes,.comment-respond .logged-in-as,.pagination .dots,.entry-content hr:not(.has-background),hr.styled-separator,:root .has-secondary-color { color: #6d6d6d; }:root .has-secondary-background-color { background-color: #6d6d6d; }pre,fieldset,input,textarea,table,table *,hr { border-color: #dcd7ca; }caption,code,code,kbd,samp,.wp-block-table.is-style-stripes tbody tr:nth-child(odd),:root .has-subtle-background-background-color { background-color: #dcd7ca; }.wp-block-table.is-style-stripes { border-bottom-color: #dcd7ca; }.wp-block-latest-posts.is-grid li { border-top-color: #dcd7ca; }:root .has-subtle-background-color { color: #dcd7ca; }body:not(.overlay-header) .primary-menu > li > a,body:not(.overlay-header) .primary-menu > li > .icon,.modal-menu a,.footer-menu a, .footer-widgets a,#site-footer .wp-block-button.is-style-outline,.wp-block-pullquote:before,.singular:not(.overlay-header) .entry-header a,.archive-header a,.header-footer-group .color-accent,.header-footer-group .color-accent-hover:hover { color: #cd2653; }.social-icons a,#site-footer button:not(.toggle),#site-footer .button,#site-footer .faux-button,#site-footer .wp-block-button__link,#site-footer .wp-block-file__button,#site-footer input[type="button"],#site-footer input[type="reset"],#site-footer input[type="submit"] { background-color: #cd2653; }.header-footer-group,body:not(.overlay-header) #site-header .toggle,.menu-modal .toggle { color: #000000; }body:not(.overlay-header) .primary-menu ul { background-color: #000000; }body:not(.overlay-header) .primary-menu > li > ul:after { border-bottom-color: #000000; }body:not(.overlay-header) .primary-menu ul ul:after { border-left-color: #000000; }.site-description,body:not(.overlay-header) .toggle-inner .toggle-text,.widget .post-date,.widget .rss-date,.widget_archive li,.widget_categories li,.widget cite,.widget_pages li,.widget_meta li,.widget_nav_menu li,.powered-by-wordpress,.to-the-top,.singular .entry-header .post-meta,.singular:not(.overlay-header) .entry-header .post-meta a { color: #6d6d6d; }.header-footer-group pre,.header-footer-group fieldset,.header-footer-group input,.header-footer-group textarea,.header-footer-group table,.header-footer-group table *,.footer-nav-widgets-wrapper,#site-footer,.menu-modal nav *,.footer-widgets-outer-wrapper,.footer-top { border-color: #dcd7ca; }.header-footer-group table caption,body:not(.overlay-header) .header-inner .toggle-wrapper::before { background-color: #dcd7ca; }
    </style>
    <link rel='stylesheet' id='twentytwenty-print-style-css'  href='http://example.test/wp/wp-content/themes/twentytwenty/print.css?ver=1.3' media='print' />
    <script src='http://example.test/wp/wp-content/themes/twentytwenty/assets/js/index.js?ver=1.3' id='twentytwenty-js-js' async></script>
    <link rel="https://api.w.org/" href="http://example.test/wp-json/" />
    <link rel="alternate" type="application/json" href="http://example.test/wp-json/wp/v2/pages/14" />
    <link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://example.test/wp/xmlrpc.php?rsd" />
    <link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://example.test/wp/wp-includes/wlwmanifest.xml" />
    <meta name="generator" content="WordPress 5.5" />
    <link rel="canonical" href="http://example.test/" />
    <link rel='shortlink' href='http://example.test/' />
    <link rel="alternate" type="application/json+oembed" href="http://example.test/wp-json/oembed/1.0/embed?url=http%3A%2F%2Fexample.test%2F" />
    <link rel="alternate" type="text/xml+oembed" href="http://example.test/wp-json/oembed/1.0/embed?url=http%3A%2F%2Fexample.test%2F&#038;format=xml" />
    <script>document.documentElement.className = document.documentElement.className.replace( 'no-js', 'js' );</script>
    <style id="custom-background-css">
      body.custom-background { background-color: #fff; }
    </style>
  </head>
  <body class="home page-template-default page page-id-14 custom-background wp-embed-responsive singular enable-search-modal missing-post-thumbnail has-no-pagination not-showing-comments show-avatars footer-top-visible">