# WordPress plugin

The Octany plugin adds a block and a shortcode that embed any Octany
widget — donation flows, 1-click Swish, donation goals, activity feeds,
Pulse, greetings, client portals and forms — in WordPress posts and
pages. Editors don't need the `unfiltered_html` capability: the plugin
writes the [embed snippet](frontend.md#1-fundraising) itself and only
loads it from Octany's own servers.

## Download

- **Zip:** [`/downloads/octany-wordpress-0.1.0.zip`](../downloads/octany-wordpress-0.1.0.zip)
- **Version:** 0.1.0
- **Requires:** WordPress 6.5+ (tested up to 7.1), PHP 7.4+
- **Languages:** English, Swedish
- **License:** GPLv2 or later
- **SHA-256:** `4741f6a830acf3287bb5c94f68a06b342b2f37858954f9e1d9ea0f26339502fe`

## Install and update

1. WordPress admin → **Plugins → Add New Plugin → Upload Plugin**.
2. Choose the zip, click **Install Now**, then **Activate**.

The plugin is not on WordPress.org, so updates don't appear in the
dashboard. Upload the newer zip the same way; WordPress offers to replace
the installed version. Existing blocks and shortcodes keep working.

## Block

1. In Octany admin, open the widget and copy its embed code.
2. In the block editor, add the **Octany widget** block (Embeds category;
   searchable as "octany", "donate", "swish").
3. Paste the embed code and click **Embed**.

The block parses type, account, widget ID, language and references from
the embed code. Everything can then be edited in the block sidebar:

- **Widget:** Type, Account ID, Widget ID.
- **Advanced:** Octany URL, Language, Reference ID, Reference name.

**Replace** in the block toolbar clears the widget so you can paste a
different embed code. The editor shows a placeholder; the widget renders
on the front end. Supports `wide`/`full` alignment and margin spacing.

## Shortcode

```text
[octany type="donate-v1" account="1234" widget="01HXXXXXXXXXXXXXXXXXXXXXXX"]
```

| Attribute | Required | Description |
| --- | --- | --- |
| `type` | yes | Widget type, see below. |
| `account` | yes | Octany account ID. Digits only. |
| `widget` | yes | Widget ID (26 characters). For forms, the form ID. |
| `url` | no | Octany app URL. Default `https://app.octany.com`. |
| `lang` | no | Two-letter language code (`sv`, `en`). Empty uses the widget's language. |
| `reference_id` | no | Passed to the loader as `referenceId`; stored on orders from the widget. |
| `reference_name` | no | Passed as `referenceName`; human-readable label for the reference. |

A shortcode in the block editor can be transformed into an Octany widget
block; all attributes carry over.

## Widget types

| `type` | Widget | Loader path | Container class |
| --- | --- | --- | --- |
| `donate-v1` | Donation flow | `donate-v1` | `.octany-donate` |
| `swish-v1` | 1-click Swish | `swish-v1` | `.octany-swish-widget` |
| `target-v1` | Donation goal | `target-v1` | `.octany-target-widget` |
| `feed-v1` | Activity feed | `feed-v1` | `.octany-feed-widget` |
| `pulse-v1` | Pulse | `pulse-v1` | `.octany-pulse-widget` |
| `greeting-v1` | Greeting | `greeting-v1` | `.octany-greeting-widget` |
| `portal-v1` | Client portal | `portal-v1` | `.octany-portal-widget` |
| `form-v1` | Form | `registration-v1` | `.octany-registration-widget` |

Forms are the exception: type `form-v1`, loader `registration-v1`, and
the `api` URL gets a `/forms` suffix (`…/widget/{account}/forms`).

## Output and validation

The block and shortcode render the same markup Octany admin hands out,
in place:

```html
<!-- [octany type="donate-v1" account="1234" widget="01HXXXXXXXXXXXXXXXXXXXXXXX" lang="sv"] -->
<div class="octany-donate" data-widget="01HXXXXXXXXXXXXXXXXXXXXXXX"></div>
<script
  type="module"
  src="https://give.octany.com/donate-v1/loader.js?api=https%3A%2F%2Fapp.octany.com%2Fwidget%2F1234&widget=01HXXXXXXXXXXXXXXXXXXXXXXX&lang=sv"
></script>
```

Nothing is rendered (no error, no empty container) when:

- `type` is not one of the widget types above;
- `account` is not digits only;
- `widget` is not 26 letters/digits;
- `url` is set but is not `https://` on `octany.com` or a subdomain
  (`localhost` also allowed), or has a path, query, fragment or
  credentials.

An invalid `lang` is dropped instead. Reference values are sanitized as
plain text.

Loaders are served from the `give.` host next to the app URL:
`https://app.octany.com` → `https://give.octany.com`.

Donor details (`data-donor-*`) and `data-terms-accepted` from the
[Fundraising embed](frontend.md#1-fundraising) are not exposed by the
plugin. Render the snippet yourself in your theme if you need them.

## Developer filters

| Filter | Default | Purpose |
| --- | --- | --- |
| `octany_domains` | `['octany.com', 'localhost']` | Hosts `url` may point at. Subdomains of each entry are allowed. |
| `octany_loader_origin` | `https://give.{host}` | Where loaders are served from. Receives the origin and the validated app URL. |

```php
// Allow a staging Octany in addition to production.
add_filter('octany_domains', function (array $domains) {
    $domains[] = 'octany.test';

    return $domains;
});
```
