Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@murilocarvalhodev
Copy link
Contributor

@murilocarvalhodev murilocarvalhodev commented Nov 19, 2025

Fixes #1124

@crftwrk crftwrk added this to v6.4.0 Nov 20, 2025
@crftwrk crftwrk moved this to In Progress in v6.4.0 Nov 20, 2025
@crftwrk
Copy link
Member

crftwrk commented Nov 20, 2025

Thank you! Confirm that this one works with the WC filter widget button. Unfortunately, the core buttons are not rendered correctly anymore. Any idea?

Wrong Correct
https://dev.bootscore.me/theme/blocks/#block-buttons https://bootscore.me/documentation/theme/blocks/#buttons
buttons wrong buttons correct

@crftwrk crftwrk marked this pull request as draft November 20, 2025 09:54
@murilocarvalhodev
Copy link
Contributor Author

I'll check that out. Do you know if it's only apparent? Has it affected any functionality?

@crftwrk
Copy link
Member

crftwrk commented Nov 20, 2025

Do you know if it's only apparent? Has it affected any functionality?

I honestly do not know where WC or any other plugin this type of button uses.

But while we are here, maybe adding general support to the WC product filter block seems a good idea. In that case we can add a new clear filter button.

I have a made rough sketch, not everything can be replaced with PHP filters, there are some !important CSS overrides needed as well.

Just an idea, see it in action on the right sidebar https://themes.bootscore.me/boilerplate/shop/

Let me know what you think.

Bildschirmfoto 2025-11-20 um 17 49 59
/**
 * Product Filters Block
 */
if (!function_exists('bootscore_wc_block_widget_product_filter_classes')) {
  /**
   * Adds Bootstrap classes to WC product filter block
   *
   * @param string $block_content The block content.
   * @param array  $block         The full block, including name and attributes.
   * @return string The filtered block content.
   */
  function bootscore_wc_block_widget_product_filter_classes($block_content, $block) {
    
    $search  = array(
      
      // Remove Moblie overlay
      'wc-block-product-filters__open-overlay',
      'wc-block-product-filters__overlay',
      'wc-block-product-filters__overlay-wrapper',
      'wc-block-product-filters__overlay-dialog',
      
      // Chips
      'wc-block-product-filter-removable-chips__items',
      'wc-block-product-filter-removable-chips__item',
      'wc-block-product-filter-removable-chips__remove',
      'btn-close-icon',
      
      // Clear filters button
      'class="btn btn-outline-primary has-text-align-center wp-element-button"',

      // Range
      // form-control seems not working
      //'wp-block-woocommerce-product-filter-price',
      //'min',
      //'max',
      
      // Checks
      'wc-block-product-filter-checkbox-list__item',
      'wc-block-product-filter-checkbox-list__label',
      'wc-block-product-filter-checkbox-list__input',
      'wc-block-product-filter-checkbox-list__text-wrapper'
    );
    $replace = array(
      
      // Remove Moblie overlay
      '',
      '',
      '',
      '',

      // Chips
      'list-unstyled d-flex flex-wrap gap-2',
      'badge bg-light-subtle border border-light-subtle text-light-emphasis rounded-pill text-decoration-none d-flex align-items-center',
      'btn-close ms-1',
      'btn-close-icon d-none',
      
      // Clear filters button
      'class="btn btn-sm btn-outline-danger w-100" data-wp-on--click="actions.removeAllActiveFilters" ',

      // Range
      // form-control seems not working
      //'wp-block-woocommerce-product-filter-price',
      //'min form-control',
      //'max form-control',
      
      // Checks
      'form-check',
      'form-check-label',
      'form-check-input',
      ''
    );
    
    $block_content = str_replace($search, $replace, $block_content);

    return apply_filters('bootscore/block/product/filters/content', $block_content, $block);
  }
}
add_filter('render_block_woocommerce/product-filters', 'bootscore_wc_block_widget_product_filter_classes', 10, 2);
.wc-block-product-filters {

  // Hide the mobile dialog stuff
  .-header,
  .-footer,
  [data-wp-on--click="actions.openOverlay"] {
    display: none;
  }

  // Chips
  .badge {
    .btn-close {
      font-size: 0.75em;
    }
  }
}


.wc-block-product-filter-price-slider {
  
  // Fake Range
  &__range .range-bar {
    background: var(--#{$prefix}secondary-bg) !important;
    border-radius: $form-range-track-border-radius !important;
    height: $form-range-track-height;
  }

  &__range input[type=range]::-webkit-slider-thumb {
    width: $form-range-thumb-width !important;
    height: $form-range-thumb-height !important;
    background: $form-range-thumb-bg !important;
    border: none !important;
  }

  // Fake form-control
  .text input[type=text] {
    border: 1px solid;
      border-color: var(--#{$prefix}border-color) !important;
    border-radius: $input-border-radius !important;
    background-color: $input-bg !important;
    font-size: $input-font-size !important;
    padding: $input-padding-y $input-padding-x !important;

    &:focus {
      box-shadow: $input-focus-box-shadow;
      outline: 0;
      border-color: $input-focus-border-color;
    }
  }
}

@murilocarvalhodev
Copy link
Contributor Author

I tried to analyze as many scenarios as possible and came to the following conclusions:

The problem with the button appearance is due to CSS hierarchy. In my code suggestion, the wp-block-button__link class is maintained.

Furthermore, after closer analysis, I saw that it's this replacement ( https://github.com/bootscore/bootscore/blob/main/inc/blocks/block-buttons.php#L29) that prevents WooCommerce from adding data-wp-on--click="actions.removeAllActiveFilters" to the button.

Wrong Correct
https://dev.bootscore.me/theme/blocks/#block-buttons https://bootscore.me/documentation/theme/blocks/#buttons
buttons wrong 2

In this scenario, by keeping the wp-block-button__link class, some styles were recognized again, but the main problem is with styles that carry is-style-outline--{some number}, such as is-style-outline--7 in this case.

This style

:root :where(.wp-block-button.is-style-outline--7 .wp-block-button__link) {
    background: transparent none;
    border-color: currentColor;
    border-width: 2px;
    border-style: solid;
    color: currentColor;
    padding-top: 0.667em;
    padding-right: 1.33em;
    padding-bottom: 0.667em;
    padding-left: 1.33em;
}

is above the .btn and .btn-outline-primary styles.

buttons correct 1

Here it doesn't have that class is-style-outline--{some number}
only:

:root :where(.wp-element-button, .wp-block-button__link) {
    background-color: #32373c;
    border-width: 0;
    color: #fff;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
    padding: calc(0.667em + 2px) calc(1.333em + 2px);
    text-decoration: none;
}

but that also exists in the other scenario and is below the .btn and .btn-outline-primary styles.

Asking ChatGPT, he explained that this is-style-outline--{some number} class is added by the WordPress Blocks system as a way to separate styles when it identifies more than one instance of the same block type, something like that, and that it would be an unpredictable scenario, potentially resulting in different numbering. In my tests here, for example, the style is is-style-outline--4. And whenever it uses this specific style, it appears above .btn and .btn-outline-primary.

This makes me think that we need a solution for !important in CSS anyway.

Regarding your suggestion to add general support, I thought it was a great idea. I wasn't aware of this filtering possibility; I tried to find it in the files, and then ChatGPT also explained that it's created automatically using some name field from block.json, and I actually found the name: woocommerce/product-filters. That seemed quite interesting.

My only concern is that you need to declare everything explicitly, including data-wp-on--click="actions.removeAllActiveFilters". If WC changes this in the future, it will require modifications in the file as well.

I analyzed my code suggestion more carefully and realized I missed some details.

Here's a new suggestion:

/**
  * Buttons
  *
  * Adds btn and btn-primary or btn-outline-primary classes to the block buttons
  */
if (!function_exists('bootscore_block_buttons_classes')) {
  function bootscore_block_buttons_classes($block_content, $block) {
    if ($block['blockName'] !== 'core/buttons') {
        return $block_content;
    }

    // Replace wp-block-buttons-is-layout-flex with gap-1 mb-3
    $block_content = str_replace('wp-block-buttons-is-layout-flex', 'gap-1 mb-3', $block_content);

    // Detect outline wrapper
    $has_outline = (strpos($block_content, 'is-style-outline') !== false);

    // Use regex to rebuild the button
    $block_content = preg_replace_callback(
        '/<a([^>]*)class="([^"]*)"/i',
        function ($matches) use ($has_outline) {

            $before   = $matches[1]; // previous attributes
            $classes = $matches[2]; // classes

            // Add classes btn btn-primary
            if (strpos($classes, 'btn btn-primary') === false) {
                $classes .= ' btn btn-primary';
            }

            /**
             * If any parent wrapper declares is-style-outline
             * we switch btn-primary to btn-outline-primary
             * Otherwise, default to btn-primary
             */
            if ($has_outline) {
                $classes = str_replace('btn-primary', '', $classes);
                if (strpos($classes, 'btn-outline-primary') === false) {
                    $classes .= ' btn-outline-primary';
                }
            } else {
                $classes = str_replace('btn-outline-primary', '', $classes);
                if (strpos($classes, 'btn-primary') === false) {
                    $classes .= ' btn-primary';
                }
            }

            // Normalize spaces
            $classes = trim(preg_replace('/\s+/', ' ', $classes));

            return '<button' . $before . 'class="' . $classes . '"';
        },
        $block_content
    );
    
    return apply_filters('bootscore/block/buttons/content', $block_content, $block);
  }
}
add_filter('render_block_core/buttons', 'bootscore_block_buttons_classes', 10, 2);

The $before in the code is actually empty, but perhaps this prevents future problems if new attributes are added before the class for some reason.

Initially I thought it was responsible for preventing the data-wp-on--click="actions.removeAllActiveFilters", but as I said, it seems to be added through a selection of the wp-block-button__link class.

3

In the image, I've marked the style that contains .is-style-outline--4 in the path, and it's actually above the hierarchy. But as you can see, we maintain the entire button structure and add the classes .btn and .btn-outline-primary.

Since we'll be forced to use !important anyway, perhaps there's no need to create the general support; that's what I think at the moment. But I still consider myself a layman, so I need you to analyze everything I say.

One last observation about the inline style style="border-width:1px;padding-top:5px;padding-right:8px;padding-bottom:5px;padding-left:8px;text-decoration:none" that appears... This comes from the widget's own style as soon as we add it. When I reset all that I could, the only one that remained was text-decoration: none;.

Sorry for any issues with my English, I'm using a translator. Thank you!

@murilocarvalhodev
Copy link
Contributor Author

Where would this CSS be applied?

.wc-block-product-filters {

  // Hide the mobile dialog stuff
  .-header,
  .-footer,
  [data-wp-on--click="actions.openOverlay"] {
    display: none;
  }

  // Chips
  .badge {
    .btn-close {
      font-size: 0.75em;
    }
  }
}


.wc-block-product-filter-price-slider {
  
  // Fake Range
  &__range .range-bar {
    background: var(--#{$prefix}secondary-bg) !important;
    border-radius: $form-range-track-border-radius !important;
    height: $form-range-track-height;
  }

  &__range input[type=range]::-webkit-slider-thumb {
    width: $form-range-thumb-width !important;
    height: $form-range-thumb-height !important;
    background: $form-range-thumb-bg !important;
    border: none !important;
  }

  // Fake form-control
  .text input[type=text] {
    border: 1px solid;
      border-color: var(--#{$prefix}border-color) !important;
    border-radius: $input-border-radius !important;
    background-color: $input-bg !important;
    font-size: $input-font-size !important;
    padding: $input-padding-y $input-padding-x !important;

    &:focus {
      box-shadow: $input-focus-box-shadow;
      outline: 0;
      border-color: $input-focus-border-color;
    }
  }
}

I also don't know much about how to format the answers here, so if you have any tips, that would be great. 😅

@crftwrk
Copy link
Member

crftwrk commented Nov 21, 2025

I also don't know much about how to format the answers here, so if you have any tips, that would be great. 😅

Yes, here https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax ;-)

I quickly opened e new PR to support the filter block #1126. So you can download, install and play around with this branch https://github.com/bootscore/bootscore/tree/Add-support-to-WC-product-filter-block.

Let me know what you think.

@murilocarvalhodev
Copy link
Contributor Author

Thank you very much for the link!

Regarding the PR you opened, I now have some questions:

  • So you decided to add specific support for the clear filters button?
  • Will you keep the block-buttons code as it was?
  • What are your thoughts on having to pass the attributes explicitly?
  • Regarding the other tasks in your PR, are they problems that appeared with my code suggestion or other problems that already existed before?

Sorry if some of my questions are silly, I'm a little lost now. Should I continue editing my PR or will you take over now?

@crftwrk
Copy link
Member

crftwrk commented Nov 21, 2025

Sorry if some of my questions are silly, I'm a little lost now. Should I continue editing my PR or will you take over now?

All good here, nothing is silly. Yes please, if you can work on the button fix in your PR would be great. Maybe we have to wait/recheck on WP 6.9 (coming December 02), because they change the block <button> element into a <a>.

But in general, the current button code seems too complicated. I am sure we can fix this much more simpler by just changing the classes.

Will you keep the block-buttons code as it was?

No, this must be fixed.

So you decided to add specific support for the clear filters button?, What are your thoughts on having to pass the attributes explicitly?

At best, there is no additional attribute needed for the filter block. #1126 is just a rough sketch and must be fine tuned. We can continue work here after the core buttons block is fixed.

I didnt checked your code yet, can you push this to your PR?

@murilocarvalhodev
Copy link
Contributor Author

Hi, I reviewed your code.

I merged your branch 'Add-support-to-WC-product-filter-block' into my branch 'Fix-block-buttons-removes-wc-attributes'. I'm not sure if that's correct.

The main problem is that using $search and $replace with $str_replace ends up making an incorrect replacement.

The chips contain the class 'wc-block-product-filter-removable-chips__remove' in the <button> and 'wc-block-product-filter-removable-chips__remove-icon' in the <svg> inside.

The line https://github.com/bootscore/bootscore/blob/Add-support-to-WC-product-filter-block/woocommerce/inc/blocks/wc-block-widget-product-filters.php#L39

affects the <button> and the <svg>.

The class in the svg that was 'wc-block-product-filter-removable-chips__remove-icon' becomes 'btn-close ms-1-icon'. From there, I think everything could become a mess.

With the help of ChatGPT, I made a modification. Let me know what you think.

With my code in the bootscore/inc/block-buttons.php file, the attribute data-wp-on-click="actions.removeAllActiveFilters" is not removed, so we no longer need to add it manually in bootscore/woocommerce/inc/blocks/wc-block-widget-product-filters.php.

Just to remind you, this attribute data-wp-on-click="actions.removeAllActiveFilters" is removed when we replace the class .wp-block-button__link in the bootscore/inc/blocks/block-buttons.php file. However, removing it through bootscore/woocommerce/inc/blocks/wc-block-widget-product-filters.php using the render_block_woocommerce/product-filters filter doesn't seem to cause any problems. It runs at a point when WooCommerce has already done what it needed to.

…er' with '' to prevent a style from being added in the ::before
@murilocarvalhodev
Copy link
Contributor Author

murilocarvalhodev commented Nov 24, 2025

I just realized that the problem I mentioned also occurred with wc-block-product-filter-checkbox-list__input, which was also replacing wc-block-product-filter-checkbox-list__input-wrapper, creating form-check-input-wrapper, and this broke the default style added in wc-block-product-filter-checkbox-list__input-wrapper:before. With the change in the code, the class returned to normal and had 2 checkbox squares. The commit above fixed this.

@crftwrk
Copy link
Member

crftwrk commented Nov 24, 2025

Unfortunately, the content buttons are still rendered wrong:

screenshot

Go in backend to a page and add two block buttons. Mark one in the style tab as outlined and view in the frontend.

However, add support to the WC product filter block is a different story and we should not mix them together. So, I merged your branch 'Add-support-to-WC-product-filter-block' into my branch 'Fix-block-buttons-removes-wc-attributes'. I'm not sure if that's correct. is not a good idea.

Let's first fix only the buttons that they rendered correct in frontend and do not remove the attribute in the filter block. If this one is good and merged, then we can open another PR and make the filter block look nice.

This PR has already too many changed files, the only one which is important here is the block-button.php. Are you able to clean this up or should we close this PR and open a new one?

@murilocarvalhodev
Copy link
Contributor Author

murilocarvalhodev commented Nov 25, 2025

Although I can see that the code still needs modifications, the problem is no longer the Bootstrap class assignment, but rather the CSS hierarchy issue I mentioned before. I think we'll need to resort to some !important tags for the outline-styled buttons.

Or we need to make the paths :root :where(.wp-block-button.is-style-outline--1 .wp-block-button__link) stop working. Previously, removing the class .wp-block-button__link would stop that style from working, but at the same time it removed the data-wp-on--click="actions.removeAllActiveFilters" attribute that WooCommerce needs. When we keep .wp-block-button__link, the style path to :root :where(.wp-block-button.is-style-outline--{number} .wp-block-button__link) is recognized again when WordPress encounters more than one button.

The WordPress core adds the class is-style-outline--{number/like an id} when it identifies more than one block button. This scenario is unavoidable (I don't know if we can remove that individual class (is-style-outline--{number}) or if it's a good idea.); it adds it to give access to an individual class for styling.

Captura de tela 2025-11-24 213437

But notice that the HTML structure is correct now. I have an updated code here, tell me what I should do now.

@murilocarvalhodev
Copy link
Contributor Author

murilocarvalhodev commented Nov 25, 2025

I think we finally did it:

/**
  * Buttons
  *
  * Add the classes btn and btn-primary or btn-outline-primary to the block buttons.
  */
if (!function_exists('bootscore_block_buttons_classes')) {
  function bootscore_block_buttons_classes($block_content, $block) {
    // Process only core/buttons blocks
    if ($block['blockName'] !== 'core/buttons') {
        return $block_content;
    }

    // Replace wp-block-buttons-is-layout-flex with gap-1 mb-3
    $block_content = str_replace(
        'wp-block-buttons-is-layout-flex',
        'gap-1 mb-3',
        $block_content
    );

    /**
     * Use preg_replace_callback to process each individual button <div> in the block.
     * The regex matches:
     * 1. <div class="wp-block-button"> and captures any additional classes in $matches[1]
     * 2. The <a> tag inside the div, capturing attributes before class="" in $matches[2]
     * 3. The classes of the <a> element in $matches[3]
     * This allows us to manipulate each button individually, detect outline styles,
     * and apply Bootstrap btn classes appropriately.
     */
    $block_content = preg_replace_callback(
    '/<div class="wp-block-button\b([^"]*)">\s*<a([^>]*)class="([^"]*)"/i',
    function ($matches) {
        // Classes of the wp-block-button div.
        $div_classes = trim($matches[1]);

        // Remove any is-style-outline--<number> class from the div.
        $div_classes = preg_replace('/\bis-style-outline--\d+\b/', '', $div_classes);

        // Normalize whitespace in div classes.
        $div_classes = trim(preg_replace('/\s+/', ' ', $div_classes));

        // Attributes of <a> before class="".
        $a_before = $matches[2];

        // Classes of the <a> element.
        $a_classes = $matches[3];

        // Detect if this p-block-button div has the outline style.
        $has_outline = (strpos($div_classes, 'is-style-outline') !== false);

        // Ensure base .btn class exists.
        if (strpos($a_classes, 'btn') === false) {
            $a_classes .= ' btn';
        }

        /**
         * Determine the correct button style:
         * If the parent div has is-style-outline, use btn-outline-primary.
         * Otherwise, use btn-primary as default.
         */
        if ($has_outline) {
            $a_classes = str_replace('btn-primary', '', $a_classes);
            if (strpos($a_classes, 'btn-outline-primary') === false) {
                $a_classes .= ' btn-outline-primary';
            }
        } else {
            $a_classes = str_replace('btn-outline-primary', '', $a_classes);
            if (strpos($a_classes, 'btn-primary') === false) {
                $a_classes .= ' btn-primary';
            }
        }

        // Normalize whitespace in <a> classes.
        $a_classes = trim(preg_replace('/\s+/', ' ', $a_classes));

        // Reconstruct the div + <a> with updated classes.
        return '<div class="wp-block-button' . ($div_classes ? ' ' . $div_classes : '') . '"><a' . $a_before . 'class="' . $a_classes . '"';
        },
        $block_content
    );

    return apply_filters('bootscore/block/buttons/content', $block_content, $block);
  }
}
add_filter('render_block_core/buttons', 'bootscore_block_buttons_classes', 10, 2);
Captura de tela 2025-11-24 232303 This second screenshot still contains the solution from your branch #1126, but I also made changes to it when I did the merge. Captura de tela 2025-11-24 232409

@crftwrk
Copy link
Member

crftwrk commented Nov 25, 2025

Yes! Tested it with upcoming WP 6.9 and seems to work well.

If:

  • that button code has been updated
  • your branch has been cleaned-up to remove the WC product filter support and only block-buttons.php has been changed

Then we can merge this PR immediately and step into a new PR which adds support for the WC filter block.

Agree?

@murilocarvalhodev
Copy link
Contributor Author

Okay, just give me a little help because this is my biggest interaction with GitHub/Contributing. What's smarter? Deleting the files that came from your branch or saving the current code and reverting the commits (to the point of deleting them from the history)?

@crftwrk
Copy link
Member

crftwrk commented Nov 25, 2025

Not so complicated...

In your branch:

  • Delete ‎assets/scss/bootscore-woocommerce/blocks/_wc-product-filters.scss
  • Delete ‎woocommerce/inc/blocks/wc-block-widget-product-filters.php‎
  • Replace assets/scss/_bootscore-woocommerce.scss‎ with the actual downloaded one
  • Replace inc/blocks/disable-unsupported-blocks.php‎ with the actual downloaded one
  • Replace woocommerce/wc-functions.php‎with the actual downloaded one
  • After pushing the commit, only block-buttons.php should remain https://github.com/bootscore/bootscore/pull/1125/files

When done, I will merge that immediately and we can open a new PR with product filter support.

@murilocarvalhodev
Copy link
Contributor Author

Sorry for the delay, I've been busy. I think I did everything right. Let me know how it goes.

Copy link
Member

@crftwrk crftwrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's it! 👍 Let's open now a new PR to add support to the filter block.

@crftwrk crftwrk marked this pull request as ready for review November 26, 2025 09:45
@crftwrk crftwrk merged commit c075c7b into bootscore:main Nov 26, 2025
@github-project-automation github-project-automation bot moved this from In Progress to Done in v6.4.0 Nov 26, 2025
@murilocarvalhodev murilocarvalhodev deleted the Fix-block-buttons-removes-wc-attributes branch November 26, 2025 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[BUG] 'bootscore_block_buttons_classes' removes required data attributes from WooCommerce clear filters buttons

2 participants