Creating an Addon
This guide walks you through creating a new addon from scratch using the Artisan command-line tool.
Generate the Addon
Open your terminal, navigate to the Mumara Campaigns root directory, and run:
php artisan module:make YourAddonName
Replace YourAddonName with your addon's name using PascalCase (e.g., EmailValidator, CrmConnector, AdvancedReports).
Create Multiple Addons
You can create multiple addons at once:
php artisan module:make EmailValidator CrmConnector AdvancedReports
Generated Structure
The command creates a new directory under /Addons/YourAddonName/ with the following structure:
Addons/YourAddonName/
├── module.json
├── composer.json
├── package.json
├── webpack.mix.js
├── functions.php
├── menu.json
├── Config/
│ └── config.php
├── Console/
├── Database/
│ ├── Migrations/
│ └── Seeders/
│ └── YourAddonNameDatabaseSeeder.php
├── Entities/
├── Http/
│ ├── Controllers/
│ │ └── YourAddonNameController.php
│ ├── Middleware/
│ └── Requests/
├── Providers/
│ ├── YourAddonNameServiceProvider.php
│ ├── EventServiceProvider.php
│ └── RouteServiceProvider.php
├── Resources/
│ ├── assets/
│ │ ├── js/
│ │ │ └── app.js
│ │ └── sass/
│ │ └── app.scss
│ ├── lang/
│ └── views/
│ ├── layouts/
│ │ └── master.blade.php
│ └── index.blade.php
├── Routes/
│ ├── web.php
│ └── api.php
├── Settings/
│ ├── config.php
│ ├── install/
│ └── uninstall/
├── hooks/
│ └── hooks.php
└── Tests/
├── Feature/
└── Unit/
Configure the Addon
After generation, configure your addon's metadata.
1. Edit module.json
The module.json file is your addon's manifest:
{
"name": "YourAddonName",
"alias": "youraddonname",
"description": "Description of what your addon does",
"keywords": ["mumara", "addon", "feature"],
"priority": 0,
"providers": [
"Addons\\YourAddonName\\Providers\\YourAddonNameServiceProvider",
"Addons\\YourAddonName\\Providers\\EventServiceProvider"
],
"files": [],
"requires": []
}
| Field | Description |
|---|---|
name | Addon name (PascalCase) |
alias | Lowercase identifier used in views and routes |
description | Brief description of the addon |
keywords | Search keywords |
priority | Load order (lower loads first) |
providers | Service providers to register |
files | Additional PHP files to autoload |
requires | Dependencies on other addons |
2. Edit Settings/config.php
Configure addon properties displayed in the admin panel:
<?php
$setting = [
'name' => 'Your Addon Name',
'vendor' => 'Your Company',
'type' => 'Integration',
'logo' => 'logo.png',
'version' => '1.0.0',
'route' => 'youraddon',
'install_dir' => 'YourAddonName',
'license_type' => 'free', // native, marketplace, remote, or free
'new_version_url' => '',
'update_url' => '',
'license_key' => ''
];
| Field | Description |
|---|---|
name | Display name in addon manager |
vendor | Your company/developer name |
type | Category (Integration, Feature, Utility, etc.) |
logo | Logo filename in Settings/ directory |
version | Current version number |
route | Base route prefix for your addon |
install_dir | Directory name under /Addons |
license_type | Licensing model |
new_version_url | URL to check for updates |
update_url | URL to download updates |
license_key | License key (if applicable) |
3. Configure composer.json
Set up PHP autoloading and dependencies:
{
"name": "yourcompany/youraddonname",
"description": "Your addon description",
"type": "library",
"require": {},
"autoload": {
"psr-4": {
"Addons\\YourAddonName\\": ""
}
}
}
Set Up the Service Provider
The main service provider bootstraps your addon. Edit Providers/YourAddonNameServiceProvider.php:
<?php
namespace Addons\YourAddonName\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Console\Scheduling\Schedule;
class YourAddonNameServiceProvider extends ServiceProvider
{
protected string $moduleName = 'YourAddonName';
protected string $moduleNameLower = 'youraddonname';
public function boot(): void
{
$this->registerHooks();
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
}
public function register(): void
{
$this->app->register(RouteServiceProvider::class);
$this->app->register(EventServiceProvider::class);
}
protected function registerHooks(): void
{
foreach (glob(module_path($this->moduleName, 'hooks/*.php')) as $file) {
require_once $file;
}
}
protected function registerTranslations(): void
{
$langPath = resource_path('lang/modules/' . $this->moduleNameLower);
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
} else {
$this->loadTranslationsFrom(module_path($this->moduleName, 'Resources/lang'), $this->moduleNameLower);
}
}
protected function registerConfig(): void
{
$this->publishes([
module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'),
], 'config');
$this->mergeConfigFrom(
module_path($this->moduleName, 'Config/config.php'),
$this->moduleNameLower
);
}
protected function registerViews(): void
{
$viewPath = resource_path('views/modules/' . $this->moduleNameLower);
$sourcePath = module_path($this->moduleName, 'Resources/views');
$this->publishes([
$sourcePath => $viewPath
], ['views', $this->moduleNameLower . '-views']);
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
}
private function getPublishableViewPaths(): array
{
$paths = [];
foreach (config('view.paths') as $path) {
if (is_dir($path . '/modules/' . $this->moduleNameLower)) {
$paths[] = $path . '/modules/' . $this->moduleNameLower;
}
}
return $paths;
}
}
Create Your First Route
Edit Routes/web.php to add routes:
<?php
use Illuminate\Support\Facades\Route;
use Addons\YourAddonName\Http\Controllers\YourAddonNameController;
Route::middleware(['web', 'auth'])->prefix('youraddon')->group(function () {
Route::get('/', [YourAddonNameController::class, 'index'])->name('youraddon.index');
Route::get('/settings', [YourAddonNameController::class, 'settings'])->name('youraddon.settings');
});
Create a Controller
Edit Http/Controllers/YourAddonNameController.php:
<?php
namespace Addons\YourAddonName\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class YourAddonNameController extends Controller
{
public function __construct()
{
$this->middleware(['auth', '2fa']);
}
public function index()
{
return view('youraddonname::index', [
'title' => 'Your Addon'
]);
}
public function settings()
{
return view('youraddonname::settings');
}
}
Create a View
Edit Resources/views/index.blade.php:
@extends('layouts.master2')
@section('title', $title)
@section('content')
<div class="kt-container kt-container--fluid kt-grid__item kt-grid__item--fluid">
<div class="kt-portlet">
<div class="kt-portlet__head">
<div class="kt-portlet__head-label">
<h3 class="kt-portlet__head-title">{{ $title }}</h3>
</div>
</div>
<div class="kt-portlet__body">
<p>Welcome to your addon!</p>
</div>
</div>
</div>
@endsection
Add a Menu Item
Edit menu.json to add navigation:
[
{
"title": "Your Addon",
"icon": "<i class='kt-menu__link-icon flaticon-app'></i>",
"url": "youraddon",
"hidden": false,
"hasChild": false,
"childrens": []
}
]
For nested menus:
[
{
"title": "Your Addon",
"icon": "<i class='kt-menu__link-icon flaticon-app'></i>",
"url": "#",
"hidden": false,
"hasChild": true,
"childrens": [
{
"title": "Dashboard",
"icon": "<i class='menu-bullet menu-bullet-dot'><span></span></i>",
"url": "youraddon",
"hidden": false
},
{
"title": "Settings",
"icon": "<i class='menu-bullet menu-bullet-dot'><span></span></i>",
"url": "youraddon/settings",
"hidden": false
}
]
}
]
Install the Addon
After setting up your addon:
- Log into Mumara Campaigns as admin
- Navigate to Setup > Addons
- Find your addon in the list
- Click Install
The system will:
- Run database migrations
- Publish translations and configuration
- Enable the addon
Verify Installation
After installation:
- Clear the cache:
php artisan cache:clear - Navigate to your addon's route (e.g.,
/youraddon) - Verify the menu item appears in the sidebar
Next Steps
- Directory Structure - Understand each component
- Configuration - Advanced configuration options
- Routes & Controllers - Build your addon's pages