Notifal 2.x / 3.x is organized as modules on top of shared infrastructure and domain layers. This page maps the moving parts so you know where to hook in or resolve services.
Start with Getting Started for Developers if you have not read the boot sequence yet.
High-level layout
notifal/
├── app/
│ ├── Bootstrap/Plugin.php # init orchestration
│ ├── Core/ # Container, AbstractServiceProvider, helpers
│ ├── Domain/ # Tags, Settings (cross-cutting)
│ ├── Infrastructure/WordPress/ # Admin UI, hooks, migrations
│ ├── Modules/ # Feature modules (OnPageNotification, Templates, Campaign, Forms, Ai)
│ └── Shared/ # Admin list views, fields, toasts
└── build/ # Compiled JS/CSS (enqueue these in production)
Notifal Pro adds notifal-pro/app/ with the same module pattern and bridges into base hooks (display rules, analytics, content source).
Module discovery
Plugin::boot_modules() scans:
app/Modules/*/ServiceProvider.php
Each provider extends Notifal\Core\Foundation\AbstractServiceProvider and defines:
| Piece | Purpose |
|---|---|
protected static array $services | Classes to instantiate via the container |
protected const FILTER_HOOK | Optional filter to add/remove services (per module) |
boot() | Optional early setup on the provider itself |
Registration flow:
- Filter service list (if
FILTER_HOOKis set) - Provider
boot() - For each service:
Container::get(), thenregister()/boot()on the instance
Example module filters:
| Module | Service filter hook |
|---|---|
| On-page notifications | notifal/onpage/services |
| Templates | notifal/templates/services |
| Campaigns | notifal/campaign/services |
| Forms | notifal/forms/services |
| Ai | notifal/ai/services |
| Tags domain | notifal/tags/services |
| Settings domain | notifal/settings/services |
| Global infrastructure | notifal/infrastructure/services |
Dependency injection
notifal_app( string $class ) resolves singletons from Notifal\Core\Foundation\Container.
Typical usage:
- Inside Notifal services (constructor injection via container)
- In your extension code after
notifal/initialized
Avoid new \Full\Namespace\Class() for Notifal services unless the class is documented as a value object or DTO.
Custom post types (CPT)
| CPT slug | Purpose |
|---|---|
notifal_onpage_notif | On-page notification posts |
notifal_template | Notification templates (HTML Builder, Block, Elementor) |
notifal_campaign | Campaigns |
notifal_form | Forms identity, field definitions, emails, and integration secrets (@since 3.0.0) |
Post type registration args are filterable:
| Filter | CPT |
|---|---|
notifal/onpage_post_type/args | On-page notifications |
notifal/template_post_type/args | Templates |
Notification settings are stored in post meta on the notification CPT. Campaign settings use campaign post meta. Forms store fields and settings on the Form CPT.
On-page notification module (largest surface)
Under app/Modules/OnPageNotification/:
| Layer | Responsibility |
|---|---|
Application/Services/ | Business logic: eligibility, save, tracking, display rules, content source |
Infrastructure/WordPress/ | CPT, REST ApiRegistrar, repositories |
Presentation/ | Admin views, frontend assets, API controllers |
Frontend flow:
- JS calls
GET /wp-json/notifal/v1/onpage/eligible EligibilityService+NotificationEligibilityCheckerapply rulesNotificationDataPreparerbuilds payload (filters apply here)- JS tracks via
POST /wp-json/notifal/v1/onpage/track
See REST API Reference and Hooks: Notifications and Eligibility.
Templates module
Handles template CRUD, HTML Builder sanitization, Elementor widgets, import/export, and preview routes.
Key integration filters: notifal/template/import/result, notifal/template/html/sanitize/before, notifal/templates/services.
See Hooks: Templates and Rendering.
Campaign module
Campaigns link notifications through campaign assignment meta. Schedule checks run in CampaignSettingsService and integrate with NotificationEligibilityChecker through notifal/campaign/schedule_check.
User-facing behavior: What Are Campaigns?.
Forms module (@since 3.0.0)
Under app/Modules/Forms/:
| Layer | Responsibility |
|---|---|
Application/Services/ | Submit pipeline, validation, emails, integrations, field sync |
Infrastructure/WordPress/ | notifal_form CPT, AJAX submit, repositories |
Presentation/ | Admin Forms UI, submissions inbox, frontend assets |
HTML templates own presentation. The Form CPT owns secrets and durable field definitions. Public submit uses WordPress AJAX with server-side integrity and spam checks.
See Hooks: Forms and Notifal Forms Overview.
AI module (@since 3.0.0)
Under app/Modules/Ai/:
| Layer | Responsibility |
|---|---|
Application/Services/ | Connection, usage, generation bridge to notifal.com |
Infrastructure/Gateway/ | Server-side HTTP client for hosted AI (credentials stay in PHP) |
Presentation/ | Admin UI assets for Noti chat and the OnPage wizard |
HTML Builder uses floating Noti chat (html_template). OnPage list uses the hosted wizard (onpage_notification). The browser never receives hosted AI credentials.
Tags domain
app/Domain/Tags/ is booted before modules because templates and notifications depend on tag resolution.
RegisterTags.phpregisters built-in tags onnotifal/tag/registerTagManagerresolves{tag}placeholders in content- REST:
/wp-json/notifal/v1/tags,/wp-json/notifal/v1/dynamic-keys
See Hooks: Tags and Dynamic Data.
Admin UI building blocks
Shared admin UI lives in app/Shared/AdminUI/:
FieldRenderer, form controls used in notification and campaign editorsBaseListView, list tables for notifications, templates, campaigns
Extension points: notifal/admin/onpage/%s/before, notifal/admin/onpage/%s/%s/before (tab and section), plus field-level notifal/field/*/before/{id} actions.
See Hooks: Admin UI Extension.
What to read next
- Architecture Overview (you are here)
- REST API Reference
- Hook Reference Hub