Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable search box geocoder provider selection #14622

Merged
merged 20 commits into from
Jan 24, 2019

Conversation

jesusbotella
Copy link
Contributor

This PR enables geocoder configuration for Builder's search box by configuring it in app_config.yml.

The way it was working until now didn't allow to configure the geocoding provider even if we were injecting API Keys of each provider into HTML templates.

I researched this matter deeply and the more straightforward way to do it is injecting the geocoding configuration properties to search overlay's configuration held in vizjson. But as we're caching them and we might not want to update them all or just not exposing those variables in vizjson for safety reasons I had to look for another way to do it.

So, I added a new property to app_config.yml named provider inside geocoder configuration that will hold the string of the selected geocoding provider.

From now on, when rendering Builder, Datasets or Embeds page templates, there will be new injected variable named geocoderConfiguration that replicates app_config.yml to be used by CARTO.js to configure search box geocoder.

CARTO.js will read that configuration and configure geocoding for search box. This code is modified in this CARTO.js PR.

I took the opportunity to remove injected useless variables like mapzenApiKey, mapboxApiKey and tomtomApiKey because they were not used anymore as we changed the way we configure geocoder in CARTO.js' search box.

Related to CartoDB/carto.js#2223.

@jesusbotella
Copy link
Contributor Author

@javitonino @ivanmalagon Let me know what you think of this approach! :)

Copy link
Contributor

@javitonino javitonino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good approach. Some comments:

  • This requires platform config changes
  • When we deploy this, we must not forget to tick the invalidate public pages checkbox.

@@ -201,6 +201,7 @@ defaults: &defaults
geocoder:
#force_batch: true
#disable_cache: true
provider: ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename to something more explicit like search_bar_provider or similar.


def tomtom_api_key
Cartodb.get_config(:geocoder, 'tomtom', 'search_bar_api_key')
geocoder_config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above code is equivalent to:

geocoder_config = {
  provider: Cartodb.get_config(:geocoder, 'provider'),
  mapbox: Cartodb.config[:geocoder]['mapbox'],
  tomtom: Cartodb.config[:geocoder]['tomtom']
}

assuming you don't care that missing parameters are marked as null. e.g, where current code would return {}, mine returns { provider: null, mapbox: null, tomtom: null }.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be perfectly fine! Just one question, why do you use Cartodb.get_config in first place and then Cartodb.config? Is there any major difference?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to use get_config for everything. The main difference is that if the string is blank (e.g: mapbox: ''), then config returns '' and get_config returns null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed this a bit to avoid injecting unneeded parameters

Copy link
Contributor

@javitonino javitonino Jan 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this idea, maybe too complicated:

    GEOCODER_PROVIDERS = ['tomtom', 'mapbox', 'mapzen'].freeze

    def geocoder_config
      configured_providers = GEOCODER_PROVIDERS.select { |p| Cartodb.get_config(:geocoder, p, 'search_bar_api_key') }

      selected_provider = Cartodb.get_config(:geocoder, 'search_bar_provider')
      selected_provider = configured_providers.first unless configured_providers.include?(selected_provider)

      provider_configuration = Cartodb.get_config(:geocoder, selected_provider)

      {
        :provider => selected_provider,
        selected_provider => provider_configuration
      }
    end

It:

  1. List all configured providers
  2. Try to use the configured one
  3. If not, use the first in the array (priority system)

This should work in all cases, but we should write some tests, since the behaviour starts to get complicated :/.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not, we can revert to your previous version of listing all keys. It's simpler although it has the problem you mentioned (exposing too much) which I don't think it's a big problem, but it's certainly ugly.

Copy link
Contributor Author

@jesusbotella jesusbotella Jan 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, maybe the flow above is too complicated for this :/

The previous version was good. I didn't discard it because its ugliness but for "security" and to optimize the rendered HTML, but if it's not a big deal for you I am not going to say so 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reverted the change that I did. So now it is back as it was before :)

@jesusbotella
Copy link
Contributor Author

I assume that the platform changes would be because of the new app_config.yml property. It would be good to add the property to our production/development configurations but we covered that case by adding a default provider that is tomtom.

I would take care of the deploy so I'll write that down so I don't forget to tick the checkbox! :)

def tomtom_api_key
Cartodb.get_config(:geocoder, 'tomtom', 'search_bar_api_key')
def geocoder_config
geocoder_config = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useless assignment to variable - geocoder_config.


if provider_configuration.present?
geocoder_config[provider] = Cartodb.config[:geocoder][provider]
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change breaks backwards compatibility. If a user does not update his configuration file, the search bar will break. We try to really minimize them, so we should make this to keep working if the geocoder -> provider option is not specified.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I thought about it too. I thought this change wouldn't break anything. So, what would be the best way to handle it without breaking compatibility for a rails noob like me? 😂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can just use a default value: Cartodb.get_config(:geocoder, 'search_bar_provider') || 'tomtom' (for example)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the old code so no need to do this anymore

@alrocar alrocar self-assigned this Jan 24, 2019
Cartodb.get_config(:geocoder, 'tomtom', 'search_bar_api_key')
def geocoder_config
{
provider: Cartodb.get_config(:geocoder, 'provider'),
Copy link
Contributor

@alrocar alrocar Jan 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After your last commit this should be search_bar_provider to match the app_config.yml.sample.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woah! Yes, that's wrong!

var dashboardNotifications = <%= safe_js_object @dashboard_notifications.to_json %>;
var ACTIVE_LOCALE = 'en';
var geocoderConfiguration = <%= safe_js_object geocoder_config.to_json %>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question, where is this being used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is being used in CARTO.js through Builder, you can see the code here: https://github.com/CartoDB/carto.js/pull/2224/files#diff-7ead12936599aa5b9c6b5340db29cf33R214

@@ -69,16 +69,12 @@ def saas?
Cartodb.config[:cartodb_com_hosted] == false
end

def mapzen_api_key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like we are getting rid of mapzen api key, should we remove it from app_config.yml.sample as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, yes, I think we should now


if provider_configuration.present?
geocoder_config[provider] = Cartodb.config[:geocoder][provider]
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can just use a default value: Cartodb.get_config(:geocoder, 'search_bar_provider') || 'tomtom' (for example)

Copy link
Contributor

@alrocar alrocar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of questions and something you missed :)

@alrocar alrocar assigned jesusbotella and unassigned alrocar Jan 24, 2019
Copy link
Contributor

@alrocar alrocar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@jesusbotella jesusbotella merged commit 06f053f into master Jan 24, 2019
@jesusbotella jesusbotella deleted the 2223-search-box-provider branch January 24, 2019 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants