diff --git a/%plugin_name%.php b/%plugin_name%.php index cdcec18..5eaf8d4 100644 --- a/%plugin_name%.php +++ b/%plugin_name%.php @@ -8,9 +8,9 @@ * Author URI: %plugin_author_uri% * Text Domain: %plugin_name% * Domain Path: /languages - * Requires at least: 6.0 - * Tested up to: 6.9 - * Requires PHP: 8.2 + * Requires at least: 7.1 + * Tested up to: 7.1 + * Requires PHP: 8.4 * Network: false * License: MIT * License URI: https://opensource.org/licenses/MIT diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..1d56325 --- /dev/null +++ b/.github/README.md @@ -0,0 +1,71 @@ +

+ + Pollora plugin template: the starting point for a Pollora WordPress plugin + +

+ +

+ Version + License +

+ +The plugin template that `php artisan pollora:make:plugin` downloads: a WordPress plugin registered with [Pollora](https://pollora.dev), with a PSR-4 `app/` directory, service providers, hooks declared with PHP attributes, Blade views and an optional Vite build. You start from a plugin that already loads, instead of wiring `add_action()` calls and a bootstrap file by hand. + +## Installation + +```bash +php artisan pollora:make:plugin my-plugin +``` + +The command downloads the latest tag of this template, replaces its placeholders with your plugin's name, namespace and header, and offers to activate the plugin. With assets (`--asset`), it also runs `npm install` and `npm run build`; without them, the Vite files are left out. + +Requirements: a Pollora project (PHP 8.4+ and WordPress 7.1+ for a new one; the framework itself runs on PHP 8.3+), and Node.js 20.19+ or 22.12+ (Vite 8) when the plugin has assets. + +## Structure + +``` +%plugin_name%/ +├── app/ # Application code (PSR-4 autoloaded) +│ ├── Providers/ # Service providers (plugin, assets) +│ └── %plugin_namespace%Plugin.php # Main plugin class: activation, hooks +├── config/plugin.php # Name, version, text domain, assets path +├── resources/ +│ ├── assets/ # CSS, JS files (Vite) +│ └── views/ # Blade templates +└── %plugin_name%.php # Main plugin file: header, pollora_register() +``` + +The main class declares its hooks with attributes, which Pollora discovers on its own: + +```php +#[Action('init', priority: 10)] +public function onInit(): void +{ + // … +} +``` + +## Development + +```bash +npm install # once +npm run dev # Vite dev server with hot reload +npm run build # production build +``` + +## Documentation + +- [Plugins](https://pollora.dev/advanced/plugins/): creating a plugin, its architecture, the command's options and asset management +- [Hooks](https://pollora.dev/hooks/actions-filters/), [post types](https://pollora.dev/content/post-types/) and the rest of the framework at [pollora.dev](https://pollora.dev) + +## Template development + +This repository is a template: its files carry placeholders that `pollora:make:plugin` substitutes, and the PHP classes in `app/` are `.stub` files, so it does not run as is. Develop on a plugin generated under the code name set in `bin/package-plugin.sh`, then copy it back with `./bin/package-plugin.sh /path/to/the/plugin`, which turns the names back into placeholders. `php bin/tests/run.php` checks the result. + +## Contributing + +Contributions are welcome: see the [contributing guide](https://github.com/Pollora/.github/blob/main/CONTRIBUTING.md). Report security issues privately, as described in the [security policy](https://github.com/Pollora/.github/blob/main/SECURITY.md). + +## License + +The Pollora plugin template is open-source software licensed under the [MIT license](../LICENSE). © [RuBee group](https://rubee.group) diff --git a/LICENSE b/LICENSE index 4c0ea40..bc3cb93 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 RuBee group +Copyright (c) 2025 RuBee group (https://rubee.group) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 79bb647..8c604f6 100644 --- a/README.md +++ b/README.md @@ -2,47 +2,51 @@ %plugin_description% -## Description +Built with [Pollora](https://pollora.dev) from the [plugin-default](https://github.com/Pollora/plugin-default) template. -This plugin is built using the Pollora Framework, which provides a modern development experience by bridging Laravel and WordPress. - -## Requirements - -- WordPress 6.0 or higher -- PHP 8.2 or higher -- Pollora Framework - -## Directory Structure +## What's inside ``` %plugin_name%/ -├── app/ # Application code (PSR-4 autoloaded) -│ ├── Providers/ # Service providers -│ └── %plugin_namespace%Plugin.php # Main plugin class -├── config/ # Configuration files +├── app/ # PHP classes, namespace Plugin\%plugin_namespace% +│ ├── Providers/ # Service providers (plugin, assets) +│ └── %plugin_namespace%Plugin.php # Main class: activation, hooks declared with attributes +├── config/plugin.php # Name, version, text domain, assets path ├── resources/ -│ ├── assets/ # CSS, JS files (Vite) -│ └── views/ # Blade templates -└── %plugin_name%.php # Main plugin file +│ ├── assets/ # CSS and JS, built with Vite (when generated with assets) +│ └── views/ # Blade templates +└── %plugin_name%.php # Plugin header, registers the plugin with Pollora ``` -## Development +Hooks are declared on methods with attributes and discovered by Pollora, no `add_action()` needed: -```bash -# Install dependencies -npm install +```php +#[Action('init', priority: 10)] +public function onInit(): void +{ + // … +} +``` -# Development with HMR -npm run dev +## Commands -# Production build -npm run build +Run from the plugin's directory, when it has assets: + +```bash +npm run dev # Vite dev server with hot reload +npm run build # production assets ``` -## License +From the project root: -MIT — see [LICENSE](LICENSE). +```bash +php artisan pollora:make:block my-block --plugin=%plugin_name% # a new Gutenberg block +php artisan discovery:clear # after adding attribute-based classes +php artisan pollora:doctor # when something fails without an error +``` -## Credits +## Read more -- Built with [Pollora Framework](https://pollora.dev) +- [Plugins](https://pollora.dev/advanced/plugins/): architecture, namespaces, discovery, assets +- [Actions and filters](https://pollora.dev/hooks/actions-filters/) +- [Gutenberg blocks](https://pollora.dev/blocks/gutenberg-blocks/) diff --git a/bin/package-plugin.sh b/bin/package-plugin.sh index b722aa3..89ddeab 100755 --- a/bin/package-plugin.sh +++ b/bin/package-plugin.sh @@ -35,6 +35,15 @@ if [ ! -d "$SOURCE" ]; then exit 1 fi +# The WordPress and PHP requirements in the plugin header belong to the +# template, which follows the framework; the development copy lags behind. +# Read them before the sync and put them back after it. +TEMPLATE_MAIN="$TARGET_DIR/%plugin_name%.php" +REQUIREMENTS="" +if [ -f "$TEMPLATE_MAIN" ]; then + REQUIREMENTS=$(grep -E '^ \* (Requires at least|Tested up to|Requires PHP):' "$TEMPLATE_MAIN" || true) +fi + # Sync files (exclude node_modules, locks, build artifacts, .git) echo "Syncing files..." rsync -av --delete \ @@ -43,13 +52,39 @@ rsync -av --delete \ --exclude='yarn.lock' \ --exclude='.git' \ --exclude='bin/' \ + --exclude='/README.md' \ + --exclude='/.github/' \ + --exclude='/LICENSE' \ + --exclude='/license.txt' \ "$SOURCE/" "$TARGET_DIR/" \ --quiet +# package.json comes from the development copy, which declares no license (or +# another one): the template's is MIT, the same as LICENSE. +echo "Setting the package.json license to MIT..." +node -e ' +const fs = require("fs"); +const [file, license] = process.argv.slice(1); +const pkg = JSON.parse(fs.readFileSync(file, "utf8")); +let out = pkg; +if ("license" in pkg) { + pkg.license = license; +} else { + out = {}; + for (const [key, value] of Object.entries(pkg)) { + out[key] = value; + if (key === "private") out.license = license; + } + if (!("license" in out)) out.license = license; +} +fs.writeFileSync(file, JSON.stringify(out, null, 4) + "\n"); +' "$TARGET_DIR/package.json" "MIT" + echo "Replacing code name with placeholders..." find "$TARGET_DIR" -type f \ -not -path "*/.git/*" \ + -not -path "*/.github/*" \ -not -path "*/node_modules/*" \ -not -path "*/bin/*" \ -not -name "package-plugin.sh" \ @@ -105,6 +140,14 @@ elif [ -f "$TARGET_DIR/%plugin_name%.php" ]; then true fi +if [ -n "$REQUIREMENTS" ] && [ -f "$TEMPLATE_MAIN" ]; then + echo "Restoring the template's requirements in the plugin header..." + while IFS= read -r line; do + key="${line%%:*}" + sed -i "s|^${key//\*/\\*}:.*|${line}|" "$TEMPLATE_MAIN" + done <<< "$REQUIREMENTS" +fi + echo "Checking nothing kept the code name..." # The replacement rules above are a hand-maintained list, and theme-default @@ -112,7 +155,7 @@ echo "Checking nothing kept the code name..." # blocks added under resources/views went out naming the development theme. # Nothing there noticed, because nothing looked afterwards. This looks. if leaked=$(grep -rn "${CODE_NAME}\|${CODE_STUDLY}\|${CODE_FUNCTION}\|${CODE_UPPER}" "$TARGET_DIR" \ - --exclude-dir=.git --exclude-dir=node_modules --exclude=package-plugin.sh); then + --exclude-dir=.git --exclude-dir=.github --exclude-dir=bin --exclude-dir=node_modules --exclude=package-plugin.sh); then echo "" echo "Error: the code name survived packaging:" echo "$leaked"