Travelopia WordPress Blade WP Registry grade A. No security issues foundWP RegistryNo security issues foundOpen the reportA
Use Laravel Blade components in WordPress
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/travelopia/wordpress-blade/archive/refs/heads/main.zipWordPress Blade Plugin
Use Laravel Blade components in WordPress.
🚨 Note: Only Anonymous Components are currently supported: https://laravel.com/docs/10.x/blade#anonymous-components
|
Built by the super talented team at Travelopia. |
|
Video Tutorial
▶ ️tutorial
Installation
Install via Composer (recommended):
$ composer require travelopia/wordpress-blade
-
Your composer file should include this
{ "name": "your/packagename", "description": "Description", "extra": { "installer-paths": { "wp-content/mu-plugins/{$name}/": ["type:wordpress-muplugin"] } }, "require": { "travelopia/wordpress-blade": "^1.0.0", "composer/installers": "^2.3" }, "config": { "allow-plugins": { "composer/installers": true } }, "scripts": { "wordpress-blade": "wordpress-blade" } } -
This installs it as an MU Plugin.
-
Then load this plugin in your mu plugins loader file e.g. mu-plugins/loader.php
require_once WPMU_PLUGIN_DIR . '/wordpress-blade/plugin.php'; -
Then require the autoload file from vendor directory by adding the following code in your wp-config.php file.
require_once 'vendor/autoload.php';
Manual Installation (if you know what you are doing):
- Download this repository as a ZIP file.
- Run
composer install --no-dev --optimize-autoloader - Use it either as an MU plugin or a normal plugin!
Building for Production
Compile your Blade components for production as a best practice. Some production environments are read-only, in which case this step is necessary.
Run the following command:
composer exec wordpress-blade -- --config-file=blade.config.php - Ensure the path to the Blade config is correct.
Usage
First, create a blade.config.php file at the root of your project, and add the following code in there:
<?php
/**
* Blade Config.
*
* @package wordpress-blade
*/
define(
'WORDPRESS_BLADE',
[
'paths_to_views' => [
__DIR__ . '/wp-content/themes/<your-theme>/<path-to-your-components>',
'parts' => __DIR__ . '/wp-content/themes/<your-theme>/<path-to-your-components>', // With namespace.
// Any other paths where Blade needs to look for components.
],
'path_to_compiled_views' => __DIR__ . '/wp-content/themes/<your-theme>/dist/blade', // Where you want Blade to save compiled files.
'never_expire_cache' => false, // Use `true` on production environments.
'base_path' => __DIR__, // The base path that is common to the front-end and admin.
'encode_echo' => true, // Double-encode entities in `{{ }}` output. See "Echo encoding" below.
'register_wp_directives' => true, // Register `@escHtml`, `@escUrl`, `@escAttr`, `@wpKsesPost`, `@stripTags`, `@safeEscape` directives. See "WordPress-aware escape directives" below.
]
);
Echo encoding
By default Blade's {{ $value }} calls e( $value, true ), which double-encodes HTML entities. This is the Laravel default and is preserved by setting encode_echo => true.
If your templates receive values that have already been escaped upstream (for example, the output of WordPress's esc_html(), esc_attr(), or wptexturize()), double-encoding turns & into the literal text &amp;. Set encode_echo => false to switch to single-encoding (e( $value, false )) so upstream encoding is preserved.
WordPress-aware escape directives
The package registers six Blade directives that wrap WordPress's escape helpers, letting templates express intent rather than the function call:
| Directive | Compiles to | Use for |
|---|---|---|
@escHtml( $v ) |
echo esc_html( $v ); |
Plain text in HTML bodies |
@escUrl( $v ) |
echo esc_url( $v ); |
href / src attribute values |
@escAttr( $v ) |
echo esc_attr( $v ); |
Other HTML attribute values |
@wpKsesPost( $v ) |
echo wp_kses_post( $v ); |
Rich text from editors (block content, ACF WYSIWYG, etc.) |
@stripTags( $v ) |
echo wp_strip_all_tags( $v ); |
Atomic strip-only — for values that need tag removal but will be escaped or used somewhere else (JSON, plain text response, an upstream-escaped pipeline). |
@safeEscape( $v ) |
echo esc_html( wp_strip_all_tags( $v ) ); |
The combined "strip then escape" path — the safe default for plain-text fields that may receive wpautop-wrapped or otherwise tag-laden content (post titles via filters, ACF text fields rendered alongside WYSIWYG siblings). |
Directive names are prefixed / cased to correlate with the underlying WordPress helper (@esc* → esc_*(), @wp* → wp_*(), @stripTags → wp_strip_all_tags(), @safeEscape → the combined safe-default) and stay out of Laravel's reserved-directive namespace.
The expression — including its surrounding parentheses — is forwarded verbatim to the underlying WordPress helper. To skip registration (for example, if your project registers its own escape directives), set 'register_wp_directives' => false in the bootstrap config or filter wordpress_blade_register_wp_directives.
Bootstrap a layout.
As a best practice, and if applicable, bootstrap an entire layout like so:
# bootstrap.blade.php
<x-layout>
<x-hello name="Jane">Hi there!</x-hello>
</x-layout>
# layout.blade.php
@php
get_header();
@endphp
<main>
{{ $slot }}
</main>
@php
get_footer();
@endphp
# hello.blade.php
@props( [
'name' => '',
] )
<div>
<h1>{{ $slot }}</h1>
<p>Hello, {{ $name }}</p>
</div>
And then load the view in your template:
Travelopia\Blade\load_view( 'bootstrap' );
You can also load an individual component like so:
$name = 'hello'; // The name of the component.
$attributes = [ 'name' => 'Jane' ]; // Properties / attributes to pass into the component.
$echo = true; // Whether to echo the component. `false` returns the component as a string.
Travelopia\Blade\load_view( $name, $attributes, $echo );
This is especially useful when you want to load components from Blocks and Full Site Editing.
If you've used namespaces, you can use them like so:
<x-parts::my-part></x-parts::my-part>Releases
8 releases.
These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.