Skip to content
Public template

About

WordPress plugin skeleton written with Phel which is a production grade Clojure dialect targeting PHP.

Topics

Resources

Stars

2 stars

Watchers

2 watching

Forks

Repository files navigation

, _                          , _     , _
 /|/ \|     _ |\    (|  |  |_//|/ \   /|/ \|\        _, o
  |__/|/\  |/ |/     |  |  |   |__/    |__/|/ |  |  / | | /|/|
  |   |  |/|_/|_/     \/ \/    |       |   |_/ \/|_/\/|/|/ | |_/
                                                     (|

WordPress plugin skeleton for Phel, a functional programming language inspired by Clojure and Janet.

Plugin sets up a simple admin widget querying the database and rendering HTML using Phel HTML library in way familiar from Clojure hiccup.

Image of WordPress 6.6.1 Admin Dashboard with this plugin installed

Installation

Existing WordPress installation

Requires PHP 8.4+ and Composer.

  1. Clone this repository into plugins directory of an existing WordPress installation e.g. wp-content/plugins/phel-wp-plugin.
  2. Install Composer dependencies cd phel-wp-plugin && composer install.
  3. Activate plugin on plugin management page or with WP-CLI wp plugin activate phel-wp-plugin.

The widget should be visible on admin dashboard. Try editing src/main.phel and see changes after page refresh.

Development with devenv

This repository includes a devenv development environment using Caddy, PHP-FPM, and MariaDB.

Start the environment from the repository root:

devenv up -d

Open WordPress at http://localhost:8080/. Provisioning automatically downloads WordPress, installs the plugin dependencies, activates phel-wp-plugin, creates the demo post, and ensures the default administrator exists.

Development credentials:

Username: admin
Password: password

The database is available on 127.0.0.1:3307 with database/user/password wordpress.

Useful commands:

# Enter the development shell
devenv shell

# Run provisioning again (safe to repeat)
devenv tasks run wordpress:setup

# Check or update WordPress options
devenv shell -- wp option get home --path=wordpress
devenv shell -- wp plugin status phel-wp-plugin --path=wordpress

# Stop and restart services
devenv processes down
devenv up -d

Logs

PHP-FPM logs are stored at:

.devenv/state/php-fpm/php-fpm.log

Follow service logs with:

devenv processes logs caddy
devenv processes logs phpfpm-web
devenv processes logs mysql

WordPress debug logging is enabled by default with errors hidden from the browser. The development configuration uses:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

WordPress writes PHP errors to wordpress/wp-content/debug.log.

Development container

For quick testing, a docker-compose.yml is included with custom Dockerfile that adds some extra tools to the official WordPress image (e.g. Composer, WP-CLI, XDebug). The custom-entrypoint.sh sets up the plugin on first run and creates an admin user.

Ensure that the port 8089 is not being exposed to unsafe network from host as the default admin credentials are weak.

Replace podman with docker in the commands if preferred. Tested on Debian 13 using APT packages podman, podman-compose, aardvark-dns.

git clone git@github.com:jasalt/phel-wp-plugin.git
cd phel-wp-plugin
podman compose up -d && podman compose logs -f

Following a success message, use the default credentials (admin / password) to access WordPress admin page http://localhost:8089/wp-admin.

For historical reasons the default WordPress container running Apache may occasionally shut down with caught SIGWINCH, shutting down gracefully when it's attached to terminal. This can be avoided by running it in the background by using podman compose up -d.

REPL usage

Phel REPL starts with vendor/bin/phel command. Quick way to connect to into running development container:

podman compose exec -u www-data -w /var/www/html/wp-content/plugins/phel-wp-plugin wp vendor/bin/phel

Interfacing with the REPL works mostly as expected, examples:

(php/require_once "../../../wp-load.php")  ; instantiate WordPress
(get php/$GLOBALS "wpdb")                  ; refer to wpdb for database operations

(require phel.html :refer [html])          ; load Phel core libraries
(require phel-wp-plugin.my-other-ns :as my-other-ns)  # load a Phel source file from src/
(use Laminas.XmlRpc.Client)               ; load installed Composer PHP libraries

Note that to include your own namespaces declared in the plugin directory with require, the shell working directory should be set to plugin root directory before starting the REPL.

Packaging notes

Composer is not required if vendor directory is included with the plugin distribution. Note that Composer autoloader does not play very well with WP plugins out-of-box and something like PHP-Scoper or Strauss is probably required for plugin distribution (see also #9).

Related projects

See also wp.phel for some wrapper functions over WP API's and woocommerce-memberships-migrator as a example project (a WP-CLI utility).

Advanced topics

phel-config.php recommendations

  • XDebug's (included with VVV) infinite loop detection gives false positive on default setting and requires ini_set('xdebug.max_nesting_level', 300);
  • Plugin Phel error log file path is set into the plugin directory with ->withErrorLogFile($projectRootDir . 'error.log'); change this for production.

Instantiating WordPress with wp-load.php from Phel

WordPress runs wp-load.php in beginning of each HTTP request instantiating WordPress Core which loads user plugins including the phel-wp-plugin.php which bootstraps Phel by running Phel::run.

From a standalone Phel REPL session or a script it can be loaded with (php/require_once "wp-load.php"), but this would lead to bootstrapping Phel the second time without some conditional checking in phel-wp-plugin.php e.g.

// Avoid bootstrapping Phel the second time from REPL session
if (isset($PHP_SELF) && $PHP_SELF !== "./vendor/bin/phel"){
 Phel::run($projectRootDir, 'phel-wp-plugin.main');
} else {
 // This debug print should be removed
 print("Running REPL, skip running plugin Phel::run \n");
}

About

WordPress plugin skeleton written with Phel which is a production grade Clojure dialect targeting PHP.

Topics

Resources

Stars

2 stars

Watchers

2 watching

Forks

Contributors

Languages