Winnow WordPress plugin

The Winnow WordPress plugin makes it easy to add Winnow to your WordPress site. You can read the source code below.

If you are looking for the plugin itself, ready to install on your WordPress site, you can download it here: Download the plugin.

winnow-search Winnow Search WordPress plugin source code
README.md 135 lines
# Winnow Search - WordPress Plugin

A WordPress plugin that adds [Winnow Search](https://winnow-sear.ch) to your site.
Configure your Site ID in the WordPress admin and let Winnow know when public content changes.

## Features

- Injects the Winnow Search embed script into the `<head>` of every public page
- Admin settings page under **Settings > Winnow Search** to enter your Site ID
- Optional automatic updates when public pages, posts, custom post types, or attachments change
- No external dependencies beyond WordPress core

## Installation

### From ZIP (for production use)

1. Download or build the plugin ZIP (see below)
2. In WordPress admin, go to **Plugins > Add New > Upload Plugin**
3. Upload the ZIP and activate

### Manual

1. Copy the `winnow-search` directory into `wp-content/plugins/`
2. Activate via **Plugins** in WordPress admin

## Configuration

1. Go to **Settings > Winnow Search**
2. Paste your Winnow Site ID (looks like `site_abc123`)
3. Keep **Automatic updates** checked if you want Winnow Search to re-index changed pages automatically
4. Save changes

The embed script will appear in the `<head>` of all public pages that call `wp_head()`.
WordPress can also notify Winnow Search when public content or attachments change.

## Development

### Dev Container (recommended)

This project includes a fully containerized development environment:

1. Open this directory in [VS Code](https://code.visualstudio.com/) or any editor that supports Dev Containers
2. When prompted, click **Reopen in Container** (or run **Dev Containers: Reopen in Container** from the command palette)
3. The container will build, install WordPress, symlink the plugin, and activate it
4. Visit `http://localhost:8080` to see the WordPress site
5. Visit `http://localhost:8080/wp-admin/options-general.php?page=winnow-search` for plugin settings

**Credentials:** `admin` / `admin`

### Local CLI with Docker Compose

If you prefer the terminal over a dev container editor, you can bring up the full WordPress test site with plain Docker Compose commands. You only need [Docker](https://docs.docker.com/get-docker/) installed.

From the `winnow-search` plugin directory:

```bash
# Build and start WordPress + MariaDB
docker compose -f .devcontainer/docker-compose.yml up -d --build

# Run the one-time setup (install WordPress, symlink the plugin, activate it)
docker compose -f .devcontainer/docker-compose.yml exec -T plugin bash /workspaces/winnow-search/bin/setup.sh
```

Then open your browser:

| What            | URL                                                                   |
| --------------- | --------------------------------------------------------------------- |
| WordPress site  | http://localhost:8080                                                 |
| Admin dashboard | http://localhost:8080/wp-admin                                        |
| Plugin settings | http://localhost:8080/wp-admin/options-general.php?page=winnow-search |

**Credentials:** `admin` / `admin`

Run the test suite:

```bash
docker compose -f .devcontainer/docker-compose.yml exec plugin php /workspaces/winnow-search/tests/run-tests.php
```

Tear everything down when you are done:

```bash
docker compose -f .devcontainer/docker-compose.yml down
```

To also remove the WordPress database and uploaded files (fresh start next time):

```bash
docker compose -f .devcontainer/docker-compose.yml down -v
```

### Running Tests (without Docker)

If you have PHP 7.4+ installed locally:

```bash
php tests/run-tests.php
```

The test suite uses stub WordPress functions so it runs without a full WordPress installation.

### Building a Distribution ZIP

```bash
bin/build-zip.sh
```

This creates `dist/winnow-search.zip` containing only the files needed for production deployment (no devcontainer, tests, or build tooling).

## File Structure

```
winnow-search/
├── .devcontainer/          Dev container configuration for local testing
│   ├── devcontainer.json
│   ├── docker-compose.yml
│   └── Dockerfile
├── bin/
│   ├── setup.sh            WordPress installation and plugin activation
│   └── build-zip.sh        Build a distributable ZIP
├── tests/
│   └── run-tests.php       Standalone test suite with WP function stubs
├── winnow-search.php        Main plugin file
├── uninstall.php            Cleanup options on plugin uninstall
└── README.md
```

## Uninstalling

When you delete the plugin through WordPress, `uninstall.php` runs automatically and removes all stored options from the database.

## License

This plugin is licensed under the [GNU General Public License v2.0 or later](https://www.gnu.org/licenses/gpl-2.0.html) (GPLv2+), which is the same license as WordPress itself. This is required for plugins published in the [WordPress.org Plugin Directory](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/#1-plugins-must-be-compatible-with-the-gnu-general-public-license).