The Themify Builder has a plethora of modules (you can see a list of them here: https://themify.me/docs/builder) and addons, all of which are used to add more Builder functionality. Although these cover majority of the needs of users, we're continuing to see an increase with the demand for custom modules that's made based on user design/layout. Understanding that it's impossible for us to keep up with this growing demand, we decided to create this tutorial to allow you to create your own Builder module.
Advantages:

  • Flexibility customizing the look and feel of your site
  • Customize how the content is displayed
  • Re-use your module on any site
  • Easy to build for developers
  • Easy to use for anyone
  • Same functionality as the Themify Builder module

LET'S GET STARTED:

Each module in the Builder consists of two files, a module-*.php file (registers the module and it's options), and a template-*.php file (handles the display of the module). These file for the default modules that come with the Builder are located in the /modules directory inside the Builder, and the template files can be found in the /templates directory. We can add new modules via a plugin, or include them in the theme.

Below is a sample module that includes most of the field types supported by Builder, you can use this module as a guideline on how to create options for your custom modules.

Example 1: Hello World module

Let's start by creating a simple module that displays a Hello World message. First under wp-content/plugins/ directory of your WordPress installation create a new folder (you can name this folder anything that you would like). This folder will hold all of the files required for the module. Inside that folder create a file named "init.php" and paste this inside:


<?php
/*
Plugin Name:  Hello World
Version:      1.0
Author:       Themify
Description:  Sample Builder module to greet the world!
*/

defined( 'ABSPATH' ) or die;

This is all that is needed for WordPress to identify the plugin, now if you head over to the Plugins manager in admin dashboard, you can activate it:

activate-plugin

Now let's add the codes to register the directories where the Builder can load our module and it's template files:


function hello_world_register_module( $ThemifyBuilder ) {
	$ThemifyBuilder->register_directory( 'templates', plugin_dir_path( __FILE__ ) . '/templates' );
	$ThemifyBuilder->register_directory( 'modules', plugin_dir_path( __FILE__ ) . '/modules' );
}
add_action( 'themify_builder_setup_modules', 'hello_world_register_module' );

This tells the Builder to look for the module's definition file inside the /modules folder in our plugin, and to look for the module's template file inside the /templates directory in our plugin, so create those two folder. Next, create "module-helloworld.php" file inside the modules folder and paste:

<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

class Hello_World_Module extends Themify_Builder_Component_Module {
	function __construct() {
		parent::__construct(array(
			'name' => __( 'Hello World', 'hello-world' ),
			'slug' => 'helloworld'
		));
	}
}

Themify_Builder_Model::register_module( 'Hello_World_Module' );

By extending the "Themify_Builder_Module" class in our code and then using the Themify_Builder_Model::register_module method call we have registered the module, and here it is:

new-module

Now, you may run into a slight issue, the Builder might not save the module. This is due to the fact that the module has no options, since there are no options set when adding the module to a page, the Builder removes the module. We can fix this by adding options to the module. To do this we need to add get_options method to the Hello_World_Module class and return an array of option definitions:


public function get_options() {
		return array(
			array(
				'id' => 'module_title',
				'type' => 'text',
				'label' => __('Module Title', 'hello-world'),
				'class' => 'large'
			),
		);
	}

This defines one option for the module, now when you add a module you can see the option to set the module title:

module-title-option

So what does the module display on the front end? At the moment, nothing. We haven't add the template file for the module that will actually render it, to do that create "template-helloworld.php" file inside the /templates folder and paste this in:

	<h1> Hello World! </h1>

Viola! Now if add the module to a page and view that page on front end, you can see the output:

hello-world

Showing the same HTML snippet each time we add the module might be what we need, however often you want to add options to the module that dynamically changes it's output, so let's change the get_options method to show an option where we can change who we want to say hello to:


public function get_options() {
	return array(
		array(
			'id' => 'say_hello',
			'type' => 'text',
			'label' => __('Say hello to:', 'hello-world'),
			'class' => 'large'
		),
	);
}

Builder has a plethora of field types which allows you to make advanced forms to customize the module. You can checkout the Builder Field Types module, it's a sample module with nearly all different field types in Builder and can be used as a guide on how to work with said field types.
In the module's template file the options are accessible using the $mod_settings array, every key of this array is an option saved for the module, so now change the template file:


	<h1> Hello <?php echo $mod_settings['say_hello']; ?>! </h1>

For the last step, we have to determine how the module preview should work. In the module-helloworld.php file add this method:


public function get_visual_type() {
	return 'ajax';
}

That tells Builder to load a new version of the module via Ajax. Alternatively you can have real live preview by rendering the module on frontend using JavaScript, the second module in this guide uses this method.

Congratulations, you just made your first Builder module. You can download the complete code here.

Example 2: Quotes module

Now let's dig deeper and create a more practical module. Let's say our client runs a heavy-content website and regularly posts quotes, so to pimp up the pages let's design a quote style module that our client can use:

quote-design

The quote style consists of an image, the quote text itself and the name of it's author. The only problem is this requires a specific bit of HTML to make. Handing a txt file to the client to copy and paste, then change the bits and pieces is not very practical. An option is to create a shortcode that outputs the quote, however shortcodes are not user friendly either. Your client will have to remember the exact shortcode and parameters used to replicate the same output.

First step like our Hello World module, create a directory inside the wp-content/plugins/ folder, add an init.php file inside it and paste this in:

<?php
/*
Plugin Name:  Custom Quotes
Plugin URI:   https://themify.me/
Version:      1.0
Author:       Themify
Description:  Custom Quotes
*/

defined( 'ABSPATH' ) or die( '-1' );

function custom_quotes_enqueue() {
	wp_enqueue_style( 'custom-quotes', plugin_dir_url( __FILE__ ) . '/assets/style.css' );
}
add_action( 'wp_enqueue_scripts', 'custom_quotes_enqueue' );

function custom_quotes_register_module( $ThemifyBuilder ) {
	$ThemifyBuilder->register_directory( 'templates', plugin_dir_path( __FILE__ ) . '/templates' );
	$ThemifyBuilder->register_directory( 'modules', plugin_dir_path( __FILE__ ) . '/modules' );
}
add_action( 'themify_builder_setup_modules', 'custom_quotes_register_module' );

As before, we register two directories for Builder to load the module definition and it's template file, we also use the wp_enqueue_scripts hook (info: ) to load an stylesheet from the /assets folder inside our plugin. Now activate the plugin in the Plugins manager.

Next create "module-quotes.php" file inside the the /modules folder and paste this in:

<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

class TB_Quotes_Module extends Themify_Builder_Component_Module {
	function __construct() {
		parent::__construct(array(
			'name' => __( 'Quote', 'custom-quotes' ),
			'slug' => 'quotes'
		));
	}

	public function get_options() {
		return array(
			array(
				'id' => 'quote_text',
				'type' => 'textarea',
				'label' => __( 'Text', 'custom-quotes' ),
				'class' => '',
			),
			array(
				'id' => 'quote_image',
				'type' => 'image',
				'label' => __( 'Image', 'custom-quotes' ),
				'class' => '',
			),
			array(
				'id' => 'quote_author',
				'type' => 'text',
				'label' => __( 'Quote Author', 'custom-quotes' ),
				'class' => '',
			),
			array(
				'id' => 'quote_link',
				'type' => 'text',
				'label' => __( 'Link', 'custom-quotes' ),
				'class' => '',
			),
		);
	}
}

Themify_Builder_Model::register_module( 'TB_Quotes_Module' );

First we extend the Themify_Builder_Module class, then register it using Themify_Builder_Model::register_module( 'TB_Quotes_Module' ); call, and also add four options in the module, three text options to put the quote text, the name of it's author, and the link to the quote author's website, and an option to put the image. Now when you add the module you can see the options:

quotes-module

Perfect! Now for the module's template, create "template-quotes.php" in the /templates folder and add:

<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
 * Template Quotes
 * 
 * Access original fields: $mod_settings
 */

$fields_default = array(
	'quote_text' => '',
	'quote_image' => '',
	'quote_author' => '',
	'quote_link' => '',
	'animation_effect' => ''
);

$fields_args = wp_parse_args( $mod_settings, $fields_default );
extract( $fields_args, EXTR_SKIP );
$animation_effect = $this->parse_animation_effect( $animation_effect );

$container_class = implode(' ', 
	apply_filters( 'themify_builder_module_classes', array(
		'module', 'module-' . $mod_name, $module_ID
	), , $mod_name, $module_ID, $fields_args )
);
?>

<div id="<?php echo $module_ID; ?>" class="<?php echo esc_attr( $container_class ); ?>">

	<?php do_action( 'themify_builder_before_template_content_render' ); ?>

	<div class="quote-wrap">

		<?php if( '' != $quote_image ) : ?>
			<img class="quote-image" src="<?php echo esc_url( $quote_image ); ?>" alt="<?php echo $quote_author; ?>" />
		<?php endif; ?>

		<div class="quote-content">

			<div class="quote-text">
				<span><?php echo $quote_text; ?></span>
			</div>

			<div class="quote-author">
				<?php if ( '' == $quote_link ) : ?>
					<span><?php echo $quote_author; ?></span>
				<?php else : ?>
					<a href="<?php echo $quote_link; ?>"><span><?php echo $quote_author; ?></span></a>
				<?php endif; ?>
			</div>

		</div>

	</div>

	<?php do_action( 'themify_builder_after_template_content_render' ); ?>
</div>

The snippet is pretty straight forward, we just check if some options in the module are set and if so output the proper markup.

NOTE: To set the default options for the module we use wp_parse_args function and pass it two things: $mod_settings array that holds the saved settings of the module, and an array of defaults, this way we'll have a default value. Also the extract function is used to turn each of the options into a separate variable, this makes working with them easier.
The rest of the code is just spitting out the proper markup we need to show the quote.

Last step is to add the CSS codes that style the quote, in the plugin we have used wp_enqueue_style to add an stylesheet to the front-end. That loads the assets/style.css file inside the plugin on front-end.

You can download the finished plugin here which includes an alternative layout for displaying quotes, sets up the Styling options for the module, and adds live preview as well.

Field Types

The Builder has a variety of field types you can use to create the options for the modules, the table below lists some of available field types:

Type Description * Repeatable?
text General text box to input texts. You can set the "colorpicker" parameter to true to turn the text box into a color picker field. Yes
icon Icon picker, user can choose from the icons included in the Builder. For an example of this check the Feature module. Yes
image Image uploader, user can upload images or select one from the Media Library. Yes
textarea Multi-line text input. Yes
wp_editor Shows the TinyMCE editor to input formatted texts. Yes
radio Multiple choice option where only one can be chosen. Yes
checkbox Multiple choice option where none or any number of the choices can be chosen. Yes
query_category Select box to choose terms from a category. You can use the taxonomy parameter to show the terms from a custom taxonomy.
builder "builder" field can be used to create repeatable rows of data (for example Accordion and Tabs modules use this feature), field types that in this table are highlighted as Repeatble can be used in the "builder" field type.

* whether the field type is repeatable and can be used in "builder" fields.

We have also developed a sample module that includes most of the field types supported by Builder, you can use this module as a guideline on how to create options for your custom modules. This addon can be downloaded here.

Override module templates in themes

The built-in Builder modules are also customizable, where you can change the look using the options provided by the module. However sometimes you need to change how the modules structure its output, and in such cases overriding the template files of the modules comes very handy. To achieve this first navigate to <theme_root>/themify/themify-builder/templates/ directory, here you can find the template files used by various modules. Now copy the template file for the module you want to change and paste it in <theme_root>/themify-builder/ directory and customize it.