Jonah Coyote Design

Custom Visual Composer Elements in The X Theme

Hi everybody,

I’m loving the new X Theme for WordPress. It’s a great framework for simple to complex websites I’m building, and it utilizes a customized version of the Visual Composer plugin which I also love for easily laying out pages. The only problem is, I needed to be able to create custom Visual Composer elements. If you’re using the X Theme, here’s how to do it.

In all of my projects I’ve got a pretty common set of plugins that I like to use on a regular basis. One of them is the Custom Post Widget that let’s you create modular blocks of content that you can edit in once place and place all throughout your website via a widget or shortcode. Very useful. Sure you could just place a Custom Post Widget shortcode into a Text element, but I wanted something more elegant that let’s you easily select which Custom Post Widget to show on the fly.

Create the Visual Composer Mapping

The first thing you need to do is create the Visual Composer mapping for your new element. Basically this just creates the form config for your element when you click on it in Visual Composer. To do this, create a file somewhere in your theme directory (can be in functions.php but I recommend you include it somehow for better organization) and label it ‘custom-vc-mappings.php’ and place the following code in it:

<?php
/*-------------------------------------------------------------------------------
	Custom Content Blocks Config
-------------------------------------------------------------------------------*/
global $wpdb;
$blocks = $wpdb->get_results(
  "
  SELECT ID, post_title
  FROM $wpdb->posts
  WHERE post_type = 'content_block'
  "
);

$blocks_array = array('');
if ($blocks) {
	foreach ( $blocks as $block ) {
		$blocks_array[$block->post_title] = $block->ID;
	}
} else {
	$blocks_array["No content blocks found"] = 0;
}

vc_map( array(
        "name"      => __( "Content Block", "__x__" ),
        "base"      => "the_content_block",
        'icon'        => 'text-output',
        'description' => __( 'Place a Content Block in your content.', '__x__' ),
        "wrapper_class" => "clearfix",
        "category" => __( 'Content', '__x__' ),
        "params"    => array(

            array(
                "type" => "textfield",
                "heading" => __( "Custom Title", "__x__" ),
                "param_name" => "title",
                "value" => "",
                "description" => __( "Entering a title here will override the default item title. You also need to have the show title option checked.", "__x__" )
            ),

            array(
              'type' => 'checkbox',
              'heading' => __( 'Display the title?', 'js_composer' ),
              'param_name' => 'show_title',
              'value' => array( __( '', 'js_composerp' ) => true )
            ),

            array(
                "type" => "dropdown",
                "heading" => __( "Content Block", "__x__" ),
                'admin_label' => true,
                "param_name" => "block",
                "value" => $blocks_array,
                "description" => __("Choose a Content Block from the drop down list.", "__x__")
            ),

            array(
              'param_name'  => 'id',
              'heading'     => __( 'ID', '__x__' ),
              'description' => __( '(Optional) Enter a unique ID.', '__x__' ),
              'type'        => 'textfield',
              'holder'      => 'div'
            ),
            array(
              'param_name'  => 'class',
              'heading'     => __( 'Class', '__x__' ),
              'description' => __( '(Optional) Enter a unique class name.', '__x__' ),
              'type'        => 'textfield',
              'holder'      => 'div'
            ),
            array(
              'param_name'  => 'style',
              'heading'     => __( 'Style', '__x__' ),
              'description' => __( '(Optional) Enter inline CSS.', '__x__' ),
              'type'        => 'textfield',
              'holder'      => 'div'
            )
        )
    ) );

Create the Shortcode

Next we need to add the actual shortcodes for use with the element. Create another file ‘shortcodes.php’ and include it (recommended) or place the code in your themes functions.php file:

<?php

// Content Block Shortcode
// =============================================================================

function x_shortcode_content_block( $atts ) {
  extract( shortcode_atts( array(
    'title' => '',
    'show_title' => '',
    'id'          => '',
    'class'       => '',
    'style'       => '',
    'block' => ''
  ), $atts ) );

  $id            = ( $id          != ''          ) ? 'id="' . esc_attr( $id ) . '"' : '';
  $class         = ( $class       != ''          ) ? 'x-content-block cf ' . esc_attr( $class ) : 'x-content-block cf';
  $style         = ( $style       != ''          ) ? 'style="' . $style . '"' : '';

  $output = "<div {$id} class=\"{$class}\" {$style}>";

  if($show_title) {
  	if($title) {
  		$title = $title;
  	} else {
  		$title = get_the_title($block);
  	}

      $output .= '<div id="post-' . get_the_ID($block) . '" class="' . implode( ' ', get_post_class($block) ) . '">'
                       . '<h4 class="h-widget">' . $title . '</h4>'
                       . do_shortcode( '' )
                       . '</div>';
  } else {
       $output .= '<div id="post-' . get_the_ID($block) . '" class="' . implode( ' ', get_post_class($block) ) . '">'
                        . do_shortcode( '' )
                        . '</div>';
  }

  $output .= '</div>';

  return $output;
}

add_shortcode( 'the_content_block', 'x_shortcode_content_block' );

Call The Code From X

Finally we need to have X load this custom code. Unfortunately X doesn’t provide a hook in where it registers the other elements, so it needs to be hacked in, but it’s a small hack and if you’re managing your projects with Git it’s relatively easy to re-insert if you update X. Just remember, we’re hacking a core theme file here and if you update the theme you’ll likely overwrite this file and lose this change rendering your custom elements useless until you re-insert this line. I’m asking the X theme devs to add a hook so we can add in custom elements the right way and will update this tutorial when they do so, but until then, this is the only way.

Find the file ‘/wp-content/themes/x/framework/functions/global/admin/visual-composer.php’ and around line 160 paste in this line that references your custom-vc-mapping.php file. Note that this is referencing an include in a /library/includes/vc folder inside my theme:

/* CUSTOM HACK */
include_once (get_stylesheet_directory() . '/library/includes/vc/custom-vc-mappings.php');

 Final Notes

This is just the tip of the iceberg. With this technique the possibilities are limitless and you’ll be able to easily add Visual Composer elements for other code or plugins and use them in X. Fantastic! I hope you enjoyed this little tutorial and if you have any comments or suggestions do let me know.

Exit mobile version