---
title: 'Grav Core Service Manager'
url: 'https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-core-service-manager'
markdown: 'https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-core-service-manager.md'
date: '2026-09-25'
description: 'Adds a service manager to Grav.'
taxonomy:
  category:
    - docs
  devtype:
    - mit
---

[](#)  [ Home ](https://www.twelvetone.tv/docs/)     [ Developer Tools ](https://www.twelvetone.tv/docs/developer-tools)     [ Grav Plugins ](https://www.twelvetone.tv/docs/developer-tools/grav-plugins)      Grav Core Service Manager    

This product is in active development and has been released under the [MIT license](https://opensource.org/licenses/MIT).

Adds a service manager to Grav.

#### Table of Contents

- [Overview](#overview)
- [Usage](#usage)
    - [Obtaining The Service Manager](#obtaining-the-service-man)
    - [Registering Services](#registering-services)
    - [Obtaining Services](#obtaining-services)
    - [Using Services In Twigs](#using-services-in-twigs)
        - [service\_list](#service-list)
        - [service\_info\_list](#service-info-list)
        - [service\_list\_filter](#service-list-filter)
        - [service\_render](#service-render)
        - [service\_items](#service-items)
    - [Adding Service Listeners](#adding-service-listeners)
- [Core Service API](#core-service-api)
    - [renderer](#renderer)
    - [asset](#asset)
    - [action](#action)
        - [Look and Feel](#look-and-feel)
        - [Behavior](#behavior)
        - [Forms](#forms)
        - [Properties](#properties)
    - [page](#page)
    - [report](#report)
- [Additional Features](#additional-features)
    - [Client-Server Notifications](#client-server-notificatio)
    - [Dialogs and Alerts](#dialogs-and-alerts)
    - [Dependency Utilities](#dependency-utilities)

# Overview

The service manager is inspired by the OSGi service pattern. Services are registered by name, along with a list of properties. Clients can listen for service registrations, and also query the registry for services using service names and/or LDAP filters. Registrations can use factory methods to provide lazy instantiation.

# Usage

## Obtaining The Service Manager

The service manager singleton can be accessed from any point in the lifecycle.

```php
$manager = \Grav\Plugin\Admin\ServiceManager::getInstance();
```

## Registering Services

Services are registered using:

- *service name*
- an array, object, or primitive that *implements* or *fullfills* the service requirements
- an optional *properties* array

```php
$manager->registerService("has-label-service", ['label'=>'A sample label']);
$manager->registerService("has-label-service", ['label'=>'Another sample label'], ['scope'=>'private', 'type'=>'testing']);
```

A service also can be registered using a factory by providing an function closure that returns the service. The function will only be called if a client requests the service implementation. This provides a *lazy* service instantiation. The services properties can be used to published and queries do not require that the service is instantiated.

```php
$manager->registerService("has-label-service", function() {
    // take some time...
    return ['label'=>'A lazy label'];
});
```

## Obtaining Services

You can obtain a list of services by using the registered service name.

```php
$services = $manager->getServices('has-label-service');
foreach($services as $service) {
    $theLabel = $service['label'];
}
```

You can also get a service by its ID. The ID is returned when the service is first registered.

```php
$service = $manager->getService($serviceId);
```

You can obtain services and ServiceInfo objects using an [LDAP filter](http://www.ldapexplorer.com/en/manual/109010000-ldap-filter-syntax.htm) to query the service properties.

In this example, only has-label-service with properties *scope* set to *public* and *type* starting with *testing* will be returned.

```php
$services = $manager->find('has-label-service', '(&(scope=public)(type=testing*))');
```

More info on LDAP filters is available [here](https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx) and [here](https://confluence.atlassian.com/kb/how-to-write-ldap-search-filters-792496933.html).

## Using Services In Twigs

Several twig functions have been added to inject content into a document.

### service\_list

The service implementations matching the given parameters.

```
    /**
     * @param string $serviceName The service name.
     * @param string $scope The scope to filter.  null or 'any' to match all scopes.
     * @param string $order The order.  null or 'any' to match all items.
     * @param null $context A context used when filtering the items
     * @return array The services matching the given parameters
     */
    function service_list($serviceName, $scope = 'any', $order = 'any', $context = null)
```

### service\_info\_list

The service implementations matching the given parameters.

```php
    /**
     * @param string $serviceName The service name.
     * @param string $scope The scope to filter.  null or 'any' to match all scopes.
     * @param string $order The order.  null or 'any' to match all items.
     * @param null $context A context used when filtering the items
     * @return array The ServiceInfo objects matching the given parameters
     */
    function service_info_list($serviceName, $scope = 'any', $order = 'any', $context = null)
```

### service\_list\_filter

The service implementations matching the given LDAP filter.

```php
    /**
     * @param string $ldapFilter A LDAP filter
     * @param null $context A context used when filtering the items.
     * @return array The services matching the given parameters.
     * @throws \Exception
     */
    function service_list_filter($ldapFilter, $context = null)
```

### service\_render

The concatinated result of calling render() or rendering an action based on scope.

```php
    /**
     * 
     * Renders "renderer" and "action" services
     * 
     * @param $serviceName The service name.
     * @param string $scope The scope to filter.  null or 'any' to match all scopes.
     * @param string $order The order.  null or 'any' to match all items.
     * @param null $context
     * @return string
     */
    public function service_render($serviceName, $scope = null, $order = null, $context = null)
```

### service\_items

A concatenated string list of calling 'items' on each service.

```php
    /**
     * @param string $serviceName The service name.
     * @param string $scope The scope to filter.  null or 'any' to match all scopes.
     * @param string $order The order.  null or 'any' to match all items.
     * @return array Concatenated list of calling 'items' on each service.
     */
    function service_items($serviceName, $scope = 'any', $order = 'any')
```

## Adding Service Listeners

The Service Manager allows adding listeners for service registrations.

```php
$manager = ServiceManager::getInstance();

$manager->registerServiceListener('asset', function (&$serviceInfo) {
  log("Asset registered: " . $serviceInfo['implementation']['url']);
});
```

```
    /**
     * @param string $serviceName
     * @param callable string,array $listener
     * @param bool|null $fireOnExisting If true, the listener will be invoked for existing items.
     */
    public function registerServiceListener($serviceName, $listener, $fireOnExisting = false)
```

# Core Service API

Most core services have the following fields:

Scopearray of string 
The scope in which the service applies. Known scopes: page | pages | configuration | dashboard | admin:sidebar | page:more | page:add 

Orderstring: first | last | before:parent | after:parent
The order of the item.todo: Add order before-xxx, after-xxx 

todo: Add order integer weight 

isEnabledfunction: truthy 
By default all services are enabled. If a service declares a function called isEnabled($context) that returns a falsy value, the service will be considered *disabled*.isVisiblefunction: truthy 
By default all services are visible. If a service declares a function called isVisible($context) that returns a falsy value, the service will be considered *hidden*.isSelectedfunction: truthy 
By default all services unselected. If a service declares a function called isSelected($context) that returns a truthy value, the service will be considered *selected*.groupA target group within the scopetodo: implement group 

These are the current services implemented in the Grav Admin. \[minitoc\]

## renderer

A general interface for rendering content.

Common Fieldsscope, orderisVisible(context): BooleanReturns boolean. `true` if the system should display the item.render(context) : StringReturns html. The context parameter is dependent on the registered scope.## asset

A general interface for adding assets to a page. Assets can be added at any time, even before and after the *onAssetsInitialized* event is fired by the Grav system. You can now also register *link* assets (for our *web component* fans).

Common Fieldsscope, order, isEnabled 
Assets that return **false** for isEnabled() will not be added to the document.typeString: The asset type.
Allowed values: css | javascript | js | twig | linkurlString: The url of the asset.contentString: The content to inject. todo: implement content

## action

A general interface for declaring an action.

Actions can be *rendered* by the system as menu items, buttons, links, callable methods, etc. based on their target scope. Actions can also provided their own rendered content.

An action callback can be executed on the client, the server, or both. The server callback can be asynchronous (AJAX) or synchronous (POST). The client callback can manually invoke the server callback if needed for validation, confirmations, etc. Action callbacks receive a context from the scope in which they are called.

Actions can specify the forms that opened when they are triggered. They can optionally submit a grav task when the forms are submitted.

Common Fieldsscope, order, isVisible, isEnabled, isSelected### Look and Feel

captionString,optional: The caption to displayicon String,optional: The icon to displayrenderfunction(context): String, optional: A callback function that returns an HTML string. The context provided is dependant on the scope.### Behavior

clientCallbackString: The Javascript to be executed on the browser.serverCallbackIdString: A unique ID used to identify the callback when the client posts the action to the server.serverCallbackContextString | Array The context sent to the server callback.serverAsyncCallbackFunction: The PHP to be executed on the server. This is posted AJAX. The client will not be refreshed.serverCallbackFunction: The PHP to be executed on the server. This is posted using a standard form POST. The client will be refreshed.serverHandlerFunction: Same as ServerCallback, but must be manually invoked from client-side code.```
_asyncActionCallback(actionId, scopeContext);
_syncActionCallback(actionId, scopeContext);
```

### Forms

confirmationMessageString: A message to display before callbacks are executed. If the user chooses to cancel, neither the clientCallback or serverCallback will be invoked.form\_idThe ID to use for the the form.form\_blueprintThe form blueprint .form\_dataA callback function the returns the data for the form. function($context) { return [ ]; }

### Properties

menuThe dropdown menu to add the action to.## page

A service to register page routes and generate pagesscopeString: site | adminpriorityInteger: The priority of the the route.rxrouteString: The route, starting with '/' and containing a regular expression to match.getPagefunction getPage(route:String) : Pagetodo: Implement priority when multiple routes are matched 

## report

Adds a report to the reports list.

scopeString: The scope of the report. Valid values are site | admincaptionThe report captiongeneratefunction generate(): String# Additional Features

The plugin also includes built-in features for the following items.

## Client-Server Notifications

Synchronous and asynchronous posts to the server.

## Dialogs and Alerts

Simple modal dialogs for confirmations and alerts.

## Dependency Utilities

A class for checking runtime plugin dependencies has been added.

 [ ](https://www.twelvetone.tv/docs/developer-tools/grav-plugins) [](https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-power-tools)

---

## Navigation

- Parent: [Grav Plugins](https://www.twelvetone.tv/docs/developer-tools/grav-plugins.md)
- Next: [Grav Admin Power Tools](https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-power-tools.md)
