Template filters written for WP Store Locator v2 still work in v3, through a backward-compatibility layer. However, the legacy helper functions are now deprecated, and several v2 settings work differently.
For example, if your wpsl_listing_template callback stops showing the phone, fax and email after upgrading to v3, it’s probably because it checks $wpsl_settings['show_contact_details']. That option was removed from the admin, so saving your settings sets it to 0.
Another example: the v2 code prints <%= distance %> without a check. When visitors search by store name there’s no distance, and every result disappears from the list.
This post covers every filter on the filters documentation page that ends in _template. For each one, you get the v2 code from the docs, the v3 version, and what changed. Copy the v3 version into your theme’s functions.php in place of the old callback.
- What changed in v3
- wpsl_listing_template
- wpsl_info_window_template
- wpsl_cpt_info_window_template
- wpsl_more_info_template
- wpsl_store_header_template
- wpsl_skip_cpt_template
- Checklist after updating your code
If you only need small changes, you may not need a filter. Since 3.0 you can edit the search results and info window HTML directly in Store Locator > Settings > Fields Manager > Section Editor.
Use the Section Editor when
- you want to add a field, move things around or change the markup, and the result is the same on every page.
- you’d rather not edit theme files. The code is saved in the database, so it keeps working if you switch themes.
- the check depends on the store’s own data, for example only showing a line when a store has a phone number. The editor supports the same
<% if ( ... ) { %>checks as the filters.
Use a filter when
- the template has to change based on something PHP knows, like the current page, the logged-in user, the site language, a setting, or a value from your own code.
- you want to add translatable text with
__()oresc_html__(). - you want the change in your theme or plugin code, under version control, rather than in the database.
wpsl_more_info_template and wpsl_store_header_template from changing the search results. The setting is per template and applies to every language, so uncheck it for every template you use. The store page pop-up (wpsl_cpt_info_window_template) has no section and always uses the filter.
While a filter is active, the code you load in the Section Editor already includes that filter’s changes. If you save and activate it, the search results look the same as before, but the filter no longer runs, so later changes to your filter code won’t show up.
What changed in v3
In v2, a template callback used the $wpsl and $wpsl_settings globals and a set of wpsl_*() helper functions. In v3, the same work is done through two services: template_sections builds the template parts, and wpsl_settings reads the settings.
| $sections = wpsl_get_service( 'template_sections' ); | |
| $settings = wpsl_get_service( 'wpsl_settings' ); |
A setting
| // v2 | |
| global $wpsl_settings; | |
| $hide_country = $wpsl_settings['hide_country']; | |
| // v3 | |
| $settings = wpsl_get_service( 'wpsl_settings' ); | |
| $hide_country = $settings->get( 'ux', 'hide_country' ); |
Show contact details?
| // v2 | |
| $show_contact_details = $wpsl_settings['show_contact_details']; | |
| // v3: true when "Below the address in the search results" | |
| // is selected for the contact details | |
| $show_contact_details = in_array( 'search_results', (array) $settings->get( 'ux', 'contact_details', [] ), true ); |
Store name / link
| // v2 | |
| $listing_template .= wpsl_store_header_template( 'listing' ); | |
| // v3 | |
| $sections = wpsl_get_service( 'template_sections' ); | |
| $listing_template .= $sections->store_header( 'listing' ); |
Address in the configured format
| // v2 | |
| $listing_template .= '<span>' . wpsl_address_format_placeholders() . '</span>'; | |
| // v3 | |
| $listing_template .= '<span>' . $sections->format_address() . '</span>'; |
Phone, fax and email block
| // v2: the phone, fax and email written out by hand | |
| $listing_template .= '<p class="wpsl-contact-details">'; | |
| $listing_template .= '<% if ( phone ) { %>'; | |
| $listing_template .= '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'phone_label', __( 'Phone', 'wpsl' ) ) ) . '</strong>: <%= formatPhoneNumber( phone ) %></span>'; | |
| $listing_template .= '<% } %>'; | |
| // ... the same for the fax and email | |
| $listing_template .= '</p>'; | |
| // v3: one call, with the translated labels and the icon setting | |
| $listing_template .= $sections->contact_details(); |
“More info” link and content
| // v2 | |
| $listing_template .= wpsl_more_info_template(); | |
| // v3 | |
| $listing_template .= $sections->more_info_template(); |
A translated label
| // v2 | |
| $listing_template .= '<strong>' . esc_html( $wpsl->i18n->get_translation( 'phone_label', __( 'Phone', 'wpsl' ) ) ) . '</strong>'; | |
| // v3: the {{...}} tag goes inside the template string, | |
| // the plugin replaces it with the translated label | |
| $listing_template .= '<strong>' . "{{wpsl_label( 'phone_label' )}}" . '</strong>'; |
Distance unit
| // v2 | |
| $listing_template .= '<%= distance %> ' . esc_html( $wpsl_settings['distance_unit'] ); | |
| // v3: the {{...}} tag goes inside the template string, | |
| // and follows the shortcode's distance_unit attribute | |
| $listing_template .= '<%= distance %> {{wpsl_get_distance_unit()}}'; |
The old functions still work, but each call logs a deprecation notice when WP_DEBUG is on.
The {{...}} tags are filled in by the plugin after your filter runs. That's why labels can be written straight into the template string. Only wpsl_label and wpsl_get_distance_unit are allowed by default; you can add your own functions with the wpsl_template_functions filter. {{wpsl_get_distance_unit()}} also respects the shortcode's distance_unit attribute, which $wpsl_settings['distance_unit'] didn't.
Contact details are now placed per location. The single "Show contact details" checkbox from v2 became a multiselect under Settings > User Experience. The values you can check for are:
| Setting option | Value |
|---|---|
| Below the address in the search results | search_results |
| The "more info" section in the search results | more_info |
| The store locator marker pop-up | marker_popup |
| Below the address on the landing page | landing_page |
| The landing page marker pop-up | landing_page_marker_popup |
Hours (ux → hours) and the location description (ux → description) use the same values. The last two options only show up when store permalinks are enabled.
Every template filter still receives the default v3 template as its first argument. For a small change, you can edit that string instead of rebuilding the whole template.
wpsl_listing_template
This filter controls the HTML of each location in the search results. The example adds a custom field called my_textinput below the address.
| add_filter( 'wpsl_listing_template', 'custom_listing_template' ); | |
| function custom_listing_template() { | |
| $sections = wpsl_get_service( 'template_sections' ); | |
| $settings = wpsl_get_service( 'wpsl_settings' ); | |
| $icons = $settings->get( 'appearance', 'icons', [] ); | |
| $icons_enabled = ! empty( $icons['enabled'] ); | |
| $cta = $settings->get( 'appearance', 'cta', [] ); | |
| $contact_details = (array) $settings->get( 'ux', 'contact_details', [] ); | |
| $hours = (array) $settings->get( 'ux', 'hours', [] ); | |
| $description = (array) $settings->get( 'ux', 'description', [] ); | |
| $is_name_search = $sections->is_name_search(); | |
| $listing_template = '<li data-store-id="<%= id %>">' . "\r\n"; | |
| $listing_template .= "\t" . '<div class="wpsl-store-location">' . "\r\n"; | |
| // The thumbnail, store name and address. | |
| if ( $icons_enabled ) { | |
| $address_icon = isset( $icons['address'] ) ? $icons['address'] : 'marker'; | |
| $listing_template .= "\t\t" . '<p class="wpsl-icon-address wpsl-icon-address-' . esc_attr( $address_icon ) . '"><%= typeof thumb !== "undefined" ? thumb : "" %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<span class="wpsl-location-content">' . "\r\n"; | |
| } else { | |
| $listing_template .= "\t\t" . '<p><%= typeof thumb !== "undefined" ? thumb : "" %>' . "\r\n"; | |
| } | |
| // Linked or plain store name | |
| $listing_template .= "\t\t\t" . $sections->store_header( 'listing' ) . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<span class="wpsl-street"><%= address %></span>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% if ( address2 ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<span class="wpsl-street"><%= address2 %></span>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| // Address format from the settings page | |
| $listing_template .= "\t\t\t" . '<span>' . $sections->format_address() . '</span>' . "\r\n"; | |
| if ( ! $settings->get( 'ux', 'hide_country' ) ) { | |
| $listing_template .= "\t\t\t" . '<span class="wpsl-country"><%= country %></span>' . "\r\n"; | |
| } | |
| if ( $icons_enabled ) { | |
| $listing_template .= "\t\t\t" . '</span>' . "\r\n"; | |
| } | |
| $listing_template .= "\t\t" . '</p>' . "\r\n"; | |
| /** | |
| * Include the data from a custom field called 'my_textinput'. | |
| * | |
| * Fields created in Store Locator > Settings > Fields Manager are included | |
| * automatically. For other custom fields, add them to the location data | |
| * with the wpsl_frontend_meta_fields filter. | |
| * | |
| * The typeof check keeps the template working for locations without the field. | |
| */ | |
| $listing_template .= "\t\t" . '<% if ( typeof my_textinput !== "undefined" && my_textinput ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<p><%= my_textinput %></p>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| // The phone, fax and email, if "Below the address in the search results" | |
| // is selected for the contact details. | |
| if ( in_array( 'search_results', $contact_details, true ) ) { | |
| $listing_template .= $sections->contact_details(); | |
| } | |
| // The opening hours, if "Below the address in the search results" | |
| // is selected for the opening hours. | |
| if ( in_array( 'search_results', $hours, true ) ) { | |
| $listing_template .= "\t\t" . '<% if ( typeof hours !== "undefined" && hours ) { %>' . "\r\n"; | |
| if ( $icons_enabled ) { | |
| $listing_template .= "\t\t" . '<div class="wpsl-icon-hours"><%= hours %></div>' . "\r\n"; | |
| } else { | |
| $listing_template .= "\t\t" . '<%= hours %>' . "\r\n"; | |
| } | |
| $listing_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| } | |
| // The "temporarily closed" or "permanently closed" notice. | |
| $status_class = ( $icons_enabled ) ? 'wpsl-location-status wpsl-icon-attention' : 'wpsl-location-status'; | |
| $listing_template .= "\t\t" . '<% if ( typeof location_status !== "undefined" && location_status ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<p class="' . esc_attr( $status_class ) . '"><%= location_status %></p>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| // The post content, if "Below the address in the search results" | |
| // is selected for the post content. | |
| if ( in_array( 'search_results', $description, true ) ) { | |
| $listing_template .= "\t\t" . '<% if ( typeof description !== "undefined" && description ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<p><%= description %></p>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| } | |
| // The "More info" link and content, if any of the | |
| // "Location(s) of ..." settings includes the "more info" section. | |
| if ( in_array( 'more_info', $contact_details, true ) || in_array( 'more_info', $hours, true ) || in_array( 'more_info', $description, true ) ) { | |
| $listing_template .= "\t\t" . $sections->more_info_template() . "\r\n"; | |
| } | |
| $listing_template .= "\t" . '</div>' . "\r\n"; | |
| // The directions link moves to its own section when the | |
| // links are styled as buttons, or the "More details" link is enabled. | |
| $cta_details = ! empty( $cta['details'] ); | |
| $has_cta_section = ! empty( $cta['enabled'] ) || $cta_details; | |
| // A search by store name has no distance or route, so the wrapper is left out. | |
| if ( ! $is_name_search ) { | |
| $listing_template .= "\t" . '<div class="wpsl-direction-wrap">' . "\r\n"; | |
| if ( ! $settings->get( 'ux', 'hide_distance' ) ) { | |
| $distance_class = ( $icons_enabled ) ? 'wpsl-distance wpsl-icon-road' : 'wpsl-distance'; | |
| $listing_template .= "\t\t" . '<% if ( typeof distance !== "undefined" ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<span class="' . esc_attr( $distance_class ) . '"><%= distance %> <% if ( typeof distance_unit !== "undefined" ) { %><%= distance_unit %><% } else { %>{{wpsl_get_distance_unit()}}<% } %></span>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| } | |
| if ( ! $has_cta_section ) { | |
| $listing_template .= "\t\t" . '<%= createDirectionUrl() %>' . "\r\n"; | |
| } | |
| $listing_template .= "\t" . '</div>' . "\r\n"; | |
| } | |
| if ( $has_cta_section && ( $cta_details || ! $is_name_search ) ) { | |
| $listing_template .= $sections->cta_section( $cta_details, ! $is_name_search ); | |
| } | |
| $listing_template .= '</li>'; | |
| return $listing_template; | |
| } |
| add_filter( 'wpsl_listing_template', 'custom_listing_template' ); | |
| function custom_listing_template() { | |
| global $wpsl, $wpsl_settings; | |
| $listing_template = '<li data-store-id="<%= id %>">' . "\r\n"; | |
| $listing_template .= "\t\t" . '<div class="wpsl-store-location">' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<p><%= thumb %>' . "\r\n"; | |
| $listing_template .= "\t\t\t\t" . wpsl_store_header_template( 'listing' ) . "\r\n"; | |
| $listing_template .= "\t\t\t\t" . '<span class="wpsl-street"><%= address %></span>' . "\r\n"; | |
| $listing_template .= "\t\t\t\t" . '<% if ( address2 ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t\t\t" . '<span class="wpsl-street"><%= address2 %></span>' . "\r\n"; | |
| $listing_template .= "\t\t\t\t" . '<% } %>' . "\r\n"; | |
| $listing_template .= "\t\t\t\t" . '<span>' . wpsl_address_format_placeholders() . '</span>' . "\r\n"; | |
| if ( !$wpsl_settings['hide_country'] ) { | |
| $listing_template .= "\t\t\t\t" . '<span class="wpsl-country"><%= country %></span>' . "\r\n"; | |
| } | |
| $listing_template .= "\t\t\t" . '</p>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% if ( my_textinput ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<p><%= my_textinput %></p>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| if ( $wpsl_settings['show_contact_details'] ) { | |
| $listing_template .= "\t\t\t" . '<p class="wpsl-contact-details">' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% if ( phone ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'phone_label', __( 'Phone', 'wpsl' ) ) ) . '</strong>: <%= formatPhoneNumber( phone ) %></span>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% if ( fax ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'fax_label', __( 'Fax', 'wpsl' ) ) ) . '</strong>: <%= fax %></span>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% if ( email ) { %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'email_label', __( 'Email', 'wpsl' ) ) ) . '</strong>: <%= email %></span>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| $listing_template .= "\t\t\t" . '</p>' . "\r\n"; | |
| } | |
| $listing_template .= "\t\t\t" . wpsl_more_info_template() . "\r\n"; | |
| $listing_template .= "\t\t" . '</div>' . "\r\n"; | |
| $listing_template .= "\t\t" . '<div class="wpsl-direction-wrap">' . "\r\n"; | |
| if ( !$wpsl_settings['hide_distance'] ) { | |
| $listing_template .= "\t\t\t" . '<%= distance %> ' . esc_html( $wpsl_settings['distance_unit'] ) . '' . "\r\n"; | |
| } | |
| $listing_template .= "\t\t\t" . '<%= createDirectionUrl() %>' . "\r\n"; | |
| $listing_template .= "\t\t" . '</div>' . "\r\n"; | |
| $listing_template .= "\t" . '</li>'; | |
| return $listing_template; | |
| } |
What changed
- Contact details: the
show_contact_detailscheck became a check forsearch_resultsin the contact details setting.$sections->contact_details()builds the block with the translated labels, and it follows the icon and “clickable contact details” settings. To change the order or add your own fields, see Customize the Contact Details. - New in v3: the opening hours and the post content, each following its own “Location(s) of …” setting, and the “temporarily / permanently closed” notice, which is always included. The opening hours are shown below the address by default.
- Icons and buttons: the example adds the icon classes when icons are enabled, and moves the directions link into its own section when the links are styled as buttons or the “More details” link is on.
- Thumbnail:
thumbonly exists on some result paths in v3, so it’s guarded withtypeof. - Distance: it’s now wrapped in
<span class="wpsl-distance">, which the v3 CSS styles, and guarded withtypeof distance. A search by store name has no distance, and without the check every result disappears. For name searches the distance wrapper is left out completely.
wpsl_info_window_template
This filter controls the pop-up that opens when you click a marker on the store locator map. The example adds my_textinput below the address.
| add_filter( 'wpsl_info_window_template', 'custom_info_window_template' ); | |
| function custom_info_window_template() { | |
| $sections = wpsl_get_service( 'template_sections' ); | |
| $settings = wpsl_get_service( 'wpsl_settings' ); | |
| $icons = $settings->get( 'appearance', 'icons', [] ); | |
| $icons_enabled = ! empty( $icons['enabled'] ); | |
| $contact_details = (array) $settings->get( 'ux', 'contact_details', [] ); | |
| $hours = (array) $settings->get( 'ux', 'hours', [] ); | |
| $description = (array) $settings->get( 'ux', 'description', [] ); | |
| $info_window_template = '<div data-store-id="<%= id %>" class="wpsl-info-window">' . "\r\n"; | |
| // The store name and address. | |
| if ( $icons_enabled ) { | |
| $address_icon = isset( $icons['address'] ) ? $icons['address'] : 'marker'; | |
| $info_window_template .= "\t" . '<p class="wpsl-icon-address wpsl-icon-address-' . esc_attr( $address_icon ) . '">' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<span class="wpsl-location-content">' . "\r\n"; | |
| } else { | |
| $info_window_template .= "\t" . '<p>' . "\r\n"; | |
| } | |
| $info_window_template .= "\t\t" . $sections->store_header() . "\r\n"; // Linked or plain store name | |
| $info_window_template .= "\t\t" . '<span class="wpsl-street"><%= address %></span>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% if ( address2 ) { %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<span class="wpsl-street"><%= address2 %></span>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<span>' . $sections->format_address() . '</span>' . "\r\n"; // Address format from the settings page | |
| if ( $icons_enabled ) { | |
| $info_window_template .= "\t\t" . '</span>' . "\r\n"; | |
| } | |
| $info_window_template .= "\t" . '</p>' . "\r\n"; | |
| /** | |
| * Include the data from a custom field called 'my_textinput'. | |
| * | |
| * Fields created in Store Locator > Settings > Fields Manager are included | |
| * automatically. For other custom fields, add them to the location data | |
| * with the wpsl_frontend_meta_fields filter. | |
| * | |
| * The typeof check keeps the template working for locations without the field. | |
| */ | |
| $info_window_template .= "\t" . '<% if ( typeof my_textinput !== "undefined" && my_textinput ) { %>' . "\r\n"; | |
| $info_window_template .= "\t" . '<p><%= my_textinput %></p>' . "\r\n"; | |
| $info_window_template .= "\t" . '<% } %>' . "\r\n"; | |
| // The phone, fax and email, if "In the marker popup" is selected for the contact details. | |
| if ( in_array( 'marker_popup', $contact_details, true ) ) { | |
| $info_window_template .= $sections->contact_details(); | |
| } | |
| // The short open / closed status, if "In the marker popup" is | |
| // selected for the opening hours and the status is enabled. | |
| if ( in_array( 'marker_popup', $hours, true ) && $settings->get( 'ux', 'show_hour_status' ) ) { | |
| $info_window_template .= "\t" . '<% if ( typeof hours_status !== "undefined" && hours_status && ( typeof location_status === "undefined" || !location_status ) ) { %>' . "\r\n"; | |
| if ( $icons_enabled ) { | |
| $info_window_template .= "\t" . '<div class="wpsl-icon-hours"><%= hours_status %></div>' . "\r\n"; | |
| } else { | |
| $info_window_template .= "\t" . '<%= hours_status %>' . "\r\n"; | |
| } | |
| $info_window_template .= "\t" . '<% } %>' . "\r\n"; | |
| } | |
| // The post content, if "In the marker popup" is selected for the post content. | |
| if ( in_array( 'marker_popup', $description, true ) ) { | |
| $info_window_template .= "\t" . '<% if ( typeof description !== "undefined" && description ) { %>' . "\r\n"; | |
| $info_window_template .= "\t" . '<p><%= description %></p>' . "\r\n"; | |
| $info_window_template .= "\t" . '<% } %>' . "\r\n"; | |
| } | |
| // The "temporarily closed" or "permanently closed" notice. | |
| $status_class = ( $icons_enabled ) ? 'wpsl-location-status wpsl-icon-attention' : 'wpsl-location-status'; | |
| $info_window_template .= "\t" . '<% if ( typeof location_status !== "undefined" && location_status ) { %>' . "\r\n"; | |
| $info_window_template .= "\t" . '<p class="' . esc_attr( $status_class ) . '"><%= location_status %></p>' . "\r\n"; | |
| $info_window_template .= "\t" . '<% } %>' . "\r\n"; | |
| // The directions, street view and zoom links, | |
| // plus the "More details" link when it's enabled. | |
| $info_window_template .= "\t" . '<%= createInfoWindowActions( id, url, typeof permalink !== "undefined" ? permalink : "" ) %>' . "\r\n"; | |
| $info_window_template .= '</div>'; | |
| return $info_window_template; | |
| } |
| add_filter( 'wpsl_info_window_template', 'custom_info_window_template' ); | |
| function custom_info_window_template() { | |
| global $wpsl_settings, $wpsl; | |
| $info_window_template = '<div data-store-id="<%= id %>" class="wpsl-info-window">' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<p>' . "\r\n"; | |
| $info_window_template .= "\t\t\t" . wpsl_store_header_template() . "\r\n"; | |
| $info_window_template .= "\t\t\t" . '<span><%= address %></span>' . "\r\n"; | |
| $info_window_template .= "\t\t\t" . '<% if ( address2 ) { %>' . "\r\n"; | |
| $info_window_template .= "\t\t\t" . '<span><%= address2 %></span>' . "\r\n"; | |
| $info_window_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| $info_window_template .= "\t\t\t" . '<span>' . wpsl_address_format_placeholders() . '</span>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '</p>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% if ( phone ) { %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'phone_label', __( 'Phone', 'wpsl' ) ) ) . '</strong>: <%= formatPhoneNumber( phone ) %></span>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% if ( fax ) { %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'fax_label', __( 'Fax', 'wpsl' ) ) ) . '</strong>: <%= fax %></span>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% if ( email ) { %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'email_label', __( 'Email', 'wpsl' ) ) ) . '</strong>: <%= formatEmail( email ) %></span>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% if ( my_textinput ) { %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<p><%= my_textinput %></p>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| $info_window_template .= "\t\t" . '<%= createInfoWindowActions( id ) %>' . "\r\n"; | |
| $info_window_template .= "\t" . '</div>' . "\r\n"; | |
| return $info_window_template; | |
| } |
What changed
- Contact details: the three hand-written blocks became
$sections->contact_details(). Fax is now also run throughformatPhoneNumber(). - Following the settings: the contact details and the post content only show when “The store locator marker pop-up” is selected for them. The short open / closed status also needs “Show the current open / closed status?” to be on. The closed notice is always included.
- createInfoWindowActions(): now takes the store URL and permalink as well, so it can show the “More details” button.
createInfoWindowActions( id )still works, but without that button. - Missing fields: in v3, a custom field the location doesn’t have breaks the whole pop-up. Always use the
typeofcheck for custom fields. - Known issue in 3.0: the plugin’s own pop-up currently also shows the store thumbnail and country. The example follows the intended design without them, so they disappear when you switch to it. This will be fixed in 3.1.
wpsl_cpt_info_window_template
This filter controls the marker pop-up on individual store pages and on maps made with the [wpsl_map] shortcode. The example adds my_textinput below the address.
| add_filter( 'wpsl_cpt_info_window_meta_fields', 'custom_cpt_info_window_meta_fields', 10, 2 ); | |
| function custom_cpt_info_window_meta_fields( $store_meta, $store_id ) { | |
| /** | |
| * Fields are saved with a 'wpsl_' prefix, | |
| * so 'my_textinput' is stored as 'wpsl_my_textinput'. | |
| */ | |
| $store_meta['my_textinput'] = esc_html( get_post_meta( $store_id, 'wpsl_my_textinput', true ) ); | |
| return $store_meta; | |
| } |
| add_filter( 'wpsl_cpt_info_window_template', 'custom_cpt_info_window_template' ); | |
| function custom_cpt_info_window_template() { | |
| $sections = wpsl_get_service( 'template_sections' ); | |
| $settings = wpsl_get_service( 'wpsl_settings' ); | |
| $icons = $settings->get( 'appearance', 'icons', [] ); | |
| $icons_enabled = ! empty( $icons['enabled'] ); | |
| $contact_details = (array) $settings->get( 'ux', 'contact_details', [] ); | |
| $hours = (array) $settings->get( 'ux', 'hours', [] ); | |
| $description = (array) $settings->get( 'ux', 'description', [] ); | |
| $cpt_info_window_template = '<div class="wpsl-info-window">' . "\r\n"; | |
| /** | |
| * The store name, linked to the store page or | |
| * store URL when one is available, and the address. | |
| */ | |
| $cpt_info_window_template .= "\t" . '<p class="wpsl-no-margin">' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . $sections->store_header( 'wpsl_map' ) . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<span><%= address %></span>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<% if ( address2 ) { %>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<span><%= address2 %></span>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| // Address format from the settings page | |
| $cpt_info_window_template .= "\t\t" . '<span>' . $sections->format_address() . '</span>' . "\r\n"; | |
| if ( ! $settings->get( 'ux', 'hide_country' ) ) { | |
| $cpt_info_window_template .= "\t\t" . '<span class="wpsl-country"><%= country %></span>' . "\r\n"; | |
| } | |
| $cpt_info_window_template .= "\t" . '</p>' . "\r\n"; | |
| /** | |
| * Include the data from a custom field called 'my_textinput'. | |
| * | |
| * Before you can access the 'my_textinput' data, you first need to | |
| * add it through the 'wpsl_cpt_info_window_meta_fields' filter. | |
| * | |
| * The typeof check keeps the template working for locations without the field. | |
| */ | |
| $cpt_info_window_template .= "\t" . '<% if ( typeof my_textinput !== "undefined" && my_textinput ) { %>' . "\r\n"; | |
| $cpt_info_window_template .= "\t" . '<p><%= my_textinput %></p>' . "\r\n"; | |
| $cpt_info_window_template .= "\t" . '<% } %>' . "\r\n"; | |
| /** | |
| * The phone, fax and email, if "In the marker popup on | |
| * the landing page" is selected for the contact details. | |
| */ | |
| if ( in_array( 'landing_page_marker_popup', $contact_details, true ) ) { | |
| $cpt_info_window_template .= $sections->contact_details(); | |
| } | |
| /** | |
| * The short open / closed status, if it's selected for | |
| * the landing page marker popup and the status is enabled. | |
| */ | |
| if ( in_array( 'landing_page_marker_popup', $hours, true ) && $settings->get( 'ux', 'show_hour_status' ) ) { | |
| $cpt_info_window_template .= "\t" . '<% if ( typeof hours_status !== "undefined" && hours_status ) { %>' . "\r\n"; | |
| if ( $icons_enabled ) { | |
| $cpt_info_window_template .= "\t" . '<div class="wpsl-icon-hours"><%= hours_status %></div>' . "\r\n"; | |
| } else { | |
| $cpt_info_window_template .= "\t" . '<%= hours_status %>' . "\r\n"; | |
| } | |
| $cpt_info_window_template .= "\t" . '<% } %>' . "\r\n"; | |
| } | |
| // The post content, if it's selected for the landing page marker popup. | |
| if ( in_array( 'landing_page_marker_popup', $description, true ) ) { | |
| $cpt_info_window_template .= "\t" . '<% if ( typeof description !== "undefined" && description ) { %>' . "\r\n"; | |
| $cpt_info_window_template .= "\t" . '<p><%= description %></p>' . "\r\n"; | |
| $cpt_info_window_template .= "\t" . '<% } %>' . "\r\n"; | |
| } | |
| $cpt_info_window_template .= '</div>'; | |
| return $cpt_info_window_template; | |
| } |
| add_filter( 'wpsl_cpt_info_window_template', 'custom_cpt_info_window_template' ); | |
| function custom_cpt_info_window_template() { | |
| $cpt_info_window_template = '<div class="wpsl-info-window">' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<p class="wpsl-no-margin">' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t\t" . '<strong><%= store %></strong>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t\t" . '<span><%= address %></span>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t\t" . '<% if ( address2 ) { %>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t\t" . '<span><%= address2 %></span>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t\t" . '<span>' . wpsl_address_format_placeholders() . '</span>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t\t" . '<span class="wpsl-country"><%= country %></span>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '</p>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<% if ( my_textinput ) { %>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<p><%= my_textinput %></p>' . "\r\n"; | |
| $cpt_info_window_template .= "\t\t" . '<% } %>' . "\r\n"; | |
| $cpt_info_window_template .= "\t" . '</div>' . "\r\n"; | |
| return $cpt_info_window_template; | |
| } |
What changed
- Store name:
$sections->store_header( 'wpsl_map' )links the name to the store page or store URL when one is available. Otherwise it shows the same plainstrongname as v2. - Country: it now follows the “Hide the country in the results?” setting.
- New in v3: the contact details and the post content, each shown when “The landing page marker pop-up” is selected for it. The short open / closed status needs that option for the hours, and “Show the current open / closed status?” to be on.
wpsl_more_info_template
This filter controls the “More info” link in the search results and the content that opens below it. It changed the most, because the v2 “More info” settings no longer exist.
In v2 you turned on “Show more info” and chose where the details appeared: in the store listings or in the info window. In v3 you pick a location for each type of detail instead. Contact details, hours and description each have a “The ‘more info’ section in the search results” option. The “More info” link appears when at least one of them uses it.
| add_filter( 'wpsl_more_info_template', 'custom_more_info_template' ); | |
| function custom_more_info_template() { | |
| $sections = wpsl_get_service( 'template_sections' ); | |
| $settings = wpsl_get_service( 'wpsl_settings' ); | |
| $icons = $settings->get( 'appearance', 'icons', [] ); | |
| $icons_enabled = ! empty( $icons['enabled'] ); | |
| $contact_details = (array) $settings->get( 'ux', 'contact_details', [] ); | |
| $hours = (array) $settings->get( 'ux', 'hours', [] ); | |
| $description = (array) $settings->get( 'ux', 'description', [] ); | |
| /** | |
| * Show the "More info" link when a location has data for one of the enabled | |
| * "more info" fields, or data in the custom 'my_textinput' field. | |
| */ | |
| $more_info_template = '<% if ( hasMoreInfoData || ( typeof my_textinput !== "undefined" && my_textinput ) ) { %>' . "\r\n"; | |
| $more_info_template .= "<p class='wpsl-more-info'><a class=\"wpsl-store-details wpsl-store-listing\" aria-expanded=\"false\" href=\"#wpsl-id-<%= id %>\">" . "{{wpsl_label( 'more_label' )}}" . '</a></p>' . "\r\n"; | |
| $more_info_template .= "\t\t" . '<div id="wpsl-id-<%= id %>" class="wpsl-more-info-listings">' . "\r\n"; | |
| // The phone, fax and email, if "In the more info section" is selected for the contact details. | |
| if ( in_array( 'more_info', $contact_details, true ) ) { | |
| $more_info_template .= "\t" . $sections->contact_details(); | |
| } | |
| // The opening hours, if "In the more info section" is selected for the opening hours. | |
| if ( in_array( 'more_info', $hours, true ) ) { | |
| $more_info_template .= "\t\t\t" . '<% if ( typeof hours !== "undefined" && hours ) { %>' . "\r\n"; | |
| if ( $icons_enabled ) { | |
| $more_info_template .= "\t\t\t" . '<div class="wpsl-store-hours wpsl-icon-hours"><%= hours %></div>' . "\r\n"; | |
| } else { | |
| $more_info_template .= "\t\t\t" . '<div class="wpsl-store-hours"><strong>' . "{{wpsl_label( 'hours_label' )}}" . '</strong><%= hours %></div>' . "\r\n"; | |
| } | |
| $more_info_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| } | |
| // The post content, if "In the more info section" is selected for the post content. | |
| if ( in_array( 'more_info', $description, true ) ) { | |
| $more_info_template .= "\t\t\t" . '<% if ( typeof description !== "undefined" && description ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '<%= description %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| } | |
| /** | |
| * Include the data from a custom field called 'my_textinput'. | |
| * | |
| * Fields created in Store Locator > Settings > Fields Manager are included | |
| * automatically. For other custom fields, add them to the location data | |
| * with the wpsl_frontend_meta_fields filter. | |
| */ | |
| $more_info_template .= "\t\t\t" . '<% if ( typeof my_textinput !== "undefined" && my_textinput ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '<p><%= my_textinput %></p>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '<% } %>' . "\r\n"; | |
| $more_info_template .= "\t\t" . '</div>' . "\r\n"; | |
| $more_info_template .= '<% } %>' . "\r\n"; | |
| return $more_info_template; | |
| } |
| add_filter( 'wpsl_more_info_template', 'custom_more_info_template' ); | |
| function custom_more_info_template() { | |
| global $wpsl_settings, $wpsl; | |
| $more_info_url = '#'; | |
| if ( $wpsl_settings['template_id'] == 'default' && $wpsl_settings['more_info_location'] == 'info window' ) { | |
| $more_info_url = '#wpsl-search-wrap'; | |
| } | |
| if ( $wpsl_settings['more_info_location'] == 'store listings' ) { | |
| $more_info_template = '<% if ( !_.isEmpty( phone ) || !_.isEmpty( fax ) || !_.isEmpty( email ) ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '<p><a class="wpsl-store-details wpsl-store-listing" href="#wpsl-id-<%= id %>">' . esc_html( $wpsl->i18n->get_translation( 'more_label', __( 'More info', 'wpsl' ) ) ) . '</a></p>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '<div id="wpsl-id-<%= id %>" class="wpsl-more-info-listings">' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% if ( description ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<%= description %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% } %>' . "\r\n"; | |
| if ( !$wpsl_settings['show_contact_details'] ) { | |
| $more_info_template .= "\t\t\t\t" . '<p>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% if ( phone ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'phone_label', __( 'Phone', 'wpsl' ) ) ) . '</strong>: <%= formatPhoneNumber( phone ) %></span>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% } %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% if ( fax ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'fax_label', __( 'Fax', 'wpsl' ) ) ) . '</strong>: <%= fax %></span>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% } %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% if ( email ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<span><strong>' . esc_html( $wpsl->i18n->get_translation( 'email_label', __( 'Email', 'wpsl' ) ) ) . '</strong>: <%= email %></span>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% } %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '</p>' . "\r\n"; | |
| } | |
| if ( !$wpsl_settings['hide_hours'] ) { | |
| $more_info_template .= "\t\t\t\t" . '<% if ( hours ) { %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<div class="wpsl-store-hours"><strong>' . esc_html( $wpsl->i18n->get_translation( 'hours_label', __( 'Hours', 'wpsl' ) ) ) . '</strong><%= hours %></div>' . "\r\n"; | |
| $more_info_template .= "\t\t\t\t" . '<% } %>' . "\r\n"; | |
| } | |
| $more_info_template .= '<% if ( my_textinput ) { %>' . "\r\n"; | |
| $more_info_template .= '<p><%= my_textinput %></p>' . "\r\n"; | |
| $more_info_template .= '<% } %>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '</div>' . "\r\n"; | |
| $more_info_template .= "\t\t\t" . '<% } %>'; | |
| } else { | |
| $more_info_template = '<p><a class="wpsl-store-details" href="' . $more_info_url . '">' . esc_html( $wpsl->i18n->get_translation( 'more_label', __( 'More info', 'wpsl' ) ) ) . '</a></p>'; | |
| } | |
| return $more_info_template; | |
| } |
What changed
- One code path: the “store listings” vs. “info window” branches are gone. Details you want in the marker pop-up now go there directly, through the “The store locator marker pop-up” option, without a “More info” link.
- The old callback: the v2 “More info” location setting no longer exists in v3, so the v2 callback always takes the “info window” branch. It then prints a “More info” link that does nothing, even if you used the store listings option in v2. Replace it with the v3 version.
- When the link shows:
hasMoreInfoDatareplaces the!_.isEmpty( phone ) || ...check. The plugin sets it to true when a field placed in “more info” has a value. It doesn’t know about your custom fields, so add those to the check yourself, as shown. - Settings checks:
!$wpsl_settings['show_contact_details']and!$wpsl_settings['hide_hours']became checks formore_infoin the contact details and hours settings. - Accessibility: the link now has
aria-expanded, which the plugin toggles when the section opens and closes. - When the filter runs: only when at least one detail is placed in “more info”. If none is, the “More info” link isn’t added to the template at all, so your callback never runs.
- Replacing the listing too: calling
$sections->more_info_template()inside yourwpsl_listing_templatecallback runs this filter as well, so both customizations work together.
wpsl_store_header_template
This filter controls the store name at the top of each search result and pop-up. The example keeps the default markup and adds my_textinput below the store name.
| add_filter( 'wpsl_store_header_template', 'custom_store_header_template', 10, 2 ); | |
| /** | |
| * The $location is 'listing' ( search results ), 'info_window' ( marker popup | |
| * on the store locator ) or 'wpsl_map' ( marker popup from the [wpsl_map] shortcode ). | |
| */ | |
| function custom_store_header_template( $header_template, $location ) { | |
| $sections = wpsl_get_service( 'template_sections' ); | |
| $settings = wpsl_get_service( 'wpsl_settings' ); | |
| // Opens the link in a new window if that's enabled on the settings page | |
| $new_window = $sections->new_window(); | |
| if ( $settings->get( 'local_pages', 'permalinks' ) ) { | |
| // The [wpsl_map] shortcode doesn't always include the permalink, so check for it. | |
| if ( $location == 'wpsl_map' ) { | |
| $header_template = '<% if ( typeof permalink !== "undefined" && permalink ) { %>' . "\r\n"; | |
| $header_template .= '<strong class="wpsl-location-name"><a tabindex="0"' . $new_window . ' href="<%= permalink %>"><%= store %></a></strong>' . "\r\n"; | |
| $header_template .= '<% } else { %>' . "\r\n"; | |
| $header_template .= '<strong><%= store %></strong>' . "\r\n"; | |
| $header_template .= '<% } %>'; | |
| } else { | |
| $header_template = '<strong class="wpsl-location-name"><a tabindex="0"' . $new_window . ' href="<%= permalink %>"><%= store %></a></strong>'; | |
| } | |
| } else { | |
| // Link to the store URL if "Make the store name clickable if a store URL exists?" is enabled. | |
| $header_template = '<% if ( wpslSettings.storeUrl == 1 && url ) { %>' . "\r\n"; | |
| $header_template .= '<strong class="wpsl-location-name"><a tabindex="0"' . $new_window . ' href="<%= url %>"><%= store %></a></strong>' . "\r\n"; | |
| $header_template .= '<% } else { %>' . "\r\n"; | |
| $header_template .= '<strong><%= store %></strong>' . "\r\n"; | |
| $header_template .= '<% } %>'; | |
| } | |
| /** | |
| * Include the data from a custom field called 'my_textinput' below the store name. | |
| * | |
| * On the store locator, fields created in Store Locator > Settings > Fields Manager | |
| * are included automatically. For other custom fields, add them to the location data | |
| * with the wpsl_frontend_meta_fields filter. | |
| * | |
| * In the marker popup of the [wpsl_map] shortcode ( 'wpsl_map' location ), no custom | |
| * fields are included. Add them with the wpsl_cpt_info_window_meta_fields filter. | |
| */ | |
| $header_template .= '<% if ( typeof my_textinput !== "undefined" && my_textinput ) { %>' . "\r\n"; | |
| $header_template .= '<span class="wpsl-store-subtitle" style="display: block;"><%= my_textinput %></span>' . "\r\n"; | |
| $header_template .= '<% } %>'; | |
| return $header_template; | |
| } |
| // Use only one of the two examples below. | |
| // Store permalinks enabled | |
| add_filter( 'wpsl_store_header_template', 'custom_store_header_template' ); | |
| function custom_store_header_template() { | |
| $header_template = '<h3><a href="<%= permalink %>"><%= store %></a></h3>'; | |
| return $header_template; | |
| } | |
| // Store permalinks disabled | |
| add_filter( 'wpsl_store_header_template', 'custom_store_header_url_template' ); | |
| function custom_store_header_url_template() { | |
| $header_template = '<% if ( wpslSettings.storeUrl == 1 && url ) { %>' . "\r\n"; | |
| $header_template .= '<h3><a href="<%= url %>"><%= store %></a></h3>' . "\r\n"; | |
| $header_template .= '<% } else { %>' . "\r\n"; | |
| $header_template .= '<h3><%= store %></h3>' . "\r\n"; | |
| $header_template .= '<% } %>'; | |
| return $header_template; | |
| } |
What changed
- Location argument: the filter now also passes
$location:listing,info_windoworwpsl_map(store pages and[wpsl_map]). Use it to change the header in only one place, for exampleif ( $location !== 'listing' ) { return $header_template; }at the top. - Permalink check: on [wpsl_map] maps the permalink can be missing from the data. The
typeof permalinkcheck keeps the pop-up from breaking there. - New window:
$sections->new_window()addstarget="_blank" rel="noopener"when “Open links in a new window?” is enabled. The v2 example ignored that setting. - Class: the linked store name in the default v3 header uses
class="wpsl-location-name". Keep it if you want the v3 styling for the store name to apply. - Headings: the header sits inside a
pelement in every template, so don’t replace thestrongwith an h1–h6. To mark the name as a heading for screen readers, add a heading role instead, as shown in Use a Heading for the Store Name.
wpsl_skip_cpt_template
This filter stops the plugin from adding the map, address and opening hours to individual store pages. It’s typically used together with a custom single-wpsl_stores.php template. Nothing changes in v3; the same line still works:
add_filter( 'wpsl_skip_cpt_template', '__return_true' );
| v2 | v3 | |
|---|---|---|
| Map | [wpsl_map] |
[wpsl_map] |
| Address | [wpsl_address] |
[wpsl_address directions="true"], with a directions link |
| Opening hours | [wpsl_hours], unless hours are hidden |
[wpsl_hours], only when “Below the address on the landing page” is selected for the hours |
| Location status | Not available | A “temporarily / permanently closed” message replaces the hours |
Checklist after updating your code
-
Check the Section Editor. If you activated a custom List or Info window section on the settings page, the plugin uses that saved code and skips
wpsl_listing_templateorwpsl_info_window_templatefor it. Use either the Section Editor or the filter for a section, not both. -
Check where your details appear. The upgrade moves your v2 choices into the new contact details, hours and description settings under Settings > User Experience. If you used “More info” in v2, your contact details may now be set to “more info” or the marker pop-up instead of below the address.
-
Guard every custom field with
typeof. In v3, a field that a location doesn’t have makes that result disappear from the list, or stops the pop-up from opening. The browser console then shows “a template section failed to render” for the search results, or aReferenceErrorfor the pop-up. -
Turn on
WP_DEBUGonce. Any leftover v2 helper function logs a deprecation notice that names its v3 replacement. -
Custom fields: fields you add in the Fields Manager are included in the store locator data automatically, but not in the [wpsl_map] pop-up on store pages. Fields registered in code still need wpsl_meta_box_fields and wpsl_frontend_meta_fields. For the store page pop-up, use wpsl_cpt_info_window_meta_fields, including for Fields Manager fields.
-
Clear your page cache. The plugin builds the templates on every page load, so template changes show up straight away. If you added a new field with
wpsl_frontend_meta_fields, clear the cache under Store Locator > Settings > Tools > Autoload cache. A caching plugin can still serve the old version. -
Styling: if the v3 styles clash with your custom CSS, try “Disable v3 theme rules?” under Settings > Tools.