This is NOT production ready! DON't USE! ;)
A Drupal module that provides a framework for creating embeddable widgets that can be displayed in iframes or external applications.
Overview
The Widget Provider API module allows developers to create custom widget providers that can render content outside of the main Drupal site context. These widgets can be embedded in external websites, applications, or iframes with proper security controls including checksums, referrer validation, and parameter validation.
Features
- Plugin-based architecture for creating custom widget providers
- Security controls including secret-based checksums and referrer validation
- Parameter validation for required and optional parameters
- Administrative interface for viewing and managing widget providers
- URL generation with proper security tokens
- Iframe-friendly rendering without site theme wrapper
Installation
- Enable the Widget Provider API module
- Grant appropriate permissions to users who need to view the widget provider list
- Optionally enable the Widget Provider Example module to see sample implementations
Permissions
-
View Widget Provider List: Allows users to access the administrative interface at
/admin/reports/widget-provider/list
Administrative Interface
Widget Provider List
Visit /admin/reports/widget-provider/list to view all available widget providers. This page displays:
- Label: Human-readable name of the widget provider
- Group: The plugin group identifier
- ID: The widget provider identifier
- Required Parameters: Parameters that must be provided in the URL
- Optional Parameters: Parameters that can optionally be provided
- Allowed Referrers: Domains that are allowed to embed this widget
- Secret: Whether the widget uses secret-based security
- Generated URL: Complete URL that can be copied and used for embedding
Copying Widget URLs
From the widget provider list page, you can copy the generated URLs for each widget provider. These URLs include:
- Proper route structure (
/widget-provider/{group}/{widgetProvider}) - Required security checksums (when applicable)
- Placeholder parameter values that need to be replaced with actual values
Creating Your Own Widget Provider
Basic Structure
Create a new plugin class that extends WidgetProviderBase:
getParameterValue('param1');
$param2 = $this->getParameterValue('param2');
$optionalParam = $this->getParameterValue('optional_param');
// Build and return your content
return [
'#markup' => 'Your widget content here',
];
}
}
Plugin Annotation Parameters
-
id: Unique identifier in format
group:widget-name - label: Human-readable name for the widget
- description: Description of what the widget does
- requiredParameters: Array of parameter names that must be provided
- optionalParameters: Array of parameter names that can optionally be provided
- allowedReferrers: Array of domains allowed to embed this widget (optional)
- secret: Secret key for generating security checksums (optional)
Security Features
Secret-based Checksums
When a secret is defined, the widget requires a valid checksum (h parameter) in the URL. This prevents unauthorized access and parameter tampering.
Referrer Validation
Use allowedReferrers to restrict which domains can embed your widget. This prevents unauthorized embedding.
Parameter Validation
The framework automatically validates that all required parameters are present and throws appropriate exceptions if they're missing.
Building Content
The buildContent() method should return either:
- A Drupal render array (recommended)
- A Symfony Response object (e.g. JsonResponse)
- Raw HTML/text content
Render arrays are automatically wrapped in a bare HTML page without the site theme, making them perfect for iframe embedding.
Embedding Widgets
Basic Iframe Embedding
- Note, that you should use the "sandbox" attribute for any iframes created. Read more on the sandbox property here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/sandbox
Iframe Sandbox Options Reference
Script and Plugin Control
| Option | Description |
|---|---|
allow-scripts |
Allows JavaScript execution |
allow-plugins |
Allows plugins (Flash, etc.) - deprecated in modern browsers |
Origin and Navigation Control
| Option | Description |
|---|---|
allow-same-origin |
Treats content as being from its normal origin (enables access to parent page resources) |
allow-top-navigation |
Allows navigation of the top-level browsing context (parent page) |
allow-top-navigation-by-user-activation |
Allows navigation of top-level context only with user gesture |
allow-top-navigation-to-custom-protocols |
Allows navigation to non-HTTP(S) protocols |
User Interaction
| Option | Description |
|---|---|
allow-forms |
Allows form submission |
allow-popups |
Allows popups (window.open, target="_blank", etc.) |
allow-popups-to-escape-sandbox |
Allows popups to open without inheriting sandbox restrictions |
allow-modals |
Allows modal dialogs (alert, confirm, prompt) |
allow-orientation-lock |
Allows locking screen orientation |
allow-pointer-lock |
Allows pointer lock API |
Media and Features
| Option | Description |
|---|---|
allow-presentation |
Allows Presentation API |
allow-downloads |
Allows downloading files |
allow-downloads-without-user-activation |
Allows downloads without user gesture |
Storage and State
| Option | Description |
|---|---|
allow-storage-access-by-user-activation |
Allows Storage Access API with user gesture |
Security Notes
â ï¸ Important Security Considerations:
-
allow-same-origin+allow-scriptstogether can effectively disable sandbox security if the iframe content is from the same origin
JavaScript Integration
// Generate widget URL with parameters
const widgetUrl = 'https://yoursite.com/widget-provider/your-group/your-widget-name' +
'?param1=' + encodeURIComponent(value1) +
'¶m2=' + encodeURIComponent(value2) +
'&h=' + encodeURIComponent(checksum);
// Create iframe dynamically
const iframe = document.createElement('iframe');
iframe.src = widgetUrl;
iframe.width = '400';
iframe.height = '300';
iframe.frameBorder = '0';
iframe.sandbox = '';
document.getElementById('widget-container').appendChild(iframe);
URL Structure
Widget URLs follow this pattern:
/widget-provider/{group}/{widgetProvider}?param1=value1¶m2=value2&h=checksum
- group: The first part of the plugin ID
- widgetProvider: The second part of the plugin ID
- Parameters: Query parameters as defined in the plugin
- h: Security checksum (when using secrets)
Error Handling
The module handles errors gracefully:
- Missing required parameters result in validation exceptions
- Invalid referrers are blocked
- Wrong checksums are rejected
- All errors are converted to 404 responses to prevent information disclosure
Example Module
The included widget_provider_example module provides sample implementations:
- Node rendering widget with secret-based security
- Demonstrates parameter handling and access control
Best Practices
- Use secrets for widgets containing sensitive data
- Validate referrers to prevent unauthorized embedding
- Keep widgets lightweight for fast loading in iframes
- Handle errors gracefully without exposing system information
-
Use descriptive plugin IDs following the
group:namepattern - Document required parameters clearly in your plugin description
Troubleshooting
- 404 errors: Check that the plugin ID matches the URL structure
- Access denied: Verify referrer restrictions and secret checksums
- Missing parameters: Ensure all required parameters are provided in the URL
- Checksum errors: Verify the secret and checksum generation logic
Support
For issues and feature requests, please use the project's issue queue or contact the module maintainers.
Project information
- Project categories: Developer tools, Import and export
- Created by anybody on , updated
Stable releases for this project are covered by the security advisory policy.
There are currently no supported stable releases.



