diff --git a/CHANGELOG.md b/CHANGELOG.md
index e048a3f..10f2eab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased]
+## 0.8.0 (May 17, 2026)
+
+### Added
+- **Geolocation** field on the content plugin and site module — dropdown (Widget Default / On / Off) to enable or disable location-based search (the Near Me button and typed-location search). On the content plugin, can be overridden per shortcode via `geolocation="true"` / `geolocation="false"` (already supported). `widget_config` JSON `geolocation` key still wins over the admin setting.
+
## 0.7.0 (May 12, 2026)
### Added
diff --git a/packages/module/language/en-GB/mod_crumb.ini b/packages/module/language/en-GB/mod_crumb.ini
index 338e080..120ca2c 100644
--- a/packages/module/language/en-GB/mod_crumb.ini
+++ b/packages/module/language/en-GB/mod_crumb.ini
@@ -29,6 +29,12 @@ MOD_CRUMB_FIELD_CSS_TEMPLATE_NONE="— None —"
MOD_CRUMB_FIELD_CSS_TEMPLATE_FW="Full Width"
MOD_CRUMB_FIELD_CSS_TEMPLATE_FW_FORCE="Full Width (Force Viewport)"
+MOD_CRUMB_FIELD_GEOLOCATION_LABEL="Geolocation"
+MOD_CRUMB_FIELD_GEOLOCATION_DESC="Optional. Enable or disable location-based search (the Near Me button and typed-location search). Widget defaults to off for most servers, and on when the BMLT Server URL points at the unconstrained aggregator with no service body set. Ignored if geolocation is already set in Widget Configuration JSON."
+MOD_CRUMB_FIELD_GEOLOCATION_DEFAULT="— Widget Default —"
+MOD_CRUMB_FIELD_GEOLOCATION_ON="On"
+MOD_CRUMB_FIELD_GEOLOCATION_OFF="Off"
+
MOD_CRUMB_FIELD_GEOLOCATION_RADIUS_LABEL="Geolocation Radius"
MOD_CRUMB_FIELD_GEOLOCATION_RADIUS_DESC="Optional. Geolocation search radius. Positive integer = fixed radius in miles (or km per server settings). Negative integer = BMLT auto-radius (e.g. -50 finds ~50 nearby meetings). Leave empty to use the widget default (-50). Ignored if geolocationRadius is already set in Widget Configuration JSON."
diff --git a/packages/module/mod_crumb.xml b/packages/module/mod_crumb.xml
index 44a7b74..2e5bc72 100644
--- a/packages/module/mod_crumb.xml
+++ b/packages/module/mod_crumb.xml
@@ -7,7 +7,7 @@
GPL v2 or later
bmlt-enabled@googlegroups.com
https://github.com/bmlt-enabled/crumb-joomla
- 0.7.0
+ 0.8.0
MOD_CRUMB_XML_DESCRIPTION
BmltEnabled\Module\Crumb\Site
@@ -96,6 +96,17 @@
+
+
+
+
+
(string) $params->get('language', ''),
'css_template' => (string) $params->get('css_template', ''),
'base_path' => (string) $params->get('base_path', ''),
+ 'geolocation' => (string) $params->get('geolocation', ''),
'geolocation_radius' => (string) $params->get('geolocation_radius', ''),
'update_url' => (string) $params->get('update_url', ''),
'columns' => (string) $params->get('columns', ''),
@@ -113,6 +114,12 @@ public function render(array $settings): string
}
}
+ // Merge geolocation admin setting if not already set in widget_config JSON.
+ $geoSetting = (string) ($settings['geolocation'] ?? '');
+ if ($geoSetting !== '' && !isset($configArray['geolocation'])) {
+ $configArray['geolocation'] = ($geoSetting === '1');
+ }
+
// Merge geolocation_radius admin setting if not already set in widget_config JSON.
$geoRadiusSetting = (string) ($settings['geolocation_radius'] ?? '');
if ($geoRadiusSetting !== '' && !isset($configArray['geolocationRadius'])) {
diff --git a/packages/plugin/crumb.xml b/packages/plugin/crumb.xml
index 0874473..58cbedf 100644
--- a/packages/plugin/crumb.xml
+++ b/packages/plugin/crumb.xml
@@ -7,7 +7,7 @@
GPL v2 or later
bmlt-enabled@googlegroups.com
https://github.com/bmlt-enabled/crumb-joomla
- 0.7.0
+ 0.8.0
PLG_CONTENT_CRUMB_XML_DESCRIPTION
BmltEnabled\Plugin\Content\Crumb
@@ -95,6 +95,17 @@
+
+
+
+
+
(string) $this->params->get('language', ''),
'css_template' => (string) $this->params->get('css_template', ''),
'base_path' => (string) $this->params->get('base_path', ''),
+ 'geolocation' => (string) $this->params->get('geolocation', ''),
'geolocation_radius' => (string) $this->params->get('geolocation_radius', ''),
'update_url' => (string) $this->params->get('update_url', ''),
'columns' => (string) $this->params->get('columns', ''),
diff --git a/packages/plugin/src/Helper/CrumbRenderer.php b/packages/plugin/src/Helper/CrumbRenderer.php
index 19ae170..ed5f2ed 100644
--- a/packages/plugin/src/Helper/CrumbRenderer.php
+++ b/packages/plugin/src/Helper/CrumbRenderer.php
@@ -100,6 +100,14 @@ public static function render(array $settings, array $overrides = []): string
}
}
+ // Merge geolocation admin setting if not already set in widget_config JSON.
+ // Per-shortcode geolocation arg is handled above via data-geolocation, which the
+ // widget reads after CrumbWidgetConfig — so that override still wins.
+ $geoSetting = (string) ($settings['geolocation'] ?? '');
+ if ($geoSetting !== '' && !isset($configArray['geolocation'])) {
+ $configArray['geolocation'] = ($geoSetting === '1');
+ }
+
// Merge geolocation_radius admin setting if not already set in widget_config JSON.
$geoRadiusSetting = (string) ($settings['geolocation_radius'] ?? '');
if ($geoRadiusSetting !== '' && !isset($configArray['geolocationRadius'])) {
diff --git a/pkg_crumb.xml b/pkg_crumb.xml
index f7eb661..b97af55 100644
--- a/pkg_crumb.xml
+++ b/pkg_crumb.xml
@@ -8,7 +8,7 @@
bmlt-enabled@googlegroups.com
https://github.com/bmlt-enabled/crumb-joomla
crumb
- 0.7.0
+ 0.8.0
https://github.com/bmlt-enabled/crumb-joomla
bmlt-enabled
https://github.com/bmlt-enabled
diff --git a/tests/Unit/CrumbRendererTest.php b/tests/Unit/CrumbRendererTest.php
index 6ea5bf2..e4a6a66 100644
--- a/tests/Unit/CrumbRendererTest.php
+++ b/tests/Unit/CrumbRendererTest.php
@@ -276,6 +276,56 @@ public function testEmptyGeolocationRadiusProducesNoConfigScript(): void
$this->assertStringNotContainsString('CrumbWidgetConfig', $output);
}
+ public function testGeolocationSettingOnMergesIntoConfig(): void
+ {
+ $output = CrumbRenderer::render([
+ 'server' => 'https://x/main_server',
+ 'geolocation' => '1',
+ ]);
+ $this->assertStringContainsString('window.CrumbWidgetConfig', $output);
+ $this->assertStringContainsString('"geolocation":true', $output);
+ }
+
+ public function testGeolocationSettingOffMergesIntoConfig(): void
+ {
+ $output = CrumbRenderer::render([
+ 'server' => 'https://x/main_server',
+ 'geolocation' => '0',
+ ]);
+ $this->assertStringContainsString('"geolocation":false', $output);
+ }
+
+ public function testEmptyGeolocationSettingProducesNoConfigScript(): void
+ {
+ $output = CrumbRenderer::render([
+ 'server' => 'https://x/main_server',
+ 'geolocation' => '',
+ ]);
+ $this->assertStringNotContainsString('CrumbWidgetConfig', $output);
+ }
+
+ public function testWidgetConfigGeolocationTakesPrecedenceOverSetting(): void
+ {
+ $output = CrumbRenderer::render([
+ 'server' => 'https://x/main_server',
+ 'geolocation' => '0',
+ 'widget_config' => '{"geolocation":true}',
+ ]);
+ $this->assertStringContainsString('"geolocation":true', $output);
+ $this->assertStringNotContainsString('"geolocation":false', $output);
+ }
+
+ public function testShortcodeGeolocationOverrideEmitsDataAttribute(): void
+ {
+ // Per-shortcode geolocation override is emitted as data-geolocation, which the
+ // widget reads after CrumbWidgetConfig — so it overrides the admin setting.
+ $output = CrumbRenderer::render(
+ ['server' => 'https://x/main_server', 'geolocation' => '0'],
+ ['geolocation' => 'true']
+ );
+ $this->assertStringContainsString('data-geolocation="true"', $output);
+ }
+
public function testLanguageSettingMergesIntoConfig(): void
{
$output = CrumbRenderer::render([