This is searchable archive of our old support forums, which operated from 2012 - 2016. To find out how to get support for your current theme, please visit our support page.

Add Option Type

  • Creator
    Topic
  • #22937
    John
    Participant

    I’m trying to add a new sortable option type (ala social icons).
    Immediately after the framework in child functions.php I added:

    /**
     * Header Elements buttons option type
     *
     * @since 2.5.0
     */
    class JMA_Sortable_Headers extends Theme_Blvd_Sortable_Option {
    
    	/**
    	 * Constructor
    	 *
    	 * @since 2.5.0
    	 */
    	public function __construct() {
    
    		// Set type
    		$this->type = 'sortable_header';
    
    		// Run parent
    		parent::__construct();
    
    	}
    
    	/**
    	 * Get options
    	 *
    	 * @since 2.5.0
    	 */
    	public function get_options() {
    		$options = array(
    			array(
    				'id' 		=> 'header_element',
    				'name'		=> __('Header Element', 'themeblvd'),
    				'type'		=> 'select',
    				'std'		=> 'content',
    				'options'	=> array(
    			        'content' => 'Content',
    			        '#access' => 'Primary Menu',
    			        '#access2' => 'Secondary Menu',
    			        'image' => 'Header Image or Slider',
    					),
    				'trigger'	=> true // Triggers this option's value to be used in toggle
    			),
    			array(
    				'id' 		=> 'contents',
    				'name'		=> __('Element Contents', 'themeblvd'),
    				'type'		=> 'multicheck',
    				'std'		=> array( 'logo' => 1, 'widget' => 1, 'nav_btn' => 0 ) ,
    				'options'   => array(
    			        'logo' => 'Logo',
    			        'widget' => 'Header Widget',
    			        'nav_btn' => 'Mobile Nav Button (use exactly once)'
    				)
    			),
    		);
    		return $options;
    	}
    
    	/**
    	 * Get labels
    	 *
    	 * @since 2.5.0
    	 */
    	public function get_labels() {
    		$labels = array(
    			'add' 					=> __('Add Header Element','themeblvd'),
    			'delete' 				=> __('Delete Header Element','themeblvd'),
    			'delete_confirm'		=> __('Are you sure you want to delete this header element?', 'themeblvd'),
    			'delete_all' 			=> __('Delete All Header Elements','themeblvd'),
    			'delete_all_confirm' 	=> __('Are you sure you want to delete all header elements?','themeblvd')
    		);
    		return $labels;
    	}
    
    }

    I have a feeling I need to instantiate this or something?
    Any way the I add:

    $name = 'Header Setup';
    $description = 'A couple of additional changes to basic layout.';
    $options = array(
         array(
        'name'      => 'Sortable Header Items',
        'desc'      => 'Description',
        'id'        => 'header_content',
        'std'       => array(
    					'item_1' => array(
    						'header_element'	=> 'content',
    						'contents'	=> array( 'logo' => 1, 'widget' => 1, 'nav_btn' => 1 )
    					),
    					'item_2' => array(
    						'header_element'	=> '#access',
    						'contents'	=> array( 'logo' => 0, 'widget' => 0, 'nav_btn' => 0 )
    					),
    					'item_3' => array(
    						'header_element'	=> 'image',
    						'contents'	=> array( 'logo' => 0, 'widget' => 0, 'nav_btn' => 0 )
    					)
    				),
    	'type' 		=> 'sortable_header'
    )
    );			
    themeblvd_add_option_section( 'jma_styles_header', 'jma_header_options', $name, $description, $options, true );

    Just the title and description show up. As I said above, I think I need to do something with my new class to cause it to register.
    thx,
    John

Viewing 7 replies - 1 through 7 (of 7 total)
  • Author
    Replies
  • #22946
    Jason Bobich
    Keymaster

    This was never really meant to be extended in the way you’re doing. In the framework there’s another class Theme_Blvd_Advanced_Options where all of these options are instantiated.

    For adding an option type, in general, there are two major things you’re not doing.

    1) You need to output your option on the options page. See the filter towards the bottom of /framework/admin/options/options-interface.php called “themeblvd_option_type”.

    2) You need to create a function for sanitation and filter onto themeblvd_sanitize_{option_type} — Without this, the option’s data will never save. See /framework/admin/options/sanitize.php and look at examples of other similar option types.


    Now, because you’re trying to do a sortable option type, and create your own that’s not part of the framework system managed with Theme_Blvd_Advanced_Options. You need to instantiate that class to some sort of global object that you can reference a second time when you filter onto to display the option.

    Just sort of pulling this off the top of my head. I’ve never tested any of this from a child theme. It’s all theoretical because no one has ever asked.

    /**
     * Instantiate sortable option objects, so everything 
     * is hooked into place, and ready to display.
     */
    function jma_setup_sortable_options() {
    	if ( class_exists('JMA_Sortable_Headers') ) { 
    		$GLOBALS["jma_sortable_header"] = new JMA_Sortable_Headers();
    	}
    }
    add_action('after_setup_theme', 'jma_setup_sortable_options');
    
    /**
     * Display option.
     */
    function jma_option_type( $output, $option, $option_name, $val ) {
    
    	global $jma_sortable_header;
    
    	if ( $option['type'] == 'sortable_header' ) {
    		$output .= $jma_sortable_header->get_display( $option['id'], $option_name, $val );
    		$output = str_replace('section-sortable_header', 'section-sortable_header section-sortable', $output);
    	}
    
    	return $output;
    }
    add_filter('themeblvd_option_type', 'jma_option_type', 10, 4);
    
    /**
     * Sanitize option
     */
    function jma_sanitize_sortable_header( $input ) {
    
    	$output = array();
    
    	if ( $input && is_array($input) ) {
    		foreach ( $input as $item_id => $item ) {
    			// just an example of basic text sanitization on each input ...
    			$output[$item_id]['header_element'] = apply_filters( 'themeblvd_sanitize_text', $item['header_element'] );
    			$output[$item_id]['contents'] = apply_filters( 'themeblvd_sanitize_text', $item['contents'] );
    		}
    	}
    
    	return $output;
    }
    add_filter('themeblvd_sanitize_sortable_header', 'jma_sanitize_sortable_header');
    • This reply was modified 7 years, 9 months ago by Jason Bobich. Reason: (1) Edited jma_setup_sortable_options() and (2) edited jma_option_type()
    #22951
    John
    Participant

    Thanks Jason. I realize I was skating on thin ice here. Tried it, but with the object instantiated on the ‘wp’ hook, I got ‘Call to a member function get_display() on a non-object’. Tried replacing the ‘wp’ hook with ‘after_setup_theme’, which lets the option display, but only seems to pull the label values (button text) and no option values.

    Unless you think of something obvious I’m missing, I’ll have to try something less elegant. I don’t see any repeating (non-sortable) options available right?

    Thanks as always for your help.
    John

    #22956
    Jason Bobich
    Keymaster

    Yup, so hooking to after_setup_theme should solve that. But remember that this hook is fired every where, and all this stuff we’re doing only happens in the admin. And so things don’t break on the frontend, just make sure that:

    1) Don’t create your child class unless parent class exists:

    /**
     * Header Elements buttons option type
     */
    if ( class_exists('Theme_Blvd_Sortable_Option') ) {
        class JMA_Sortable_Headers extends Theme_Blvd_Sortable_Option {
            // ...
        }
    }

    2) Don’t instantiate your object unless your class exists:

    if ( class_exists('JMA_Sortable_Headers') ) { 
    	$GLOBALS["jma_sortable_header"] = new JMA_Sortable_Headers();
    }

    For the option not running, it’s because it needs the class “section-sortable” added to the wrapping option. This only happens if it’s one of the framework sortable options, which isn’t a filterable list. But see the edit I made above to jma_option_type() which creatively slips that class in there.

    The next issue you’re going to face is that the sortable option class doesn’t have every option type available within that the framework has. See the method get_item() of class Theme_Blvd_Sortable_Option to see all supported option types.

    So, “multicheck” isn’t going to produce anything unfortunately. You’d have to use another option type. Maybe consider using three separate “checkbox” options.

    #22961
    John
    Participant

    That did the trick! Thanks alot. I did have to do this:

    if ( is_admin() ){
    class JMA_Sortable_Headers extends Theme_Blvd_Sortable_Option {
    ….
    }
    It was tossing a fatal error on the front end. print_r on the front end is giving me what I expect, so it’s off to the races.
    thanks again,
    John

    #24178
    mizzinc
    Participant

    Great article!

    I have been able to create a new Layout Builder Element (Team Member Slider) which is saving all the data. I cant quite figure how to output on the front end. A print_r outputs the element_27840564d1e4f60eb4.

    Breakdown of entire code.

    Add Layout Builder Element

    /**
     *
     * Adds Team Member Slider element to the layout builder
    */
    $team_member_slider_options = array(	
        array(
    		'id' 		       => 'team_member_slide',
    		'name'		=> __( 'Team Member', 'theme-blvd-layout-builder' ),
    		'desc'		=> null,
    		'type'		=> 'team_member_slide'
        ),
        array(
    		'id' 		        => 'slide',
    		'name'		=> __( 'Team Members per slide', 'theme-blvd-layout-builder' ),
    		'desc'		=> __( 'Select the amount of Team Members to display for each slide of the slider.', 'theme-blvd-layout-builder' ),
    		'type'		=> 'select',
    		'std'		        => '4',
    		'options'	=> array(
    			'2' 		=> __( '2 logos per slide', 'theme-blvd-layout-builder' ),
    			'3' 		=> __( '3 logos per slide', 'theme-blvd-layout-builder' ),
    			'4' 		=> __( '4 logos per slide', 'theme-blvd-layout-builder' ),
    			'5' 		=> __( '5 logos per slide', 'theme-blvd-layout-builder' )
    		)
        ),	
        array(
    		'id' 		        => 'timeout',
    		'name'		=> __( 'Speed', 'theme-blvd-layout-builder' ),
    		'desc'		=> __( 'Enter the number of seconds you\'d like in between transitions. You may use 0 to disable the slider from auto advancing.', 'theme-blvd-layout-builder' ),
    		'type'		=> 'text',
    		'std'		        => '0'
        ),
        array(
    		'id' 		        => 'nav',
    		'name'		=> null,
    		'desc'		=> __( 'Display slider navigation.', 'theme-blvd-layout-builder' ),
    		'std'		        => '1',
    		'type'		=> 'checkbox'
        )			
    );
    themeblvd_add_builder_element( 'team_members_slider', 'Team Member Slider', 'none', $team_member_slider_options, 'mizzinc_team_members_slider' );

    Add Team Member Option Type

    if ( class_exists('Theme_Blvd_Sortable_Option') ) { 
    	class Mizzinc_Team_Member_Option extends Theme_Blvd_Sortable_Option {
    	
    		/**
    		 * Constructor
    		 *
    		 * @since 2.5.0
    		 */
    		public function __construct() {
    	
    			// Set type
    			$this->type = 'team_member_slide';
    	
    			// Run parent
    			parent::__construct();
    	
    		}
    	
    		/**
    		 * Get options
    		 *
    		 * @since 2.5.0
    		 */
    		public function get_options() {
    			$options = array(
    				array(
    					'id' 		        => 'image',
    					'name' 		=> __( 'Image', 'theme-blvd-layout-builder'),
    					'desc'		=> __( 'Select an image for this person.', 'theme-blvd-layout-builder'),
    					'type'		=> 'upload',
    					'advanced'	=> true
    				),
    				array(
    					'id' 		       => 'name',
    					'name' 		=> __( 'Name', 'theme-blvd-layout-builder'),
    					'desc'		=> __( 'Enter the name of this person.', 'theme-blvd-layout-builder'),
    					'type'		=> 'text'
    				),
    				array(
    					'id' 		       => 'tagline',
    					'name' 		=> __( 'Tagline', 'theme-blvd-layout-builder'),
    					'desc'		=> __( 'Enter a brief tagline for this person.<br>Ex: Founder and CEO', 'theme-blvd-layout-builder'),
    					'type'		=> 'text'
    				),
    				array(
    					'id' 		        => 'link',
    					'name' 		=> __( 'LinkedIn URL', 'theme-blvd-layout-builder'),
    					'desc'		=> __( 'Enter the Members URL.', 'theme-blvd-layout-builder'),
    					'type'		=> 'text'
    				)
    			);
    			return $options;
    		}
    	
    		/**
    		 * Get labels
    		 *
    		 * @since 2.5.0
    		 */
    		public function get_labels() {
    			$labels = array(
    				'add' 				=> __('Add Team Member','themeblvd'),
    				'delete' 				=> __('Remove Team Member','themeblvd'),
    				'delete_all' 			=> __('Remove All Team Members','themeblvd'),
    				'delete_all_confirm' 	=> __('Are you sure you want to remove all Team Members?','themeblvd'),
    				'modal_title'			=> __('Select Team Member','themeblvd'),
    				'modal_button'		=> __('Add Team Member','themeblvd')
    			);
    			return $labels;
    		}
    	
    	}
    }

    Instantiate, display and sanitize option

    /**
     * Instantiate sortable option objects, so everything 
     * is hooked into place, and ready to display.
     */
    function mizzinc_setup_sortable_options() {
    	if ( class_exists( 'Mizzinc_Team_Member_Option' ) ) { 
    		$GLOBALS["mizzinc_team_member_option"] = new Mizzinc_Team_Member_Option();
    	}
    }
    add_action( 'after_setup_theme', 'mizzinc_setup_sortable_options' );
    /**
     * Display option.
     */
    function mizzinc_option_type( $output, $option, $option_name, $val ) {
    
    	global $mizzinc_team_member_option;
    
    	if ( $option['type'] == 'team_member_slide' ) {
    		$output .= $mizzinc_team_member_option->get_display( $option['id'], $option_name, $val );
    		$output = str_replace('section-team_member_slide', 'section-team_member_slide section-sortable', $output);
    	}
    
    	return $output;
    }
    add_filter( 'themeblvd_option_type', 'mizzinc_option_type', 10, 4 );
    /**
     * Sanitize option
     */
    function mizzinc_sanitize_team_member_slide( $input ) {
    
    	$output = array();
    
    	if ( $input && is_array($input) ) {
    		foreach ( $input as $item_id => $item ) {
    			$output[$item_id]['image'] = apply_filters( 'themeblvd_sanitize_upload', $item['image'] );
    			$output[$item_id]['name'] = apply_filters( 'themeblvd_sanitize_text', $item['name'] );
    			$output[$item_id]['tagline'] = apply_filters( 'themeblvd_sanitize_text', $item['tagline'] );
    			$output[$item_id]['link'] = apply_filters( 'themeblvd_sanitize_text', $item['link'] );
    		}
    	}
    
    	return $output;
    }
    add_filter( 'themeblvd_sanitize_team_member_slide', 'mizzinc_sanitize_team_member_slide' );

    Get Team Member Slider for Frontend

    function mizzinc_team_members_slider( $args ) {
    		
    	$defaults = array(
            'team_member_slide'	=> array(), // Team Member
            'slide'     		=> '4',     // If slider, number of logos per slide
            'timeout'   		=> '3',     // If slider, seconds in between auto rotation
            'nav'       		=> '1'      // If slider, whether to display nav
        );
        $args = wp_parse_args( $args, $defaults );
    
        //**Build the HTML below**//
    
        //Output the HTML//
        echo $output;
    }
    • This reply was modified 7 years, 6 months ago by mizzinc.
    #24181
    John
    Participant

    function mizzinc_team_members_slider($id, $args){

    }

    The second parameter is the options.
    Hope that is of some help. I was using strictly theme options, you are using a builder element which is a little different, but might work.

    #24187
    mizzinc
    Participant

    Simple solution right there, thank you sir. Must have been staring at the screen for far to long.

Viewing 7 replies - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.