Home FacetWP filters met custom post-type loop in Breakdance
DevelopmentWebsites

FacetWP filters met custom post-type loop in Breakdance

Het probleem

Bij het combineren van FacetWP met de Post Loop Builder van Breakdance werkt de standaard AJAX-filtering niet. De filter-requests worden wel verstuurd (zichtbaar in de Network tab), maar de content op de pagina ververst niet. Daarnaast plaatst FacetWP de classname .facetwp-template op de verkeerde div.

Dit komt omdat FacetWP bij een AJAX refresh de template opnieuw probeert te renderen — maar een Breakdance Codeblock is geen geregistreerde FacetWP-template. FacetWP weet daardoor niet waar hij de vernieuwde resultaten vandaan moet halen.

 

De oplossing

In plaats van FacetWP’s AJAX te gebruiken, forceren we bij elke filter- of pagineringsactie een volledige page reload met de filterwaarden als GET-parameters. De PHP-loop in de Codeblock leest die parameters zelf uit en past de query aan.

 

Stap 1: De PHP-loop in de Breakdance Codeblock

Gebruik onderstaande code in je Codeblock. De loop leest _paged en _project_filter uit de URL en past de query daarop aan.

 

<?php
$paged = isset( $_GET['_paged'] ) ? intval( $_GET['_paged'] ) : 1;

$tax_query = array();
if ( ! empty( $_GET['_project_filter'] ) ) {
    $tax_query[] = array(
        'taxonomy' => 'project_category',
        'field'    => 'slug',
        'terms'    => explode( ',', sanitize_text_field( $_GET['_project_filter'] ) ),
    );
}

$args = array(
    'post_type'      => 'project',
    'posts_per_page' => 10,
    'paged'          => $paged,
    'facetwp'        => true,
);

if ( ! empty( $tax_query ) ) {
    $args['tax_query'] = $tax_query;
}

$query = new WP_Query( $args );
if ( $query->have_posts() ) : ?>
<div class="facetwp-template project-grid-custom">
    <?php while ( $query->have_posts() ) : $query->the_post(); ?>
        <?php echo do_shortcode( '' ); ?>
    <?php endwhile; ?>
</div>
<?php wp_reset_postdata();
endif; ?>

 

Let op: Vervang JOUW_BLOCK_ID door het ID van jouw Global Block. Dit vind je in de URL wanneer je het block bewerkt in Breakdance, bijvoorbeeld ?breakdance=builder&id=1146.

Let op: Vervang project_category door de naam van jouw taxonomy, en project door jouw post type slug.

 

 

Stap 2: JavaScript toevoegen aan functions.php

Dit script onderschept FacetWP’s refresh-event en vervangt het door een page reload met de juiste GET-parameters. Voeg dit toe aan de functions.php van je child theme.

// ******** FACETWP FORCE RELOAD (filters + paginering) ********
add_action('wp_head', function () {
?>
<script>
(function () {

    document.addEventListener('facetwp-loaded', function () {
        if (typeof FWP !== 'undefined') {
            FWP.soft_refresh = false;

            FWP.hooks.addAction('facetwp/refresh', function () {
                var url    = new URL(window.location.href);
                var facets = FWP.facets;

                // Verwijder bestaande facet parameters
                for (var key of Array.from(url.searchParams.keys())) {
                    if (key.startsWith('_') || key.startsWith('facetwp')) {
                        url.searchParams.delete(key);
                    }
                }

                // Voeg actieve facetwaarden toe als GET parameters
                for (var name in facets) {
                    var val = facets[name];
                    if (Array.isArray(val) && val.length > 0) {
                        url.searchParams.set('_' + name, val.join(','));
                    } else if (typeof val === 'string' && val !== '') {
                        url.searchParams.set('_' + name, val);
                    } else {
                        url.searchParams.delete('_' + name);
                    }
                }

                // Reset paginering bij nieuwe filter
                url.searchParams.delete('_paged');

                window.location.href = url.toString();
            });
        }
    });

    // Paginering via reload
    document.addEventListener('click', function (e) {
        var el = e.target.closest('.facetwp-page');
        if (!el) return;
        var page = el.getAttribute('data-page');
        if (!page) return;
        e.preventDefault();
        e.stopPropagation();
        var url = new URL(window.location.href);
        url.searchParams.delete('facetwp');
        url.hash = '';
        url.searchParams.set('_paged', page);
        window.location.href = url.toString();
    }, true);

})();
</script>
<?php
}, 100);
// ******** END ********

 

Stap 3: Hulpfilter toevoegen aan functions.php

Dit zorgt dat FacetWP de custom query herkent als de main query:

add_filter( 'facetwp_is_main_query', function( $is_main_query, $query ) {
    if ( true === $query->get( 'facetwp' ) ) {
        $is_main_query = true;
    }
    return $is_main_query;
}, 10, 2 );

Structuur in Breakdance

De opbouw in het Structure panel moet er zo uitzien:

  • FacetWP Facet — het filter element
  • Code Block — de loop
  • FacetWP Facet — de paginering

 

Aandachtspunten

  • De facet-teller (bijv. “Cultuurtechnisch (6)”) wordt door FacetWP zelf bepaald en kan afwijken van de werkelijke resultaten, omdat de query buiten FacetWP om draait. Dit is puur visueel.
  • Bij het wisselen van filter wordt de paginering automatisch gereset naar pagina 1.
  • Wil je meerdere filters ondersteunen? Voeg dan per taxonomy een extra $_GET check toe in de $tax_query array.

 

Extra tip

Heb je een Global Block als kaart-template? Gebruik dan do_shortcode('') binnen de loop. Dit is stabieler dan render_element_by_post_id() omdat de shortcode de juiste post-context automatisch meekrijgt via the_post().

Extra hulp nodig?

Soms kom je er ondanks de uitleg niet helemaal uit. In dat geval kun je eenvoudig een supportticket indienen. We helpen je graag verder.