WordPress / 5 MIN READ
Step 1: Create a Separate PHP File
Absolutely! Keeping your code organized is always a good idea, especially if your functions.php is getting crowded. You can place the shortcode code in a s
From the original Fervor library. Examples may use older package versions.
Absolutely! Keeping your code organized is always a good idea, especially if your functions.php is getting crowded. You can place the shortcode code in a separate file and include it in functions.php.
Here’s how to do it:
Step 1: Create a Separate PHP File
-
In your child theme directory (e.g.,
wp-content/themes/your-child-theme), create a new file namedshortcodes.php. -
Move the shortcode function into this new file:
<?php // Custom Shortcode for WooCommerce Category Cards function custom_woocommerce_category_cards_shortcode($atts) { // Parse the shortcode attributes $atts = shortcode_atts( [ 'slugs' => '', // Comma-separated slugs of categories 'columns' => 3, // Number of cards per row 'rows' => 1, // Number of rows ], $atts, 'category_cards' ); // Extract attributes for easier use $slugs = explode(',', $atts['slugs']); // Convert slugs string into an array $columns = intval($atts['columns']); $rows = intval($atts['rows']); $limit = $columns * $rows; // Fetch categories using the slugs $categories = get_terms([ 'taxonomy' => 'product_cat', 'slug' => $slugs, 'hide_empty' => true, 'number' => $limit, ]); if (is_wp_error($categories) || empty($categories)) { return '<p>No categories found.</p>'; } // Start building the HTML output ob_start(); echo '<div class="custom-category-cards-grid" style="display: grid; gap: 20px; grid-template-columns: repeat(' . esc_attr($columns) . ', 1fr);">'; foreach ($categories as $category) { // Get category thumbnail ID $thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true); $image_url = $thumbnail_id ? wp_get_attachment_url($thumbnail_id) : wc_placeholder_img_src(); // Output each category as a card echo '<div class="custom-category-card" style="text-align: center; border: 1px solid #ddd; padding: 15px; border-radius: 8px;">'; echo '<a href="' . esc_url(get_term_link($category)) . '" style="text-decoration: none; color: inherit;">'; echo '<img src="' . esc_url($image_url) . '" alt="' . esc_attr($category->name) . '" style="width: 100%; height: auto; border-radius: 8px;">'; echo '<h3 style="margin-top: 10px; font-size: 18px;">' . esc_html($category->name) . '</h3>'; echo '</a>'; echo '</div>'; } echo '</div>'; return ob_get_clean(); } add_shortcode('category_cards', 'custom_woocommerce_category_cards_shortcode');
Step 2: Include the New File in functions.php
Open your functions.php file and add the following line at the top (or wherever it makes sense for your organization):
require_once get_stylesheet_directory() . '/shortcodes.php';
This line will include your shortcodes.php file into functions.php, making the shortcode function available while keeping the main file cleaner.
Step 3: Verify It Works
- Clear your WordPress cache (if any).
- Test the shortcode on a page, just like before:
[category_cards slugs="clothing,accessories,sale" columns="3" rows="2"]
If everything is set up correctly, the shortcode should work just as it did before.
Why This Approach Is Beneficial
- Improved Readability: Keeps
functions.phpuncluttered. - Easier Maintenance: If you need to modify or debug the shortcode, you only work with
shortcodes.php. - Scalability: You can create separate files for different purposes (e.g.,
shortcodes.php,custom-post-types.php, etc.).
🎉 Done! Your shortcode is now neatly organized in its own file, and your functions.php is clean and manageable.
Bonus For making responsive and Flow
To make your WooCommerce category cards responsive with a maximum row width of 1200px, a minimum card width of 200px, and responsive “flowing” resizing, we’ll use CSS Grid with some enhancements. CSS Grid’s auto-fit and minmax() properties are perfect for this scenario.
Here’s how to update your shortcode and CSS for responsiveness:
Step 1: Update the Shortcode Output
Modify the CSS in the custom_woocommerce_category_cards_shortcode function to ensure the layout adheres to the new responsive behavior.
Updated Shortcode Code
Replace the previous echo statement in your shortcode function with this updated one:
ob_start();
echo '<div class="custom-category-cards-grid" style="display: grid; gap: 20px; max-width: 1200px; margin: 0 auto;">';
foreach ($categories as $category) {
// Get category thumbnail ID
$thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true);
$image_url = $thumbnail_id ? wp_get_attachment_url($thumbnail_id) : wc_placeholder_img_src();
// Output each category as a card
echo '<div class="custom-category-card">';
echo '<a href="' . esc_url(get_term_link($category)) . '" style="text-decoration: none; color: inherit;">';
echo '<img src="' . esc_url($image_url) . '" alt="' . esc_attr($category->name) . '">';
echo '<h3>' . esc_html($category->name) . '</h3>';
echo '</a>';
echo '</div>';
}
echo '</div>';
return ob_get_clean();
Here’s what we changed:
- Removed inline grid styles from the
grid-template-columnsproperty. - Added a class-based structure for better flexibility.
Step 2: Add Responsive CSS
Add the following CSS to your child theme’s style.css file or the WordPress Customizer > Additional CSS section:
/* Grid container styles */
.custom-category-cards-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
}
/* Individual card styles */
.custom-category-card {
text-align: center;
border: 1px solid #ddd;
padding: 15px;
border-radius: 8px;
background-color: #fff;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.custom-category-card:hover {
transform: scale(1.05);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
}
/* Image styles */
.custom-category-card img {
width: 100%;
height: auto;
border-radius: 8px;
}
/* Title styles */
.custom-category-card h3 {
margin-top: 10px;
font-size: 18px;
color: #333;
font-weight: bold;
}
How This CSS Works
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));:auto-fit: Automatically adjusts the number of columns to fit the available space.minmax(200px, 1fr): Ensures each card is at least200pxwide but stretches up to fill the available space.
-
max-width: 1200pxandmargin: 0 auto:- Centers the grid container on the page and limits its width to
1200px.
- Centers the grid container on the page and limits its width to
-
Responsive Flow:
- If the viewport width is smaller than
1200px, the cards automatically flow into fewer columns while maintaining the200pxminimum width.
- If the viewport width is smaller than
-
Padding and Gaps:
gap: 20pxensures a consistent spacing between cards.padding: 20pxinside the grid ensures the content doesn’t stick to the edges on small screens.
Step 3: Test the Responsiveness
-
Use the shortcode as before:
[category_cards slugs="clothing,accessories,sale" columns="3" rows="2"](The
columnsattribute can still be used for logical grouping but isn’t required for layout.) -
Open the page in a browser and:
- Resize the browser window.
- Verify that the cards “flow” and resize responsively.
Step 4: Bonus Enhancements
-
Add Hover Effects for Images:
.custom-category-card img { transition: transform 0.3s ease; } .custom-category-card:hover img { transform: scale(1.05); } -
Lazy Load Images: Add the
loading="lazy"attribute to images for better performance:echo '<img src="' . esc_url($image_url) . '" alt="' . esc_attr($category->name) . '" loading="lazy">'; -
Accessibility: Add
aria-labelto links for screen readers:echo '<a href="' . esc_url(get_term_link($category)) . '" aria-label="View ' . esc_attr($category->name) . ' category">';
🎉 And that’s it! Your shortcode now creates a fully responsive grid of category cards that flows beautifully on all screen sizes. 😊