If you want to change the store locator template, load your version from your theme folder. That way it isn’t lost when you update the plugin.
The built-in templates are in wp-content/plugins/wp-store-locator/includes/frontend/templates/:
| File | Template |
|---|---|
default.php |
Default |
horizontal.php |
Horizontal |
vertical.php |
Vertical |
- Create a
wpsl-templatesfolder in your active theme folder. Use a child theme if you have one. - Copy the template you want to start from into that folder and rename it to
custom.php. - Add this code to your theme’s
functions.php:
| function my_wpsl_custom_template( $templates ) { | |
| $templates[] = [ | |
| 'id' => 'my-custom-template', | |
| 'name' => 'My custom template', | |
| 'desc' => 'Shown under the template name on the Appearance page.', | |
| 'path' => get_stylesheet_directory() . '/wpsl-templates/custom.php', | |
| // Only when you copied vertical.php: | |
| // 'has_panel' => true, | |
| ]; | |
| return $templates; | |
| } | |
| add_filter( 'wpsl_templates', 'my_wpsl_custom_template' ); |
Activate the template
Go to Store Locator > Appearance > Themes. Your template appears as a card with the name you gave it. Click the toggle on that card; the change is saved straight away.
If your template isn’t used, check whether the [wpsl] shortcode on the page has a template attribute. That attribute always overrides the selection on the Appearance page. You can also use it on purpose to load your template on one page only: [wpsl template="my-custom-template"].
Things to keep in mind
- The template must echo its output. The built-in templates build up
$outputand end withecho $output;. Keep that last line. - Keep the element IDs. The store locator’s JavaScript relies on:
#wpsl-wrap,#wpsl-search-inputand#wpsl-search-btn#wpsl-mapand#wpsl-result-list#wpsl-storeswith the<ul>inside it#wpsl-direction-details#wpsl-panelin a copy of the Vertical template
- Copies of the Vertical template need
'has_panel' => truein the array you register, or the panel layout isn’t applied. - Template-specific CSS. The outer
#wpsl-wrapelement gets the classwpsl-{id}-template, for examplewpsl-my-custom-template-template. Styles written for the Horizontal and Vertical templates are scoped to.wpsl-horizontal-templateand.wpsl-vertical-template, so they don’t apply to a copy. Add the original class back:
| add_filter( 'wpsl_template_outer_classes', 'my_wpsl_template_classes' ); | |
| function my_wpsl_template_classes( $classes ) { | |
| if ( in_array( 'wpsl-my-custom-template-template', $classes, true ) ) { | |
| $classes[] = 'wpsl-vertical-template'; // or wpsl-horizontal-template | |
| } | |
| return $classes; | |
| } |
Legacy mode
Custom templates written for WP Store Locator 2 keep working on v3. You don’t have to convert them before updating, and you don’t have to switch anything on.
How it works
When the store locator renders a custom template, WP Store Locator reads the file and looks for three things that only ever appear in v2 template code:
global $wpsl;orglobal $wpsl_settings;$this->— v2 templates ran bound to a class$wpsl->— the old global template object
If it finds any of them, the template is loaded through the backward compatibility layer, which recreates the environment a v2 template expects: the $wpsl object, the flat $wpsl_settings array, the $this context, and the old template methods such as get_css_classes(), get_dropdown_list(), create_category_filter() and the various button helpers. In legacy mode, templates that end with return $output; work as well as templates that echo their output. A v3 template must echo it.
A few things follow from this:
- There is nothing to enable or disable. Detection happens per template, every time it is rendered. It isn’t a site-wide mode and it isn’t stored in your settings.
- It is decided per file. If you have two custom templates, one still on v2 code and one converted to v3, each is handled correctly on its own.
- Built-in templates are never affected. Only templates loaded from outside the plugin folder are checked — which is every template registered the way this page describes.
- Converting a template switches it over by itself. Once the last
global $wpsl,$this->and$wpsl->is gone from the file, it is treated as a v3 template on the next page load. The check also finds them inside comments, so remove them there too.
Where you’ll see it
On the Appearance page, a custom template running in legacy mode gets a warning icon next to its name. Hover it for the explanation.
Right after updating to v3, if you had custom v2 templates, an admin notice lists them and tells you they’ve been kept working.
Both are informational. Nothing is broken and nothing needs doing right away.
Why you should still update your template
- New features are built against the 3.0 template structure, so a v2 template will gradually miss out on them.
- If your template calls an old method that no longer maps onto anything, the compatibility layer returns an empty string instead of an error. That part of your template silently renders nothing, which is harder to spot than a clear failure.
Updating a template to the v3 structure
First replace the globals and $this-> calls with the services in scope. A v3 template receives everything it needs as ordinary variables:
| Variable | Use it for |
|---|---|
$wpsl_settings |
the settings array |
$assets_manager |
CSS classes and custom CSS |
$i18n |
translated labels and label visibility |
$frontend |
the GDPR checkpoint and other front-end output |
$search_filters |
the radius and result-count dropdowns |
$template_filters |
whether a filter should be shown at all |
$maps_manager |
map output |
$panel_filters |
panel-style filters (every template except Default and Horizontal) |
So $this->get_css_classes() or $wpsl->get_css_classes() becomes $assets_manager->get_css_classes().
Secondly update the settings array to the nested structure. Settings were flat in v2 and are grouped in v3:
| // 2.x | |
| $wpsl_settings['autoload'] | |
| // 3.0 | |
| $wpsl_settings['map']['autoload'] |
Finally, make sure the template echoes its output. Most v2 templates end with return $output;. Replace that line with echo $output;, the way the built-in templates end. Once the v2 code is gone, the template no longer runs through the compatibility layer, and a returned value is ignored: the store locator renders nothing.
Compare your file against the matching built-in template in wp-store-locator/includes/frontend/templates/ — it’s the clearest reference for what the v3 equivalent of each call looks like.
When you’re done, reload the Appearance page. If the warning icon next to your template is gone, WP Store Locator no longer sees any v2 code in it and the template is running natively. Then open your store locator page to check it still shows. If it’s empty, look for a leftover return $output;.