The following steps explain creating a React SPA Container component (eaem-sites-spa-dm-video-container/components/container) extending Core Container component (core/wcm/components/container/v1/container) for Video Backgrounds and Component (eg. text) overlays...
Demo | Package Install | Github
Dynamic Media Configuration
Sync Configuration at Folder Level
Set Dynamic Media Video Profile
Component Dialog
View as Published
Solution
1) Create the component /apps/eaem-sites-spa-dm-video-container/components/container extending Core Container component core/wcm/components/container/v1/container (core container component does not provide render script for React) for the SPA Editor. In the next step we'd be creating a react render script (coded in ES6)...
2) Add the component render script in eaem-sites-spa-dm-video-container\ui.frontend\src\components\DMVideoContainer\DMVideoContainer.js with the following code...
import React from 'react';
import {MapTo, withComponentMappingContext, Container, ResponsiveGrid, ComponentMapping} from '@adobe/cq-react-editable-components';
import {Helmet} from "react-helmet";
class EAEMContainer extends Container {
get containerProps() {
let containerProps = super.containerProps;
containerProps.style = {
"width": '100%',
"height": '500px'
};
return containerProps;
}
get videoDivProps() {
return {
"id": "eaem-dm-video-viewer",
"style": {
"zIndex": "0",
"position": "relative"
}
};
}
get overlayDivProps() {
return {
"style" : {
...{
"position": "absolute",
"zIndex": "1"
} ,
...this.props.overlayDivStyle
}
};
}
componentDidMount() {
const timer = setInterval((() => {
if(window.s7viewers){
clearInterval(timer);
this.loadVideo()
}
}).bind(this), 500);
}
loadVideo(){
new window.s7viewers.VideoViewer({
"containerId": "eaem-dm-video-viewer",
"params": {
"asset": this.props.dmVideoEncode,
"serverurl": this.props.dmServerUrl,
"videoserverurl": this.props.dmVideoServerUrl
}
}).init();
}
render() {
return (
<div {...this.containerProps}>
{ this.props.dmVideoPath &&
<Helmet>
<script src={ this.props.dmVideoViewerPath }></script>
</Helmet>
}
{ this.props.dmVideoPath &&
<div {...this.videoDivProps}>
<div {...this.overlayDivProps}>
{ this.childComponents }
{ this.placeholderComponent }
</div>
</div>
}
{ !this.props.dmVideoPath &&
<div>
{ this.childComponents }
{ this.placeholderComponent }
</div>
}
</div>
);
}
}
export default MapTo('eaem-sites-spa-dm-video-container/components/container')(EAEMContainer);
3) DMVideoContainer was imported in ui.frontend\src\components\import-components.js
import './DMVideoContainer/DMVideoContainer';
import './Page/Page';
import './Text/Text';
4) #88 specifies the script was mapped to component eaem-sites-spa-dm-video-container/components/container for rendering..
export default MapTo('eaem-sites-spa-dm-video-container/components/container')(EAEMContainer);
5) #63 adds the Video Viewer JS (eg. https://s7d1.scene7.com/s7viewers/html5/js/VideoViewer.js) to the <head> tag...
<Helmet>
<script src={ this.props.dmVideoViewerPath }></script>
</Helmet>
6) #48loadVideo() loads the video into container div eaem-dm-video-viewer
7) Create a Sling Model Exporter com.eaem.core.models.impl.EAEMDMVideoContainerModelImpl for exporting the component properties
SPA App Model Export: http://localhost:4502/content/eaem-sites-spa-dm-video-container/us/en.model.json
Container Component Model Export: http://localhost:4502/content/eaem-sites-spa-dm-video-container/us/en/home/jcr:content/root/responsivegrid/container.model.json
8) Add the following code in com.eaem.core.models.impl.EAEMDMVideoContainerModelImpl.
package com.eaem.core.models.impl;
import com.adobe.cq.export.json.ContainerExporter;
import com.day.cq.dam.api.Asset;
import com.day.cq.wcm.foundation.model.responsivegrid.ResponsiveGrid;
import com.eaem.core.models.EAEMDMVideoContainerModelExporter;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import com.adobe.cq.export.json.ComponentExporter;
import javax.annotation.PostConstruct;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import java.util.HashMap;
import java.util.Map;
@Model(
adaptables = {SlingHttpServletRequest.class},
adapters = {ContainerExporter.class, ComponentExporter.class},
resourceType = {"eaem-sites-spa-dm-video-container/components/container"}
)
@Exporter(
name = "jackson",
extensions = {"json"}
)
@JsonSerialize(as = EAEMDMVideoContainerModelExporter.class)
public class EAEMDMVideoContainerModelImpl extends ResponsiveGrid implements EAEMDMVideoContainerModelExporter{
@ScriptVariable
private Resource resource;
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
private String eaemDMVideo;
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
private String eaemDMEncode;
private Map<String, Object> metadata;
@PostConstruct
protected void initModel() {
super.initModel();
if( (this.resource == null) || StringUtils.isEmpty(eaemDMVideo)) {
return;
}
ResourceResolver resolver = this.resource.getResourceResolver();
Resource videoRes = resolver.getResource(eaemDMVideo);
if(videoRes == null){
return;
}
metadata = videoRes.adaptTo(Asset.class).getMetadata();
}
public String getDmAccountName(){
if(metadata == null){
return "";
}
String fileName = String.valueOf(metadata.get("dam:scene7File"));
if(StringUtils.isEmpty(fileName)){
return "";
}
return fileName.substring(0, fileName.indexOf("/"));
}
public String getDmServerUrl() {
if(metadata == null){
return "";
}
return metadata.get("dam:scene7Domain") + "is/image/";
}
public String getDmVideoViewerPath() {
if(metadata == null){
return "";
}
return metadata.get("dam:scene7Domain") + "s7viewers/html5/js/VideoViewer.js";
}
public String getDmVideoServerUrl() {
if(metadata == null){
return "";
}
return metadata.get("dam:scene7Domain") + "is/content/";
}
public Map<String, String> getOverlayDivStyle() {
Map<String, String> divStyles = new HashMap<String, String>();
ValueMap vm = this.resource.getValueMap();
divStyles.put("top" , vm.get("overlayTop", ""));
divStyles.put("left" , vm.get("overlayLeft", ""));
divStyles.put("backgroundColor" , vm.get("overlayBGColor", "#FFFFFF"));
divStyles.put("padding" , vm.get("overlayPadding", "10px 20px 10px 20px"));
return divStyles;
}
public String getDmVideoPath() {
return eaemDMVideo;
}
public String getDmVideoEncode() {
return getDmAccountName() + "/" + eaemDMEncode;
}
}