Modules

Work In progress! No support given. You are on your own.

Introduction

WemX has an advanced modular system. Modules allow you to extend the capabilities of your WemX panel. Modules are essentially a mini Laravel application with routes, providers, models, controllers, views and more. We'd love for you to develop modules and add them to the WemXModules library.

In this guide, we'll dive into the depths of WemX modules. Before we begin, you should definitely have programming experience with PHP and Laravel. What will we cover in this course? We will develop a module that creates a page in the customer area and in the admin area. On the admin side, we will create a settings page. On the client side, we will display simple text. We will also look at how to save and retrieve the settings and simply display them on the page in this example.

Creating a new Module

Using SSH you may run the following command to generate a Module: php artisan module:make <module-name>

In our example, we will develop an ExampleModule, so let's call it ExampleModule.

We will now use our command (shown below) in the directory of our development environment. In my chase /var/www/wemx-dev/

php artisan module:make ExampleModule

You will gave a newly created folder within in Folder Modules/<module-name>

In our case Modules/ExampleModule

You can use ssh to remotly work on it. VSCode and PHPStorm have this feature. And I will not use it here in the guide. Here I just download the Module so its on my PC and afer working in it I upload the module to the server.

Before we start developing the Module we need to remove one line of code to fix the page

Open the file Routes/web.php

Replace all imports with use with

use Illuminate\Support\Facades\Route;
use ExampleModule\ExampleModuleController;

After that the all imports are ready.

We first start setting up our client routes with:

Route::group(['middleware' => 'auth', 'prefix' => 'admin'], function () {
    Route::get('/examplemodule/client', [ExampleModuleController::class, 'client'])->name('examplemodule.index');
});

Then we can start putting in our admin routes

Route::group(['middleware' => ['auth', 'permission:admin.view'], 'prefix' => 'admin'], function () {
    Route::get('/admin/examplemodule', [ExampleModuleController::class, 'admin'])->name('examplemodule.admin');
});

After all this we shoud have a route file that looks like that:

<?php

use Illuminate\Support\Facades\Route;
use ExampleModule\ExampleModuleController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::group(['middleware' => 'auth', 'prefix' => 'admin'], function () {
    Route::get('/examplemodule/client', [ExampleModuleController::class, 'client'])->name('examplemodule.index');
});

Route::group(['middleware' => ['auth', 'permission:admin.view'], 'prefix' => 'admin'], function () {
    Route::get('/admin/examplemodule', [ExampleModuleController::class, 'admin'])->name('examplemodule.admin');
});

We fist need to prepare our config file.

Open config/config.php and now you need to think what you need in the folowing is my config I will use for this Module but there is also a snippet for every type.

<?php

return [

    'name' => 'Example Module',
    'icon' => 'https://imgur.png',
    'author' => 'WemXModules Team',
    'version' => '1.0.0',
    'wemx_version' => '1.0.0',

    'elements' => [

        'main_menu' =>
            [
                [
                    'name' => 'Example Module',
                    'icon' => '<i class="fa-solid fa-ticket-simple"></i>',
                    'href' => '/exaplemodule/client',
                    'style' => '',
                ],

            ],

        'admin_menu' =>
            [
                [
                    'name' => 'Example Module',
                    'icon' => '<i class="fas fa-cog"></i>',
                    'href' => '/admin/exaplemodule',
                    'style' => '',
                ],
                // ... add more menu items
            ],

    ],

];

The main_menu config is for this:

'main_menu' =>
            [
                [
                    'name' => 'Example Module',
                    'icon' => '<i class="fas fa-cog"></i>',
                    'href' => '/exaplemodule/client',
                    'style' => '',
                ],

            ],

The user_dropdown create a new line here:

'user_dropdown' =>
        [
            [
                'name' => 'Example Module',
                'icon' => '<i class="fas fa-cog"></i>',
                'href' => '#',
                'style' => '',
            ],
            // ... add more menu items
        ],

For the Admin Menu we have 2 options.

  • Normal Button

  • Dropdown Menu

First I will show the normal button

'admin_menu' =>
        [
            [
                'name' => 'Example Module',
                'icon' => '<i class="fas fa-cog"></i>',
                'href' => '#',
                'style' => '',
            ],
            // ... add more menu items
        ],

For the dropdown we use this code

'admin_menu' =>
            [

                [
                    'name' => 'Giftcards',
                    'icon' => '<i class="fas fa-gift"></i>',
                    'type' => 'dropdown',
                    'items' => [
                        [
                            'name' => 'Example',
                            'href' => '/admin/example/menu1',
                        ],
                        [
                            'name' => 'Example',
                            'href' => '/admin/example/menu2',
                        ],
                        [
                            'name' => 'Example',
                            'href' => '/admin/giftcard/menu3',
                        ],
                        // ... add more menu items
                    ],
                ],

            ],

For creating the Theme we need to prepare our folder structure. Go into the Resources/views folder. In there delete everything

Then you need to create two folders in the views directory. The first directory you name client and the second one you name admin. It shoud look like this:

Then we need to prepare the Controller. Here I will just show a example, if you need to do more then just display a view fille you need to learn laravel.

<?php

namespace Modules\ExampleModule\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;


class ExampleModuleController extends Controller
{
    /**
     * Display a listing of the resource.
     */

    public function admin()
    {
        return view('examplemodule::admin.admin');
    }
    public function client()
    {
        return view('examplemodule::client.client');
    }
}

For this to work we need to create 2 view filles. One in the client folder and one in the admin folder.

Create a file called admin.blade.php in the admin folder.

admin.blade.php
@extends(AdminTheme::wrapper(), ['title' => __('ExampleModule Admin Site'), 'keywords' => 'WemX Dashboard, WemX Panel'])

@section('css_libraries')
    <link rel="stylesheet" href="{{ asset(AdminTheme::assets('modules/summernote/summernote-bs4.css')) }}" />
    <link rel="stylesheet" href="{{ asset(AdminTheme::assets('modules/select2/dist/css/select2.min.css')) }}">

@endsection

@section('js_libraries')
    <script src="{{ asset(AdminTheme::assets('modules/summernote/summernote-bs4.js')) }}"></script>
    <script src="{{ asset(AdminTheme::assets('modules/select2/dist/js/select2.full.min.js')) }}"></script>
@endsection

@section('container')
    <h1>
        Welcome to WemX Admin Panel
    </h1>
    <form action="{{ route('admin.settings.store') }}" method="POST">
        @csrf
        <div class="row">
            <div class="form-group col-12">
                <div class="form-group col-12">
                    <label>Setting1</label>
                    <input type="url" name="example::1" value="@settings('example::1', 'Hello World 1')" class="form-control">
                </div>
                <div class="form-group col-12">
                    <label>Setting2</label>
                    <input type="password" name="example::2" value="@settings('example::3', 'Hello World 2')" class="form-control">
                </div>
                <div class="form-group col-12">
                    <label>Setting3</label>
                    <input type="text" name="example::3" value="@settings('example::3', 'Hello World 3')" class="form-control">
                </div>
            </div>
        </div>
        <div class="card-footer text-right">
            <button type="submit" class="btn btn-primary">{!! __('admin.submit') !!}</button>
        </div>
    </form>
@endsection

For impementation of the admin wrapper we need to use this template:

@extends(AdminTheme::wrapper(), ['title' => __('<-- Page Title here -->'), 'keywords' => 'WemX Dashboard, WemX Panel'])

@section('css_libraries')
    <link rel="stylesheet" href="{{ asset(AdminTheme::assets('modules/summernote/summernote-bs4.css')) }}" />
    <link rel="stylesheet" href="{{ asset(AdminTheme::assets('modules/select2/dist/css/select2.min.css')) }}">

@endsection

@section('js_libraries')
    <script src="{{ asset(AdminTheme::assets('modules/summernote/summernote-bs4.js')) }}"></script>
    <script src="{{ asset(AdminTheme::assets('modules/select2/dist/js/select2.full.min.js')) }}"></script>
@endsection

@section('container')
    <-- Webcontent here -->
@endsection

If you want to store settings you need this form:

<form action="{{ route('admin.settings.store') }}" method="POST">
        @csrf
        <div class="row">
            <div class="form-group col-12">
                <div class="form-group col-12">
                    <label>Setting</label>
                    <input type="url" name="example::example" value="@settings('example::example', 'example')" class="form-control">
                </div>
            </div>
        </div>
        <div class="card-footer text-right">
            <button type="submit" class="btn btn-primary">{!! __('admin.submit') !!}</button>
        </div>
    </form>

For the client view we will create this file in the client directory in this Module I will use this but you can set it induvidual.

@extends(Theme::wrapper())
@section('title', 'Giftcard Dashboard')


{{-- Keywords for search engines --}}
@section('keywords', 'WemX Dashboard, WemX Panel')

@section('container')

    <div class="flex items-center justify-between">
        <h2 class="mb-4 text-4xl tracking-tight font-extrabold text-gray-900 dark:text-white">Hello world! </h2>
    </div>

    <p>
        @settings('example::1', 'Hello World 1')
        @settings('example::2', 'Hello World 2')
        @settings('example::3', 'Hello World 3')
    </p>

@endsection

Last updated