WordPress短代码shortcode与自定义字段Custom Fields的合用

为了方便使用插件WP Simple Shopping Cart,将购物车短代码按钮[wp_cart_button name="Test Product" price="29.95"]中的参数从固定值切换到可变值,决定使用Custom Fields来给修改购物车短代码中的name和price赋值。

创建Custom Fields字段

创建selected_custom_field给name赋值用,再创建selected_custom_field_price给price赋值用。自定义的selected_custom_field值将与selected_custom_field_price自定义值按顺序来对应,两个自定义值缺少任意一对应值将不输出结果;

将Custom Fields字段的自定义值插入到post content中

通常是在模板中调用Custom Fields的值,但为了修改post content中的购物车短代码按钮[wp_cart_button name="Test Product" price="29.95"],必须要在编辑器中接收到Custom Fields的自定义值;另外一个原因是Custom Fields自定义字段也需要在前端显示,并且将用户来选择,经过触发,再将对应值赋值给购物车短代码按钮[wp_cart_button name="Test Product" price="29.95"],并且修改对应name和price的值,从而改变原来的默认值。

要将Custom Fields自定义值插入到编辑器中,最快的方法就是使用短代码。将Custom Fields生成一组短代码,再将短代码插入到编辑器目标位置;短代码很方便调整位置,甚至CSS样式

function custom_field_type_shortcode() {
    $post_id = get_the_ID();
    $custom_fields = get_post_custom($post_id);
    $field_values = get_post_custom_values('selected_custom_field', $post_id);
    $price_values = get_post_custom_values('selected_custom_field_price', $post_id);

    // Combine field and price values and maintain order
    $combined_values = array();
    for ($i = 0; $i < count($field_values); $i++) {
        if (isset($field_values[$i], $price_values[$i])) {
            $field = esc_attr($field_values[$i]);
            $price = esc_attr($price_values[$i]);
            $combined_values[$field] = $price;
        }
    }

    // Sort the fields and prices based on their order of addition
    asort($combined_values);

    $radioButtons = ''; // Initialize a string to store radio button inputs
    $name = 'selected_custom_field'; // Radio buttons should have the same 'name' attribute for exclusive selection

    foreach ($combined_values as $field => $price) {
        $field = esc_attr($field);
        $price = esc_attr($price);

        // Generate a radio button input for each field
        $radioButtons .= '<input type="radio" name="' . $name . '" value="' . $field . '" data-price="' . $price . '">';
        $radioButtons .= '<label>' . $field . ' ($' . $price . ')</label>';
    }

    return $radioButtons;
}
add_shortcode('custom_field_type', 'custom_field_type_shortcode');

创建Custom Fields的短代码插入按钮

如果每次手动输入短代码,麻烦且容易忘记,于是便创建一个简单Qtags来插入对应的自定义自段短代码

function appthemes_add_quicktags() {
	if (wp_script_is('quicktags')){
		wp_add_inline_script(
        'quicktags',
		QTags.addButton( 'custom_field_type', 'CFtype', '[custom_field_type]<span id=\"addtocart\"></span>', '', '', 'Insert Custom Field Type', 100);
		QTags.addButton( 'eg_nbsp', 'nbsp', ' ', '', '', 'Non Breaking Space', 111 );"    
		);
	}
}
add_action('admin_print_footer_scripts', 'appthemes_add_quicktags' );

用户选择的结果使用AJAX来调用,并将值赋给[wp_cart_button]

上述的Custom Fields自定义值,被生成了单选项radio box;相比较修改原来的购物车短代码按钮[wp_cart_button name="Test Product" price="29.95"],不如生成新的[wp_cart_button],避免查找修改的过程。

AJAX-PHP端

function handle_shortcode_request() {
    $selectedField = sanitize_text_field($_POST['selectedField']);
    $selectedPrice = sanitize_text_field($_POST['selectedPrice']);

    $shortcode = '[wp_cart_button name="' . $selectedField . '" price="' . $selectedPrice . '"]';
    $result = do_shortcode($shortcode);

    echo $result;
    wp_die();
}

add_action('wp_ajax_handle_shortcode_request', 'handle_shortcode_request');
add_action('wp_ajax_nopriv_handle_shortcode_request', 'handle_shortcode_request');

JS端

		// Function to generate and display the shortcode triggled by Custom Fields.
		function generateShortcode() {
			var selectedField = $('input[name="selected_custom_field"]:checked').val();
			var selectedPrice = $('input[name="selected_custom_field"]:checked').data('price');
			
			if ( selectedField && selectedPrice ) {
				$.ajax({
					type: 'POST',
					url: cq_ajax.ajax_url, // Use the global AJAX URL variable provided by WordPress
					data: {
						action: 'handle_shortcode_request',
						selectedField: selectedField,
						selectedPrice: selectedPrice
					},
					success: function(response) {
						$('#addtocart').html(response);
					}
				});
			}
		}
		$('input[name="selected_custom_field"]').on('change', function() {
			generateShortcode();
		});
		// Initial generation of the shortcode 默认不显示#addtocart
		//generateShortcode();

要留意在编辑器中写入<span id="addtocart"></span>来接受生成的[wp_cart_button]购物车按钮; 此问题已经在Qtags中解决,会与短代码一同写入;

同时另忘记定义AJAX文件

// ajax call for frontend
	wp_localize_script( 'script', 'cq_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' )));

创建一个meta box来验证Custom Fields结果(可选)

/*Triggle Custom Fields to control shortcode*/
add_action('add_meta_boxes', 'add_custom_meta_box');
function add_custom_meta_box() {
    add_meta_box('custom_field_selector', 'Select Custom Field', 'custom_field_selector_callback', 'post', 'normal', 'high');
}

function custom_field_selector_callback($post) {
    $selected_field = get_post_meta($post->ID, 'selected_custom_field', true);
    $all_custom_fields = get_post_custom($post->ID);
    $custom_field_values = [];

    ?>

    <label for="selected_custom_field">Select a Custom Field:</label>
    <select name="selected_custom_field" id="selected_custom_field">
        <option value="">Select a Custom Field</option>
        <?php
        foreach ($all_custom_fields as $field => $values) :
            $field = esc_attr($field);
            ?>
            <option value="<?php echo $field; ?>" <?php selected($selected_field, $field); ?>>
                <?php echo $field; ?>
            </option>
        <?php endforeach; ?>
    </select>

    <div id="custom-field-result">
        <?php if (!empty($selected_field) && isset($all_custom_fields[$selected_field])) : ?>
            <p>Selected custom field values: <?php echo implode(', ', $all_custom_fields[$selected_field]); ?></p>
        <?php endif; ?>
    </div>

    <script>
        document.getElementById('selected_custom_field').addEventListener('change', function() {
            var selectedField = this.value;
            var customFieldResult = document.getElementById('custom-field-result');
            customFieldResult.innerHTML = '';

            if (selectedField && <?php echo json_encode(array_keys($all_custom_fields)); ?>.includes(selectedField)) {
                var values = <?php echo json_encode($all_custom_fields); ?>[selectedField];
                customFieldResult.innerHTML = '<p>Selected custom field values: ' + values.join(', ') + '</p>';
            }
        });
    </script>

    <?php
}

完结

Previous/Next

Say Something!

Leave a Reply