Reference plugins
Contact Form
plugins/ContactForm/
├── ContactFormPlugin.php
├── plugin.json
├── Http/Controllers/{ContactDashboardController,ContactSubmissionController}.php
├── Http/Requests/StoreContactMessageRequest.php
├── Models/ContactMessage.php
├── database/migrations/2026_08_06_000100_create_contact_messages_table.php
├── resources/views/dashboard/index.blade.php
├── resources/views/site/{form,page}.blade.php
└── routes/web.php
Business plugin; settings heading/description/button label normalized to tag-free 80/240/40 chars. It contributes dashboard messages order 40, full-width contact-us, and before-footer (suppressed on that page). Submission uses tenant ULID model, CSRF, 5/minute, bounded name/email/message, prohibited website honeypot, and repeated active/published/effective checks. It stores messages; it does not send email.
Karam Banner
plugins/KaramBanner/
├── KaramBannerPlugin.php
├── plugin.json
├── resources/views/site/banner.blade.php
└── routes/web.php
Theme add-on requiring Karam ^1.0, Theme API ^1.0, before-footer. Two tag-free bounded text settings; no model, migration, dashboard, page, or route.
Events
plugins/Events/
├── EventsPlugin.php
├── EventsSeeder.php
├── plugin.json
├── Http/Controllers/EventController.php
├── Http/Requests/{StoreEventRequest,UpdateEventRequest}.php
├── Models/Event.php
├── Policies/EventPolicy.php
├── database/migrations/2026_08_07_010000_create_events_table.php
├── resources/views/dashboard/{_form,create,edit,index}.blade.php
├── resources/views/site/{index,show,upcoming}.blade.php
└── routes/web.php
Exact PHP and lifecycle paths:
plugins/Events/EventsPlugin.php
plugins/Events/EventsSeeder.php
plugins/Events/Models/Event.php
plugins/Events/Policies/EventPolicy.php
plugins/Events/Http/Controllers/EventController.php
plugins/Events/Http/Requests/StoreEventRequest.php
plugins/Events/Http/Requests/UpdateEventRequest.php
plugins/Events/database/migrations/2026_08_07_010000_create_events_table.php
plugins/Events/routes/web.php
The declared root EventsSeeder.php skips non-local/non-testing environments; otherwise it enters every organization context and idempotently creates a published community-open-day. EventPolicy extends the tenant-aware platform resource policy and the controller authorizes list, create, view, update, and delete operations.
Events requires home slot, pages, navigation; page-after-content is optional. Settings: heading max 80, maximum items 1..9, show location boolean, and display_style (cards or list). Dashboards: index order 30 and create order 31. Pages: navigable full-width events order 40 with 12-item pagination; contained non-navigable events/{event}. Home slot priority 40 appears only at null path and shows upcoming records.
Events management routes use /charity/{organization:slug}/plugins/events/manage and plugin.events.dashboard.* with plugin.available:events,installed, matching its dashboards' requiresEnabled: false. Platform settings remain at /charity/{organization:slug}/plugins/events.
Published queries require status/published timestamp; preview includes drafts. The tenant-scoped table has ULID, tenant FK, title, tenant-unique slug, summary/body, start/end, nullable location/capacity, status, published timestamp, timestamps, unique (organization_id, slug), and index (organization_id, status, starts_at).
CRUD sets/preserves publication time while published and clears it for draft. Install runs the package migration before this tenant-scoped sample seeder.
Fundraising
Fundraising is the complex business reference package:
plugins/Fundraising/
├── FundraisingPlugin.php
├── FundraisingSeeder.php
├── plugin.json
├── Enums/{ProjectStatus,DonationStatus}.php
├── Models/{Project,Donation,DonationChannel}.php
├── Policies/FundraisingPolicy.php
├── Http/Controllers/FundraisingController.php
├── Http/Controllers/Dashboard/{Overview,Project,Donation,DonationChannel,Supporter,Report}Controller.php
├── Http/Requests/{StoreProjectRequest,UpdateProjectRequest}.php
├── database/migrations/
├── resources/views/{site,dashboard,widgets}/
└── routes/web.php
It demonstrates grouped organization navigation, organization-home widgets, read-only Super Admin pages/widgets, project state transitions, public static/dynamic pages, guest submissions, normalized phone matching, private proof files, review attribution, verified-only progress, channels, supporters, and reports. See Fundraising plugin for exact routes, state rules, storage, and privacy boundaries.