I was wondering if anyone have a clue about using custom_markup parameter in Visual Composer? I've came across with a solution in this link but it seems outdated.
I'm using:
WordPress 4.8
Visual Composer 5.1
Any help will be appreciated. Thanks.
FYI the gist link provided in your question has been updated and his solution is working perfectly with Wordpress 4.9.2 and WPbakery Page Builder (formerly Visual Composer) 5.4.5
js :
(function($) {
window.VcCustomElementView = vc.shortcode_view.extend( {
elementTemplate: false,
$wrapper: false,
changeShortcodeParams: function ( model ) {
var params;
window.VcCustomElementView.__super__.changeShortcodeParams.call( this, model );
params = _.extend( {}, model.get( 'params' ) );
if ( ! this.elementTemplate ) {
this.elementTemplate = this.$el.find( '.vc_custom-element-container' ).html();
}
if ( ! this.$wrapper ) {
this.$wrapper = this.$el.find( '.wpb_element_wrapper' );
}
if ( _.isObject( params ) ) {
var template = vc.template( this.elementTemplate, vc.templateOptions.custom );
this.$wrapper.find( '.vc_custom-element-container' ).html( template( { params: params } ) );
}
}
} );
})(window.jQuery)
php :
vc_map(array(
'name' => __( 'Custom Markup', 'js_composer' ),
'base' => 'vc_custom_markup',
'category' => array(
__( 'Content', 'js_composer' ),
),
'description' => __( 'Custom markup element', 'js_composer' ),
'params' => array(
array(
'type' => 'textfield',
'param_name' => 'style',
'value' => 'custom style!',
'heading' => 'Style',
),
array(
'type' => 'textfield',
'param_name' => 'color',
'value' => 'custom color!',
'heading' => 'Color',
),
array(
'type' => 'textfield',
'param_name' => 'title',
'value' => 'custom title!',
'heading' => 'Title',
),
),
'js_view' => 'VcCustomElementView',
'custom_markup' => '<div class="vc_custom-element-container">Style: "{{ params.style }}", Color: "{{ params.color }}", Title: "{{{ params.title }}}"</div>',
)
);
All credits go to AngeIII
Related
I'm trying to add a custom settings tab to the WooCommerce settings screen. Basically I want to achieve a similar thing to the Products settings tab, with the subsections/subtabs:
I haven't been able to find any decent documentation on how to do this but I've been able to add a custom tab using this snippet:
class WC_Settings_Tab_Demo {
public static function init() {
add_filter( 'woocommerce_settings_tabs_array', __CLASS__ . '::add_settings_tab', 50 );
}
public static function add_settings_tab( $settings_tabs ) {
$settings_tabs['test'] = __( 'Settings Demo Tab', 'woocommerce-settings-tab-demo' );
return $settings_tabs;
}
}
WC_Settings_Tab_Demo::init();
Based on what I've dug up from various threads/tutorials, I've been trying to add the sections/subtabs to the new settings tab something like this:
// creating a new sub tab in API settings
add_filter( 'woocommerce_get_sections_test','add_subtab' );
function add_subtab( $sections ) {
$sections['custom_settings'] = __( 'Custom Settings', 'woocommerce-custom-settings-tab' );
$sections['more_settings'] = __( 'More Settings', 'woocommerce-custom-settings-tab' );
return $sections;
}
// adding settings (HTML Form)
add_filter( 'woocommerce_get_settings_test', 'add_subtab_settings', 10, 2 );
function add_subtab_settings( $settings, $current_section ) {
// $current_section = (isset($_GET['section']) && !empty($_GET['section']))? $_GET['section']:'';
if ( $current_section == 'custom_settings' ) {
$custom_settings = array();
$custom_settings[] = array( 'name' => __( 'Custom Settings', 'text-domain' ),
'type' => 'title',
'desc' => __( 'The following options are used to ...', 'text-domain' ),
'id' => 'custom_settings'
);
$custom_settings[] = array(
'name' => __( 'Field 1', 'text-domain' ),
'id' => 'field_one',
'type' => 'text',
'default' => get_option('field_one'),
);
$custom_settings[] = array( 'type' => 'sectionend', 'id' => 'test-options' );
return $custom_settings;
} else {
// If not, return the standard settings
return $settings;
}
}
I've been able to add new subsections to the Products tab using similar code to the above, but it isn't working for my new custom tab. Where am I going wrong here?
1) To add a setting tab with sections, you can firstly use the woocommerce_settings_tabs_array filter hook:
// Add the tab to the tabs array
function filter_woocommerce_settings_tabs_array( $settings_tabs ) {
$settings_tabs['my-custom-tab'] = __( 'My custom tab', 'woocommerce' );
return $settings_tabs;
}
add_filter( 'woocommerce_settings_tabs_array', 'filter_woocommerce_settings_tabs_array', 99 );
2) To add new sections to the page, you can use the woocommerce_sections_{$current_tab} composite hook where {$current_tab} need to be replaced by the key slug that is set in the first function:
// Add new sections to the page
function action_woocommerce_sections_my_custom_tab() {
global $current_section;
$tab_id = 'my-custom-tab';
// Must contain more than one section to display the links
// Make first element's key empty ('')
$sections = array(
'' => __( 'Overview', 'woocommerce' ),
'my-section-1' => __( 'My section 1', 'woocommerce' ),
'my-section-2' => __( 'My section 2', 'woocommerce' )
);
echo '<ul class="subsubsub">';
$array_keys = array_keys( $sections );
foreach ( $sections as $id => $label ) {
echo '<li>' . $label . ' ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
}
echo '</ul><br class="clear" />';
}
add_action( 'woocommerce_sections_my-custom-tab', 'action_woocommerce_sections_my_custom_tab', 10 );
3) For adding the settings, as well as for processing/saving, we will use a custom function, which we will then call:
// Settings function
function get_custom_settings() {
global $current_section;
$settings = array();
if ( $current_section == 'my-section-1' ) {
// My section 1
$settings = array(
// Title
array(
'title' => __( 'Your title 1', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_1'
),
// Text
array(
'title' => __( 'Your title 1.1', 'text-domain' ),
'type' => 'text',
'desc' => __( 'Your description 1.1', 'woocommerce' ),
'desc_tip' => true,
'id' => 'custom_settings_1_text',
'css' => 'min-width:300px;'
),
// Select
array(
'title' => __( 'Your title 1.2', 'woocommerce' ),
'desc' => __( 'Your description 1.2', 'woocommerce' ),
'id' => 'custom_settings_1_select',
'class' => 'wc-enhanced-select',
'css' => 'min-width:300px;',
'default' => 'aa',
'type' => 'select',
'options' => array(
'aa' => __( 'aa', 'woocommerce' ),
'bb' => __( 'bb', 'woocommerce' ),
'cc' => __( 'cc', 'woocommerce' ),
'dd' => __( 'dd', 'woocommerce' ),
),
'desc_tip' => true,
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_1'
),
);
} elseif ( $current_section == 'my-section-2' ) {
// My section 2
$settings = array(
// Title
array(
'title' => __( 'Your title 2', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_2'
),
// Text
array(
'title' => __( 'Your title 2.2', 'text-domain' ),
'type' => 'text',
'desc' => __( 'Your description 2.1', 'woocommerce' ),
'desc_tip' => true,
'id' => 'custom_settings_2_text',
'css' => 'min-width:300px;'
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_2'
),
);
} else {
// Overview
$settings = array(
// Title
array(
'title' => __( 'Overview', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_overview'
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_overview'
),
);
}
return $settings;
}
3.1) Add settings, via the woocommerce_settings_{$current_tab} composite hook:
// Add settings
function action_woocommerce_settings_my_custom_tab() {
// Call settings function
$settings = get_custom_settings();
WC_Admin_Settings::output_fields( $settings );
}
add_action( 'woocommerce_settings_my-custom-tab', 'action_woocommerce_settings_my_custom_tab', 10 );
3.2) Process/save the settings, via the woocommerce_settings_save_{$current_tab} composite hook:
// Process/save the settings
function action_woocommerce_settings_save_my_custom_tab() {
global $current_section;
$tab_id = 'my-custom-tab';
// Call settings function
$settings = get_custom_settings();
WC_Admin_Settings::save_fields( $settings );
if ( $current_section ) {
do_action( 'woocommerce_update_options_' . $tab_id . '_' . $current_section );
}
}
add_action( 'woocommerce_settings_save_my-custom-tab', 'action_woocommerce_settings_save_my_custom_tab', 10 );
Result:
Based on:
Implement a custom WooCommerce settings page, including page sections
woocommerce/includes/admin/settings/
I am developing a custom Divi module and I have a problem with the fb_support my module loads and works perfectly except in the visual editor. When I put the variable $this->fb_support = true my module disappear in visual editor and get this JavaScript error.
bundle.js?ver=3.0.106:formatted:1422 Uncaught TypeError: Cannot read property 'lockedParent' of undefined
at A (bundle.js?ver=3.0.106:formatted:1422)
at Object.ID_2 (bundle.js?ver=3.0.106:formatted:3571)
at e._invokeCallback (bundle.js?ver=3.0.106:formatted:35300)
at e.dispatch (bundle.js?ver=3.0.106:formatted:35288)
at Object.moduleActive (bundle.js?ver=3.0.106:formatted:7203)
at t.value (bundle.js?ver=3.0.106:formatted:8759)
at Object.l (bundle.js?ver=3.0.106:formatted:24713)
at Object.invokeGuardedCallback (bundle.js?ver=3.0.106:formatted:28497)
at Object.invokeGuardedCallbackAndCatchFirstError (bundle.js?ver=3.0.106:formatted:28500)
at h (bundle.js?ver=3.0.106:formatted:24781)
I think this error is because i don´t have registered my plugin in JavaScript part. Exist any method to do this? Is the correct way to do this?
Here is the code of my plugin:
class Price_Manager extends ET_Builder_Module
{
function init ()
{
$this->name = 'Price Manager;
$this->slug = 'et_pb_prices';
$this->fb_support = true;
$this->whitelisted_fields = array(
'widget_title',
'widget_type',
'admin_label',
'module_id',
'module_class',
);
$this->main_css_element = '%%order_class%%';
$this->advanced_options = array(
'custom_margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'filters' => array(),
);
}
function get_fields ()
{
$fields = array(
'widget_title' => array(
'label' => 'Title',
'type' => 'text',
'option_category' => 'basic_option',
'description' => 'This is your widget title',
),
'widget_type' => array(
'label' => 'Type of Widget',
'type' => 'select',
'option_category' => 'basic_option',
'options' => array(
'company' => 'Company',
'residential' => 'Residential'
),
'description' => 'Here you can choose the type of widget.',
),
'admin_label' => array(
'label' => 'Admin Label',
'type' => 'text',
'description' => 'This will change the label of the module in the builder for easy identification.',
),
'module_id' => array(
'label' => 'CSS ID',
'type' => 'text',
'option_category' => 'configuration',
'tab_slug' => 'custom_css',
'option_class' => 'et_pb_custom_css_regular',
),
'module_class' => array(
'label' => 'CSS Class',
'type' => 'text',
'option_category' => 'configuration',
'tab_slug' => 'custom_css',
'option_class' => 'et_pb_custom_css_regular',
),
);
return $fields;
}
function shortcode_callback ($atts, $content = null, $function_name)
{
$module_id = $this->shortcode_atts['module_id'];
$module_class = $this->shortcode_atts['module_class'];
$widget_title = $this->shortcode_atts['widget_title'];
$widget_type = $this->shortcode_atts['widget_type'];
$module_class = ET_Builder_Element::add_module_order_class($module_class, $function_name);
$module_id = '' !== $module_id ? sprintf('id="%s"', esc_attr($module_id)) : '';
$module_class = '' !== $module_class ? sprintf('%s', esc_attr($module_class)) : '';
$content = 'My title: ' . $widget_title; // TODO: Fetch the item from DB and prepare HTML for output.
$content .= '<br />';
$content .= 'My type of widget: ' . $widget_type;
$output = sprintf(
'<div class="et_pb_prices_module_wrapper et_pb_module">
<div %1$s class="et_pb_prices%2$s et_pb_module">%3$s</div>
</div>',
$module_id,
$module_class,
$content
);
return $output;
}
}
new Price_Manager();
Thanks.
Adding OptionTree pages is simple with the code below, but does anyone know how to retrieve the stored data?
/**
* Hook to register admin pages
*/
add_action( 'init', 'register_options_pages' );
/**
* Registers all the required admin pages.
*/
function register_options_pages() {
// Only execute in admin & if OT is installed
if ( is_admin() && function_exists( 'ot_register_settings' ) ) {
// Register the pages
ot_register_settings(
array(
array(
'id' => 'custom_options',
'pages' => array(
array(
'id' => 'test_page',
'parent_slug' => 'options-general.php',
'page_title' => 'Test Page',
'menu_title' => 'Test Page',
'capability' => 'edit_theme_options',
'menu_slug' => 'test-page',
'icon_url' => null,
'position' => null,
'updated_message' => 'Test Page updated.',
'reset_message' => 'Test Page reset.',
'button_text' => 'Save Changes',
'show_buttons' => true,
'screen_icon' => 'options-general',
'contextual_help' => null,
'sections' => array(
array(
'id' => 'test_section',
'title' => __( 'Test Section', 'motif-core' )
)
),
'settings' => array(
array(
'id' => 'test_section_input',
'label' => 'Test Input',
'desc' => 'Pretty freaking awesome!',
'std' => '',
'type' => 'text',
'section' => 'test_section',
'class' => ''
)
)
)
)
)
)
);
I tried this $my_plugin_options = get_option('custom_options'); but it only shows the word 'array' on the front end?
This is how to retrieve the stored data:
$my_plugin_options = get_option('custom_options');
echo $my_plugin_options['test_section_input'];
I use CMB2 — WordPress Plugins to create Custom Metaboxes. I have a textarea for embeding video. I need to validate the field in right way both on input and output.
$cmb = new_cmb2_box( array(
'id' => $prefix . 'video_box',
'title' => __( 'Video - Embeded from YouTube or Vimeo', 'ttt' ),
'object_types' => array( 'post' ), // Post type
'context' => 'normal',
'priority' => 'high',
'show_names' => true
) );
$cmb->add_field( array(
'name' => __( 'Embed Code', 'ttt' ),
'id' => $prefix . 'embed_code',
'type' => 'textarea',
'sanitization_cb' => false,
) );
Here is how I use it the field.
$embed_code = get_post_meta($id, 'ttt_embed_code', true )
i've got a problem with theme customizer. My code is:
function candyfloss_theme_customizer( $wp_customize ) {
class Heading extends WP_Customize_Control {
public $type = 'heading';
public function render_content() {
?>
<label>
<span class="customize-control-title" style="border-bottom: 1px dashed #666;"><strong><?php echo esc_html( $this->label ); ?></strong></span>
</label>
<?php
}
}
$wp_customize->add_setting('products_heading', array(
'default',
) );
$wp_customize->add_control(new Heading ($wp_customize, 'products_heading', array(
'label' => __('Home - products section'),
'type' => 'heading',
'section' => 'home',
) ) );
$wp_customize->add_setting('candyfloss_product_first', array(
'deafault',
) );
$wp_customize->add_control('candyfloss_product_first', array(
'label' => __('First product page'),
'type' => 'dropdown-pages',
'section' => 'home',
) );
$wp_customize->add_setting('candyfloss_product_second', array(
'deafault',
) );
$wp_customize->add_control('candyfloss_product_second', array(
'label' => __('Second product page'),
'type' => 'dropdown-pages',
'section' => 'home',
) );
$wp_customize->add_setting('candyfloss_product_third', array(
'deafault',
) );
$wp_customize->add_control('candyfloss_product_third', array(
'label' => __('Third product page'),
'type' => 'dropdown-pages',
'section' => 'home',
) );
};
add_action( 'customize_register', 'candyfloss_theme_customizer', 11 );
And the problem is in order of this. At admin panel view is
second option,
first option,
heading,
third option,
Can anyone know, what I'm doing wrong? Could You help me? I'll be thankful
I found the answer. Wordpress gives a random priority to controls. To solve it we just need to add priority number to each control.
eg.:
$wp_customize->add_control(new Heading ($wp_customize, 'products_heading', array(
'label' => __('Home - products section'),
'type' => 'heading',
'section' => 'home',
'priority' => 2,
) ) );