District Core Developer DocsDistrict Core Developer Docs
Developers
Boilerplate
Modules
Bitbucket
Developers
Boilerplate
Modules
Bitbucket
  • Modules

    • ABN
    • ActivityLog
    • AnalyticsApi
    • ApiConnector
    • BlockApi
    • CategoryApi
    • CloneApi
    • CommentApi
    • ContentApi
    • Core
    • Documents
    • EmbedApi
    • Event
    • ExportApi
    • FeatureApi
    • FormApi
    • GTM
    • GalleryApi
    • HelpApi
    • Hotspot
    • IdeaSurvey
    • ImportApi
    • InteractionsApi
    • Intercom
    • MailApi
    • MapApi
    • MapSurvey
    • MediaApi
    • MenuApi
    • MetaTagApi
    • NlpApi
    • NotificationApi
    • Page
    • ParentableContent
    • PaymentApi
    • PermissionsApi
    • Postcode
    • ReCaptcha
    • Redirects
    • Renderer
    • ReportApi
    • RestrictionApi
    • RevisionApi
    • SearchApi
    • Settings
    • ShareableApi
    • Slack
    • SlugApi
    • SubscribableApi
    • Survey
    • Team
    • TenantApi
    • TestApi
    • ThemeApi
    • Timeline
    • TranslationApi
    • Update
    • Users
    • VisualisationApi
    • WorkflowApi
    • Wysiwyg

EmbedAPI module

This module provides the ability for other sites to embed content from this site. It follows the oEmbed standard.

Embed plugins

Content can be embeded by providing an embed plugin. This defines what paths it should respond to and how it is rendered.

To add a new Embed plugin

Create a Plugins/Embed/Plugins dir in your module and create a class that extends BaseEmbed. You should just need to override the properties provided in BaseEmbed but there is plenty of flexibility should you need to do something more tricky.

EmbedPlugin example

<?php

namespace Modules\MyModule\Plugins\Embed\Plugins;

use Modules\EmbedApi\Plugins\BaseEmbed;
use Modules\MyModule\Http\Resources\MyModelResource;
use Modules\MyModule\Models\MyModel;

class SurveyEmbed extends BaseEmbed
{
    public const MACHINE_NAME = 'my_module_model';

    protected string $label = 'My Module Model';

    protected string $machine_name = self::MACHINE_NAME;

    protected string $description = 'Embed my model';

    protected string $component = '~MyModule/Components/MyModelEmbed';

    protected array $matchingRouteNames = ['my_model.show'];

    protected ?string $modelClassName = MyModel::class;

    protected ?string $modelResource = MyModelResource::class;

    protected ?string $modelParameter = 'my_model';
}

See EmbedInterface for more of a definition.

EmbedPlugin component example

You must also define how your embed will be rendered, the EmbedPlugin will be responsible for defining all the settings and props, you just need to create a vue component. Eg.

<template>
    <district-embeddable class="survey-embed">
        <h2>This is the content of my model {{ model.title }} embed</h2>
        <p>{{ model.summary }}</p>
    </district-embeddable>
</template>

<script>
import DistrictEmbeddable from '~EmbedApi/Components/Embeddable'

export default {
    name: 'survey-embed',
    components: {DistrictEmbeddable, SurveyForm},
    props: {
        model: Object,
    },
}
</script>

Just be sure to wrap your component in district-embeddable as this will be responsible for sending resize events to the parent.

oEmbed endpont

The oEmbed endpoint works with embed plugins to translate a public url into oEmbed spec and html. You just need a GET request to the /oembed path with a url parameter set which is the url to the public page you want to embed.

NOTE: There must be an Embed Plugin which matches the url provided.

Example

To work with above embed plugin example, you have a public route my_model.show with a model parameter of my_model and the uri signature is /my_module/show/{my_model:slug}

Visit /oembed?url=http://localhost/my_module/show/model-slug

It should return something like

{
    "title": "My model title",
    "author_name": "District",
    "author_url": "http://localhost",
    "type": "my_model",
    "width": "100%",
    "height": "100%",
    "version": "1.0",
    "provider_name": "District",
    "provider_url": "http://district.au",
    "html": "<a src=\"http://localhost/my_module/show/model-slug\" data-embed-url=\"http://district-core.lndo.site/embed/my_model/model-slug\" class=\"district-embed\" data-width=\"100%\" data-height=\"100%\">My model title</a><script async src=\"http://district-core.lndo.site/js/embed.js\" charset=\"utf-8\"></script>"
}

The html prop will transform into an embedded and auto resizing iframe!

Testing embedding

You can see how an embed will look (and also test out the oEmbed endpoint works as expected) via a little demo site. See the README.md here for instructions.

TODOs and Gotchas

  • Iframes have inherit security issues, we do some mitigation via the EmbeddableMiddleware and only allow the embed of specific /embed/plugin/key route but we probably want to dive deeper into security implications here.
  • A CSFR exception has been added for /media_api/upload/check to VerifyCsrfToken middleware as there was csfr errors for this route when uploading files when embedded in iframe. TODO fix or at least only add that exception when parent on embed route.
  • Minify embed.js

Edit this page
Prev
Documents
Next
Event