Update: As of Divi 2.4, the Divi Theme now supports the Page Builder on posts. Simply start a post and click "Use Divi Builder" to enable the builder – there is no need to follow the steps in this post.

One of the most impressive features of the Divi Theme is the powerful "Page Builder" feature. It lets you quickly and easily set up complex page layouts without the need to do any coding or HTML. Unfortunately, by default this feature is only available for pages, not posts or custom posts. Here is how to enable the Divi Page Builder for use on posts and custom posts.

Enabling "Page Builder for Posts"

The easiest way to enable "Page Builder for Posts" is to use my Divi Booster plugin, which lets you do so just by checking a box, like so:

Starting a Page Builder Post

Now, if you start a new post as usual ("Posts > Add New"), you'll see the Page Builder button has been added to the edit post screen, along with a Page Layout menu

Before you click the "Use Page Builder" button, decide whether you'd like your post to have a left sidebar, right sidebar, or be full width. Then select it from the Page Layout menu:

Now depending on your choice, one of three default Page Builder Layouts will be loaded, which aim to mimic as closely as possible the look of a standard blog page. These layouts are as follows.

Right Sidebar Layout

By default the (non-PageBuilder) posts use a right sidebar. The Page Builder layout for this looks like:

Don't be put off by the (possibly) unfamiliar red / orange color. That just happens because it is using one of the Page Builder "speciality sections" to make sure the sidebar is positioned correctly. It basically behaves in the same way as the standard page builder layouts you are probably more familiar with.

You'll also note that there are some modules already in the layout. I'll explain those in the next section.

Left Sidebar Layout

Very similar to the right layout is a left sidebar layout, which looks like so:

Full Width Layout

Finally, there is the full width layout, which may look more familiar to you. It is used to create posts without a sidebar.

The Default Page Builder for Post Modules

Look again at the default layouts and you'll see that there are some default modules. These are designed to make your Page Builder post look like a regular post, and they are:

  • Post Header – This is a text module which displays the featured image, post title, and meta-data (post date, author, etc). If you look in the module you'll see some shortcodes which generate each of these – you can move these, delete them, etc. to get the look you want.
  • Post Content – This is an empty module in which you can add content to the post. If there was any content in the post editor before you switched on Page Builder, it will be included in here. If you need a more complex layout that plain text, you can of course replace this with other modules, etc.
  • Post Footer – Finally, this module displays things that come at the end of the post, such as comments. Again, it uses shortcodes which you can move or delete as you please.

These modules can all be moved and deleted as necessary to achieve the effect you are after.

Finally, the first two layouts have a sidebar module which displays the default sidebar. If you want to use a custom sidebar, etc, you can simply replace the module (or edit its settings).

The default layouts created by Divi Booster are just a starting point. I suggest starting with one and then changing it until you have it looking the way you like it. Then save your layout so that you can quickly load it for use in future posts.

Known Issues

The Page Builder is complex and not intended for use on posts. As such there are quite a few things that need to be addressed to ensure that it works smoothly in all cases. I'm aware of some issues and am working on solving them. I believe that for most people the Divi Booster Page Builder for Posts feature should work correctly. If you encounter any issues using the Page Builder for posts, please let me know in the comments and I'll try to address them as soon as possible.

Technical Details: PageBuilder on Posts

My Divi Booster plugin always contains the most recent version of the code and can be easily activated by checking a box. But for the technically inclined among you, here is the do-it-yourself code version, which I try to keep reasonably up-to-date though it may not have all the latest bug-fixes etc. I must warn you that adding PHP to a site if you don't know what you're doing can break things – so make sure you back things up before adding this. The code is also quite a complex beast so I won't try to explain it here. It comes in two parts: PHP code which can be added to a functions.php file, and some CSS.

PHP:

function myprefix__et_pb_before_main_editor( $post ) {
	if (in_array( $post->post_type, array('page', 'project'))) return;
	if (!post_type_supports($post->post_type, 'editor')) { return; }

	$is_builder_used = 'on' === get_post_meta( $post->ID, '_et_pb_use_builder', true ) ? true : false;

	printf( '<a href="#" id="et_pb_toggle_builder" data-builder="%2$s" data-editor="%3$s" class="button button-primary button-large%5$s">%1$s</a><div id="et_pb_main_editor_wrap"%4$s>',
		( $is_builder_used ? __( 'Use Default Editor', 'Divi' ) : __( 'Use Page Builder', 'Divi' ) ),
		__( 'Use Page Builder', 'Divi' ),
		__( 'Use Default Editor', 'Divi' ),
		( $is_builder_used ? ' class="et_pb_hidden"' : '' ),
		( $is_builder_used ? ' et_pb_builder_is_used' : '' )
	);
}
add_action( 'edit_form_after_title', 'myprefix__et_pb_before_main_editor' );

function myprefix__et_pb_after_main_editor( $post ) {
	if (in_array( $post->post_type, array('page', 'project'))) return;
	if (!post_type_supports($post->post_type, 'editor')) { return; }
	?>
		<p class="et_pb_page_settings" style="display: none;">
		<input type="hidden" id="et_pb_use_builder" name="et_pb_use_builder" value="<?php echo esc_attr( get_post_meta( $post->ID, '_et_pb_use_builder', true ) ); ?>" />
		<textarea id="et_pb_old_content" name="et_pb_old_content"><?php echo esc_attr( get_post_meta( $post->ID, '_et_pb_old_content', true ) ); ?></textarea>
	    </p>
		</div>
	<?php
}
add_action( 'edit_form_after_editor', 'myprefix__et_pb_after_main_editor' );


function myprefix__et_pb_builder_post_types($post_types) {
	foreach(get_post_types() as $pt) {
		if (!in_array($pt, $post_types) and post_type_supports($pt, 'editor')) {
			$post_types[] = $pt;
		}
	} 
	return $post_types;
}
add_filter('et_pb_builder_post_types', 'myprefix__et_pb_builder_post_types');

// Fix Divi color picker dependency bug 
function myprefix__enqueue_admin_post_settings() { 
	wp_enqueue_script('myprefix__divi_admin_post_settings', get_template_directory_uri() . '/js/admin_post_settings.js', array('wp-color-picker')); 
}
add_action('admin_enqueue_scripts', 'myprefix__enqueue_admin_post_settings');

// Override post truncation function used by excerpt. 
// Need to remove blog module to avoid infinite loops. But can't just filter the_content as that removes the blog module from top level posts too.
if ( ! function_exists( 'truncate_post' ) ){
	function truncate_post( $amount, $echo = true, $post = '' ) {
		global $shortname;

		if ( '' == $post ) global $post;

		$post_excerpt = '';
		$post_excerpt = apply_filters( 'the_excerpt', $post->post_excerpt );

		if ( 'on' == et_get_option( $shortname . '_use_excerpt' ) && '' != $post_excerpt ) {
			if ( $echo ) echo $post_excerpt;
			else return $post_excerpt;
		} else {
			// get the post content
			$truncate = $post->post_content;

			// remove caption shortcode from the post content
			$truncate = preg_replace('@[caption[^]]*?].*?[/caption]@si', '', $truncate);
			
			// DM - remove non-exerptable modules from excerpts
			$truncate = preg_replace('@[et_pb_blog[^]]*?]@si', '', $truncate); // blog module
			$truncate = preg_replace('@[et_pb_signup[^]]*?]@si', '', $truncate); // subscribe module
			$truncate = preg_replace('@[et_pb_sidebar[^]]*?]@si', '', $truncate); // sidebar module
			
			// remove post header and footer content from excerpts
			$truncate = preg_replace('@[(db_post_meta|db_feature_image|db_post_title|db_post_ad|db_comments_form)]@si', '', $truncate); // sidebar module

			// apply content filters
			$truncate = apply_filters( 'the_content', $truncate );

			// decide if we need to append dots at the end of the string
			if ( strlen( $truncate ) <= $amount ) {
				$echo_out = '';
			} else {
				$echo_out = '...';
				// $amount = $amount - 3;
			}

			// trim text to a certain number of characters, also remove spaces from the end of a string ( space counts as a character )
			if ( ! $echo ) {
				$truncate = rtrim( et_wp_trim_words( $truncate, $amount, '' ) );
			} else {
				$truncate = rtrim( wp_trim_words( $truncate, $amount, '' ) );
			}

			// remove the last word to make sure we display all words correctly
			if ( '' != $echo_out ) {
				$new_words_array = (array) explode( ' ', $truncate );
				array_pop( $new_words_array );

				$truncate = implode( ' ', $new_words_array );

				// append dots to the end of the string
				$truncate .= $echo_out;
			}

			if ( $echo ) echo $truncate;
			else return $truncate;
		};
	}
}



// Keep Page Layout setting available at all times
function myprefix__make_page_layout_full_width_by_default() {
  
  // Set the default pagebuilder layout
  echo <<<END
<script>
jQuery(function($){ 

	$('.post-new-php.post-type-post #et_pb_toggle_builder').click(function(){ 

		var textarea_id = 'content';
	
		if ($(this).text() == 'Use Page Builder') { 
			
			old_content = wp_editor_get_content('content');
			
			layout = $('#et_pb_page_layout').val();
			
			var post_header = '[et_pb_text admin_label="Post Header" background_layout="light" text_orientation="left"]<h1>[db_post_title]</h1>[db_post_meta][db_feature_image][/et_pb_text]';
			var post_content = '[et_pb_text admin_label="Post Content" background_layout="light" text_orientation="left"]'+old_content+'[/et_pb_text]';
			var post_footer = '[et_pb_text admin_label="Post Footer" background_layout="light" text_orientation="left"][db_post_ad][db_comments_form][/et_pb_text]';
			
			if (layout == "et_left_sidebar") { wp_editor_set_content('content', '[et_pb_section fullwidth="off" specialty="on"][et_pb_column type="1_4"][et_pb_sidebar admin_label="Sidebar" orientation="left" area="sidebar-1" background_layout="light" module_id="sidebar"/][/et_pb_column][et_pb_column type="3_4" specialty_columns="3"][et_pb_row_inner][et_pb_column_inner type="4_4"]' + post_header + post_content + post_footer + '[/et_pb_column_inner][/et_pb_row_inner][/et_pb_column][/et_pb_section]'); }
			
			if (layout == "et_right_sidebar") { wp_editor_set_content('content', '[et_pb_section fullwidth="off" specialty="on"][et_pb_column type="3_4" specialty_columns="3"][et_pb_row_inner][et_pb_column_inner type="4_4"]' + post_header + post_content + post_footer + '[/et_pb_column_inner][/et_pb_row_inner][/et_pb_column][et_pb_column type="1_4"][et_pb_sidebar admin_label="Sidebar" orientation="right" area="sidebar-1" background_layout="light" module_id="sidebar" /][/et_pb_column][/et_pb_section]');  }
			
			if (layout == "et_full_width_page") { wp_editor_set_content('content', '[et_pb_section fullwidth="off" specialty="off"][et_pb_row][et_pb_column type="4_4"]' + post_header + post_content + post_footer + '[/et_pb_column][/et_pb_row][/et_pb_section]');  }
			
			$('#et_pb_page_layout').val('et_full_width_page');
			
			setTimeout("jQuery('#et_pb_old_content').val(old_content);", 1000);
			
		} 

	});
		
	function wp_editor_set_content( textarea_id, content ) {
		if ( typeof window.tinyMCE !== 'undefined' && window.tinyMCE.get( textarea_id ) && ! window.tinyMCE.get( textarea_id ).isHidden() )
			window.tinyMCE.get( textarea_id ).setContent( content, { format : 'html'  } );
		else
			$( '#' + textarea_id ).val( content );
	}
	
	function wp_editor_get_content( textarea_id ) {
		var content = typeof window.tinyMCE !== 'undefined' && window.tinyMCE.get( textarea_id ) && ! window.tinyMCE.get( textarea_id ).isHidden()
			? window.tinyMCE.get( textarea_id ).getContent()
			: $( '#' + textarea_id ).val();

		return content.trim();
	}
});
</script>
END;
}
add_action('admin_head', 'myprefix__make_page_layout_full_width_by_default', 1);

/* Make comments available as a shortcode */

function myprefix__comments_form() {
	ob_start();
	if ((comments_open()||get_comments_number()) && 'on' == et_get_option('divi_show_postcomments', 'on')) {
		comments_template('', true);
	}
	return ob_get_clean();
}
add_shortcode('db_comments_form', 'myprefix__comments_form');

function myprefix__post_title() {
	return get_the_title();
}
add_shortcode('db_post_title', 'myprefix__post_title');

function myprefix__post_meta() {
	ob_start();
	if (!post_password_required()) { 
		et_divi_post_meta(); 
	}
	return ob_get_clean();
}
add_shortcode('db_post_meta', 'myprefix__post_meta');

function myprefix__post_ad() {
	ob_start();
	if ( et_get_option('divi_468_enable') == 'on' ){
		echo '<div class="et-single-post-ad">';
		if ( et_get_option('divi_468_adsense') <> '' ) echo( et_get_option('divi_468_adsense') );
		else { ?>
			<a href="<?php echo esc_url(et_get_option('divi_468_url')); ?>"><img src="<?php echo esc_attr(et_get_option('divi_468_image')); ?>" alt="468" class="foursixeight" /></a>
<?php 	}
		echo '</div> <!-- .et-single-post-ad -->';
	}
	return ob_get_clean();
}
add_shortcode('db_post_ad', 'myprefix__post_ad');

function myprefix__featured_image() {
	ob_start();
	if (!post_password_required()) {
		$thumb = '';
		$width = (int) apply_filters( 'et_pb_index_blog_image_width', 1080 );

		$height = (int) apply_filters( 'et_pb_index_blog_image_height', 675 );
		$classtext = 'et_featured_image';
		$titletext = get_the_title();
		$thumbnail = get_thumbnail( $width, $height, $classtext, $titletext, $titletext, false, 'Blogimage' );
		$thumb = $thumbnail["thumb"];

		$post_format = get_post_format();

		if ( 'video' === $post_format && false !== ( $first_video = et_get_first_video() ) ) {
			printf(
				'<div class="et_main_video_container">
					%1$s
				</div>',
				$first_video
			);
		} else if ( ! in_array( $post_format, array( 'gallery', 'link', 'quote' ) ) && 'on' === et_get_option( 'divi_thumbnails', 'on' ) && '' !== $thumb ) {
			print_thumbnail( $thumb, $thumbnail["use_timthumb"], $titletext, $width, $height );
		} else if ( 'gallery' === $post_format ) {
			et_gallery_images();
		}
	}
	return ob_get_clean();
}
add_shortcode('db_feature_image', 'myprefix__featured_image');

function myprefix__pagebuilder_for_posts_class($classes) {
	if (is_single() && et_pb_is_pagebuilder_used(get_the_ID())) {
		$classes[] = 'db_pagebuilder_for_posts';
	}
	return $classes;
}
add_filter('body_class', 'myprefix__pagebuilder_for_posts_class');

CSS:

/* Remove padding between post title and page builder content */
.single .et_pb_section:nth-of-type(1), 
.single .et_pb_section:nth-of-type(1) .et_pb_row:nth-of-type(1), 
.single .entry-content { padding-top:0; }

/* Remove content area top margin which appears when filtering blog modules from excerpts */
#content-area { margin-top:0 !important; }

/* Fix the unclickable links issue on sidebar with old version of pagebuilder for posts */
.db_pagebuilder_for_posts.et_right_sidebar #sidebar *, 
.db_pagebuilder_for_posts.et_left_sidebar #sidebar * { 
	position: relative; 
}

/* Fix empty specialty section layout issue */
.db_pagebuilder_for_posts.et_full_width_page .et_pb_column { min-height:1px; } 

/* Hide regular post content */
.db_pagebuilder_for_posts.et_full_width_page article > :not(.entry-content) { display: none; }
.db_pagebuilder_for_posts.et_full_width_page article.comment-body > * { display: block !important; }

/* Adjust the padding to match the standard blog post format */
.db_pagebuilder_for_posts.et_full_width_page .entry-content { padding-top: 0px !important; }
.db_pagebuilder_for_posts.et_full_width_page .et_pb_widget_area_right { margin-bottom: 30px !important; margin-left:29px !important; }
.db_pagebuilder_for_posts.et_full_width_page .et_pb_widget_area_left .et_pb_widget { margin-bottom: 30px !important; margin-left: 0px !important; margin-right: 30px !important; }

Alternatives

Laterna Studios have a plugin to make the page builder available on post types of your choosing. The plugin offers manual selection of the post types on which to use the page builder, which is a different approach to the above code which automatically adds the page builder for all post types which could support it. I haven't really looked into it much so can't advise on how well it works.