3 days ago
<?php
// Google Pagespeed insights may complain about links without a href not being crawlable.
// The following code replaces these <a> tags with class .facetwp-toggle with <span> tags.
// .facetwp-toggle links are in Checkboxes, Hierarchy and Color facets.
// Option 1: with JS
add_action( 'facetwp_scripts', function() {
?>
<script>
document.addEventListener('facetwp-loaded', function() {
const anchorElements = document.querySelectorAll('a.facetwp-toggle');
anchorElements.forEach(anchor => {
const span = document.createElement('span');
for (let i = 0; i < anchor.attributes.length; i++) {
const attribute = anchor.attributes[i];
if (attribute.name !== 'href') {
span.setAttribute(attribute.name, attribute.value);
}
}
span.innerHTML = anchor.innerHTML;
if (anchor.parentNode) {
anchor.parentNode.replaceChild(span, anchor);
}
});
});
</script>
<?php
}, 100 );
// Option 2: with the 'facetwp_facet_html' hook
add_filter( 'facetwp_facet_html', function( $output, $params ) {
if ( in_array( $params['facet']['type'], [ 'checkboxes', 'hierarchy', 'color' ] ) ) {
// Regex to find <a> tags with class="facetwp-toggle" and capture their content and any other attributes
$pattern = '/<a\s+(class="[^"]*\bfacetwp-toggle\b[^"]*")([^>]*)>(.*?)<\/a>/si';
// Replacement string: change <a> to <span>, keep class and other attributes, and content
// $1 captures the class attribute
// $2 captures any other attributes
// $3 captures the inner HTML content
$replacement = '<span $1$2>$3</span>';
$output = preg_replace( $pattern, $replacement, $output );
}
return $output;
}, 10, 2 );
1 week ago
<?php
// For a Proximity facet, index an ACF Google Maps field of a post linked by an ACF Post Object field.
// The Proximity facet's data source can be set to anything as long as that value is not empty. E.g. 'Post Type'.
// The 'Return Format' of the Post Object field does not matter: it works with both 'Post Object' and 'Post ID'.
// See: https://facetwp.com/help-center/developers/hooks/indexing-hooks/facetwp_index_row/#index-values-in-a-related-custom-field
add_filter( 'facetwp_index_row', function( $params, $class ) {
if ( 'my_proximity_facet' == $params['facet_name'] ) { // Change "my_proximity_facet" to the name of your Proximity facet
$post_id = $params['post_id'];
// Get the Post Object field value
$location_id = get_field( 'my_acf_post_object field', $post_id ); // Change "my_acf_post_object field" to the name of your ACF Post Object field
$location = '';
if ( $location_id ) { // Check if the Post Object field has a value
// If we have a Post Object field value, use it to get the Google Maps field value
$location = get_field( 'my_acf_googlemapfield', $location_id ); // Change "my_acf_googlemapfield" to the name of your ACF Google Maps field
}
// If there is a location, index it, otherwise skip this post by setting facet_value to ''.
$params['facet_value'] = empty( $location ) ? '' : $location['lat'];
$params['facet_display_value'] = empty( $location ) ? '' : $location['lng'];
// Optionally replicate the extra checks that Proximity facets normally have:
// 1. Make sure lat and lng are valid floats
$params['facet_value'] = $params['facet_value'] == (float)$params['facet_value'] ? (float)$params['facet_value'] : '';
$params['facet_display_value'] = $params['facet_display_value'] == (float)$params['facet_display_value'] ? (float)$params['facet_display_value'] : '';
// 2. Check for a valid range of lat and lng
if ( '' == $params['facet_value'] || '' == $params['facet_display_value'] || 90 < abs( $params['facet_value'] ) || 180 < abs( $params['facet_display_value'] ) ) {
$params['facet_value'] = ''; // don't index
}
}
return $params;
}, 10, 2 );
1 month ago
<?php
/** fix for generate blocks 2 query loop block
** add "facetwp-template" to the query block as an
** extra css class and use this snippet to
** detect query
**/
add_filter( 'generateblocks_query_wp_query_args', function( $args, $attributes) {
if ( false !== strpos( $attributes['className'], 'facetwp-template') ) {
$args['facetwp'] = true;
}
return $args;
}, 10, 2 );
1 month ago
<?php
return [
// other query args here
"meta_query" => [
"relation" => "OR",
[
"key" => "_relevanssi_hide_post",
"compare" => "NOT EXISTS",
],
[
"key" => "_relevanssi_hide_post",
"compare" => "=",
"value" => "off"
]
]
];
1 month ago
<?php
add_filter( 'facetwp_indexer_post_facet', function( $bypass, $params ) {
if ( function_exists( 'relevanssi_hide_post' ) && relevanssi_hide_post( $params["defaults"]["post_id"] ) ) {
return true;
}
return $bypass;
}, 1, 2 );
1 month ago
<?php
/**
** processes search facet keywords with relevanssi's spam
** block settings
**/
add_action( 'facetwp_relevanssi_do_query', function($search) {
if ( !isset( $_REQUEST['s'] ) ) {
$_REQUEST['s'] = $search->get( 's' );
relevanssi_spamblock();
unset( $_REQUEST['s'] );
}
}, 1);
2 months ago
<?php
/** filter for translating facet display values which are translated
** in wpml's string translation
** works for acf fields such as a select box that has its option labels translated
** in string translation rather than post translation
**/
add_filter( 'facetwp_facet_display_value', function( $label, $params ) {
$lang = apply_filters( 'wpml_current_language', null );
$default = apply_filters( 'wpml_default_language', null );
if ( isset( FWP()->facet->http_params['lang'] ) ) {
$lang = FWP()->facet->http_params['lang'];
}
if ( $lang != $default ) {
switch ( $params['facet']['name'] ) {
case 'facet_name_one': // change 'facet_name_one' to name of facet
case 'facet_name_two': // use additional cases to combine facets that use the same domain in string translation - see screenshot https://d.pr/i/DgWa7G
return apply_filters( 'wpml_translate_single_string', $label, 'acf-field-group-2083', $label, $lang );
case 'facet_name_three': // additional case for different domain
return apply_filters( 'wpml_translate_single_string', $label, 'acf-field-group-2075', $label, $lang );
default:
return $label;
}
}
return $label;
}, 20, 2 );
2 months ago
<?php
// Example template for a Listing Builder listing in Dev mode.
// The listing shows therapists. The query must be ordering by the last name.
// We insert a full width banner with the letter of the alphabet when a new letter starts.
// Screenshot: https://d.pr/i/pEhwFf
// The classes used replicate what would be the classes in visual mode.
// This listing could be combined with an A-Z facet.
// If you do, add the script below the template part to your functions.php to remove the letter headings when the A-Z facet is in use.
if ( have_posts() ) :
echo '<style>
.fwpl-layout.therapist-listing {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 40px;
}
.fwpl-item.age-group,
.fwpl-item.modality {
padding-top: 10px;
}
.letter-heading {
width: 100%;
display: block;
grid-column: 1 / -1;
font-size: 20px;
font-weight: bold;
color: #fff;
padding: 0 20px;
line-height: 2.4em;
background-color: #015c65;
border-radius: 5px 5px 25px 5px;
}
@media (max-width: 780px) {
body .facetwp-template .fwpl-layout,
body .facetwp-template-static .fwpl-layout {
grid-template-columns: repeat(2, 1fr); /* 2 columns */
}
}
@media (max-width: 544px) {
body .facetwp-template .fwpl-layout,
body .facetwp-template-static .fwpl-layout {
grid-template-columns: repeat(1, 1fr); /* 1 columns */
}
}
</style>';
$current_letter = '';
echo '<div class="fwpl-layout therapist-listing">';
while ( have_posts() ): the_post();
// Add a letter heading for each letter in the alphabet
// We are using the last name here, as the query is ordered by the last_name field
$last_name = get_field('last_name');
$first_letter = strtoupper(substr($last_name, 0, 1));
if ($first_letter !== $current_letter) :
echo '<div class="letter-heading">' . esc_html($first_letter) . '</div>';
$current_letter = $first_letter;
endif;
echo '<div class="fwpl-row therapist border-top card">';
$post_id = get_the_ID();
$post_title = get_the_title();
echo '<div class="fwpl-item therapist-title entry-title">';
$website = get_field( 'website', $post_id );
if ( $website ) {
echo '<a href="' . $website . '" target="_blank">' . $post_title . '</a>';
} else {
echo $post_title;
}
echo '</div>';
echo '<div class="fwpl-item address">';
echo do_shortcode( '[work_address]' );
echo '</div>';
echo '<div class="fwpl-item phone">';
echo do_shortcode( '[work_phone]' );
echo '</div>';
$agegroup = get_field('age_group');
$modality = get_field('modality');
if ($agegroup) {
echo '<div class="fwpl-item age-group">';
echo '<hr style="width:30%; background-color:white; margin-bottom:10px;">';
$labels = [];
foreach ($agegroup as $item) {
if ( isset( $item['label'] ) ) {
$labels[] = $item['label'];
}
}
$agegroups = implode(', ', $labels);
echo '<div class="field-label">Age Group</div>';
echo '<div style="font-size:15px;">'. $agegroups .'</div>';
echo '</div>';
}
if ($modality) {
echo '<div class="fwpl-item modality">';
$labels = [];
foreach ($modality as $item) {
if ( isset( $item['label'] ) ) {
$labels[] = $item['label'];
}
}
$modalities = implode(', ', $labels);
echo '<div class="field-label">Modality</div>';
echo '<div style="font-size:15px;">'. $modalities .'</div>';
echo '</div>';
}
echo '</div>';
endwhile;
echo '</div>';
?>
<?php else : ?>
<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>
<?php
// Add this to your functions.php to remove the letter headings when the A-Z facet is in use
add_action( 'facetwp_scripts', function() {
?>
<script>
(function($) {
document.addEventListener('facetwp-loaded', function() {
let selected = FWP.facets['therapist_alphabetical']; // Your A-Z facet name
if ( selected.length ) { // If any choice in this facet is selected
$('.letter-heading').addClass( 'facetwp-hidden' );
}
});
})(fUtil);
</script>
<?php
}, 100 );
3 months ago
<?php
/**
** Use legacy templates instead of react for
** yith wishlist so it can be re-init easily
** after facet refresh
**/
// legacy use php templates for wishlist button
add_filter( 'yith_wcwl_rendering_method', function( $rendering ) {
return 'php-templates';
});
// Re-trigger YITH wish list init after FacetWP refreshes (after facet filtering)
add_action( 'facetwp_scripts', function() {
?>
<script>
document.addEventListener('facetwp-loaded', function() {
/** wishlist */
if (FWP.loaded) {
jQuery(document).trigger( 'yith_wcwl_init' );
}
});
</script>
<?php
});
5 months ago
<?php
/** partial support, facet pager does not work, generateblock pager does work
** but does not does not use ajax to update page
** add "facetwp-template" class to query https://d.pr/i/1R8Nds
** and the snippet below
**/
add_filter('generateblocks_query_wp_query_args', function ($args, $attributes, $block, $current) {
if ("facetwp-template" == $attributes['className']) {
$args['facetwp'] = true;
}
return $args;
}, 10, 4);