back

Fix duplicates in pagination in Bricks Builder with FacetWP and WP Grid Builder

Understanding the problem

When using the Bricks Builder, it can happen that content appears twice in a loop, especially if the sorting is set to “menu_order”. This problem often occurs in connection with the “Load more” or “Browse” function. Let’s take a closer look at why this happens and how we can fix it.

The cause

If the sort value is the same for several entries (e.g. 0), the database cannot reliably determine an identical order. Each time the entries are queried, a random sequence of entries with the same value is created. This means that the same content can appear on pages one and two of your loop.

FacetWP has already documented this error here: https://facetwp.com/how-to-prevent-duplicate-results/.
The WP Grid Builder support has also confirmed this behavior.

The solution: introduction of secondary sorting

To solve this problem, we need to add a second attribute for sorting. Here is an example of how this works:

Sorting by menu_order:
– Post “a” menu_order = 1
– Post “c” menu_order = 2
– Post “b” menu_order = 2
Posts “C” and “B” could be sorted randomly.

Sorting by menu_order AND title:
– Post “a” menu_order = 1
– Post “b” menu_order = 2
– Post “c” menu_order = 2
Now, if the menu_order is the same, sorting is based on the title. Post “B” will therefore always appear before “C”.

Multiple attributes not possible in Bricksbuilder

Unfortunately, the Bricks Builder interface does not allow you to set multiple attributes for sorting. We therefore have to use some custom code:

/**
 * If the menu_order attribute is used for sorting and the value is the same for multiple posts,
 * the order of the posts is not deterministic and can lead to duplicates when paginating.
 * This function fixes this by adding a secondary "title" attribute.
 */
add_filter('bricks/posts/query_vars', function(array $query_vars, array $settings, string $element_id) {
    if (!empty($query_vars['orderby']) && $query_vars['orderby'] === 'menu_order') {
        // Modify the 'orderby' parameter to include another parameter
        $query_vars['orderby'] = array(
            // Use the existing 'order' if set, otherwise default to "ASC" for menu_order
            'menu_order' => $query_vars['order'] ?? "ASC",
            // Use the same order for title, ensuring consistent sorting
            'title' => $query_vars['order'] ?? "ASC" 
        );
    }
    return $query_vars;
}, 10, 3);

Add this code to your functions.php file. It modifies the WP_Query arguments for all loops that sort by the menu_order attribute and adds the title as a secondary sort attribute.

The filter is documented in the Bricks Academy. It can be used for various customizations.

By implementing this solution, you ensure that the pagination in your WordPress site created with Bricks works consistently and without duplicates.

Leave the first comment

Still not enough? Suitable for this:

Let's get started!