3 days ago
<?php
// Allow FacetWP to detect Salient's Visual Composer Post Loop Builder
// Needs the 'facetwp-template' class set on the Post Loop Builder element: https://d.pr/i/x4j75G
// Disable the element's own (Load more) pagination: https://d.pr/i/4ZumQ0
// Use a Pager facet instead (numbered or load more type).
add_filter( 'nectar_post_grid_query', function( $query_args ) {
if ( $query_args['post_type'] == 'resource' ) {
// Detect Post Loop Builder Grid query
$query_args['facetwp'] = true;
// Fix FacetWP pagination. Without this, Pager or Load More Pager facet will not work
if ( array_key_exists('offset', $query_args ) ) {
unset( $query_args['offset'] );
}
}
return $query_args;
}, 10 );
3 weeks ago
<?php
// Scenario: an apply/submit/refresh button is clicked (in this case the Number Range facet's Go button)
// On click, the Proximity facet should use the first item in the dropdown if any text is entered in the input field,
// but not if the user actually made a selection (by clicking an item in the dropdown or using Enter/Return).
// This involves killing the original click event on the button first. Then detecting any selection in the Proximity.
// If there is no selection, trigger a click on the first dropdown item so it is selected, and perform the original refresh.
add_action( 'wp_head', function() {
?>
<script>
// This needs to run as early as possible, in the head
document.addEventListener('DOMContentLoaded', function() {
// First we need to kill the existing click event on the Number Range button
const selectorToIntercept = '.facetwp-type-number_range .facetwp-submit';
document.addEventListener('click', function(event) {
const clickedButton = event.target.closest(selectorToIntercept);
if (clickedButton) {
event.preventDefault();
event.stopImmediatePropagation();
const clickEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
// Then, if there is text in the Proximity facet, trigger the first item,
// if the facet is not already having a selection
const proximityFacet = document.querySelector('.facetwp-type-proximity');
const firstLocation= document.querySelector('.location-result:first-child');
if( firstLocation && proximityFacet.classList.contains('not-active')) {
firstLocation.dispatchEvent(clickEvent);
}
// Then refresh again
if ('undefined' !== typeof FWP) {
FWP.refresh();
}
}
}, true);
});
</script>
<?php
}, 100 );
2 weeks ago
<?php
// To exclude custom fields from FacetWP's get_data_sources() function, used in the admin area, you can use
// the 'facetwp_excluded_custom_fields' filter.
// To do it by partial match, e.g. for fields with a hashed part of the name,
// you can use the 'facetwp_excluded_custom_fields_like' filter,
// available in FacetWP 4.5+ :
add_filter( 'facetwp_excluded_custom_fields_like', function( $not_like ) {
$not_like[] = '_crp_cache_'; // exclude cache rows added by Contextual Related Posts plugin
return $not_like;
});
4 weeks ago
<?php
// Add this to the Listing Builder listing's Query tab in Dev mode
// Situation: 'enti' post type posts that have an ACF Relationshipship field that relates them with 'progetti' posts
// The 'progetti' posts have a custom field 'disattiva_dol' which is an ACF true/false field.
// The generated query arguments retrieve 'enti' post type posts
// that have a related 'progetti' post for which the 'disattiva_dol' custom field is false
// Step 1: Get the IDs of "project" posts where disattiva_dol is false.
$valid_project_ids_args = array(
'post_type' => 'progetti',
'posts_per_page' => -1, // Retrieve all matching projects
'fields' => 'ids', // Return only post IDs for efficiency
'meta_query' => array(
array(
'key' => 'disattiva_dol', // The ACF true/false field on 'project' posts
'value' => 0, // ACF stores 'false' as 0 (for true/false fields)
'compare' => '=',
'type' => 'NUMERIC', // Ensure numeric comparison
),
),
);
$valid_project_ids = get_posts( $valid_project_ids_args );
// Step 2: Create the WP_Query arguments for "enti" posts based on the valid_project_ids.
$enti_query_args = array(
'post_type' => 'enti',
'posts_per_page' => -1, // Or your desired number of posts
'post_status' => 'publish', // Only published 'enti' posts
);
if ( ! empty( $valid_project_ids ) ) {
$project_relationship_meta_query = array(
'relation' => 'OR', // An 'enti' post can be related to ANY of the valid projects
);
foreach ( $valid_project_ids as $project_id ) {
// Relationship field stores a single ID (numeric comparison)
$project_relationship_meta_query[] = array(
'key' => 'progetti_oggetto', // Replace with the actual name of your ACF Relationship field on 'enti' posts
'value' => $project_id,
'compare' => '=',
'type' => 'NUMERIC',
);
}
$enti_query_args['meta_query'] = $project_relationship_meta_query;
}
// For checking the resulting args, remove when it works
// echo '<pre>'; var_dump($enti_query_args); echo '</pre>';
return $enti_query_args;
1 month ago
<?php
/**
* prevent default map loading
**/
add_filter( 'facetwp_load_gmaps', '__return_false' );
/**
* load gmaps script for cmplz
*/
add_filter( 'cmplz_added_scripts', function( $added_scripts ) {
$params = [
'key' => FWP()->display->get_gmaps_api_key(),
'v' => 'quarterly',
];
$params_string = '';
foreach ( apply_filters( 'facetwp_gmaps_params', $params ) AS $param => $val ) {
$params_string .= $param . ': "' . $val . '",';
}
$script = '(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. FacetWP\'s instance is ignored."):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({';
$script .= $params_string;
$script .= '});';
$added_scripts[] = [
'name' => 'FacetWP',
'category' => 'marketing',
'editor' => $script,
'async' => 0
];
return $added_scripts;
});
/**
* Init map after cookies accepted
*
*/
add_action('wp_enqueue_scripts', function()
{
ob_start();
?>
<script>
/**
* Make functions await for 'ms' milliseconds
* https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
*
*/
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* Wait for 'facetwp-map' to be initialized
*
*/
const checkIfMapIsInitialized = () => {
const map = document.getElementById('facetwp-map');
return map.children.length > 0 && FWP_MAP.markersArray.length > 0;
}
/**
* Wait for 'FWP', 'FWP_MAP' and 'FWP_MAP.map' to be set
*
*/
const checkIfFWPExists = async () => {
if (typeof FWP !== 'undefined' && typeof FWP_MAP !== 'undefined' && typeof FWP_MAP.map !== 'undefined') {
return true;
}
await sleep(500);
checkIfFWPExists();
}
/**
* Reinitialize FacetWP Google Maps' map
*
*/
const reinitializeMap = async () => {
FWP.loaded = false;
delete FWP.frozen_facets.map; // change 'map' to name of your map
FWP.refresh();
await sleep(6000);
if (checkIfMapIsInitialized() !== true) {
reinitializeMap();
}
}
const fixMap = async (event) => {
if (!cmplz_has_consent("marketing")) {
return;
}
if (event.type === "cmplz_enable_category") {
document.removeEventListener('cmplz_enable_category', fixMap);
window.removeEventListener('load', fixMap);
}
await checkIfFWPExists();
if (checkIfMapIsInitialized() !== true) {
await reinitializeMap();
}
}
document.addEventListener('cmplz_enable_category', fixMap);
window.addEventListener('load', fixMap);
</script>
<?php
$script = ob_get_clean();
$script = str_replace(array('<script>', '</script>'), '', $script);
wp_add_inline_script('cmplz-cookiebanner', $script);
}, PHP_INT_MAX);
2 months ago
<!--
In the listing's Display tab in Dev mode, add the following to var_dump the SQL of the listing query.
This can be handy for seeing the SQL of a static listing, for which Debug Mode (FWP.settings.debug.sql in the Console) will not work.
See: https://facetwp.com/help-center/listing-templates/listing-builder/using-the-listing-builder-in-dev-mode/#debug-static-listing-queries
-->
<pre>
<?php var_dump( $GLOBALS['wp_query']->request ); ?>
</pre>
2 months ago
<?
/**
* disables map filtering if enabled when other
* filters are used instead
**/
add_action( 'facetwp_scripts', function() {
?>
<script>
(function($) {
document.addEventListener('facetwp-refresh', function() {
if ( null !== FWP.active_facet &&
'' !== $(FWP.active_facet.nodes[0]).attr('data-name' ) &&
/** change 'my_map_facet' to name of your map facet */
'my_map_facet' !== $(FWP.active_facet.nodes[0]).attr( 'data-name' ) ) {
var $button = $('.facetwp-map-filtering');
$button.text(FWP_JSON['map']['filterText']);
FWP_MAP.is_filtering = false;
$button.toggleClass('enabled');
FWP.facets.map = [];
}
});
})(fUtil);
</script>
<?php
}, 100 );
2 months ago
<?php
// Let a facet show all options instead of the ones based on the currently filtered results.
// This changes the SQL that loads the facet values.
// Only for use in highly customized situations, doing this can have unexpected side effects.
add_filter( 'facetwp_facet_where', function( $where_clause, $facet ) {
if ( 'my-facet' == $facet['name'] ) { // change 'my-facet' to the name of your facet
$post_ids = FWP()->unfiltered_post_ids;
$post_ids = empty( $post_ids ) ? [ 0 ] : $post_ids;
$where_clause = ' AND post_id IN (' . implode( ',', $post_ids ) . ')';
}
return $where_clause;
}, 10, 2 )
2 months ago
<?php
add_action( 'facetwp_scripts', function() {
?>
<script>
(function($) {
// Store original alert
var originalAlert = window.alert;
// Override window.alert
window.alert = function(msg) {
// Catch all FacetWP geolocation alerts
if (
msg === "User denied the request for Geolocation." ||
msg === "Location information is unavailable." ||
msg === "The request to get user location timed out." ||
msg === "An unknown error occurred."
) {
// Suppress FacetWP's original alert, do nothing here
return;
}
// Otherwise, let other alerts work as normal
originalAlert(msg);
};
// Now show custom messages via the FacetWP error hook
FWP.hooks.addAction('facetwp/geolocation/error', function(obj) {
let error = obj.error;
let customMessage = "We couldn’t detect your location. Please allow location access.";
switch (error.code) {
case error.PERMISSION_DENIED:
customMessage = "⚠️ You blocked location sharing. Please enable it in your browser.";
break;
case error.POSITION_UNAVAILABLE:
customMessage = "📡 Location info is not available right now.";
break;
case error.TIMEOUT:
customMessage = "⏳ The request took too long. Please try again.";
break;
case error.UNKNOWN_ERROR:
customMessage = "❌ An unknown error occurred while getting your location.";
break;
}
originalAlert(customMessage); // Show thecustom alert
});
})(fUtil);
</script>
<?php
}, 100 );
2 months ago
/**
** Styles a Radio facet to look like a Checkboxes facet, but still
** function like a (single select) Radio facet.
** Change 'my_facet' in '.facetwp-facet-my_facet' to match the facet
** name (not label, see https://facetwp.com/help-center/facets/#the-facet-label)
** of your facet and the background URL to be
** a relative or full URL to the correct image.
** Also see: https://facetwp.com/help-center/facets/facet-types/radio/#style-radio-facet-choices-as-checkboxes
**/
.facetwp-facet-my_facet .facetwp-radio {
background: url('/wp-content/plugins/facetwp/assets/images/checkbox.png') 0 50% no-repeat;
background-size: 14px 14px;
}
.facetwp-facet-my_facet .facetwp-radio.checked {
background-image: url('/wp-content/plugins/facetwp/assets/images/checkbox-on.png');
}