UI Elements

Add navigation items, sidebar links and widgets to existing WemX pages from any extension, without editing core views.

Elements are WemX's injection points. Any extension can return an elements() array to add links to menus or render its own Blade views inside core pages, such as the dashboard, the order page or the customer profile.

public function elements(): array
{
    return [
        // a link
        [
            'element' => 'navigation-item',
            'attributes' => ['name' => 'Status', 'href' => '/status', 'active' => 'status'],
        ],
        // a widget (Blade view)
        [
            'element' => 'client-dashboard-top-view',
            'view' => 'status::client_area.default.widgets.banner',
        ],
    ];
}

Elements are saved to the database when the extension is enabled. After changing elements(), disable and re-enable the extension to apply the changes.

Link elements take an attributes array.

ElementWhere it rendersAttributes
navigation-itemMain client area navigation barname, href, active
client-dropdown-itemAccount dropdown (top right)name, href, target, navigate
footer-itemClient area footername, href
admin-sidebar-itemAdmin sidebar linkname, href, icon, active
admin-sidebar-item-dropdownAdmin sidebar group with childrenname, icon, active, items[] (each: name, href, icon, active, permission)
  • active is the page key that highlights the link. It's matched against the activePage your view passes to the layout. It can also be an array of keys.
  • icon is a Tabler icon name, for example ticket or download.
  • navigate: true uses Livewire's SPA-style navigation.
[
    'element' => 'admin-sidebar-item-dropdown',
    'attributes' => [
        'name' => 'Tickets',
        'icon' => 'ticket',
        'active' => ['tickets', 'ticket-departments'],
        'items' => [
            ['name' => 'Overview', 'href' => '/admin/tickets', 'icon' => 'inbox', 'active' => 'tickets', 'permission' => 'admin.tickets'],
            ['name' => 'Departments', 'href' => '/admin/ticket-departments', 'icon' => 'folder', 'active' => 'ticket-departments', 'permission' => 'admin.ticket-departments'],
        ],
    ],
],

For admin links, put a permission on each dropdown item, so staff only see the links they're allowed to open. Always protect the routes themselves with the permission: middleware too.

View elements (widgets)

View elements take a view name, and are rendered with @includeIf inside the core page.

Client area

ElementLocationVariables
client-dashboard-top-viewTop of the customer dashboard$user
client-dashboard-sidebar-viewDashboard sidebar$user
client-dashboard-bottom-viewBottom of the dashboard$user
client-order-top-viewTop of the order page$order
client-order-sidebar-bottom-viewBottom of the order page's sidebar$order
client-order-bottom-viewBottom of the order page$order
client-login-top-view / client-login-bottom-viewAbove or below the login form—
client-register-top-view / client-register-bottom-viewAbove or below the registration form—

Admin area

ElementLocationVariables
admin-dashboard-top-viewTop of the admin dashboard—
admin-dashboard-main-viewMain column of the dashboard—
admin-dashboard-sidebar-viewDashboard sidebar—
admin-order-sidebar-viewAdmin order page sidebar$order
admin-customer-bottom-viewBottom of the admin customer page$user
admin-customer-edit-menu-itemAn extra tab on the admin customer page. Takes view plus attributes: identifier, name, show$user

Typical uses:

  • Server extensions: a Login to panel button and live usage on client-order-top-view; remote server details on admin-order-sidebar-view.
  • Modules: a summary card on the dashboard, such as "You have 1 open ticket"; a related-records table on the customer page.
  • Login/registration: an SSO or Login with Discord button on client-login-bottom-view.

Example: an order widget

extensions/Servers/Acme/Views/client/order-panel.blade.php
@if($order->isActive() && $order->hasExternalUser())
    <x-theme::card>
        <x-theme::text.h4>Control panel</x-theme::text.h4>
        <x-theme::text.p>Username: {{ $order->getExternalUser()->username }}</x-theme::text.p>
        <x-theme::button.primary href="{{ $order->package->serverConnection->config['url'] }}" target="_blank">
            Open panel
        </x-theme::button.primary>
    </x-theme::card>
@endif
['element' => 'client-order-top-view', 'view' => 'server-acme::client.order-panel'],

Views are rendered for every matching page, so check permissions and ownership inside the view before showing sensitive data.

Reading elements in a theme

Theme authors render elements with the extensionElements() helper:

@foreach(extensionElements(['client-order-top-view']) as $element)
    @includeIf($element['view'], ['order' => $order])
@endforeach

Custom themes should keep these loops in place, so extensions keep working.

On this page