WordPress / 10 MIN READ
Shortcodes Product Attributes
Creating individual shortcodes for each of your custom product attributes
From the original Fervor library. Examples may use older package versions.
Creating individual shortcodes for each of your custom product attributes
Creating individual shortcodes for each of your custom product attributes can provide greater flexibility and control over where and how each attribute is displayed on your WooCommerce product pages or any other content areas that support shortcodes.
Below, I’ll guide you through the process of creating separate shortcodes for each attribute. This approach ensures that each attribute can be inserted independently wherever you need it.
Overview
-
Define Your Attributes:
- Create an associative array mapping each attribute slug to its label.
-
Register Shortcodes:
- Loop through the attributes array and register a unique shortcode for each attribute.
-
Shortcode Handler Function:
- Define a handler function that retrieves and displays the attribute value.
-
Usage:
- Use the newly created shortcodes in your content.
Step 1: Define Your Attributes
First, define an array that contains all your custom product attributes. Each entry should map the attribute slug (used internally by WooCommerce) to a human-readable label.
// Define your attributes: 'attribute_slug' => 'Attribute Label'
$attributes = array(
'am_number' => 'AM Number',
'andover_part_number' => 'Andover Part Number',
'angle_of_incidence' => 'Angle of Incidence',
'bandwidth' => 'Bandwidth',
'blocking' => 'Blocking',
'blocking_option_1' => 'Blocking Option 1',
'blocking_option_2' => 'Blocking Option 2',
'bw_spec_minus' => 'BW Spec Minus',
'bw_spec_plus' => 'BW Spec Plus',
'clear_aperture' => 'Clear Aperture',
'customer' => 'Customer',
'customer_po' => 'Customer P.O.',
'customer_part_no' => 'Customer Part No',
'description' => 'Description',
'description_web' => 'Description Web',
'dimensions' => 'Dimensions',
'dimensions_spec_minus' => 'Dimensions Spec Minus',
'dimensions_spec_plus' => 'Dimensions Spec Plus',
'filter_type' => 'Filter Type',
'substrate_1' => 'Substrate 1',
'flatness' => 'Flatness',
'item_category' => 'Item Category',
'item_classification' => 'Item Classification',
'minimum_transmission' => 'Minimum Transmission',
'operating_temperature' => 'Operating Temperature',
'parallelism' => 'Parallelism',
'qty_in_stock' => 'Qty in Stock',
'revision_date' => 'Revision Date',
'revision_letter' => 'Revision Letter',
'ring_depth' => 'Ring Depth',
'scratch_dig' => 'Scratch Dig',
'special_specifications' => 'Special Specifications',
'thickness' => 'Thickness',
'thickness_spec_minus' => 'Thickness Spec Minus',
'thickness_spec_plus' => 'Thickness Spec Plus',
'tx_option_1' => 'Tx Option 1',
'tx_option_2' => 'Tx Option 2',
'wavelength' => 'Wavelength',
'wavelength_number' => 'Wavelength Number',
'wavelength_range_high' => 'Wavelength Range High',
'wavelength_range_low' => 'Wavelength Range Low',
'web_item_category' => 'Web Item Category',
'web_site_include' => 'Web Site Include',
'wl_spec_minus' => 'WL Spec Minus',
'wl_spec_plus' => 'WL Spec Plus',
'set_components' => 'Set Components',
'element' => 'Element',
'surplus_plate_flag' => 'Surplus Plate Flag',
'surplus_useable_area' => 'Surplus Usable Area',
'filter_glass' => 'Filter Glass',
'refractive_index' => 'Refractive Index',
'curr_domestic_base_price_qty_a' => 'CURR Domestic Base Price Qty A',
'curr_domestic_base_price_qty_b' => 'CURR Domestic Base Price Qty B',
'curr_domestic_base_price_qty_c' => 'CURR Domestic Base Price Qty C',
'curr_intl_base_price_qty_a' => 'CURR Intl Base Price Qty A',
'curr_intl_base_price_qty_b' => 'CURR Intl Base Price Qty B',
'curr_intl_base_price_qty_c' => 'CURR Intl Base Price Qty C',
'nsn' => 'NSN',
);
Step 2: Register Shortcodes
Next, we’ll create a function that loops through this attributes array and registers a unique shortcode for each attribute. Each shortcode will follow the pattern [display_attribute_slug]. For example, the bandwidth attribute will have a shortcode [display_bandwidth].
Add the following code to your theme’s functions.php file or within a custom plugin:
// Register individual shortcodes for each product attribute
function register_individual_attribute_shortcodes() {
// Define your attributes: 'attribute_slug' => 'Attribute Label'
$attributes = array(
'am_number' => 'AM Number',
'andover_part_number' => 'Andover Part Number',
'angle_of_incidence' => 'Angle of Incidence',
'bandwidth' => 'Bandwidth',
'blocking' => 'Blocking',
'blocking_option_1' => 'Blocking Option 1',
'blocking_option_2' => 'Blocking Option 2',
'bw_spec_minus' => 'BW Spec Minus',
'bw_spec_plus' => 'BW Spec Plus',
'clear_aperture' => 'Clear Aperture',
'customer' => 'Customer',
'customer_po' => 'Customer P.O.',
'customer_part_no' => 'Customer Part No',
'description' => 'Description',
'description_web' => 'Description Web',
'dimensions' => 'Dimensions',
'dimensions_spec_minus' => 'Dimensions Spec Minus',
'dimensions_spec_plus' => 'Dimensions Spec Plus',
'filter_type' => 'Filter Type',
'substrate_1' => 'Substrate 1',
'flatness' => 'Flatness',
'item_category' => 'Item Category',
'item_classification' => 'Item Classification',
'minimum_transmission' => 'Minimum Transmission',
'operating_temperature' => 'Operating Temperature',
'parallelism' => 'Parallelism',
'qty_in_stock' => 'Qty in Stock',
'revision_date' => 'Revision Date',
'revision_letter' => 'Revision Letter',
'ring_depth' => 'Ring Depth',
'scratch_dig' => 'Scratch Dig',
'special_specifications' => 'Special Specifications',
'thickness' => 'Thickness',
'thickness_spec_minus' => 'Thickness Spec Minus',
'thickness_spec_plus' => 'Thickness Spec Plus',
'tx_option_1' => 'Tx Option 1',
'tx_option_2' => 'Tx Option 2',
'wavelength' => 'Wavelength',
'wavelength_number' => 'Wavelength Number',
'wavelength_range_high' => 'Wavelength Range High',
'wavelength_range_low' => 'Wavelength Range Low',
'web_item_category' => 'Web Item Category',
'web_site_include' => 'Web Site Include',
'wl_spec_minus' => 'WL Spec Minus',
'wl_spec_plus' => 'WL Spec Plus',
'set_components' => 'Set Components',
'element' => 'Element',
'surplus_plate_flag' => 'Surplus Plate Flag',
'surplus_useable_area' => 'Surplus Usable Area',
'filter_glass' => 'Filter Glass',
'refractive_index' => 'Refractive Index',
'curr_domestic_base_price_qty_a' => 'CURR Domestic Base Price Qty A',
'curr_domestic_base_price_qty_b' => 'CURR Domestic Base Price Qty B',
'curr_domestic_base_price_qty_c' => 'CURR Domestic Base Price Qty C',
'curr_intl_base_price_qty_a' => 'CURR Intl Base Price Qty A',
'curr_intl_base_price_qty_b' => 'CURR Intl Base Price Qty B',
'curr_intl_base_price_qty_c' => 'CURR Intl Base Price Qty C',
'nsn' => 'NSN',
);
foreach ( $attributes as $slug => $label ) {
// Define the shortcode name, e.g., display_bandwidth
$shortcode = 'display_' . $slug;
// Register the shortcode with a handler function
add_shortcode( $shortcode, function( $atts ) use ( $slug, $label ) {
global $product;
// Ensure we have a valid WooCommerce product object
if ( ! is_a( $product, 'WC_Product' ) ) {
return '';
}
// Retrieve the attribute value
$value = $product->get_attribute( $slug );
// If the attribute is not empty, format and return it
if ( ! empty( $value ) ) {
return '<div class="product-attribute"><strong>' . esc_html( $label ) . ':</strong> ' . esc_html( $value ) . '</div>';
}
// Return empty string if attribute is empty
return '';
} );
}
}
add_action( 'init', 'register_individual_attribute_shortcodes' );
Explanation:
-
Looping Through Attributes:
- The function
register_individual_attribute_shortcodesloops through each attribute in the$attributesarray.
- The function
-
Creating Shortcodes:
- For each attribute, it constructs a shortcode name in the format
display_{attribute_slug}. For example, for thebandwidthattribute, the shortcode will be[display_bandwidth].
- For each attribute, it constructs a shortcode name in the format
-
Handler Function:
- The
add_shortcodefunction registers the shortcode and assigns it an anonymous function (closure) as its handler. - The closure uses the
usekeyword to capture the current$slugand$labelfrom the loop. - Inside the handler, it accesses the global
$productobject to retrieve the attribute value using$product->get_attribute( $slug ). - If the attribute value exists, it returns a formatted HTML
<div>displaying the attribute label and value.
- The
-
Hooking into WordPress:
- The
register_individual_attribute_shortcodesfunction is hooked into WordPress’sinitaction, ensuring that shortcodes are registered early in the WordPress lifecycle.
- The
Step 3: Use the Shortcodes in Your Content
With the shortcodes registered, you can now use them anywhere within your WordPress content areas that support shortcodes (e.g., product descriptions, pages, posts).
Examples:
-
To display the Bandwidth attribute:
[display_bandwidth] -
To display the Customer Part No attribute:
[display_customer_part_no] -
To display the Wavelength Range High attribute:
[display_wavelength_range_high]
Note: Ensure that you use the correct attribute slug in the shortcode name. For example, for an attribute with the slug wavelength_range_high, the shortcode would be [display_wavelength_range_high].
Step 4 (Optional): Styling the Attribute Display
To enhance the appearance of the displayed attributes, you can add custom CSS to style the .product-attribute class.
Example CSS:
/* Add this CSS to your theme's stylesheet or a custom CSS plugin */
.product-attribute {
margin-bottom: 10px;
}
.product-attribute strong {
color: #333;
}
.product-attribute {
padding: 8px;
background-color: #f5f5f5;
border-radius: 4px;
}
Full Combined Code for functions.php or Custom Plugin
For convenience, here’s the complete code you can add to your theme’s functions.php file or a custom plugin to register all individual attribute shortcodes:
<?php
// Add this code to your theme's functions.php or a custom plugin
// Function to register individual shortcodes for each product attribute
function register_individual_attribute_shortcodes() {
// Define your attributes: 'attribute_slug' => 'Attribute Label'
$attributes = array(
'am_number' => 'AM Number',
'andover_part_number' => 'Andover Part Number',
'angle_of_incidence' => 'Angle of Incidence',
'bandwidth' => 'Bandwidth',
'blocking' => 'Blocking',
'blocking_option_1' => 'Blocking Option 1',
'blocking_option_2' => 'Blocking Option 2',
'bw_spec_minus' => 'BW Spec Minus',
'bw_spec_plus' => 'BW Spec Plus',
'clear_aperture' => 'Clear Aperture',
'customer' => 'Customer',
'customer_po' => 'Customer P.O.',
'customer_part_no' => 'Customer Part No',
'description' => 'Description',
'description_web' => 'Description Web',
'dimensions' => 'Dimensions',
'dimensions_spec_minus' => 'Dimensions Spec Minus',
'dimensions_spec_plus' => 'Dimensions Spec Plus',
'filter_type' => 'Filter Type',
'substrate_1' => 'Substrate 1',
'flatness' => 'Flatness',
'item_category' => 'Item Category',
'item_classification' => 'Item Classification',
'minimum_transmission' => 'Minimum Transmission',
'operating_temperature' => 'Operating Temperature',
'parallelism' => 'Parallelism',
'qty_in_stock' => 'Qty in Stock',
'revision_date' => 'Revision Date',
'revision_letter' => 'Revision Letter',
'ring_depth' => 'Ring Depth',
'scratch_dig' => 'Scratch Dig',
'special_specifications' => 'Special Specifications',
'thickness' => 'Thickness',
'thickness_spec_minus' => 'Thickness Spec Minus',
'thickness_spec_plus' => 'Thickness Spec Plus',
'tx_option_1' => 'Tx Option 1',
'tx_option_2' => 'Tx Option 2',
'wavelength' => 'Wavelength',
'wavelength_number' => 'Wavelength Number',
'wavelength_range_high' => 'Wavelength Range High',
'wavelength_range_low' => 'Wavelength Range Low',
'web_item_category' => 'Web Item Category',
'web_site_include' => 'Web Site Include',
'wl_spec_minus' => 'WL Spec Minus',
'wl_spec_plus' => 'WL Spec Plus',
'set_components' => 'Set Components',
'element' => 'Element',
'surplus_plate_flag' => 'Surplus Plate Flag',
'surplus_useable_area' => 'Surplus Usable Area',
'filter_glass' => 'Filter Glass',
'refractive_index' => 'Refractive Index',
'curr_domestic_base_price_qty_a' => 'CURR Domestic Base Price Qty A',
'curr_domestic_base_price_qty_b' => 'CURR Domestic Base Price Qty B',
'curr_domestic_base_price_qty_c' => 'CURR Domestic Base Price Qty C',
'curr_intl_base_price_qty_a' => 'CURR Intl Base Price Qty A',
'curr_intl_base_price_qty_b' => 'CURR Intl Base Price Qty B',
'curr_intl_base_price_qty_c' => 'CURR Intl Base Price Qty C',
'nsn' => 'NSN',
);
foreach ( $attributes as $slug => $label ) {
// Define the shortcode name, e.g., display_bandwidth
$shortcode = 'display_' . $slug;
// Register the shortcode with a handler function
add_shortcode( $shortcode, function( $atts ) use ( $slug, $label ) {
global $product;
// Ensure we have a valid WooCommerce product object
if ( ! is_a( $product, 'WC_Product' ) ) {
return '';
}
// Retrieve the attribute value
$value = $product->get_attribute( $slug );
// If the attribute is not empty, format and return it
if ( ! empty( $value ) ) {
return '<div class="product-attribute"><strong>' . esc_html( $label ) . ':</strong> ' . esc_html( $value ) . '</div>';
}
// Return empty string if attribute is empty
return '';
} );
}
}
add_action( 'init', 'register_individual_attribute_shortcodes' );
Additional Considerations
-
Ensuring Attribute Slugs Are Correct:
- Make sure that the attribute slugs used in the
$attributesarray exactly match the slugs defined in your WooCommerce product attributes. - Attribute slugs are typically lowercase and use underscores (
_) instead of spaces. - You can verify or edit attribute slugs by navigating to Products > Attributes in your WordPress dashboard.
- Make sure that the attribute slugs used in the
-
Handling Attributes Without Values:
- The current handler function skips attributes that are empty. If you prefer to display all attributes regardless of whether they’re filled, you can modify the handler function by removing the
if ( ! empty( $value ) )check. - For example:
return '<div class="product-attribute"><strong>' . esc_html( $label ) . ':</strong> ' . ( ! empty( $value ) ? esc_html( $value ) : 'N/A' ) . '</div>';
- The current handler function skips attributes that are empty. If you prefer to display all attributes regardless of whether they’re filled, you can modify the handler function by removing the
-
Styling the Attributes:
- As mentioned earlier, you can add custom CSS to style the
.product-attributeclass to match your site’s design. - Consider adding margins, padding, background colors, or other styles to enhance readability and aesthetics.
- As mentioned earlier, you can add custom CSS to style the
-
Caching Considerations:
- If you have a large number of products or attributes, ensure that the additional shortcodes do not adversely affect page load times.
- Implementing caching mechanisms (like transient APIs or object caching) can help improve performance.
-
Security:
- The handler function uses
esc_htmlto sanitize the attribute values before outputting them, which helps prevent potential security issues like Cross-Site Scripting (XSS). - Ensure that all attribute data is sanitized and validated as per WordPress standards.
- The handler function uses
Testing Your Shortcodes
After implementing the code:
-
Clear Caches:
- If you’re using any caching plugins or server-side caching, clear the caches to ensure the new shortcodes are recognized.
-
Create or Edit a Product:
- Navigate to Products > All Products in your WordPress dashboard.
- Edit an existing product or create a new one.
-
Insert Shortcodes:
- In the product description, short description, or any other content area that supports shortcodes, insert the desired shortcodes. For example:
<h3>Product Specifications</h3> [display_bandwidth] [display_customer_part_no] [display_wavelength_range_high]
- In the product description, short description, or any other content area that supports shortcodes, insert the desired shortcodes. For example:
-
Preview the Product:
- Preview the product on the front end to ensure that the attributes are displayed correctly where you’ve inserted the shortcodes.
-
Verify Attribute Values:
- Ensure that the attributes with values are displayed correctly and that empty attributes are handled as intended.
Conclusion
By following the steps above, you’ve successfully created individual shortcodes for each of your custom WooCommerce product attributes. This setup allows for granular control over where each attribute is displayed, enhancing the flexibility and customization of your product pages.