estebanforge/hypermedia-api-wordpress

Add an API endpoint to WordPress to support Hypermedia libraries like HTMX, Alpine Ajax, and Datastar.

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 77

Watchers: 9

Forks: 8

Open Issues: 0

Language:JavaScript

Type:wordpress-plugin

1.3.0 2025-05-12 03:45 UTC

This package is auto-updated.

Last update: 2025-06-06 23:32:09 UTC


README

An unofficial WordPress plugin that enables the use of HTMX, Alpine AJAX, Datastar and other hypermedia libraries on your WordPress site, theme, and/or plugins. Intended for software developers.

Adds a new endpoint /wp-html/v1/ from which you can load any hypermedia template.

Hypermedia API for WordPress Demo

Check the video

Hypermedia what?

Hypermedia is a "new" concept that allows you to build modern web applications, even SPAs, without the need to write a single line of JavaScript. A forgotten concept that was popular in the 90s and early 2000s, but has been forgotten by newer generations of software developers.

HTMX, Alpine Ajax and Datastar are JavaScript libraries that allows you to access AJAX, WebSockets, and Server-Sent Events directly in HTML using attributes, without writing any JavaScript.

Unless you're trying to build a Google Docs clone or a competitor, Hypermedia allows you to build modern web applications, even SPAs, without the need to write a single line of JavaScript.

For a better explanation and demos, check the following video:

You don't need a frontend framework by Andrew Schmelyun

Why mix it with WordPress?

Because I share the same sentiment as Carson Gross, the creator of HTMX, that the software stack used to build the web today has become too complex without good reason (most of the time). And, just like him, I also want to see the world burn.

(Seriously) Because Hypermedia is awesome, and WordPress is awesome (sometimes). So, why not?

I'm using this in production for a few projects, and it's working great, stable, and ready to use. So, I decided to share it with the world.

I took this idea out of the tangled mess it was inside a project and made it into a standalone plugin that should work for everyone.

It might have some bugs, but the idea is to open it up and improve it over time.

So, if you find any bugs, please report them.

Installation

Install it directly from the WordPress.org plugin repository. On the plugins install page, search for: Hypermedia API

Or download the zip from the official plugin repository and install it from your WordPress plugins install page.

Activate the plugin. Configure it to your liking on Settings > Hypermedia API.

Installation via Composer

If you want to use this plugin as a library, you can install it via Composer. This allows you to use hypermedia libraries in your own plugins or themes, without the need to install this plugin.

composer require estebanforge/hypermedia-api-wordpress

This plugin/library will determine which instance of itself is the newer one when WordPress is loading. Then, it will use the newer instance between all competing plugins or themes. This is to avoid conflicts with other plugins or themes that may be using the same library for their Hypermedia implementation.

How to use

After installation, you can use hypermedia templates in any theme.

This plugin will include the active hypermedia library by default, locally from the plugin folder. Libraries like HTMX, Alpine.js, Hyperscript, and Datastar are supported.

The plugin has an opt-in option, not enforced, to include these third-party libraries from a CDN (using the unpkg.com service). You must explicitly enable this option for privacy and security reasons.

Create a hypermedia folder in your theme's root directory. This plugin includes a demo folder that you can copy to your theme. Don't put your templates inside the demo folder located in the plugin's directory, because it will be deleted when you update the plugin.

Inside your hypermedia folder, create as many templates as you want. All files must end with .hm.php.

For example:

hypermedia/live-search.hm.php
hypermedia/related-posts.hm.php
hypermedia/private/author.hm.php
hypermedia/private/author-posts.hm.php

Check the demo template at hypermedia/demo.hm.php to see how to use it.

Then, in your theme, use your Hypermedia library to GET/POST to the /wp-html/v1/ endpoint corresponding to the template you want to load, without the file extension:

/wp-html/v1/live-search
/wp-html/v1/related-posts
/wp-html/v1/private/author
/wp-html/v1/private/author-posts

Helper Functions

You can use the hmapi_get_endpoint_url() helper function to generate the URL for your hypermedia templates. This function will automatically add the /wp-html/v1/ prefix. The hypermedia file extension (.hm.php) is not needed, the API will resolve it automatically.

For example:

echo hmapi_get_endpoint_url( 'live-search' );

Or,

hmapi_endpoint_url( 'live-search' );

Will call the template located at:

/hypermedia/live-search.hm.php

And will load it from the URL:

http://your-site.com/wp-html/v1/live-search

This will output:

http://your-site.com/wp-html/v1/live-search

Backward Compatibility

For backward compatibility, the old hxwp_api_url() function is still available as an alias for hmapi_get_endpoint_url(). However, we recommend updating your code to use the new function names as the old ones are deprecated and may be removed in future versions.

Other helper functions available:

  • hmapi_send_header_response() / hxwp_send_header_response() (deprecated alias)
  • hmapi_die() / hxwp_die() (deprecated alias)
  • hmapi_validate_request() / hxwp_validate_request() (deprecated alias)

How to pass data to the template

You can pass data to the template using URL parameters (GET/POST). For example:

/wp-html/v1/live-search?search=hello
/wp-html/v1/related-posts?category_id=5

All of those parameters (with their values) will be available inside the template as an array named: $hmvals.

No Swap response templates

Hypermedia libraries allow you to use templates that don't return any HTML but perform some processing in the background on your server. These templates can still send a response back (using HTTP headers) if desired. Check Swapping for more info.

For this purpose, and for convenience, you can use the noswap/ folder/endpoint. For example:

/wp-html/v1/noswap/save-user?user_id=5&name=John&last_name=Doe
/wp-html/v1/noswap/delete-user?user_id=5

In this examples, the save-user and delete-user templates will not return any HTML, but will do some processing in the background. They will be loaded from the hypermedia/noswap folder.

hypermedia/noswap/save-user.hm.php
hypermedia/noswap/delete-user.hm.php

You can pass data to these templates in the exact same way as you do with regular templates.

Nothing stops you from using regular templates to do the same thing or using another folder altogether. You can mix and match or organize your templates in any way you want. This is mentioned here just as a convenience feature for those who want to use it.

Choosing a Hypermedia Library

This plugin comes with HTMX, Alpine Ajax and Datastar already integrated and enabled.

You can choose which library to use in the plugin's options page: Settings > Hypermedia API.

In the case of HTMX, you can also enable any of its extensions in the plugin's options page: Settings > Hypermedia API.

Local vs CDN Loading

The plugin includes local copies of all libraries for privacy and offline development. You can choose to load from:

  1. Local files (default): Libraries are served from your WordPress installation
  2. CDN: Optional CDN loading from jsdelivr.net. Will always load the latest version of the library.

Build System Integration

For developers, the plugin includes npm scripts to download the latest versions of all libraries locally:

# Download all libraries
npm run download:all

# Download specific library
npm run download:htmx
npm run download:alpine
npm run download:hyperscript
npm run download:datastar
npm run download:all

This ensures your local development environment stays in sync with the latest library versions.

Using Hypermedia Libraries in your plugin

You can definitely use hypermedia libraries and this Hypermedia API for WordPress in your plugin. You are not limited to using it only in your theme.

The plugin provides the filter: hmapi/register_template_path

This filter allows you to register a new template path for your plugin or theme. It expects an associative array where keys are your chosen namespaces and values are the absolute paths to your template directories.

For example, if your plugin slug is my-plugin, you can register a new template path like this:

add_filter( 'hmapi/register_template_path', function( $paths ) {
    // Ensure YOUR_PLUGIN_PATH is correctly defined, e.g., plugin_dir_path( __FILE__ )
    // 'my-plugin' is the namespace.
    $paths['my-plugin'] = YOUR_PLUGIN_PATH . 'hypermedia/';

    return $paths;
});

Assuming YOUR_PLUGIN_PATH is already defined and points to your plugin's root directory, the above code registers the my-plugin namespace to point to YOUR_PLUGIN_PATH/hypermedia/.

Then, you can use the new template path in your plugin like this, using a colon : to separate the namespace from the template file path (which can include subdirectories):

// Loads the template from: YOUR_PLUGIN_PATH/hypermedia/template-name.hm.php
echo hmapi_get_endpoint_url( 'my-plugin:template-name' );

// Loads the template from: YOUR_PLUGIN_PATH/hypermedia/parts/header.hm.php
echo hmapi_get_endpoint_url( 'my-plugin:parts/header' );

This will output the URL for the template from the path associated with the my-plugin namespace. If the namespace is not registered, or the template file does not exist within that registered path (or is not allowed due to sanitization rules), the request will result in a 404 error. Templates requested with an explicit namespace do not fall back to the theme's default hypermedia directory.

For templates located directly in your active theme's hypermedia directory (or its subdirectories), you would call them without a namespace:

// Loads: wp-content/themes/your-theme/hypermedia/live-search.hm.php
echo hmapi_get_endpoint_url( 'live-search' );

// Loads: wp-content/themes/your-theme/hypermedia/subfolder/my-listing.hm.php
echo hmapi_get_endpoint_url( 'subfolder/my-listing' );

Security

Every call to the wp-html endpoint will automatically check for a valid nonce. If the nonce is not valid, the call will be rejected.

The nonce itself is auto-generated and added to all HTMX requests automatically, using HTMX's own htmx:configRequest event.

If you are new to Hypermedia, please read the security section of the official documentation. Remember that Hypermedia requires you to validate and sanitize any data you receive from the user. This is something developers used to do all the time, but it seems to have been forgotten by newer generations of software developers.

If you are not familiar with how WordPress recommends handling data sanitization and escaping, please read the official documentation on Sanitizing Data and Escaping Data.

REST Endpoint

The plugin will perform basic sanitization of calls to the new REST endpoint, wp-html, to avoid security issues like directory traversal attacks. It will also limit access so you can't use it to access any file outside the hypermedia folder within your own theme.

The parameters and their values passed to the endpoint via GET or POST will be sanitized with sanitize_key() and sanitize_text_field(), respectively.

Filters hmapi/sanitize_param_key and hmapi/sanitize_param_value are available to modify the sanitization process if needed. For backward compatibility, the old filters hxwp/sanitize_param_key and hxwp/sanitize_param_value are still supported but deprecated.

Do your due diligence and ensure you are not returning unsanitized data back to the user or using it in a way that could pose a security issue for your site. Hypermedia requires that you validate and sanitize any data you receive from the user. Don't forget that.

Examples

Check out the showcase/demo theme at EstebanForge/Hypermedia-Theme-WordPress.

Suggestions, Support

Please, open a discussion.

Bugs and Error reporting

Please, open an issue.

FAQ

FAQ available here.

Changelog

Changelog available here.

Contributing

You are welcome to contribute to this plugin.

If you have a feature request or a bug report, please open an issue on the GitHub repository.

If you want to contribute with code, please open a pull request.

License

This plugin is licensed under the GPLv2 or later.

You can find the full license text in the license.txt file.