WooCommerce 9 Cart Hook
August 7, 2025 Β· AI Conversations
above hook not working in woocommerce 9 cart page
### β Why your hook isn't working:
add_filter('woocommerce_after_cart_item_name', array($this, 'probo_upload_field_to_cart_items'), 10, 2);
This hook is meant for the **Classic Cart Template**, not the **Cart Block** used in WooCommerce 9+ by default.
—
### π§ Solution Options
#### β Option 1: **Revert to Classic Cart Template**
You can disable the Cart Block and revert to the classic template:
1. Go to **WooCommerce β Settings β Advanced β Features**.
2. Disable **"Cart and Checkout blocks"** (name may vary; look for block-based cart/checkout toggle).
3. This will restore the PHP-based cart, allowing your hook to work.
—
#### β Option 2: **Use a Custom Block Extension (React-based)**
If you want your field to appear inside the Cart Block:
– Youβll need to **create a WooCommerce Blocks extension** using React.
– This involves **registering a block extension component** via JS that hooks into the cart item's display.
– WooCommerce Blocks provides the [Cart Block Item API](https://github.com/woocommerce/woocommerce-blocks/tree/trunk/assets/js/blocks/cart-checkout/cart) for customization.
Example of JS filter for extending cart line items:
import { registerPlugin } from '@wordpress/plugins';
import { CartLineItemRow } from '@woocommerce/blocks-checkout';
const MyCartExtension = () => {
return (
<CartLineItemRow>
<div>Your custom content here (e.g., upload filename)</div>
</CartLineItemRow>
);
};
registerPlugin('my-cart-extension', {
render: MyCartExtension,
});
You will also need to enqueue your block extension using:
add_action( 'enqueue_block_assets', function() {
wp_enqueue_script(
'my-cart-extension',
get_stylesheet_directory_uri() . '/path-to/your-extension.js',
array( 'wp-plugins', 'wp-element', 'wp-i18n', 'wc-blocks-checkout' ),
filemtime( get_stylesheet_directory() . '/path-to/your-extension.js' ),
true
);
} );
—
### β Recommended Temporary Workaround
If you just want your `probo_upload_field_to_cart_items` logic to show up in the cart and donβt want to use the Block editor:
– **Disable the Cart Block temporarily** until you develop the full React integration.
– Use `add_filter('woocommerce_after_cart_item_name', β¦)` as before with Classic Cart.
—
### Want Help Migrating to Cart Blocks?
Let me know what `probo_upload_field_to_cart_items` renders (e.g. an image preview, file name, or custom HTML), and I can help you write the JS equivalent for Cart Block extension.
To fix this and **restore legacy hook support**, you need to **disable the new Cart and Checkout blocks** and revert to the **Classic Cart and Checkout templates**.
—
## β How to Use Legacy Hooks in WooCommerce 9.0
### π Step 1: Disable Cart and Checkout Blocks
Go to:
**WooCommerce β Settings β Advanced β Features**
1. Look for the section labeled **"Cart and Checkout"**.
2. Youβll see a setting like **βEnable the block-based cart and checkout experienceβ**.
3. **Uncheck / disable** this option.
4. Save changes.
> β After doing this, WooCommerce will fall back to the classic cart/checkout templates that support legacy PHP hooks.
—
### π Step 2: Confirm Hook Now Works
After reverting to the classic templates, your code:
add_filter('woocommerce_after_cart_item_name', array($this, 'probo_upload_field_to_cart_items'), 10, 2);
should now work as expected.
—
### π§ͺ Optional: Force Classic Templates Programmatically
If you want to ensure your site never uses the new block-based cart/checkout, you can force it in your code:
add_filter( 'woocommerce_feature_enabled_block_checkout', '__return_false' );
add_filter( 'woocommerce_feature_enabled_cart_checkout_blocks', '__return_false' );
Place this in your themeβs `functions.php` or a custom plugin.
—
## β Summary
| Task | Status |
|——|——–|
| Disable Cart/Checkout Blocks | β
Required |
| Use legacy hooks like `woocommerce_after_cart_item_name` | β
Will work after above |
| Want future-proof block support? | β Requires React-based cart item rendering |
Let me know if you want to **conditionally switch between classic and block templates**, or if you'd like help **rendering your custom field inside the Cart Block**.
—
## β Confirm These Steps Exactly
### β 1. Revert to Classic Cart Template
Try **forcing classic templates programmatically** in your plugin or theme:
add_filter( 'woocommerce_feature_enabled_cart_checkout_blocks', '__return_false' );
add_filter( 'woocommerce_feature_enabled_block_checkout', '__return_false' );
Add this to your `functions.php` file or a must-use plugin, and then:
– Clear all caching (browser, server, object cache, Cloudflare, etc.)
– Refresh permalinks (`Settings β Permalinks β Save`)
—
### β 2. Make Sure Your Hook Is Reaching the Correct Place
Verify the basic hook is firing:
add_filter('woocommerce_after_cart_item_name', function($name, $cart_item) {
echo '<div style="color: red;">HOOK WORKING</div>';
return $name;
}, 10, 2);
If this does **not show up in the cart**, it means the classic cart template is **still not active**.
—
### β 3. Confirm the Cart Template in Use
Check your **themeβs cart template**:
– Copy `wp-content/plugins/woocommerce/templates/cart/cart.php`
– Paste it into `your-theme/woocommerce/cart/cart.php`
– Add a debug message like:
echo '<!-- Using classic cart template -->';
Then **view source in browser** and search for that comment.
> π΄ If the comment is missing, you are **still using the Cart Block**.
—
### β 4. Confirm Theme and Plugin Conflict
Temporarily switch to **Storefront theme** and disable all plugins **except WooCommerce** and your custom plugin/code.
– Visit the cart page again.
– Re-check for `woocommerce_after_cart_item_name`.
—
### β 5. Check Template Overriding
If your theme overrides the cart templates (`your-theme/woocommerce/cart/*.php`), it might be **missing the call to this action**.
Open your cart template and make sure this line exists:
<?php do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key ); ?>
If itβs not there, **your theme is blocking the hook**.
—
### π§ Final Fix (if theme is overriding incorrectly)
If your theme is using a custom cart template and skipped the hook, **you can inject it manually**:
Edit your overridden `cart.php` and inside the cart loop, manually insert:
do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key );
—
## β Conclusion
| β
Step | Result |
|——–|——–|
| Force classic cart with filters | `woocommerce_feature_enabled_cart_checkout_blocks` |
| Use test hook with visible output | Confirms hook firing |
| Check if theme is overriding cart.php | Make sure it has the `do_action()` |
| Clear cache & permalinks | Required after changes |
| Switch to Storefront + WooCommerce only | Isolate conflicts |
—
If you'd like, please share:
– Your full hook function code
– Theme name (or if you're overriding WooCommerce templates)
– A screenshot of your Cart pageβs HTML (with View Source) or relevant output
Iβll debug it precisely for you.
add_action( 'woocommerce_single_product_summary', array( $this, 'probo_add_configurator' ), 25 );
working well
public function probo_add_configurator() {
global $product;
if ( $product->get_type() === 'probo_configurable' ) {
include_once PROBO_TEMPLATES_PATH . 'single-product/probo-configurator.php';
}
}
β
Your **custom plugin** is active
β
Your plugin class and hooks are working (since `probo_add_configurator()` is firing correctly)
β But `woocommerce_after_cart_item_name` is **not firing**
So letβs now debug your cart issue specifically.
—
## β Key Differences
Your working hook:
add_action( 'woocommerce_single_product_summary', array( $this, 'probo_add_configurator' ), 25 );
β‘οΈ This is for the **product page**, not the **cart**.
Your **not working** hook:
add_filter( 'woocommerce_after_cart_item_name', array( $this, 'probo_upload_field_to_cart_items' ), 10, 2 );
β‘οΈ This is for the **cart page**, and will only fire if the **Classic Cart template** is in use.
—
## π Let's Debug Step-by-Step
### β Step 1: Confirm Your Cart Template Is Classic
Do this in your custom plugin temporarily:
add_filter('woocommerce_after_cart_item_name', function($name, $cart_item) {
error_log('β
Legacy cart hook triggered');
echo '<div style="color:green;">HOOK WORKING</div>';
return $name;
}, 10, 2);
If you:
– See **nothing in the cart**
– And **no log in PHP error log**
β Then the **Cart Block is still active**, even if filters were added
### β Step 2: Force Classic Cart (again)
In your custom plugin `__construct()` or main plugin file:
add_filter( 'woocommerce_feature_enabled_cart_checkout_blocks', '__return_false', 99 );
add_filter( 'woocommerce_feature_enabled_block_checkout', '__return_false', 99 );
This disables Cart & Checkout blocks *early enough*.
After this:
– Go to **WooCommerce β Settings β Permalinks** β Click "Save Changes"
– Clear browser & site cache
– Reload the cart page
Try `View Page Source` in browser and check if your `HOOK WORKING` is there.
—
## π Also: Check Theme Template
If your theme overrides `woocommerce/cart/cart.php`, make sure this hook exists:
<?php do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key ); ?>
If not, you can **manually add it** inside the loop, like:
<td class="product-name">
<?php
echo $cart_item['data']->get_name();
do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key );
?>
</td>
—
## β Summary
| Check | How |
|——-|—–|
| Is classic cart enabled? | Add filters + check for HTML output or error_log |
| Is theme overriding cart.php? | Look for `do_action( 'woocommerce_after_cart_item_name', …)` |
| Is your plugin class and hook loading? | Test with simple output like `echo 'test'` |
| Is caching causing issues? | Clear object, full-page, and browser cache |
| Is `$this` valid in `add_filter(…)`? | Try replacing with a standalone function temporarily |
—
## π Final Diagnostic Suggestion
Please try this minimal hook in your plugin constructor (outside class context):
add_filter('woocommerce_after_cart_item_name', function($name, $cart_item) {
echo '<div style="color:blue;">β Classic Cart Hook Reached</div>';
return $name;
}, 10, 2);
If this doesnβt show on the cart page, you're 100% still on the Block Cart.
Let me know what output you see, and Iβll pinpoint the exact fix for your setup.
– Added the `woocommerce_after_cart_item_name` hook
– Tried forcing the classic cart with filters
– And even added debug HTML (but still see **nothing**)
That means one of the following is definitely true:
—
## π΄ You're Still Using the Cart Block β 100% Guaranteed
Even if you think you've disabled the Cart Block using:
add_filter( 'woocommerce_feature_enabled_cart_checkout_blocks', '__return_false' );
add_filter( 'woocommerce_feature_enabled_block_checkout', '__return_false' );
These filters **only affect core fallback logic**. If your **cart page is still set to the Block-based "Cart" page in admin**, then PHP templates and hooks **will not run**.
—
## β The Definitive Fix: Replace the Cart Page With a Classic Shortcode Page
### π Step-by-step:
1. Go to **Pages β Cart**
2. Check the content inside that page. If you see this:
<!-- wp:woocommerce/cart /-->
β Thatβs a **Block-based cart page** β it **wonβt fire PHP hooks**.
3. π₯ Replace it with this classic shortcode:
[woocommerce_cart]
4. Update the page and save.
5. Then go to:
**WooCommerce β Settings β Advanced β Page Setup**
– Make sure that "Cart page" is assigned to the one using `[woocommerce_cart]`.
6. Clear all caches (WooCommerce, object cache, page cache, Cloudflare, browser, etc.).
7. Refresh the cart page and try this code again:
add_filter('woocommerce_after_cart_item_name', function($name, $cart_item) {
echo '<div style="color:red;">β
Hook fired</div>';
return $name;
}, 10, 2);
—
## β Confirm Itβs Working
Go to the cart page in browser, right-click β **View Source**, and search for:
β
Hook fired
If you see it β your legacy hook is working.
—
## π‘ Bonus: Permanent Classic Template Lock (Optional)
If you're building a plugin and **never want Cart Blocks to be used**, you can use this extra filter in your pluginβs main file:
add_filter( 'woocommerce_blocks_use_cart_block', '__return_false' );
This overrides deeper logic in WooCommerce Blocks itself.
—
## β Summary
| Step | Status |
|——|——–|
| Your hook isn't firing | β Because Cart Block is active |
| `add_filter(…)` didn't help alone | β
Expected |
| Page content shows “ | β Not classic |
| Replacing it with `[woocommerce_cart]` | β
Will fix your issue |
| Confirm with HTML output or `View Source` | β
Recommended |
—
Let me know once youβve updated the **Cart page content to `[woocommerce_cart]`**, and Iβll help you further with the exact integration.
—
## β Goal: Show Custom Upload Field in WooCommerce 9 Cart Block
You **cannot use PHP hooks** like `woocommerce_after_cart_item_name` inside Cart Blocks because theyβre rendered in JavaScript (React). So you need to:
—
## π§ Step-by-Step: Extend WooCommerce Cart Block with JS
### π Step 1: Add Custom Meta to the Cart Item (During Add to Cart)
In your plugin, when the product is added to the cart, store your custom field as **cart item data**:
add_filter('woocommerce_add_cart_item_data', function($cart_item_data, $product_id, $variation_id) {
if (!empty($_POST['probo_upload_field'])) {
$cart_item_data['probo_upload_field'] = sanitize_text_field($_POST['probo_upload_field']);
}
return $cart_item_data;
}, 10, 3);
And make it visible in the cart item:
add_filter('woocommerce_get_item_data', function($item_data, $cart_item) {
if (isset($cart_item['probo_upload_field'])) {
$item_data[] = [
'name' => __('Upload File', 'your-textdomain'),
'value' => esc_html($cart_item['probo_upload_field']),
];
}
return $item_data;
}, 10, 2);
β This makes the value visible in Classic Cart **and available to the Block Cart system as meta**.
—
### π¦ Step 2: Enqueue a Block Extension Script
Now letβs hook into the **JS-rendered Cart Block** to show this value.
add_action('enqueue_block_assets', function () {
if (is_cart()) {
wp_enqueue_script(
'probo-cart-extension',
plugin_dir_url(__FILE__) . 'assets/js/probo-cart-extension.js',
['wp-element', 'wp-hooks', 'woocommerce-blocks-checkout'],
filemtime(plugin_dir_path(__FILE__) . 'assets/js/probo-cart-extension.js'),
true
);
}
});
—
### π‘ Step 3: Create `probo-cart-extension.js`
Place this in `assets/js/probo-cart-extension.js`:
import { registerPlugin } from '@wordpress/plugins';
import { CartLineItemRow } from '@woocommerce/blocks-checkout';
const ProboUploadField = (props) => {
const meta = props.extensions?.['woocommerce/blocks/cart-line-item']?.meta_data || [];
const uploadField = meta.find(item => item.key === 'Upload File');
if (!uploadField) return null;
return (
<CartLineItemRow>
<div style={{ fontStyle: 'italic', fontSize: '0.9em' }}>
π {uploadField.value}
</div>
</CartLineItemRow>
);
};
registerPlugin('probo-cart-extension', {
render: ProboUploadField,
scope: 'woocommerce-cart-item',
});
β This will show the uploaded value (like a filename or string) underneath the cart item name **inside the Block Cart**.
—
### π¦ Optional: Bundle with Webpack (if needed)
If you're already bundling other JS (e.g. via `@wordpress/scripts`), include this script as part of your build setup.
—
## β Final Output Example in Cart Block
Your cart block item will look like:
Product Name
π uploaded_file.pdf
—
## β Summary
| Task | Done |
|——|——|
| Store custom field in `add_cart_item_data` | β
|
| Expose it via `woocommerce_get_item_data` | β
|
| Enqueue block extension JS | β
|
| Inject field using `CartLineItemRow` | β
|
| Use `meta_data` to match your label | β
|
—
Let me know if your upload field is more than text (e.g., a file preview), and Iβll update the example to render an image or link.
I want disable this link until user upload file for each line item in cart
1. **Track file uploads in PHP (server-side)** per cart item.
2. **Expose missing uploads as item meta data**.
3. **In the Cart Block (React), disable the button and show a warning** if any cart item is missing a file.
—
## β Step-by-Step Implementation
### π Step 1: Store Upload Info on Add to Cart
Make sure your upload field is added to the cart item (this should already exist):
add_filter('woocommerce_add_cart_item_data', function($cart_item_data, $product_id, $variation_id) {
if (!empty($_POST['probo_upload_field'])) {
$cart_item_data['probo_upload_field'] = sanitize_text_field($_POST['probo_upload_field']);
}
return $cart_item_data;
}, 10, 3);
—
### π Step 2: Show a Flag in Item Meta if Missing
This exposes whether a file is uploaded or not, for each item:
add_filter('woocommerce_get_item_data', function($item_data, $cart_item) {
if (empty($cart_item['probo_upload_field'])) {
$item_data[] = [
'name' => 'upload_status',
'value' => 'missing',
];
} else {
$item_data[] = [
'name' => 'upload_status',
'value' => 'uploaded',
];
}
return $item_data;
}, 10, 2);
—
### β Step 3: Create `probo-cart-checkout-lock.js`
This JavaScript will **disable the checkout button** if any line item is missing a file:
“`js
import { registerPlugin } from '@wordpress/plugins';
import { useSelect } from '@wordpress/data';
import
You want to:
β
**Disable the "Proceed to checkout" button**
β
**Until each cart item has an uploaded file**
Letβs implement this fully for the **classic cart**.
—
## β Step-by-Step: Disable Checkout Button Until All Cart Items Have Uploads
### β 1. Store Upload Info in Cart Item Data
Youβre probably already doing this, but to confirm:
add_filter('woocommerce_add_cart_item_data', function($cart_item_data, $product_id, $variation_id) {
if (!empty($_POST['probo_upload_field'])) {
$cart_item_data['probo_upload_field'] = sanitize_text_field($_POST['probo_upload_field']);
}
return $cart_item_data;
}, 10, 3);
—
### β 2. Render a Hidden Flag per Item (in Cart Template)
Add this in your theme or plugin using:
add_filter('woocommerce_after_cart_item_name', function($cart_item, $cart_item_key) {
$has_upload = !empty($cart_item['probo_upload_field']) ? 'yes' : 'no';
echo "<div class='has-upload-flag' data-upload='{$has_upload}'></div>";
}, 10, 2);
This adds a flag like:
<div class="has-upload-flag" data-upload="yes"></div>
or
<div class="has-upload-flag" data-upload="no"></div>
—
### β 3. Add JavaScript to Disable the Checkout Button
Put this script in your footer or enqueue it via your plugin:
add_action('wp_footer', function () {
if (is_cart()) {
?>
<script>
document.addEventListener('DOMContentLoaded', function () {
function checkUploads() {
const flags = document.querySelectorAll('.has-upload-flag');
let allUploaded = true;
flags.forEach(flag => {
if (flag.dataset.upload !== 'yes') {
allUploaded = false;
}
});
const checkoutBtn = document.querySelector('.checkout-button');
if (checkoutBtn) {
checkoutBtn.style.pointerEvents = allUploaded ? 'auto' : 'none';
checkoutBtn.style.opacity = allUploaded ? '1' : '0.5';
checkoutBtn.title = allUploaded ? '' : 'Please upload files for all items';
}
}
checkUploads();
// Optional: recheck on quantity change or other dynamic updates
document.querySelector('form.woocommerce-cart-form').addEventListener('change', checkUploads);
});
</script>
<?php
}
});
—
### β Result:
– β
If any item in the cart is missing a file, the **βProceed to checkoutβ** button is **disabled (pointerEvents: none + opacity)**.
– β
Once all items have `probo_upload_field` data, the button becomes active.
—
## β Optional Enhancements
– Display a user-friendly error message when the button is disabled.
– Dynamically check when uploads happen via JS (if using frontend file uploads).
– Submit missing uploads via AJAX and update the cart item if needed.
—
Let me know if youβd like to include a **custom error message below the button**, or **prevent checkout on the server side** as a backup.
—
## β Step-by-Step: Override WooCommerce Template in Your Theme
### π 1. **Find the Template You Want to Override**
WooCommerce templates live in this folder:
wp-content/plugins/woocommerce/templates/
Examples:
– Cart page: `woocommerce/templates/cart/cart.php`
– Checkout page: `woocommerce/templates/checkout/form-checkout.php`
– Product page: `woocommerce/templates/single-product/title.php`
—
### π 2. **Copy the File to Your Theme**
Letβs say you want to override the cart template:
1. Copy:
wp-content/plugins/woocommerce/templates/cart/cart.php
2. Paste into:
wp-content/themes/your-theme/woocommerce/cart/cart.php
> β Maintain the **same folder structure** under a `woocommerce/` folder in your theme.
—
### β 3. WooCommerce Will Now Use Your Themeβs File
Once copied, WooCommerce will **automatically load your
—
## β Goal: Override WooCommerce template from a custom plugin
For example, override:
woocommerce/templates/cart/cart.php
From this path inside your plugin:
wp-content/plugins/your-plugin/templates/woocommerce/cart/cart.php
—
## β Step-by-Step: Force WooCommerce to Use Your Plugin Template
### π 1. Hook into WooCommerce template loading
Add this in your plugin's main file:
add_filter('woocommerce_locate_template', function($template, $template_name, $template_path) {
$plugin_path = plugin_dir_path(__FILE__) . 'templates/woocommerce/';
// Check if template exists in your plugin
if (file_exists($plugin_path . $template_name)) {
return $plugin_path . $template_name;
}
return $template;
}, 10, 3);
—
### π 2. Create This Folder Structure in Your Plugin
your-plugin/
βββ your-plugin.php
βββ templates/
βββ woocommerce/
βββ cart/
βββ cart.php
Inside your `cart.php`, you can now customize freely.
—
### β 3. Clear Cache and Test
– Visit the cart page.
– Add a comment in your pluginβs version (e.g. “) and check **View Source** to confirm itβs loading.
—
## π‘ Bonus: Support Child Theme Fallback (Optional)
To keep WooCommerce fallback logic (child theme β parent theme β plugin), use:
add_filter('woocommerce_locate_template', function($template, $template_name, $template_path) {
$plugin_path = plugin_dir_path(__FILE__) . 'templates/woocommerce/';
$theme_template = locate_template($template_name);
if ($theme_template) {
return $theme_template;
}
if (file_exists($plugin_path . $template_name)) {
return $plugin_path . $template_name;
}
return $template;
}, 10, 3);
—
## β Summary
| Task | Done |
|——|——|
| Create custom template in plugin | β
`templates/woocommerce/…` |
| Hook into `woocommerce_locate_template` | β
|
| Return plugin path if file exists | β
|
| Clear cache and test in browser | β
|
—
Let me know which template you want to override and Iβll help tailor the hook for it (e.g. mini-cart, single product, thank you page, etc.).
—
## β Goal: Load `cart/cart.php` template from your plugin
### π Plugin Folder Structure:
your-plugin/
βββ your-plugin.php
βββ templates/
βββ woocommerce/
βββ cart/
βββ cart.php β (your custom cart page)
—
## β 1. PHP Code (in your plugin file)
Add this to your pluginβs main file (e.g. `your-plugin.php`):
add_filter('woocommerce_locate_template', function($template, $template_name, $template_path) {
// Only override the cart page template
if ($template_name === 'cart/cart.php') {
$plugin_template = plugin_dir_path(__FILE__) . 'templates/woocommerce/cart/cart.php';
if (file_exists($plugin_template)) {
return $plugin_template;
}
}
return $template;
}, 10, 3);
—
## β 2. Customize `cart.php` in Plugin
You can now fully customize the cart page inside:
your-plugin/templates/woocommerce/cart/cart.php
Add a debug line at the top to confirm itβs loading:
<?php echo '<!-- Loaded from plugin cart.php -->'; ?>
Then βView Page Sourceβ on the cart page to check.
—
## β 3. Clear Cache & Test
– Clear any caching plugin, server cache, and browser cache
– Reload the cart page
– Confirm your version is loaded
—
## β Summary
| Step | β
Done |
|——|——–|
| Hook into `woocommerce_locate_template` | β
|
| Check `cart/cart.php` only | β
|
| Return custom plugin path | β
|
| Confirm by editing template or checking HTML | β
|
—
Let me know if you want to override more cart sub-templates like `cart-totals.php`, `cart-shipping.php`, etc., or conditionally load different cart layouts.
notices/success.php
—
## β Why You See `notices/success.php`
WooCommerce includes various template parts **during cart rendering**, such as:
– `notices/success.php`
– `global/form-start.php`
– `cart/cart.php`
– `cart/cart-totals.php`
So `woocommerce_locate_template()` fires multiple times β once for **each template WooCommerce attempts to locate**.
—
## β How to Override `cart/cart.php` Only
Here's how to **target and override only the cart page layout template** correctly from your plugin:
—
### β 1. Final Filter Code (Only `cart/cart.php`)
add_filter('woocommerce_locate_template', function($template, $template_name, $template_path) {
// Match exactly the cart page template
if ($template_name === 'cart/cart.php') {
$plugin_template = plugin_dir_path(__FILE__) . 'templates/woocommerce/cart/cart.php';
if (file_exists($plugin_template)) {
return $plugin_template;
}
}
// Let WooCommerce load everything else normally
return $template;
}, 10, 3);
—
### β 2. Your Plugin Folder Structure
your-plugin/
βββ your-plugin.php
βββ templates/
βββ woocommerce/
βββ cart/
βββ cart.php β your custom cart template
—
### β 3. Confirm It Works
Edit your `cart.php` in your plugin and add:
<?php echo '<!-- Custom cart.php from plugin loaded -->'; ?>
Then:
– Visit the Cart page
– Right-click β View Source
– Search for `Custom cart.php from plugin loaded`
If found β your override is working β
—
## π You Still See `notices/success.php`?
Thatβs **expected** β WooCommerce loads other templates **before** `cart/cart.php`.
To confirm you're seeing `cart/cart.php` override:
– Put a `error_log()` inside the filter to track exactly which templates pass through:
add_filter('woocommerce_locate_template', function($template, $template_name, $template_path) {
error_log("Checking template: $template_name");
if ($template_name === 'cart/cart.php') {
$plugin_template = plugin_dir_path(__FILE__) . 'templates/woocommerce/cart/cart.php';
error_log("Overriding cart.php with plugin template");
if (file_exists($plugin_template)) {
return $plugin_template;
}
}
return $template;
}, 10, 3);
Check your PHP error log β youβll see something like:
[...date...] PHP message: Checking template: cart/cart.php
[...date...] PHP message: Overriding cart.php with plugin template
—
## β Summary
| Task | Status |
|——|——–|
| `woocommerce_locate_template` runs for all templates | β
|
| Must match `$template_name === 'cart/cart.php'` | β
|
| Return plugin path if file exists | β
|
| Confirm override with comment or `error_log()` | β
|
—
Let me know if you also want to override sub-parts like `cart/cart-totals.php` or conditionally load different templates based on cart contents.
// Match exactly the cart page template
if ($template_name === 'cart/cart.php') {
$plugin_template = plugin_dir_path(__FILE__) . 'templates/woocommerce/cart/cart.php';
if (file_exists($plugin_template)) {
return $plugin_template;
}
}
// Let WooCommerce load everything else normally
return $template;
}, 10, 3);
not working
You're using the correct approach in theory, but `woocommerce_locate_template` **does not always intercept `cart/cart.php`** because WooCommerce may use a different internal path. So let's go step-by-step and correct it.
—
## β Use `template_include` for Full Template Override (Best for Main Pages)
When you're overriding **top-level templates like `cart/cart.php`**, the **most reliable way** is to hook into `template_include` instead.
—
### β Recommended Fix:
Replace your current code with this:
add_filter('template_include', function($template) {
if (is_cart()) {
$plugin_template = plugin_dir_path(__FILE__) . 'templates/woocommerce/cart/cart.php';
if (file_exists($plugin_template)) {
return $plugin_template;
}
}
return $template;
});
β This hook runs **after WooCommerce determines it's the Cart page**, and replaces the full template file β even if blocks or shortcodes are used.
—
### π Folder Structure in Plugin:
your-plugin/
βββ your-plugin.php
βββ templates/
βββ woocommerce/
βββ cart/
βββ cart.php
—
### π§ͺ Add Debug Line in Your Custom `cart.php`:
Inside your pluginβs `cart/cart.php`:
<?php echo '<!-- Custom cart.php loaded from plugin -->'; ?>
Then βView Page Sourceβ on the Cart page to verify it loads.
—
## β Why Your Original Code Didnβt Work
Your previous `woocommerce_locate_template` code didnβt work because:
– WooCommerce may load `cart.php` indirectly via a page template (like `page.php`)
– Or use a **custom template loader** when `[woocommerce_cart]` shortcode is used
– It works best for **partials** (like `cart/cart-totals.php`) but **not entire page loads**
—
## β Summary
| Task | Status |
|——|——–|
| Replace top-level cart template reliably | β
Use `template_include` |
| Works with plugin template | β
Yes |
| Fallback if file not found | β
Original template is returned |
| Confirmed with debug HTML | β
Check via View Source |
—
Let me know if you're trying to override **just a cart section** (like cart items or totals) instead of the full cart page β I can give a more precise hook for that.
—
## β Why Your Current Override Fails
The shortcode `[woocommerce_cart]` loads `cart/cart.php` **indirectly** using `wc_get_template()` inside WooCommerce's shortcode handler.
That means:
– `template_include` does **not apply** here.
– `woocommerce_locate_template` is triggered, but **only if** WooCommerce calls `wc_get_template('cart/cart.php')` directly.
– If the theme or WooCommerce caches or alters paths, your plugin override might be skipped.
—
## β β 100% Working Solution: Use `woocommerce_cart_template` Filter
WooCommerce provides a **special filter** for this case:
add_filter( 'woocommerce_cart_template', function( $template ) {
$custom = plugin_dir_path(__FILE__) . 'templates/woocommerce/cart/cart.php';
if ( file_exists( $custom ) ) {
return $custom;
}
return $template;
} );
β This filter **specifically overrides the template used by the `[woocommerce_cart]` shortcode**, and it **works from inside a plugin**.
—
## π Required Plugin Folder Structure
your-plugin/
βββ your-plugin.php
βββ templates/
βββ woocommerce/
βββ cart/
βββ cart.php β your custom version
β Add a comment like this inside your plugin's `cart.php` to confirm:
<?php echo '<!-- Plugin override of cart.php -->'; ?>
Then **View Page Source** on your Cart page and search for `Plugin override of cart.php`.
—
## β Summary
| Override Method | Works with `[woocommerce_cart]` shortcode? | Plugin-Friendly |
|—————-|———————————————|——————|
| `template_include` | β No | β
Yes but not for shortcodes |
| `woocommerce_locate_template` | β Not reliably for full page templates | β
For partials only |
| `woocommerce_cart_template` | β
YES | β
β
Best method for your use case |
—
Let me know if you also want to override `cart/cart-totals.php` or individual sections of the cart. I can show you filters for those too.
We will do it using the **low-level `wc_get_template` override**, which WooCommerce **always uses to load templates**, including from shortcodes.
—
## β 100% Working: Override Any WooCommerce Template from a Plugin
Use this in your plugin:
add_filter('wc_get_template', function($located, $template_name, $args, $template_path, $default_path) {
// Target ONLY cart/cart.php
if ($template_name === 'cart/cart.php') {
$custom_template = plugin_dir_path(__FILE__) . 'templates/woocommerce/cart/cart.php';
if (file_exists($custom_template)) {
return $custom_template;
}
}
return $located;
}, 10, 5);
—
### π Folder Structure:
your-plugin/
βββ your-plugin.php
βββ templates/
βββ woocommerce/
βββ cart/
βββ cart.php
β Add this in your pluginβs `cart.php` to verify:
<?php echo '<!-- Plugin template loaded: cart/cart.php -->'; ?>
—
## β Explanation
| Filter | What It Does |
|——–|————–|
| `wc_get_template` | Core WooCommerce function that loads **every template** |
| Your code | Intercepts when WooCommerce is about to load `cart/cart.php`, and returns your plugin's version instead |
—
## β Final Steps to Confirm
1. Visit Cart page with `[woocommerce_cart]` shortcode.
2. Right-click β View Source.
3. Search for: “
β If you see it, you're overriding it correctly from the plugin.
—
## π§Ό Bonus: Clear Cache
– Clear browser + plugin cache (WP Super Cache, etc.)
– Purge object cache if you're using Redis/Memcached
– Disable full page caching temporarily
—
## β Summary
| Step | β
Done |
|——|——–|
| Use `wc_get_template` filter | β
Most reliable for plugin-based overrides |
| Target `cart/cart.php` only | β
Prevents other templates from being affected |
| View source to confirm | β
Yes |
—
Let me know if you'd also like to override:
– Only a **section** like `cart/cart-totals.php`
– Or show/hide fields conditionally (like based on file upload per item) inside the cart
I'll tailor that too.