how can i list locations whose postcode starts with a specific number
-
hi!
i’m trying to list all locations whose postcode starts with a specific number, e.g. “4” β postcodes in germany have 5 digits, so the list should display locations with the postcodes 40667, 41469 as well as 44892… so, all postcodes “4*”, basically.
how would i hand over a wildcard like that to the list shortcode?
[locations_list postcode=”4*”]
does not give the desired result.
i haven’t seen anything like this in the documentation or the forum.
i appreciate any help you can give me…
thanks!The page I need help with: [log in to see the link]
-
You could use create your own shortcode which uses the em_locations_output_locations filter. Something like this:
add_shortcode('my_locations_list', 'my_em_locations_list_func');
function my_em_locations_list_func($args, $formats='') {
global $em_postcode_re;
$args = (array) $args;
if (!empty($args['location_postcode'])) {
$em_postcode_re = $args['location_postcode'];
add_filter('em_locations_output_locations', 'my_em_locations_output_locations');
}
else {
$em_postcode_re = null;
}
$ret = em_get_locations_list_shortcode($args, $formats);
if ($em_postcode_re !== null) {
remove_filter('em_locations_output_locations', 'my_em_locations_output_locations');
}
return $ret;
}
function my_em_locations_output_locations($locations) {
$global $em_postcode_re;
$new_locations = [];
foreach ($locations as $EM_location) {
if (!empty($EM_location->location_postcode) && preg_match('/^' . $em_postcode_re . '/', $EM_location->location_postcode ) ) {
$new_locations[] = $EM_location;
}
}
return $new_locations;
}Then use the following shortcode:
[my_locations_list location_postcode="4*"]The postcode attribute on the locations_list shortcode can have the value of true or false. Which tells it whether to search for events with locations.
Actually the shortcode should look like this:
[my_locations_list location_postcode="4[0-9]{4}"]The regular expression
4[0-9]{4}matches any five-digit number that starts with the digit 4oooh, i am going to try this. thank you so much! π
hm. initial test failed, it returned
Keine Veranstaltungsorte
{4}β]since the problem seemed to be the regex, i had chatGPT write that into the code, so that by entering location_postcode=”1″ it shows all locations whose 5-digit postcode begins with 1. this results in the following code:
add_shortcode('my_locations_list', 'my_em_locations_list_func');
function my_em_locations_list_func($args, $formats = '') {
global $em_postcode_re;
$args = (array) $args; // Ensure $args is an array
if (!empty($args['location_postcode']) && ctype_digit($args['location_postcode']) && strlen($args['location_postcode']) === 1) {
// Build regex to match a 5-digit postcode starting with the specified digit
$em_postcode_re = '/^' . $args['location_postcode'] . '\d{4}$/';
add_filter('em_locations_output_locations', 'my_em_locations_output_locations'); // Add the filter
} else {
$em_postcode_re = null;
}
$ret = em_get_locations_list_shortcode($args, $formats); // Call the locations list function
if ($em_postcode_re !== null) {
remove_filter('em_locations_output_locations', 'my_em_locations_output_locations'); // Remove the filter after use
}
return $ret;
}
function my_em_locations_output_locations($locations) {
global $em_postcode_re;
$new_locations = [];
foreach ($locations as $EM_location) {
// Ensure location_postcode exists and matches the 5-digit regex
if (!empty($EM_location->location_postcode) && preg_match($em_postcode_re, $EM_location->location_postcode)) {
$new_locations[] = $EM_location;
}
}
return $new_locations;
}this works, BUT not consistently: for input location_postcode=”0″ it produces a list of locations starting with any number. for input location_postcode=”4″ it produces no results even though there are many location that fit the postcode requirements. so i guess there’s something wrong with the way events calendar’s variables are parsed? i don’t understand.
i’ve made a results page here that shows what happens for which input: https://padelfinder.de/feeds/- location_postcode=β1β³ returns 1 location, but there are at least 7
- location_postcode=β2β³ returns 4, out of at least 11 that would match
- location_postcode=β4β³ returns nothing, but there are at least 9 locations
- location_postcode=β0β³ returns random locations that donβt seem to match at all
does any of this make sense to you? i appreciate any help you might be able to give. thank you!
π
update:
adding limit=”999″ lists all matching locations.
BUT location_postcode=β0β³ still returns random locations with postcodes starting with 0 up to 9, NOT limited to those starting with 0. huh.alright! after an additional round of debugging, chatGPT comes up with this, which works fine with this kind of shortcode:
[my_locations_list location_postcode="0"]
this is the new script, in case anybody needs it:add_shortcode('my_locations_list', 'my_em_locations_list_func');
function my_em_locations_list_func($args, $formats = '') {
global $em_postcode_re;
$args = (array) $args; // Ensure $args is an array
// Force a high limit if not set, to ensure all locations are fetched
if (!isset($args['limit']) || !ctype_digit((string) $args['limit'])) {
$args['limit'] = '999';
}
if (isset($args['location_postcode']) && strlen($args['location_postcode']) === 1 && ctype_digit($args['location_postcode'])) {
// Strict regex to match a 5-digit postcode starting with the specified digit (including 0)
$em_postcode_re = '/^' . preg_quote($args['location_postcode'], '/') . '\d{4}$/';
add_filter('em_locations_output_locations', 'my_em_locations_output_locations'); // Add the filter
} else {
$em_postcode_re = null; // Ensure it's null if invalid
}
$ret = em_get_locations_list_shortcode($args, $formats); // Call the locations list function
if ($em_postcode_re !== null) {
remove_filter('em_locations_output_locations', 'my_em_locations_output_locations'); // Remove the filter after use
}
return $ret;
}
function my_em_locations_output_locations($locations) {
global $em_postcode_re;
if (!$em_postcode_re) {
return $locations; // No filtering needed if regex is null
}
$new_locations = [];
foreach ($locations as $EM_location) {
// Ensure location_postcode exists and strictly matches the regex
if (!empty($EM_location->location_postcode) && preg_match($em_postcode_re, $EM_location->location_postcode)) {
$new_locations[] = $EM_location;
}
}
return $new_locations;
}-
This reply was modified 1 year, 1 month ago by
Oliver Gelbrich.
You don’t really need to use regular expressions for this. Here’s a simpler version:
add_shortcode('my_locations_list', 'my_em_locations_list_func');
function my_em_locations_list_func($args, $formats = '') {
global $postcode_first_char;
$args = (array) $args; // Ensure $args is an array
// Force a high limit if not set, to ensure all locations are fetched
if (!isset($args['limit']) || !ctype_digit((string) $args['limit'])) {
$args['limit'] = '999';
}
if (isset($args['location_postcode']) && strlen($args['location_postcode']) === 1 && ctype_digit($args['location_postcode'])) {
$postcode_first_char = $args['location_postcode'];
add_filter('em_locations_output_locations', 'my_em_locations_output_locations'); // Add the filter
} else {
$postcode_first_char = null;
}
$ret = em_get_locations_list_shortcode($args, $formats); // Call the locations list function
if ($postcode_first_char !== null) {
remove_filter('em_locations_output_locations', 'my_em_locations_output_locations'); // Remove the filter after use
}
return $ret;
}
function my_em_locations_output_locations($locations) {
global $postcode_first_char;
if ($postcode_first_char === null) {
return $locations;
}
$new_locations = [];
foreach ($locations as $EM_location) {
// Ensure location_postcode exists and the first char matches
if (!empty($EM_location->location_postcode) && $EM_location->location_postcode[0] == $postcode_first_char) {
$new_locations[] = $EM_location;
}
}
return $new_locations;
}-
This reply was modified 1 year, 1 month ago by
joneiseman.
-
This reply was modified 1 year, 1 month ago by
joneiseman.
nice! simpler, more elegant and works like a charm – thank you!
do you think I can use this placeholder thing to render a map of said locations?
thank you for any ideas.-
This reply was modified 1 year, 1 month ago by
Oliver Gelbrich.
-
This reply was modified 1 year, 1 month ago by
Oliver Gelbrich.
-
This reply was modified 1 year, 1 month ago by
Oliver Gelbrich.
I used ChatGPT to generate code to create a shortcode to put the locations on a map:
function google_map_shortcode($atts) {
// Extract attributes (if any)
$atts = shortcode_atts(
array(
'width' => '100%',
'height' => '500px',
'scope' => 'all' // default scope for EM_Locations::get
),
$atts,
'google_map'
);
// Get markers data with $atts
$markers = get_markers($atts);
// Start output buffering
ob_start();
?>
<div id="map" style="height: <?php echo esc_attr($atts['height']); ?>; width: <?php echo esc_attr($atts['width']); ?>;"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<script>
function initMap() {
// PHP array of markers
var markers = <?php echo json_encode($markers); ?>;
// Calculate the center of the map
var latSum = 0;
var lngSum = 0;
for (var i = 0; i < markers.length; i++) {
latSum += markers[i].coords.lat;
lngSum += markers[i].coords.lng;
}
var centerLat = latSum / markers.length;
var centerLng = lngSum / markers.length;
// Map options
var options = {
zoom: 4,
center: {lat: centerLat, lng: centerLng}
};
// New map
var map = new google.maps.Map(document.getElementById('map'), options);
// Loop through markers
for(var i = 0; i < markers.length; i++){
addMarker(markers[i]);
}
// Add Marker Function
function addMarker(props){
var marker = new google.maps.Marker({
position: props.coords,
map: map
});
// Check content
if(props.content){
var infoWindow = new google.maps.InfoWindow({
content: props.content
});
marker.addListener('click', function(){
infoWindow.open(map, marker);
});
}
}
}
// Load map when page is ready
document.addEventListener('DOMContentLoaded', function() {
initMap();
});
</script>
<?php
// Return the buffered content
return ob_get_clean();
}
// Register the shortcode
add_shortcode('google_map', 'google_map_shortcode');
// Function to get markers data from Events Manager locations
function get_markers($atts) {
$markers = [];
// Check if the Events Manager plugin is active
if (class_exists('EM_Locations')) {
// Get locations based on attributes
$em_locations = EM_Locations::get($atts);
foreach ($em_locations as $location) {
$lat = $location->location_latitude;
$lng = $location->location_longitude;
$content = '<h1>' . esc_html($location->location_name) . '</h1><a href="' . esc_url($location->get_permalink()) . '" target="_blank">More info</a>';
$markers[] = [
'coords' => ['lat' => (float) $lat, 'lng' => (float) $lng],
'content' => $content
];
}
}
return $markers;
}Don’t forget to change YOUR_API_KEY to your actual Google API key.
The topic ‘how can i list locations whose postcode starts with a specific number’ is closed to new replies.