This script is intended for WordPress plugins that provide hooks that can be used by other plugins. By parsing its source code, it creates a documentation in a Github wiki.
You can configure this tool either through a JSON configuration file or directly through GitHub Action inputs. For local usage, you'll need a configuration file, but for GitHub Actions, you can specify all configuration directly in your workflow file.
- https://github.com/akirk/extract-hooks/wiki/Hooks (extracted from example.php)
- https://github.com/akirk/friends/wiki/Hooks
- https://github.com/akirk/enable-mastodon-apps/wiki/Hooks
The PHP script doesn't have any dependencies. It uses PHP's internal parser (using token_get_all) to identify PHP function calls to apply_filters() or do_action().
It generates a markdown file for each filter which is suitable for a Github wiki. The page contains potentially provided documentation (via a comment in the source code), an (auto-generated) example, parameters, return value, references to the source code (including extracted source snippet).
For each filter, it looks at the comment preceeding the filter, so that you can document it, for example:
/*
* This is example filter 1.
*
* @param string $text The text to modify.
* @param string $mode Extra information that might be useful.
* @return string The modified text.
*/
$result = apply_filters( 'example_filter1', $text, $mode );This will generate an example_filter1.md that contains the text This is an example filter and a list of parameters and return value:
This is an example filter.
string$textThe text to modify.string$modeExtra information that might be useful.
stringThe modified text.
But not only that, it will contain an auto-generated example:
add_filter( 'example_filter1', function( string $text, string $mode ) { // Your code return $text; }, 10, 2 );
You can also provide your own example in the comment, that will override the auto-generated example:
/*
* This is example filter 2.
*
* Example:
* ```php
* add_filter( 'example_filter2', function ( $text ) {
* return strtolower( $text );
* } );
* ```
*
* @param string $text The text to modify.
* @param string $mode Extra information that might be useful.
* @return string The modified text.
*/
$result = apply_filters( 'example_filter2', $text, $mode );It generates this output: example_filter2
add_filter( 'example_filter2', function ( $text ) { return strtolower( $text ); } );
Finally, if you have an filter without any documentation, the script attempts to create a useful auto-generated example. So suppose you have code
$result = apply_filters( 'example_filter3', $text, $mode );
It generates this output: example_filter3
add_filter( 'example_filter3', function ( $text, $mode ) { // Your code here return $text; }, 10, 2 );
$text$mode
Add the following workflow file to your WordPress plugin repository at .github/workflows/extract-hooks.yml:
name: Extract WordPress Hooks
on:
push:
branches: [ main, master ]
paths: [ '**.php' ]
workflow_dispatch:
jobs:
extract-hooks:
runs-on: ubuntu-latest
permissions:
contents: write # Required to push to wiki repository
steps:
- uses: actions/checkout@v4
- uses: akirk/extract-wp-hooks@mainThis will automatically extract hooks from your PHP files and update your GitHub wiki whenever you push changes.
You can configure the action in two ways:
- Using action inputs (recommended):
- uses: akirk/extract-wp-hooks@main
with:
namespace: "My_Plugin"
base-dir: "."
wiki-directory: "wiki"
exclude-dirs: "vendor,tests,node_modules"
ignore-filters: "debug_hook,internal_filter"
section: "file"- Using a configuration file:
Create an .extract-wp-hooks.json file in your repository root:
{
"namespace": "My_Plugin", // PHP Namespace used in the project.
"base_dir": ".", // The directory to analyse for php files.
"wiki_directory": "wiki", // Where the files will be written to.
"github_blob_url": "https://github.com/username/my-plugin/blob/main/", // This is the base url for the links to the source files.
"exclude_dirs": ["vendor", "tests"],
"ignore_filter": ["debug_hook", "internal_filter"]
}| Input | Description | Default |
|---|---|---|
namespace |
PHP Namespace that's used | |
base-dir |
Base directory to scan for hooks | . |
wiki-directory |
Directory to store wiki files | wiki |
github-blob-url |
GitHub blob URL for source links | Auto-generated from repository |
exclude-dirs |
Comma-separated list of directories to exclude | vendor,node_modules |
ignore-filters |
Comma-separated list of filter names to ignore | |
ignore-regex |
Regex pattern to ignore filter names | |
section |
How to group hooks in documentation: 'file' or 'dir' | file |
wiki-repo |
Wiki repository URL (e.g., username/repo.wiki.git) | Auto-generated from repository |
config-file |
Path to config file (optional if other inputs are provided) | .extract-wp-hooks.json |
Via composer:
composer require --dev akirk/extract-wp-hooks
You will then be able to run extract-wp-hooks.php from the vendor bin directory:
./vendor/bin/extract-wp-hooks.php
Place a .extract-wp-hooks.json or extract-wp-hooks.json in your project directory to use it.