Note: This tutorial series is intended for advanced users. At least a basic understanding of coding in PHP and JavaScript is required.
Divi module setting fields support the use of Dynamic Content, allowing you to build dynamic modules that display information pulled from the site's database.
Dynamic content can be enabled for a module setting using the dynamic_content
parameter in the setting's definition.
- dynamic_content (string) — Type of content. Accepts
text
,image
, orurl
.
Rendering dynamic content on the frontend requires a minor adjustment to the module's render()
method:
In the above example you can see the usage of the _esc_attr( $attribute, $html )
utility method which:
- Escapes html in the prop's value, unless
$html
is set to'full'
. - Resolves dynamic content, if the field contains any.
Fields which have dynamic content support declared will have their values automatically available in an object passed to your React component using the dynamic
prop:
Each field in the dynamic
prop is an object with a couple of properties:
Property | Type | Description |
---|---|---|
value |
String |
The resolved value. If the user has not selected dynamic content, this will hold the value the user has entered manually. |
type |
String |
The type of dynamic content as specified in the field configuration. |
dynamic |
Boolean |
Shows whether the current value is dynamic or not. |
loading |
Boolean |
Shows whether the current value is still being resolved. |
hasValue |
Boolean |
Shows whether the value is loading or is not empty. |
render |
Function |
A utility function which handles rendering a loading state, dynamic content or static content. Renders an editable rich text field for tiny_mce fields when the value is not dynamic. |
Here we will demonstrate how you can build a simple blurb module with a title, a title link, an image and a content field.
The module's PHP class:
<?php
class SIMP_SimpleBlurb extends ET_Builder_Module {
public $slug = 'simp_simple_blurb';
public $vb_support = 'on';
protected $module_credits = array(
'module_uri' => '',
'author' => '',
'author_uri' => '',
);
public function init() {
$this->name = esc_html__( 'Simple Blurb', 'simp-simple-extension' );
}
public function get_fields() {
return array(
'title' => array(
'label' => esc_html__( 'Title', 'simp-simple-extension' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input your desired title here.', 'simp-simple-extension' ),
'toggle_slug' => 'main_content',
// We need text values so we specify 'text' as the dynamic content type.
'dynamic_content' => 'text',
),
'title_link' => array(
'label' => esc_html__( 'Title Link', 'simp-simple-extension' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input your desired title link here.', 'simp-simple-extension' ),
'toggle_slug' => 'main_content',
// We need URL values so we specify 'url' as the dynamic content type.
'dynamic_content' => 'url',
),
'image' => array(
'label' => esc_html__( 'Heading', 'simp-simple-extension' ),
'type' => 'upload',
'option_category' => 'basic_option',
'description' => esc_html__( 'Select your desired image here.', 'simp-simple-extension' ),
'toggle_slug' => 'main_content',
// We need image URL values so we specify 'image' as the dynamic content type.
'dynamic_content' => 'image',
),
'content' => array(
'label' => esc_html__( 'Content', 'simp-simple-extension' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Content entered here will appear below the title text.', 'simp-simple-extension' ),
'toggle_slug' => 'main_content',
// We need text values so we specify 'text' as the dynamic content type.
'dynamic_content' => 'text',
),
);
}
public function render( $attrs, $content = null, $render_slug ) {
$title = $this->_esc_attr( 'title' );
$title_link = $this->_esc_attr( 'title_link' );
$image = $this->_esc_attr( 'image' );
// We pass 'full' as the second argument so html is not escaped in the resulting value.
$content = $this->_esc_attr( 'content', 'full' );
if ( ! empty( $title ) ) {
if ( ! empty( $title_link ) ) {
$title = sprintf(
'<a href="%1$s">%2$s</a>',
esc_url( $title_link ),
$title
);
}
$title = sprintf(
'<h2>%1$s</h2>',
$title
);
}
if ( ! empty( $image ) ) {
$image = sprintf(
'<img src="%1$s" alt="" />',
esc_url( $image )
);
}
return sprintf(
'
%2$s
%1$s
%3$s
',
$title,
$image,
$content
);
}
}
new SIMP_SimpleBlurb;
The module's React component:
// External Dependencies
import React, { Component, Fragment } from 'react';
// Internal Dependencies
import './style.css';
class SimpleBlurb extends Component {
static slug = 'simp_simple_blurb';
_renderTitle() {
const title = this.props.dynamic.title;
const titleLink = this.props.dynamic.title_link;
let titleComponent = title.render();
if (title.loading) {
// Let Divi render the loading placeholder.
return titleComponent;
}
if (titleLink.hasValue) {
// Wrap the title in a link
titleComponent = (
<a href={titleLink.value}>
{titleComponent}
</a>
);
}
return (
<h2>
{titleComponent}
</h2>
);
}
_renderImage() {
const image = this.props.dynamic.image;
if (image.loading) {
// Let Divi render the loading placeholder.
return image.render();
}
if (!image.hasValue) {
// No image selected or the dynamic content selected does resolves to an empty value.
// This can happen in cases where the user selects "Featured Image" as dynamic
// content, but has not assigned a feature image to the post.
return null;
}
return (
<img src={image.value} alt="" />
);
}
_renderContent() {
const content = this.props.dynamic.content;
// Let Divi handle all of the rendering.
return content.render('full');
}
render() {
return (
<Fragment>
{this._renderImage()}
{this._renderTitle()}
{this._renderContent()}
</Fragment>
);
}
}
export default SimpleBlurb;