ideasonpurpose / wp-theme-addons
WordPress Block Editor add-ons — JavaScript blocks, utilities, and PHP components
Requires
None
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Version 0.4.1
This repository contains JavaScript and PHP add-ons for the WordPress Block Editor and Hybrid themes. The project is used in production, but is under active development and implementations are likely to change.
What's in here
Block Variations
Linked Group Block
A variation on the Group block which adds standard Link controls. The link implementation uses ideas from Accessible cards and Inclusive Components: Cards.
new LinkedGroup() wraps the core/group render callback and, when the variation has a URL, appends an empty overlay link inside the group. The stretch-link rules live in editor/Block/Variation/Group/LinkedGroup/linked-group.css. The editor script imports that file. PHP reads the same file and inlines it on the iop-linked-group handle from wp_enqueue_scripts, so the rules print in the head. No theme copy is required.
Related Posts Query
A variation on the Query Loop block which replaces the query with ranked related posts. Ranking lives in lib/RelatedPosts (IdeasOnPurpose\WP\RelatedPosts) — weighted shared taxonomies, post type, and recency, with optional REST at GET /wp-json/ideasonpurpose/v1/related_posts/{id} (see PHP usage to enable it).
Block Extensions
Button Icons
This extension adds an icon-picker to the core/button block. Markup is unchanged, icons are specified by adding classes. Classes are added in the Block Editor as well as the front end, so authors can work with a true representation of the final button.
import { initButtonIconPicker } from "@ideasonpurpose/wp-theme-addons"; initButtonIconPicker( [ { label: "Arrow Right", value: "arrow-right" }, { label: "Mail", value: "mail" }, { label: "Download", value: "download" }, ], "arrow-right", // optional default icon, defaults to "" );
Icons are displayed using CSS in the theme. Each icon maps to a mask variable the theme defines:
.wp-block-button.iop-button-icon.icon-arrow-right .wp-block-button__link::before { mask-image: var(--i-arrow-right); }
CSS Local Props
Injects block color attributes as CSS custom properties (--local-text-color, --local-bg-color, --local-border-color) so theme styles can use them.
This feature includes a pair of front-end and block editor files:
| File | Runtime | Role |
|---|---|---|
CssLocalProps/CssLocalProps.php |
PHP (frontend + editor bootstrap) | On render_block, writes the local props onto the outer wrapper tag. On enqueue_block_editor_assets, localizes the allowed-block list to window.iopLocalProps. |
CssLocalProps/css-local-props.js |
Block editor | Higher-order component on editor.BlockListBlock that injects the same vars into wrapperProps.style for live editor preview. |
Named colors from theme.json are converted to var(--wp--preset--color--*); custom hex/rgb values pass through as-is.
By default only core/button is targeted. Change the list from PHP:
add_filter('iop/add_css_local_props_allowed_blocks', fn() => ['core/button', 'core/group']);
Both sides must stay in sync: enable PHP for frontend output and call initCssLocalProps() in the editor bundle so the canvas matches the saved markup.
The PHP block list is localized to the script handle {stylesheet}-editor (from get_stylesheet()). If the theme's editor script uses a different handle, or is enqueued after enqueue_block_editor_assets priority 10, the editor falls back to core/button. Pass the list to initCssLocalProps(['core/button', 'core/group']) directly in that case.
Utilities
A few utility hooks are exported. usePublicPostTypes and usePublicTaxonomies are direct lifts from the WordPress Gutenberg source code. These functions are useful for pre-populating a WordPress data-store with all PostType and Taxonomy data for use in interfaces or block rendering.
Installation
Prerequisites
- SSH access to GitHub configured (your SSH key must be added to your GitHub account)
- You or the consuming project must have access to this private repository
npm
npm install @ideasonpurpose/wp-theme-addons
Or in package.json:
{
"dependencies": {
"@ideasonpurpose/wp-theme-addons": "^0.4.1"
}
}
Composer
Add the VCS repository and require the package in your project's composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "git@github.com:ideasonpurpose/wp-theme-addons.git"
}
],
"require": {
"ideasonpurpose/wp-theme-addons": "dev-main"
}
}
Usage
JavaScript
Import into editor.js. Minimal required styles are bundled with the JS:
// @link https://github.com/ideasonpurpose/wp-theme-addons import { initButtonIconPicker, initCssLocalProps, initLinkedGroupBlock, initRelatedPostsQueryBlock, } from "@ideasonpurpose/wp-theme-addons"; initLinkedGroupBlock(); initRelatedPostsQueryBlock(); initCssLocalProps(); initButtonIconPicker([...]);
The package ships untranspiled source: .js files contain JSX and import .scss files. The theme's build must transpile JSX and compile Sass for this package inside node_modules. @wordpress/* packages are expected to be provided as externals by the theme's build (for example @wordpress/scripts).
PHP
use IdeasOnPurpose\WP\RelatedPosts; use IdeasOnPurpose\WP\Theme\Addons\Block\Variation\Group\LinkedGroup\LinkedGroup; use IdeasOnPurpose\WP\Theme\Addons\Block\Variation\Query\RelatedPostsQuery\RelatedPostsQuery; use IdeasOnPurpose\WP\Theme\Addons\CssLocalProps\CssLocalProps; new LinkedGroup(); new RelatedPostsQuery(); // uses RelatedPosts for ranking new CssLocalProps(); // Optional: enables the REST endpoint. Must run before `rest_api_init`, e.g. in functions.php new RelatedPosts(); // Optional: use the ranker directly // $posts = (new RelatedPosts())->get(['post' => $id, 'posts_per_page' => 4]);
PHP components require WordPress 6.2 or later (WP_HTML_Tag_Processor).
Coexistence
npm and Composer operate independently in the same repository:
| npm | Composer | |
|---|---|---|
| Config | package.json |
composer.json |
| Package name | @ideasonpurpose/wp-theme-addons |
ideasonpurpose/wp-theme-addons |
| Installs to | node_modules/ |
vendor/ |
| Serves | JS + SCSS | PHP |
| Imports resolve via | npm package name | PSR-4 autoloading |
No conflicts: separate config files, separate dependency directories, separate language ecosystems.
graph TD
subgraph REPO["Single Git Repository: ideasonpurpose/wp-theme-addons"]
PJ[package.json]
CJ[composer.json]
JS[JS + SCSS files]
PHP[PHP files]
end
subgraph NPM_CONSUMER["npm Consumer Project"]
NPJ[package.json]
NM[node_modules/]
end
subgraph COMPOSER_CONSUMER["Composer Consumer Project"]
CPJ[composer.json]
VD[vendor/]
end
NPJ -- "npm install" --> PJ
PJ -- "resolves to" --> NM
JS -- "import from" --> NM
CPJ -- "composer require" --> CJ
CJ -- "resolves to" --> VD
PHP -- "PSR-4 autoload" --> VD
Loading
- npm reads
package.json→ installs tonode_modules/→ JS/SCSS imports resolve via@ideasonpurpose/wp-theme-addons - Composer reads
composer.json→ installs tovendor/→ PHP classes autoload via PSR-4 - No conflicts: separate config files, separate dependency directories, separate language ecosystems.
Brought to you by IOP
| This project is actively developed and used in production at Ideas On Purpose. |
|---|