- Shell 48.6%
- Dockerfile 26.4%
- PHP 25%
| src | WP-CLI command example | |
| .gitignore | chore: update gitignore with local/ and phel-config-local.php | |
| composer.json | upgrade Phel 0.19.1 -> 0.29.0 | |
| composer.lock | upgrade Phel 0.19.1 -> 0.29.0 | |
| custom-entrypoint.sh | run initialization as www-data for better working file permissions | |
| demo.png | update demo.png | |
| docker-compose.yml | run without root | |
| Dockerfile | improve waiting db to be available (requires image rebuild) | |
| LICENSE | Change to MIT license | |
| phel-config.php | Updated Phel 0.19.1, removed TempDir permission workaround | |
| phel-wp-plugin.php | disable WP_CLI command for now failing with \WP_CLI missing | |
| README.md | run without root | |
, _ , _ , _
/|/ \| _ |\ (| | |_//|/ \ /|/ \|\ _, 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
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 8080 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:8080/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.
Existing WordPress installation
Requires PHP 8.3+ and Composer.
- Clone this repository into plugins directory of an existing WordPress installation e.g.
wp-content/plugins/phel-wp-plugin. - Install Composer dependencies
cd phel-wp-plugin && composer install. - 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.
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 https://github.com/jasalt/phel-wp-plugin/issues/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 plugin dir with
->setErrorLogFile($projectRootDir . 'error.log'), but this should be changed 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");
}