Locations Plugin

*** Mapzen was removed as a supported provider on Wednesday, 10th Jan . See further. ***

Repo: https://github.com/angusmcleod/discourse-locations

This plugin allows you to associate locations with topics, and list topics with locations on a map.

You can see an example of it in action on my sandbox.

Maps are handled by Leaflet.js and multiple geocoding providers are supported. Both are customizable via admin settings as explained below in ‘Admin Settings’.


  • Locations can be turned on for specific categories by toggling ‘Allow locations to be added to topics in this category’ in the Category settings.

  • When locations are turned on a for a category:

    • The composer will include an ‘Add Location’ button when composing a new topic in that category.

      11 PM

      This opens a modal which allows the user to enter the location details, including a geocoded address:

    • ‘Map’ will be added to the category nav items. This will display a map in place of the topic list with topics that have geocoded locations associated with them marked on it. This list can be set as the default for the category in the category settings. When multiple topics are associated with the same location, they are grouped into expandable clusters (using the Marker Cluster plugin for Leaflet). Clicking on the markers navigates the user to the associated topic.

  • When a location is added to a topic:

    • The location details will appear underneath the topic title. If the location is geocoded a ‘Show Map’ button appears to the right of the location details. This button toggles a mini-map showing the location.

    • Locations can be edited in the ‘topic title’ edit controls.

  • The map controls available to users are:

    • Expand 01 PM. This will expand the map to take over the whole window aside from the Header bar.

    • Zoom 13 PM. These are standard leaflet zoom controls.

    • Attribution 12 PM. This toggles the visibility of the attribution.

Admin Settings:

  • location input fields enabled: toggles whether ‘Add Location’ modal displays specific location input fields or a single location query input

    51 PM
    10 PM

  • location input fields: sets what input fields are used if location input fields enabled is true

  • location geocoding:

    • none: User is required to enter either a name or an address when adding a location. Addresses are stored as a string.

    • optional: User is required to enter either a name or an address when adding a location. Addresses are geocoded and will display on any associated maps.

    • required: User is required to enter an address when adding a location. Addresses are geocoded and will display on any associated maps.

  • location geocoding provider: the service that translates user input into coordinates that can be displayed on a map. Geocoding is handled by the Geocoder gem, which supports a number of geocoding providers. Think of these providers like you would a transactional email provider. The list of providers available in this plugin is a sub-set of the list in the gem. The providers currently supported by this plugin are:

    Nominatim is the default, as it doesn’t require an api key, has no (relevant) restrictions in terms of use and is good for testing and light use. Each provider has strengths and weaknesses. I suggest you review each of them (e.g. check the Terms; test relevant addresses) if you’re serious about using this plugin.

    This sub-set of providers available through the Geocoder gem were chosen according to these criteria:

    • Ease of integration. The reason I didn’t include Google is because Google Maps is not designed to be used with Leaflet.js (or any other 3rd party software). I did get it working, however it requires multiple customizations specific to Google and the end result is not great, so I don’t want to support it considering there are a number of other more customizable providers that can do the job just as well. If for some reason you must use Google Maps with this plugin, it is possible, but you will need to handle and support the integration yourself.

    • Terms of Service. A number of the Geocoding providers only allow you to use their geocoding data in conjunction with their own maps. This is true of some of the providers this plugin does support. For example, you can’t use Mapbox data on non-Mapbox maps. For the providers that have this restriction I have only included those that make it relatively easy to use both their geocoding service and their mapping service with Leaflet.js, so the service can be used without breaching the provider’s terms.

    • Functionality. Some of the providers listed in the Geocoder gem docs no longer work.

  • location geocoding api key: When a geocoding provider requires an API key, enter it here before you switch to that service in the location geocoding provider setting. If you switch to a provider that requires a key before entering a key you will get an error.

  • location geocoding timeout: This sets the timeout for the Geocoder gem. It is unlikely you will need to change this.

  • location map tile layer: Aka the “basemap”. This is the actual map image on which locations are shown. There is a large variety of basemaps that can be used. Keep in mind that some Geocoding providers require you to use their basemaps when using their geocoding service. There’s a nice basemap showcase here.

  • location map tile layer subdomains: Relevant for some basemap providers. It is unlikely you will need to use this.

  • location map attribution: This string will appear when the ‘i’ button in the bottom right corner of the map is clicked. Please always give attribution to the providers you are using.


Thanks @angus for yet another amazing plugin!

I was wondering if any of these features are on your roadmap?

  • Automatically updating a user’s location on the map based on their last known IP address (obviously opt-in, and ideally only at a city level)
  • Which leads me to: an option to only show user’s location on a city level (could use this API for that: Teleport public APIs - Teleport Developer Program)
  • An option to only show the user map to logged in users. I think many of my users are unlikely to share their location completely publicly.

In my case (a community for nomads, frequent travelers, and remote workers), users’ locations are likely to change very often, and it’s unlikely that many will manually update their location every time they step on a plane, so some sort of automatically updating location would be very useful.

While I worked at Teleport we launched a product called Sundial which primarily is a way for remote teams to show their members on an interactive map (e.g. see GitLab’s team page).

That’s basically what I would love to provide to my community, to make it easier for people to meet up in real life when they happen to cross paths.

While my Ruby skills are quite limited (the most I ever did was this fork of the affiliate plugin), do let me know if there’s any way I can help or contribute to make any of these features easier to implement :slight_smile:


Hi @tkrunning :wave:t2:

We manage this through the use of a Discourse setting:

Not sure if that’s an ideal setting for you to use, but it will solve the concerns your users may have :+1:t2:

1 Like

@angus, I upgraded my discourse to 2.1.5 from 2.1.4 today and had issues that were resolved by removing my locations plugin.

This seems to be where the things went off the rails in the log:

Successfully installed geocoder-1.4.4
1 gem installed

I, [2018-12-17T19:25:21.677523 #13]  INFO -- : Terminating async processes
I, [2018-12-17T19:25:21.677661 #13]  INFO -- : Sending INT to HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/10/bin/postmaster -D /etc/postgresql/10/main pid: 69
2018-12-17 19:25:21.678 UTC [69] LOG:  received fast shutdown request
I, [2018-12-17T19:25:21.678000 #13]  INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 185
185:signal-handler (1545074721) Received SIGTERM scheduling shutdown...
2018-12-17 19:25:21.682 UTC [69] LOG:  aborting any active transactions
2018-12-17 19:25:21.685 UTC [69] LOG:  worker process: logical replication launcher (PID 78) exited with exit code 1
2018-12-17 19:25:21.688 UTC [73] LOG:  shutting down
185:M 17 Dec 19:25:21.689 # User requested shutdown...
185:M 17 Dec 19:25:21.689 * Saving the final RDB snapshot before exiting.
2018-12-17 19:25:21.712 UTC [69] LOG:  database system is shut down
185:M 17 Dec 19:25:21.893 * DB saved on disk
185:M 17 Dec 19:25:21.893 # Redis is now ready to exit, bye bye...

Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate' failed with return #<Process::Status: pid 13046 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"bundle_exec", "cmd"=>["su discourse -c 'bundle install --deployment --verbose --without test --without development --retry 3 --jobs 4'", "su discourse -c 'bundle exec rake db:migrate'", "su discourse -c 'bundle exec rake assets:precompile'"]}
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one

Any thoughts?

@Jeff_Vienneau hm, I’m not seeing a similar issue on my sandbox (I just tried rebuilding and it worked).

Can you:

  • Post a longer version of the log (hide it with the “details” functionality)
  • Confirm that you only removed the locations plugin to rectify the issue (i.e. did you do anything else? remove another plugin for instance?)

I removed each plugin one by one until it was just the locations plugin and then tried with and without it.

Not sure how to do this^^^

Edit: nevermind… You mean discourse details annotation.

Looking closer, it looks to be low memory in redis.

Tried to capture more but my “| tee to_file” did not work as expected.


Stopping old container
cd /pups && git pull && /pups/bin/pups --stdin
Already up-to-date.
.-__ ''-._ _.- . . ‘’-._ Redis 3.0.6 (00000000/0) 64 bit
.- .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.-.|’_.-'| Port: 6379 | -. ._ / _.-' | PID: 185 -._ -._ -./ .-’ .-’
-.__.-' _.-'_.-'| | -.
-._ _.-'_.-' | http://redis.io -._ -._-..-’.-’ .-’
-.__.-' _.-'_.-'| | -.
-._ _.-'_.-' | -._ -._-.
.-’_.-’ _.-’
-._ -..-’ _.-’
-._ _.-' -.

185:M 18 Dec 18:45:51.146 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
185:M 18 Dec 18:45:51.146 # Server started, Redis version 3.0.6
185:M 18 Dec 18:45:51.146 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add ‘vm.overcommit_memory = 1’ to /etc/sysctl.conf and then reboot or run the command ‘sysctl vm.overcommit_memory=1’ for this to take effect.
185:M 18 Dec 18:45:51.146 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command ‘echo never > /sys/kernel/mm/transparent_hugepage/enabled’ as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
185:M 18 Dec 18:45:51.301 * DB loaded from disk: 0.155 seconds
185:M 18 Dec 18:45:51.301 * The server is now ready to accept connections on port 6379
228:M 18 Dec 18:46:01.439 # Creating Server TCP listening socket *:6379: bind: Address already in use
185:signal-handler (1545158905) Received SIGTERM scheduling shutdown…
185:M 18 Dec 18:48:25.983 # User requested shutdown…
185:M 18 Dec 18:48:25.983 * Saving the final RDB snapshot before exiting.
185:M 18 Dec 18:48:26.180 * DB saved on disk
185:M 18 Dec 18:48:26.181 # Redis is now ready to exit, bye bye…


Pups::ExecError: cd /var/www/discourse && su discourse -c ‘bundle exec rake db:migrate’ failed with return #<Process::Status: pid 13087 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn’
exec failed with the params {“cd”=>"$home", “hook”=>“bundle_exec”, “cmd”=>[“su discourse -c ‘bundle install --deployment --verbose --without test --without development --retry 3 --jobs 4’”, “su discourse -c ‘bundle exec rake db:migrate’”, “su discourse -c ‘bundle exec rake assets:precompile’”]}
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one

My server has 3GB ram and is running at 59% utilized.

I really like this plugin, the ability to see topics by location is pretty useful. We’re looking for ways for our community members to connect with each other in their locale. Actually the community is looking for it…

Is it possible to integrate the location at the user profile level?

Find users near you
Allow users to set a default location for their posts

1 Like

@angus Happy New Year mate :smiley:

Can I throw another feature request in to the mix?

Any chance we could add User Map in to this ‘Top Menu’ list? :thinking:

As you know, we love the User Map more than anything - this would be a great addition :+1:t2:

same here, upgrade and rebuild failed. @angus

I tried it on a brand new instance and tried this as the first plugin.

looks like it is broken in the latest version

1 Like

Thanks, I’ll fix it tomorrow.

1 Like

@Jeff_Vienneau @Tommy_Trojan Guys, I just rebuilt discourse.angusmcleod.com.au which has the locations plugin (and most of my other plugins) running on a $5 DO droplet. It rebuilt fine with the latest version of Discourse and this plugin. Could you double check everything is up to date?

1 Like

Hi Angus, It works now. Thank you. I upgrade from V2.2.0.beta7 +49 to +76, then rebuild first time, it gives the same error message, after a second rebuild, it works. Interesting, but great it works again.


We just went from v2.2.0.beta6 +5 to v2.2.0.beta7 +83

No issues to report :+1:t2:


Thanks for much for this plugin. It works nicely.

1 Like

This plugin is not available in hosted instances, is that correct?

If you mean discourse.org hosted instances, I think it’d only be possible if you were an enterprise customer. But you’d have to check with the Discourse team.

In the category “Map”

Why I can see some locations pointed by some posts, while some other locations are not marked on the map?

Some are there, some are not.

Anyone having issues with the Locations plugin on Discourse 2.2.0beta9+51 ?

We’re getting no suggestions:


Also unable to Save any profile changes :scream: