pressgang-wp / pressgang-snippets
A collection of reusable snippets for WordPress themes, specifically tailored for integration with the PressGang parent theme framework.
Installs: 120
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/pressgang-wp/pressgang-snippets
Requires
- php: ^8.0
- timber/timber: ^2.0
README
Stop copy-pasting from functions.php. Start composing.
PressGang Snippets is a library of 45+ self-contained, Composer-installable WordPress theme components for PressGang themes. Each snippet is a single PHP class that does one thing well โ from injecting Google Analytics to disabling emojis to generating breadcrumbs โ and can be enabled or disabled with a single line of config.
๐ค Why Snippets?
Every WordPress developer has done this: you need Google Analytics on a new site, so you open functions.php, paste in 30 lines you copied from the last project, tweak a couple of values, and move on. Six months later that file is 800 lines of unrelated code that nobody wants to touch.
Snippets fix this. Instead of a monolithic functions.php, each piece of functionality lives in its own class:
// config/snippets.php โ your entire "functions.php" replacement return [ 'PressGang\\Snippets\\Theme\\DisableEmojis' => [], 'PressGang\\Snippets\\Google\\Analytics' => [], 'PressGang\\Snippets\\Theme\\ImageSizes' => [ 'hero' => ['width' => 1920, 'height' => 600, 'crop' => true], ], 'PressGang\\Snippets\\Content\\DuplicatePost' => [], 'PressGang\\Snippets\\Seo\\OpenGraph' => [], ];
That's it. Five features enabled, zero boilerplate, fully reversible by deleting a line.
| Traditional approach | PressGang Snippets |
|---|---|
| Copy-paste between projects | composer require once, use everywhere |
| Enable/disable by commenting code | Add or remove a config line |
One massive functions.php |
One focused class per concern |
| Arguments buried in code | Configuration passed explicitly |
| No standard structure | Every snippet implements SnippetInterface |
๐ฆ Installation
composer require pressgang-wp/pressgang-snippets
That's all. PressGang automatically discovers the package's Twig templates โ no path configuration needed.
โ๏ธ Configuration
Activate snippets in your child theme's config/snippets.php. Each entry maps a class name to an arguments array:
<?php return [ // No args needed โ just enable it 'PressGang\\Snippets\\Theme\\DisableEmojis' => [], // Pass configuration via the args array 'PressGang\\Snippets\\Theme\\ImageSizes' => [ 'thumbnail' => ['width' => 150, 'height' => 150, 'crop' => true], 'medium' => ['width' => 600, 'height' => 600, 'crop' => false], 'hero' => ['width' => 1920, 'height' => 600, 'crop' => true], ], // Customizer-based snippets โ the user enters values in the WP Customizer 'PressGang\\Snippets\\Google\\Analytics' => [], 'PressGang\\Snippets\\Google\\TagManager' => [], // Or your own child theme snippets 'MyTheme\\Snippets\\CustomFeature' => ['enabled' => true], ];
Namespace resolution: Snippets are grouped by category namespace (e.g. PressGang\\Snippets\\Google\\Analytics). Use fully qualified class names for clarity.
๐ Available Snippets
๐ Analytics & Tracking
| Snippet | Description |
|---|---|
Google\\Analytics |
Google Analytics (gtag.js) with Customizer controls and logged-in user toggle |
Google\\TagManager |
Google Tag Manager container โ injects into <head> and <body> |
Google\\AdsTag |
Google Ads global site tag |
Google\\ConversionTracking |
Google Ads conversion tracking pixel |
Google\\AnalyticsWoocommerce |
GA e-commerce event tracking for WooCommerce |
Facebook\\Pixel |
Meta (Facebook) Pixel |
Integration\\Pinterest |
Pinterest Tag |
Integration\\Hotjar |
Hotjar behaviour analytics |
Integration\\Tawkto |
Tawk.to live chat widget |
Integration\\CookieYes |
CookieYes consent management |
Integration\\Trustpilot |
Trustpilot review widget |
๐ SEO & Meta
| Snippet | Description |
|---|---|
Seo\\OpenGraph |
Open Graph meta tags for social sharing (title, description, image) |
Seo\\Title |
SEO-friendly <title> tag management |
Seo\\Sitemap |
XML sitemap generation with support for CPTs, taxonomies, and WPML |
Theme\\Breadcrumb |
Breadcrumb navigation โ registers a {{ breadcrumb() }} Twig function |
Google\\Webmaster |
Google Search Console verification meta tag |
Facebook\\Verify |
Facebook domain verification meta tag |
๐ผ๏ธ Media & Assets
| Snippet | Description |
|---|---|
Theme\\ImageSizes |
Configure, add, and disable WordPress image sizes |
Theme\\BigImageScaling |
Set the threshold for WordPress big image scaling |
Theme\\Logo |
Logo image Customizer control |
Theme\\LogoSvg |
SVG logo support via Customizer |
Theme\\EditorStyles |
Add editor stylesheet support |
โก Performance
| Snippet | Description |
|---|---|
Theme\\DisableEmojis |
Remove WordPress emoji scripts, styles, and DNS prefetch (~15 KB saved) |
Content\\RemoveOembedAuthor |
Strip author info from oEmbed responses |
๐ ๏ธ Admin & Editor
| Snippet | Description |
|---|---|
Content\\DuplicatePost |
"Duplicate" link on post/page rows โ clones content, meta, and taxonomies |
Theme\\AdminLogo |
Custom logo on the WordPress login page |
Theme\\TinyMceBlockFormats |
Customise TinyMCE block format dropdown |
Content\\RemovePosts |
Remove the default "Posts" menu from the admin |
Theme\\PostTypeMenuHighlighter |
Fix admin menu highlighting for custom post types |
Theme\\Copyright |
Copyright notice Customizer control |
Theme\\ArchiveTitles |
Customiser controls for archive page titles |
๐ง Theme Utilities
| Snippet | Description |
|---|---|
Theme\\Permalinks |
Custom rewrite rules for CSS, JS, images, and fonts |
Theme\\AddQueryVars |
Register custom query variables |
Content\\SearchExcludePostTypes |
Exclude specific post types from search results |
Content\\PasswordProtection |
Custom template for password-protected posts |
Google\\Recaptcha |
Google reCAPTCHA site + secret key management |
๐จ ACF Integration
| Snippet | Description |
|---|---|
Acf\\ColorPickerThemeSync |
Sync theme.json colour palette to ACF colour picker |
Acf\\GoogleMaps |
Google Maps API key for ACF map fields |
Acf\\WysiwygMin |
Minimal toolbar for ACF WYSIWYG fields |
๐ WooCommerce
| Snippet | Description |
|---|---|
WooCommerce\\AjaxCartCount |
AJAX-powered cart count updates |
WooCommerce\\Backorders |
Enable backorder support |
WooCommerce\\DequeueStyles |
Remove default WooCommerce stylesheets |
WooCommerce\\DequeueSelectWoo |
Remove the SelectWoo library |
WooCommerce\\RemoveUncategorized |
Hide the default "Uncategorized" product category |
WooCommerce\\RemoveDownloads |
Remove the "Downloads" endpoint from My Account |
โ๏ธ Writing Your Own Snippets
The real power of the snippet pattern is that your own code follows the same conventions. Instead of adding custom functionality to functions.php, create a snippet class in your child theme:
// src/Snippets/StaffDirectory.php namespace MyTheme\Snippets; use PressGang\Snippets\SnippetInterface; /** * Registers a "Staff" custom post type with a configurable slug and enables * the archive page. Designed for company/team directory pages. */ class StaffDirectory implements SnippetInterface { public function __construct(array $args) { $this->slug = $args['slug'] ?? 'staff'; \add_action('init', [$this, 'register']); } public function register(): void { \register_post_type('staff', [ 'label' => \__('Staff', THEMENAME), 'public' => true, 'has_archive' => true, 'rewrite' => ['slug' => $this->slug], 'supports' => ['title', 'editor', 'thumbnail'], 'show_in_rest' => true, ]); } }
Then enable it with one line:
// config/snippets.php return [ 'StaffDirectory' => ['slug' => 'team'], ];
Every custom feature you build this way is:
- Discoverable โ one class, one file, one purpose
- Configurable โ args passed from config, not hardcoded
- Portable โ move it to another project or extract it into a Composer package
- Removable โ delete one config line, feature gone
๐๏ธ How It Works Under the Hood
- PressGang reads
config/snippets.phpduring boot - Each class name is resolved (child theme namespace first, then
PressGang\Snippets\) - The class is instantiated with
new $class($args) - The constructor registers WordPress hooks โ
add_action,add_filter, etc. - WordPress fires those hooks at the appropriate time during the request lifecycle
Snippets never need a second method call to "activate". Construction is activation.
๐งช Testing
The library uses PHPUnit 9.6 with BrainMonkey (via yoast/wp-test-utils) for unit testing โ the same stack as the PressGang parent theme. Tests mock WordPress functions without a running WordPress installation.
Running tests
composer test # run the full unit suite composer test:unit # same as above # Single class or test vendor/bin/phpunit --filter DisableEmojisTest vendor/bin/phpunit --filter test_script_skips_rendering_when_tracking_id_empty
Writing tests
Tests live in tests/Unit/ and mirror the src/Snippets/ directory structure:
tests/
โโโ bootstrap.php
โโโ stubs/
โ โโโ SnippetInterface.php
โโโ Unit/
โโโ TestCase.php
โโโ Snippets/
โโโ Content/
โ โโโ DuplicatePostTest.php
โโโ Google/
โ โโโ AnalyticsTest.php
โโโ Theme/
โ โโโ BreadcrumbTest.php
โ โโโ DisableEmojisTest.php
โ โโโ ImageSizesTest.php
โโโ WooCommerce/
โโโ DequeueStylesTest.php
New test classes should extend PressGang\Tests\Snippets\Unit\TestCase and use Brain\Monkey\Functions\expect() to mock WordPress functions. For snippets that call Timber::render(), extract the call to a protected render_template() method and override it in a named test subclass (see AnalyticsTest for the pattern).
๐ Requirements
- PHP 8.3+
- WordPress 6.4+
- Timber 2.0+
- PressGang parent theme
๐ License
MIT โ use it, fork it, ship it.