Deprecated: This approach is still working, but we propose to use oEmbed for Twitter instead.
This guide will show you how to add a custom Include for Twitter. We will show the implementation for the design, server and editor. This is more of a quick-guide where you can just copy and paste code. For a deeper understanding you can dive into Includes Overview.
Component definition
In the projectConfig
you define a twitter component.
{
name: "twitterIncludeComponent",
html: "<div doc-include='twitterInclude' class='placeholder'><div className='example-inline-placeholder-styles' style='min-height: 100px;outline: 1px dashed rgba(0, 0, 0, 0.2);position: relative;'/></div>",
label: "Twitter Include",
description: "Embed a tweet",
directives: [
{
name: "twitterInclude",
type: "include",
service: "twitterInclude"
}
]
}
(Don’t forget to add this to the contentTypes where you want to use this component)
Server - rendering the include and defining the service
In the server you will define the twitterInclude
service.
This twitterInclude service has one main job - rendering the include with parameters filled in the editor.
// app/server.js
liServer.registerInitializedHook(() => {
liServer.registerIncludeServices([
require('./include-services/tweet')
])
})
// app/include-services/tweet.js
const fetch = require('node-fetch')
module.exports = {
name: 'twitterInclude',
uiComponents: [
{
type: 'vue-component',
sidebarLabel: 'Twitter-include',
sidebarContentComponent: 'liTwitterInclude' // TwitterPlugin registered in the editor.
}
],
rendering: {
type: 'function',
render: renderTweet
}
}
async function renderTweet (params, context) {
if (!params.embedLink) {
return context.preview
? {doNotRender: true} // render the placeholder in the editor
: {html: ''} // do not render anything
}
// we are using the twitter oembed api, so we expect a link in the editor
const url = `https://publish.twitter.com/oembed?url=${params.embedLink};omit_script=true`
const res = await fetch(url, {method: 'GET'})
if (res.status === 404) {
const err = new Error(`Could not find twitter link.`)
err.status = 404
throw err
}
const tweetData = await res.json()
return {
html: tweetData.html,
doNotRender: false,
embed: 'liTwitterRenderPlugin', // Twitter rendering plugin registered in the editor.
dependencies: {
js: [
{src: 'https://platform.twitter.com/widgets.js', namespace: 'includes.twitter'}
]
}
}
}
Editor - Sidebar and trigger twitter script
You will have to define two things, the sidebar where one can paste the embed code or twitter link and in certain cases once the script has already loaded you will need to trigger it again. For example when components are moved or a second twitter component been pasted in the same document.
We have a special onIncludeRendered
hook for includes where you can trigger a script.
// register the sidebar Vue Component
liEditor.vueComponentRegistry.registerComponent({
type: 'includeParamsSidebarForm',
name: 'twitterIncludeSidebar',
component: require('../plugins/includes/twitter-include/twitter-include-sidebar.vue').default
})
// register the render plugin implementing 'onIncludeRendered'
liEditor.includeRenderPlugins.register('liTwitterRenderPlugin',
require('../plugins/doc_include_render_plugins/twitter'))
You are free to render any kind of form for the sidebar. Any params the user can define here will be passed to the include service.
<!-- ../plugins/includes/twitter-include/twitter-include-sidebar.vue -->
<template>
<div class="ld-panel">
<div class="ld-panel__header">
<h2 class="ld-panel__header__title">Include embed settings</h2>
</div>
<div class="ld-panel__body">
<form name="idForm" novalidate>
<div class="ld-form-group"
ng-class="{'has-error': idForm.idInput.$invalid && idForm.idInput.$touched}">
<div class="ld-form-group__label">
<label class="ld-form-label">Twitter-embed</label>
</div>
<div class="ld-form-group__content">
<input
name="idInput"
class="ld-text-input"
v-model="paramsDraft.embedLink"
@change="save()"
placeholder="Twitter embed link"
required>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
export default {
props: {
params: {
type: Object,
required: true
}
},
data: function () {
return {
paramsDraft: {
embedLink: this.params.embedLink || '',
}
}
},
methods: {
save () {
// you have to dispatch a CustomEvent named 'update:params'
// the let livingdocs know when your params have changed
// send the new params object as event.detail
const event = new CustomEvent('update:params', {
detail: this.paramsDraft,
bubbles: true
})
this.$el.dispatchEvent(event)
}
}
}
</script>
Once the server has returned the include object with the HTML and scripts,
as everything has loaded the onIncludeRendered
hook will be fired and you can fire twttr.widgets.load()
and it should be nicely displayed!
// ../plugins/doc_include_render_plugins/twitter
liEditor.includeRenderPlugins.register('liTwitterRenderPlugin', {
onIncludeRendered (err, {componentId, directiveName, includeValue, renderer}) {
if (err) return
const {twttr} = renderer.renderingContainer.window
twttr != null ? twttr.ready(() => twttr.widgets.load()) : undefined
}
})