Skip to content

Entity Builder UI#

The eb_ui module provides the base UI functionality for Entity Builder, including a YAML editor interface and shared API endpoints used by all grid providers.

Overview#

eb_ui serves two primary purposes:

  1. YAML Editor Fallback: Provides a CodeMirror-based YAML editor when no grid provider is active
  2. Shared API Endpoints: Provides validation, preview, and entity configuration endpoints used by all UI components

Architecture#

1
2
3
4
5
6
eb_ui (Submodule of eb)
├── GridProviderManager (discovers providers via hook)
├── EbUiYamlForm (YAML textarea + CodeMirror)
├── EbUiApiController (shared API endpoints)
├── EbUiSettingsForm (editor configuration)
└── Routes: /eb/api/validate, /eb/api/preview, etc.

Installation#

drush en eb_ui -y

For AG-Grid spreadsheet interface, also enable:

drush en eb_aggrid -y

Grid Provider System#

eb_ui discovers available grid providers via the hook_eb_ui_grid_provider_info hook:

#[Hook('eb_ui_grid_provider_info')]
public function gridProviderInfo(): array {
  return [
    'my_provider' => [
      'id' => 'my_provider',
      'label' => $this->t('My Custom Grid'),
      'form_class' => '\Drupal\my_module\Form\MyGridForm',
      'library' => 'my_module/grid',
      'theme_class' => 'my-theme-class',
    ],
  ];
}

Provider Selection#

The active provider is determined by eb_ui.settings.editor_mode:

Value Behavior
yaml Always use YAML editor
auto Use first available provider, fall back to YAML
{provider_id} Use specific provider

API Endpoints#

POST /eb/api/validate#

Validates YAML/JSON content against EB operations.

Headers Required: - X-Requested-With: XMLHttpRequest - X-CSRF-Token: {token} - Content-Type: application/json or text/plain

Response:

1
2
3
4
{
  "valid": true,
  "operation_count": 5
}

POST /eb/api/preview#

Generates a preview of operations that will be performed.

Headers Required: - X-Requested-With: XMLHttpRequest - X-CSRF-Token: {token}

Response:

{
  "success": true,
  "operation_count": 5,
  "previews": [
    {
      "index": 0,
      "type": "create_bundle",
      "summary": "Create node bundle 'article'",
      "details": {...},
      "warnings": []
    }
  ]
}

GET /eb/api/bundles/{entity_type}#

Fetches available bundles for an entity type.

Response:

1
2
3
4
5
6
7
{
  "success": true,
  "bundles": {
    "article": {"id": "article", "label": "Article"},
    "page": {"id": "page", "label": "Basic page"}
  }
}

GET /eb/api/entity-config/{entity_type}/{bundle}#

Fetches existing field configuration for an entity/bundle.

Response:

{
  "success": true,
  "entity_type": "node",
  "bundle": "article",
  "fields": {
    "field_body": {
      "name": "field_body",
      "label": "Body",
      "type": "text_long",
      "required": false
    }
  }
}

YAML Editor#

When no grid provider is active or when accessing the /source route, eb_ui displays a CodeMirror-based YAML editor:

Features#

  • Syntax highlighting for YAML
  • Line numbers
  • Auto-indentation
  • Error markers from validation

CodeMirror CDN#

The editor loads CodeMirror from CDN:

1
2
3
4
5
6
7
# eb_ui.libraries.yml
codemirror:
  js:
    https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.18/codemirror.min.js: { type: external }
    https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.18/mode/yaml/yaml.min.js: { type: external }
  css:
    https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.18/codemirror.min.css: { type: external }

Configuration#

Navigate to Configuration > Development > Entity Builder > UI Settings:

Setting Default Description
editor_mode auto Editor selection: yaml, auto, or provider ID
yaml_editor codemirror_cdn YAML editor type

Security#

All API endpoints include:

  • CSRF Protection: X-CSRF-Token header required for POST requests
  • AJAX Validation: X-Requested-With header required
  • Authentication: User must be authenticated
  • Content Size Limits: Configurable maximum payload size
  • Nesting Depth Limits: Configurable maximum JSON nesting

Creating Custom Grid Providers#

To create a custom grid provider:

  1. Implement the hook:

    #[Hook('eb_ui_grid_provider_info')]
    public function gridProviderInfo(): array {
      return [
        'my_grid' => [
          'id' => 'my_grid',
          'label' => $this->t('My Custom Grid'),
          'form_class' => '\Drupal\my_module\Form\MyGridForm',
          'library' => 'my_module/grid',
        ],
      ];
    }
    

  2. Create the form class extending FormBase:

    class MyGridForm extends FormBase {
      public function getFormId() {
        return 'my_grid_form';
      }
    
      public function buildForm(array $form, FormStateInterface $form_state) {
        // Build your grid interface
        // Use the shared API endpoints for validation/preview
      }
    }
    

  3. Add access checker (optional, for route priority):

    1
    2
    3
    4
    5
    6
    class MyGridAccess {
      public function access(AccountInterface $account): AccessResultInterface {
        $provider = $this->providerManager->getActiveProvider();
        return AccessResult::allowedIf($provider && $provider['id'] === 'my_grid');
      }
    }
    

Permissions#

Permission Description
administer entity builder Access the UI
  • eb_aggrid: AG-Grid spreadsheet provider for eb_ui
  • eb: Core Entity Builder functionality