merefield
(Robert)
January 31, 2026, 7:06pm
1213
If you are paying, yes
This is an independent plugin, support is not free and I do not provide any guarantees - you use it at your own risk.
I could have easily not shared that at all, anywhere.
Link to support options.
4 Likes
merefield
(Robert)
January 31, 2026, 9:04pm
1214
This is now merged, thanks again to the sponsors @祁同伟 and @nathank
main ← automated_ip_based_user_location_determination
merged 09:02PM - 31 Jan 26 UTC
## IP‑based User Location (MaxMind → GeoNames)
### What this adds
- Auto… matically determines a user’s location from their IP after post creation.
- Uses **MaxMind (DiscourseIpInfo)** for identity + GeoNames for canonical lat/lon.
- Stores exactly **one granularity level** per user (`country` / `province` / `city`) in `UserCustomField`
`geo_location`.
- Ensures lat/lon match the chosen granularity (privacy‑correct coordinates).
- Caches GeoNames lookups by `geoname_id` (no extra gems; uses `FinalDestination::HTTP`).
---
## Prerequisites (official accounts)
You must have valid accounts and credentials from:
- **MaxMind GeoLite2**
Sign up and obtain an Account ID + License Key:
https://www.maxmind.com/en/geolite2/signup
- **GeoNames**
Create a username for the GeoNames API and **enable Web Services** in your GeoNames account settings:
https://www.geonames.org/login
---
## Required Configuration
**Env vars (MaxMind) for `app.yml`**
- `DISCOURSE_MAXMIND_ACCOUNT_ID`
- `DISCOURSE_MAXMIND_LICENSE_KEY`
**Site settings**
- `location_geonames_username` (GeoNames username)
**Dev note (MaxMind DBs)**
- In development, ensure the MaxMind DBs are downloaded:
DISCOURSE_MAXMIND_ACCOUNT_ID=... DISCOURSE_MAXMIND_LICENSE_KEY=... bundle exec rake maxminddb:get
Restart web/sidekiq afterward so `DiscourseIpInfo` reloads the DBs.
---
## Settings
| Setting | Default | Description |
|---|---:|---|
| `location_ip_granularity` | `city` | Controls stored level: `country`, `province` (admin1), `county` (admin2), or `city`. |
| `location_geonames_username` | `""` | GeoNames username for `getJSON` requests. Acts as a feature flag (blank => skip). |
| `location_ip_lookup_cooldown_days` | `1` | Per‑user cooldown between IP lookups (0 disables cooldown). |
| `locations_skip_ip_based_location_update_if_existing` | `true` | Skip IP lookup when existing `geo_location` already has **lat + lon**. |
| `location_ip_auto_lookup_enabled` | `false` | Auto‑enqueue IP lookups on post creation. Rake task still works when off. |
---
## Flow
- `post_created` → enqueue `Jobs::Locations::IpLocationLookup` with user ID + IP.
- Job:
- Guards: plugin enabled, users map enabled, GeoNames username present, MaxMind env vars present, cooldown
OK, and optional “existing location” check.
- Uses `DiscourseIpInfo.get(ip)` to get `geoname_ids`.
- Resolves GeoNames IDs, picks feature by granularity (`country` / `province` / `county` / `city`), builds
`geo_location`.
- Saves `geo_location` to user custom field + updates `locations_user` table.
---
## Job + Hook
**Hook**
- `post_created` now enqueues `Jobs::Locations::IpLocationLookup`
- In development, IP is overridden to a fixed test IP (`2.139.231.7`) to ensure resolvable data.
**Job**
- `Jobs::Locations::IpLocationLookup` (new, in `app/jobs/regular/locations/ip_location_lookup.rb`)
- Logs key steps, skips when prerequisites are missing.
- Writes `geo_location` only when successfully built.
---
## GeoNames Helpers
New modules in `lib/locations/`:
- `GeoNamesClient`
- Calls `https://secure.geonames.org/getJSON` via `FinalDestination::HTTP`.
- Normalizes `geoname_id`, `fcl`, `fcode`, `lat`, `lon`, etc.
- Caches only successful lookups (avoids caching nil).
- `GeoNamesGranularityPicker`
- Selects best `PCLI` / `ADM1` / `PPL*` by desired granularity.
- `GeoLocationBuilder`
- Builds `geo_location` hash with correct `lat/lon`, `state`/`city` based on granularity.
---
## Rake Task
New rake task in `lib/tasks/locations.rake`:
**Task**
rake locations:enqueue_user_ip_location_lookups[username_pattern,pattern_type,delay]
**Behavior**
- Iterates users and enqueues the IP lookup job using `user.ip_address`.
- Progress is based on **matched population** (not total users).
- Skips enqueue when IP is blank.
**Options**
- `username_pattern` (optional): filter users by username.
- `pattern_type`: `string` (default substring match) or `regex`.
- `delay`: seconds between enqueues (float, default `0`).
**Help**
rake locations:enqueue_user_ip_location_lookups:help
Extensive details on the PR.
@Roi I note you are not paying for support - however I believe I may have improved the code in this PR, please try that script I published again. If you need me to take a closer look, you can hire me.
5 Likes
Roi
January 31, 2026, 10:11pm
1215
@merefield not yet.
I just checked, the bad entry stayed with the new version as well.
But as it only was one user, I checked manually and he had a city in the “normal” location field and I recreated the location field with this information. Now the query is empty.
2 Likes
Quacken
February 1, 2026, 3:10pm
1216
Hey, I posted a bug report elsewhere and got redirected to repost it in this topic.
Turns out if you enable locations for a category and set the default view for the category to the Map navigating to that category results in a crash.
Here are some screenshots (pardon the localization, the words mean “Appearance: Default topic list: Hot, Latest, Top, Map):
Seems the plugin accesses siteSettings assuming it is defined when it isn’t
Original bug report:
Support
Discourse Locations
Environment Discourse Version: v2026.2.0-latest +15 Plugin Commit: c1547ead Steps to Reproduce When using Locations plugin if I check Allow locations to be added to topics in this category and then try to set the map tab as the default view for...
Reading time: 1 mins 🕑
Likes: 1 ❤
1 Like
merefield
(Robert)
February 1, 2026, 3:25pm
1217
thanks, if this is important enough for you, you can hire me to fix it. PR welcome.
1 Like
祁同伟
February 9, 2026, 10:52am
1218
How do I hide location info from topic rows in the topic list?
gilles
February 24, 2026, 6:50pm
1221
I have a display issue since the Discourse update.
I am on version 2026.2.0 latest
Here is what I have
Maybe there is a way to fix it with CSS
Thanks
1 Like
Canapin
(Coin-coin le Canapin)
February 25, 2026, 6:46pm
1223
I had a look out of curiosity. Seems that the locations are inside a button, which CSS has changed in the modern foundation theme and constrains the content.
There may be a future incompatibility between locations and this theme, but the latter is still experimental, so we need to wait for the official release and see how it goes
4 Likes
merefield
(Robert)
February 26, 2026, 2:29pm
1224
Maintenance release:
main ← maintenance_release
merged 11:09PM - 25 Feb 26 UTC
## New Features
- Added a new enum setting: location_ip_auto_lookup_mode wi… th options:
- disabled
- posting
- login_and_posting
- Wired automatic IP-based location lookup into login flow (on(:user_logged_in)) when mode is login_and_posting.
- Added helper methods in plugin.rb to centralize IP auto-lookup mode/eligibility checks and enqueue behavior.
## Fixes
- Fixed composer default location initialization so user geo location is correctly prefilled when location_topic_default = user.
- Fixed category default-map rendering regression:
- category routes now render the map template safely when filter resolves to map
- avoids blank page / broken SPA behavior when category default view is map
- Fixed category map data loading by passing category context into the map template/component.
- Fixed map fallback fetch path to absolute /map.json to avoid route-relative request issues.
- Standardized users map route to users-map and removed legacy users_map usage paths.
## Configuration
- Introduced location_ip_auto_lookup_mode in config/settings.yml.
- Bumped plugin version to 7.1.6.
- Synced plugin JS devDependencies/config with core lint/tooling expectations.
## Code Formatting
- Migrated/modernized frontend code to satisfy current core lint rules:
- import path updates (discourse-i18n, moved package paths, etc.)
- removed deprecated patterns and jQuery usage
- template strict-mode migrations where required
- formatter/lint compliance cleanup across JS/GJS/HBS
- Updated prettier handling for vendored Leaflet assets to keep CI formatting checks clean.
## New Tests
- Added system spec: spec/system/composer_default_location_spec.rb
Validates composer initializes location from user location under the "user" default setting.
- Added system spec: spec/system/category_default_map_view_spec.rb
Validates category default map view renders map container without route error.
- Added request spec: spec/requests/users_map_controller_spec.rb
Covers canonical /locations/users-map route behavior.
- Extended request coverage for IP lookup posting/login mode behavior.
- Updated QUnit acceptance tests to assert intended behavior with stricter assertions and stable selectors.
followed by fixes:
main ← copilot/fix-35533304-102999061-d25577a9-2d35-4b64-9e45-583c49295ad7
merged 02:05PM - 26 Feb 26 UTC
- [x] Analyze root cause: missing `.replace-location` CSS wrapper in both user c… ard connector and profile component templates
- [x] Fix `components/replace-location.gjs`: add `.replace-location` wrapper and update `showUserLocation` to use `model.geo_location`
- [x] Fix `connectors/user-card-location-and-website/replace-location.gjs`: add `.replace-location` wrapper
- [x] Add system tests for profile geo location visibility, native location hiding, website display, and user card location display
- [x] Bump patch version to 7.1.7
- [x] Fix CI: use `fab!(:user_with_location, :user)` shorthand (Rubocop Discourse/FabricatorShorthand)
- [x] Fix failing system test: replace fragile CSS-visibility check with content-based check
- [x] Fix test setup error: use `user_profile.update!(location: ...)` instead of `user.update!(location: ...)` — location is on UserProfile not User
- [x] Align user card and profile system tests: add "hides native location" and "shows website" scenarios to user card describe block, matching the full scope of the profile tests (selector differences only reflect the different component markup)
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>Locations are not showing on profile and user card</issue_title>
> <issue_description>Since merefield/discourse-locations#155 locations are not showing on user card and profile page like they did before.
>
> The code should be hiding core location profile information but showing website.
>
> In the old code this was handled well, but seems have been lost during maintenance work.
>
> Check code prior to merefield/discourse-locations#155 to confirm how it should work.
>
> We should add system tests to ensure visibility of geo location and that we are hiding standard profile location field whilst exposing website from profile if any. </issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
- Fixes merefield/discourse-locations#156
---
✨ Let Copilot coding agent [set things up for you](https://github.com/merefield/discourse-locations/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
main ← fix_review_followup
merged 03:09PM - 26 Feb 26 UTC
- Strengthened the user-card system spec to assert rendered location label text … (city), not just element presence.
- Added the required blank line after the magic comment in the location visibility spec for RuboCop compliance.
- Strengthened the profile-page system spec to assert formatted location text (city, country) in the visible label.
- Hardened profile website links to always include noopener noreferrer with target="_blank" while preserving nofollow/ugc behavior logic.
- Bumped the plugin version in plugin.rb from 7.1.7 to 7.1.8.
Highlights include:
you can now update people’s location automatically upon login (not just when they post) (@祁同伟 )
controlled by new setting DEFAULT OFF - so if you use this feature, set your preference now or Locations will stop updating users locations completely - necessary as style of setting was changed to accommodate the new feature.
Map can now once again be selected as default view for a Category (via Category Settings) (@Quacken )
Topic default location from user location works again. (@祁同伟 )
Plus a thousand modernisations to latest linting rules.
9 Likes
pomodoren
(pomodoren)
February 26, 2026, 4:13pm
1225
Is there any chance that we can have user-location page per group specifically?
So practically I can provide a list of group names, and for each of them, create a user map. In our use-case for example we were thinking to map users, NGOs, and/or Companies separately.
I mean, one can always put ‘ngo_’ in front of the name/username and filter by that, but thats not really nice
4 Likes
merefield
(Robert)
February 26, 2026, 6:57pm
1226
If you’d like to provide some nominal sponsorship, sure I’d back that - DM me if you have budget.
6 Likes
merefield
(Robert)
February 27, 2026, 11:54am
1227
Ok, going to make this a crowd funding effort
If I see an increase from current recurring monthly sponsorship from the community by at least $37 (I’m currently sponsored $43 a month by my existing kind sponsors) I will add the following:
User Map improvements:
group filter on map
For logged in users only, group list at least visible by all logged in users
ability to link to map for specific user group (same limit on choice of groups)
filter for number of max users shown (prioritising last seen) - performance win for user map if you have a lot of users who don’t visit anymore and prefer just active users.
apply default map view settings that currently applies only to topic map - so it always shows your area of interest.
One more monthly business sponsorship (>=$40) would clinch it straight away (SILVER tier)
I will also accept a one-time sponsorship from an individual for $150
Sponsor me here:
https://github.com/sponsors/merefield
Note the rewards for higher levels.
4 Likes