rails_google_map 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c730ca865297fdd78afc25746eccf4de2b97b89b61ccf664387675da6239092
4
- data.tar.gz: bfae7aa4b5883c2599ff1850b6b7a77369b7e38e0bd22927070edce3bd9c96f5
3
+ metadata.gz: 7526211ca0c5217b5f39c2e9724760e2c2dfaf639b60c216b622b9bc63beee0d
4
+ data.tar.gz: 85b6fc8fd7ccafb91636bae05abe1440a4d039eb93c8ea3a50e2afabd73a17da
5
5
  SHA512:
6
- metadata.gz: 2f36c8ece99a43f71e0797bb46310341dc0e4c715bee3b94d95e691d74d6b31b8f6fe7e4f4c7c0acece0ab694eaa5d091a0797c0c884dbbca19fd03190861eae
7
- data.tar.gz: 7e7c3d47db516653be733426afe6177e0cac2299f644b2bcf6f680f676d604247f99767a2979327ed6672f4a3893a112fa06750897d86a569c32de9a3394e514
6
+ metadata.gz: '0666917b75276658ab3e8d51b730094a7322ffdb84808ac3c6a2a95b24808f862870ce00bf6de0d2bcd34d18b3f822b60d25c94920273e229f1ed38ec2fd7dcf'
7
+ data.tar.gz: fff3ba9831489b023f4c39f662faf76414a465f747745185d6424446fe625eaf4832ca646f399b2646e9b1d12d8e015f650fb936a9b845ddff1f59ebc586e253
data/CHANGELOG.md CHANGED
@@ -12,6 +12,13 @@
12
12
  so a map renders without a key or a billing account.
13
13
  - `RailsGoogleMap::Geocoder.coordinates_for` turns an address into coordinates
14
14
  via the Google Geocoding API.
15
+ - `render_google_map` renders the map through an overridable partial, wrapper
16
+ div and all, and passes unrecognised options to it as extra locals.
17
+ - `rails generate rails_google_map:views [--format slim|erb]` copies that partial
18
+ into the host app, where it takes precedence over the engine's.
19
+ - `google_map_for` takes a `wrapper:` option (`true`, a CSS class, or a Hash of
20
+ attributes) for the same surrounding div without a template.
21
+ - Configurable `wrapper_class`, `map_class` and `partial`.
15
22
  - Rails engine mixes the helpers into ActionView automatically.
16
23
  - Supports Ruby >= 2.5.1 and Rails (ActionView) 5.0 through 8.x.
17
24
  - Requires "logger" before ActionView, so Rails 5 and 6 still load against
data/README.md CHANGED
@@ -13,6 +13,14 @@ for a staging box, a side project, or a page that just needs to show where you a
13
13
  <%= google_map_for("Thamel, Kathmandu") %>
14
14
  ```
15
15
 
16
+ Three ways in, depending on how much of the markup you want to own:
17
+
18
+ | | |
19
+ | --- | --- |
20
+ | `google_map_embed_url(query)` | just the URL — build your own markup |
21
+ | `google_map_for(query, ...)` | an `<iframe>` tag, optionally wrapped in a div |
22
+ | `render_google_map(query, ...)` | a partial you can copy into your app as ERB or Slim and edit |
23
+
16
24
  ## Installation
17
25
 
18
26
  Add it to your Gemfile:
@@ -63,6 +71,11 @@ RailsGoogleMap.configure do |config|
63
71
  config.width = "100%" # default iframe width
64
72
  config.height = "450" # default iframe height
65
73
  config.language = nil # e.g. "en", "ne" — omitted when nil
74
+
75
+ # used by render_google_map and the partial
76
+ config.wrapper_class = "google-map" # class on the surrounding div
77
+ config.map_class = nil # class on the iframe
78
+ config.partial = "rails_google_map/map"
66
79
  end
67
80
  ```
68
81
 
@@ -105,10 +118,20 @@ Recognised options:
105
118
  | `language` | `nil` | Embed API only |
106
119
  | `api_key` | configured key | override the key for one call |
107
120
  | `lat` / `lng` | — | used when no address is given |
121
+ | `wrapper` | `nil` | `true` for the configured wrapper class, a CSS class, or a Hash of div attributes |
108
122
 
109
123
  Any other option is passed straight through as an iframe attribute (`class`,
110
124
  `title`, `data`, …).
111
125
 
126
+ By default it returns a bare `<iframe>`. Pass `wrapper:` to get the surrounding
127
+ div without reaching for the partial:
128
+
129
+ ```erb
130
+ <%= google_map_for("Thamel", wrapper: true) %>
131
+ <%= google_map_for("Thamel", wrapper: "map-box", class: "partners-map") %>
132
+ <%= google_map_for("Thamel", wrapper: { class: "map-box", data: { controller: "map" } }) %>
133
+ ```
134
+
112
135
  `google_map_for` returns `nil` when there is nothing to show — a blank address, or
113
136
  coordinates that are missing or `0,0`. So a caller can guard on it:
114
137
 
@@ -127,6 +150,72 @@ The same thing with a plain options hash, if that reads better at the call site:
127
150
  <%= embed_google_map(lat: 27.7172, long: 85.3240) %>
128
151
  ```
129
152
 
153
+ ### `render_google_map` — the full markup, from a partial you can edit
154
+
155
+ `google_map_for` builds its tag in Ruby, so the markup is fixed. When you want to
156
+ own the markup, `render_google_map` renders a partial instead — wrapper div and
157
+ all:
158
+
159
+ ```slim
160
+ = render_google_map(@business.map_query, title: t("partners.map_of", name: @business.name), map_class: "partners-map")
161
+ ```
162
+
163
+ ```erb
164
+ <%= render_google_map(@business.map_query, title: t("partners.map_of", name: @business.name), map_class: "partners-map") %>
165
+ ```
166
+
167
+ Both produce:
168
+
169
+ ```html
170
+ <div class="google-map">
171
+ <iframe src="https://www.google.com/maps/embed?origin=mfe&amp;pb=!1m2!2m1!1sThamel%2C+Kathmandu"
172
+ class="partners-map" title="Map of Thamel" width="100%" height="450"
173
+ style="border:0;" loading="lazy"
174
+ referrerpolicy="no-referrer-when-downgrade"
175
+ allowfullscreen frameborder="0"></iframe>
176
+ </div>
177
+ ```
178
+
179
+ Like `google_map_for`, it returns `nil` when there is nothing to map, so the
180
+ surrounding `if` is optional.
181
+
182
+ Options: `title`, `wrapper_class`, `map_class`, `width`, `height`, plus the URL
183
+ options (`zoom`, `map_type`, `language`, `api_key`) and `lat`/`lng`. Anything else
184
+ is handed to the partial as an extra local, which is how a partial of your own
185
+ receives its data:
186
+
187
+ ```erb
188
+ <%= render_google_map(@business.address, partial: "maps/card", label: "Find us") %>
189
+ ```
190
+
191
+ #### Editing the markup
192
+
193
+ The gem ships the partial as ERB, which renders fine in a Slim app — Rails picks
194
+ the handler per template. To change the markup, copy it into your app:
195
+
196
+ ```bash
197
+ rails generate rails_google_map:views # app/views/rails_google_map/_map.html.erb
198
+ rails generate rails_google_map:views --format slim # app/views/rails_google_map/_map.html.slim
199
+ ```
200
+
201
+ App view paths win over an engine's, so the copy takes over with no further
202
+ configuration. The Slim copy is the markup you probably came here for:
203
+
204
+ ```slim
205
+ - if url.present?
206
+ div class=wrapper_class
207
+ iframe src=url class=map_class title=title width=width height=height style="border:0;" loading="lazy" referrerpolicy="no-referrer-when-downgrade" allowfullscreen=true frameborder="0"
208
+ ```
209
+
210
+ Or point at a partial of your own and leave the gem's alone:
211
+
212
+ ```ruby
213
+ RailsGoogleMap.configure { |config| config.partial = "shared/google_map" }
214
+ ```
215
+
216
+ Your partial receives `url`, `title`, `wrapper_class`, `map_class`, `width` and
217
+ `height` as locals.
218
+
130
219
  ### `google_map_embed_url`
131
220
 
132
221
  Returns just the URL, for when you want to write the markup yourself:
@@ -158,7 +247,8 @@ API call fails.
158
247
 
159
248
  ### Outside Rails
160
249
 
161
- There's no dependency on a booted Rails app — include the helper anywhere:
250
+ `google_map_embed_url` and `google_map_for` need no booted Rails app — include the
251
+ helper anywhere. (`render_google_map` does need one, since it renders a template.)
162
252
 
163
253
  ```ruby
164
254
  require "rails_google_map"
@@ -0,0 +1,42 @@
1
+ <%#
2
+ Renders one embedded Google Map.
3
+
4
+ Locals -- #render_google_map passes all of them, and each falls back to a
5
+ configured default, so the partial also works when rendered directly:
6
+
7
+ url the embed URL, from google_map_embed_url (required)
8
+ title iframe title, read out by screen readers
9
+ wrapper_class CSS class for the surrounding div
10
+ map_class CSS class for the iframe; attribute omitted when blank
11
+ width, height iframe dimensions
12
+
13
+ To change this markup, copy it into your own app and edit it there:
14
+ rails generate rails_google_map:views # ERB
15
+ rails generate rails_google_map:views --format slim # Slim
16
+
17
+ content_tag drops attributes whose value is nil, which is how title and class
18
+ disappear when unset, and it escapes every value for us.
19
+ %>
20
+ <%
21
+ url = local_assigns[:url]
22
+ title = local_assigns[:title]
23
+ wrapper_class = local_assigns.fetch(:wrapper_class) { RailsGoogleMap.configuration.wrapper_class }
24
+ map_class = local_assigns.fetch(:map_class) { RailsGoogleMap.configuration.map_class }
25
+ width = local_assigns.fetch(:width) { RailsGoogleMap.configuration.width }
26
+ height = local_assigns.fetch(:height) { RailsGoogleMap.configuration.height }
27
+ %>
28
+ <% if url.present? %>
29
+ <div class="<%= wrapper_class %>">
30
+ <%= content_tag :iframe, "",
31
+ src: url,
32
+ class: map_class.presence,
33
+ title: title.presence,
34
+ width: width,
35
+ height: height,
36
+ style: "border:0;",
37
+ loading: "lazy",
38
+ referrerpolicy: "no-referrer-when-downgrade",
39
+ allowfullscreen: true,
40
+ frameborder: "0" %>
41
+ </div>
42
+ <% end %>
@@ -0,0 +1,42 @@
1
+ <%#
2
+ Renders one embedded Google Map.
3
+
4
+ Locals -- #render_google_map passes all of them, and each falls back to a
5
+ configured default, so the partial also works when rendered directly:
6
+
7
+ url the embed URL, from google_map_embed_url (required)
8
+ title iframe title, read out by screen readers
9
+ wrapper_class CSS class for the surrounding div
10
+ map_class CSS class for the iframe; attribute omitted when blank
11
+ width, height iframe dimensions
12
+
13
+ To change this markup, copy it into your own app and edit it there:
14
+ rails generate rails_google_map:views # ERB
15
+ rails generate rails_google_map:views --format slim # Slim
16
+
17
+ content_tag drops attributes whose value is nil, which is how title and class
18
+ disappear when unset, and it escapes every value for us.
19
+ %>
20
+ <%
21
+ url = local_assigns[:url]
22
+ title = local_assigns[:title]
23
+ wrapper_class = local_assigns.fetch(:wrapper_class) { RailsGoogleMap.configuration.wrapper_class }
24
+ map_class = local_assigns.fetch(:map_class) { RailsGoogleMap.configuration.map_class }
25
+ width = local_assigns.fetch(:width) { RailsGoogleMap.configuration.width }
26
+ height = local_assigns.fetch(:height) { RailsGoogleMap.configuration.height }
27
+ %>
28
+ <% if url.present? %>
29
+ <div class="<%= wrapper_class %>">
30
+ <%= content_tag :iframe, "",
31
+ src: url,
32
+ class: map_class.presence,
33
+ title: title.presence,
34
+ width: width,
35
+ height: height,
36
+ style: "border:0;",
37
+ loading: "lazy",
38
+ referrerpolicy: "no-referrer-when-downgrade",
39
+ allowfullscreen: true,
40
+ frameborder: "0" %>
41
+ </div>
42
+ <% end %>
@@ -0,0 +1,19 @@
1
+ / Renders one embedded Google Map.
2
+ Locals -- #render_google_map passes all of them; each has a sensible default
3
+ so the partial also works when rendered directly:
4
+ url the embed URL, from google_map_embed_url (required)
5
+ title iframe title, read out by screen readers
6
+ wrapper_class CSS class for the surrounding div
7
+ map_class CSS class for the iframe; omitted when blank
8
+ width, height iframe dimensions
9
+
10
+ - url = local_assigns[:url]
11
+ - title = local_assigns[:title]
12
+ - wrapper_class = local_assigns.fetch(:wrapper_class) { RailsGoogleMap.configuration.wrapper_class }
13
+ - map_class = local_assigns.fetch(:map_class) { RailsGoogleMap.configuration.map_class }
14
+ - width = local_assigns.fetch(:width) { RailsGoogleMap.configuration.width }
15
+ - height = local_assigns.fetch(:height) { RailsGoogleMap.configuration.height }
16
+
17
+ - if url.present?
18
+ div class=wrapper_class
19
+ iframe src=url class=map_class title=title width=width height=height style="border:0;" loading="lazy" referrerpolicy="no-referrer-when-downgrade" allowfullscreen=true frameborder="0"
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module RailsGoogleMap
6
+ module Generators
7
+ # Copies the map partial into the host app so its markup can be edited:
8
+ #
9
+ # rails generate rails_google_map:views
10
+ # rails generate rails_google_map:views --format slim
11
+ #
12
+ # App view paths take precedence over the engine's, so the copy is picked
13
+ # up with no further configuration.
14
+ class ViewsGenerator < Rails::Generators::Base
15
+ FORMATS = %w[erb slim].freeze
16
+
17
+ source_root File.expand_path("templates", __dir__)
18
+
19
+ desc "Copies rails_google_map's map partial into app/views so you can edit it."
20
+
21
+ # No short alias here on purpose: Thor already claims -f for --force.
22
+ class_option :format, type: :string, default: "erb",
23
+ desc: "Template format to copy: #{FORMATS.join(' or ')}"
24
+
25
+ def copy_map_partial
26
+ format = options[:format].to_s.downcase
27
+ unless FORMATS.include?(format)
28
+ raise Thor::Error, "Unknown format #{options[:format].inspect}. Use #{FORMATS.join(' or ')}."
29
+ end
30
+
31
+ copy_file "_map.html.#{format}", "app/views/rails_google_map/_map.html.#{format}"
32
+ end
33
+ end
34
+ end
35
+ end
@@ -24,6 +24,14 @@ module RailsGoogleMap
24
24
  attr_accessor :width, :height
25
25
  # Language for map labels, e.g. "en" or "ne" (Embed API only).
26
26
  attr_accessor :language
27
+ # CSS class for the div the partial wraps the map in.
28
+ attr_accessor :wrapper_class
29
+ # CSS class applied to the iframe itself. Nil leaves the attribute off.
30
+ attr_accessor :map_class
31
+ # Partial that #render_google_map renders. Override it in your own app by
32
+ # creating a template at the same path -- app view paths win over the
33
+ # engine's -- or point this at a partial of your own.
34
+ attr_accessor :partial
27
35
 
28
36
  def initialize
29
37
  @api_key = ENV["GOOGLE_MAPS_EMBED_KEY"] || ENV["GOOGLE_MAPS_API_KEY"]
@@ -32,6 +40,9 @@ module RailsGoogleMap
32
40
  @width = "100%"
33
41
  @height = "450"
34
42
  @language = nil
43
+ @wrapper_class = "google-map"
44
+ @map_class = nil
45
+ @partial = "rails_google_map/map"
35
46
  end
36
47
 
37
48
  # True when an API key is present, i.e. when the Maps Embed API can be used.
@@ -34,9 +34,10 @@ module RailsGoogleMap
34
34
  #
35
35
  # Any option other than the ones named below is passed straight through as
36
36
  # an iframe attribute, e.g. `class: "map"` or `title: "Our office"`.
37
- def google_map_for(query = nil, width: nil, height: nil, zoom: nil,
37
+ def google_map_for(query = nil, wrapper: nil, width: nil, height: nil, zoom: nil,
38
38
  map_type: nil, language: nil, api_key: nil, **html_options)
39
- query = map_query(query, html_options.delete(:lat), html_options.delete(:lng) || html_options.delete(:long))
39
+ query = google_map_query(query, html_options.delete(:lat),
40
+ html_options.delete(:lng) || html_options.delete(:long))
40
41
  src = google_map_embed_url(query, zoom: zoom, map_type: map_type,
41
42
  language: language, api_key: api_key)
42
43
  return if src.nil?
@@ -44,6 +45,7 @@ module RailsGoogleMap
44
45
  config = RailsGoogleMap.configuration
45
46
  attributes = {
46
47
  src: src,
48
+ class: config.map_class,
47
49
  width: width || config.width,
48
50
  height: height || config.height,
49
51
  style: "border:0;",
@@ -53,7 +55,45 @@ module RailsGoogleMap
53
55
  frameborder: "0"
54
56
  }.merge(html_options)
55
57
 
56
- content_tag(:iframe, "", attributes)
58
+ iframe = content_tag(:iframe, "", attributes)
59
+ wrapper_attributes = google_map_wrapper_attributes(wrapper, config)
60
+ return iframe if wrapper_attributes.nil?
61
+
62
+ content_tag(:div, iframe, wrapper_attributes)
63
+ end
64
+
65
+ # Renders the map through a partial instead of building the tag in Ruby, so
66
+ # the markup is yours to change. Ships as ERB; run
67
+ #
68
+ # rails generate rails_google_map:views --format slim
69
+ #
70
+ # to copy it into your app as Slim (or ERB) and edit it there -- app view
71
+ # paths win over the engine's, so the copy takes over automatically.
72
+ #
73
+ # = render_google_map(@business.map_query, title: t("partners.map_of", name: @business.name))
74
+ # = render_google_map(@business.address, map_class: "partners-map")
75
+ #
76
+ # Returns nil when there is nothing to map, exactly like #google_map_for.
77
+ # Options it does not recognise are passed to the partial as extra locals,
78
+ # which is how a custom partial receives its own data.
79
+ def render_google_map(query = nil, partial: nil, title: nil, wrapper_class: nil,
80
+ map_class: nil, width: nil, height: nil, zoom: nil,
81
+ map_type: nil, language: nil, api_key: nil, **locals)
82
+ query = google_map_query(query, locals.delete(:lat),
83
+ locals.delete(:lng) || locals.delete(:long))
84
+ url = google_map_embed_url(query, zoom: zoom, map_type: map_type,
85
+ language: language, api_key: api_key)
86
+ return if url.nil?
87
+
88
+ config = RailsGoogleMap.configuration
89
+ render(partial: partial || config.partial, locals: {
90
+ url: url,
91
+ title: title,
92
+ wrapper_class: wrapper_class || config.wrapper_class,
93
+ map_class: map_class || config.map_class,
94
+ width: width || config.width,
95
+ height: height || config.height
96
+ }.merge(locals))
57
97
  end
58
98
 
59
99
  # The embeddable Google Maps URL for +query+ (an address or a "lat,lng").
@@ -100,12 +140,26 @@ module RailsGoogleMap
100
140
  # An address wins over coordinates: lat/lng columns are often unreliable
101
141
  # (many rows share one default pin), so they only stand in when no address
102
142
  # was given. Treats 0/nil coordinates as "no pin".
103
- def map_query(address, lat, lng)
143
+ def google_map_query(address, lat, lng)
104
144
  return address.to_s.strip unless address.nil? || address.to_s.strip.empty?
105
145
  return if lat.nil? || lng.nil?
106
146
  return if lat.to_f.zero? && lng.to_f.zero?
107
147
 
108
148
  "#{lat},#{lng}"
109
149
  end
150
+
151
+ # wrapper: nil/false -> bare iframe; true -> the configured wrapper class;
152
+ # a String -> that class; a Hash -> attributes for the surrounding div.
153
+ def google_map_wrapper_attributes(wrapper, config)
154
+ case wrapper
155
+ when nil, false then nil
156
+ when true then { class: config.wrapper_class }
157
+ when String, Symbol then { class: wrapper.to_s }
158
+ when Hash then wrapper
159
+ else
160
+ raise ArgumentError,
161
+ "wrapper must be true, false, a CSS class or a Hash of attributes, got #{wrapper.class}"
162
+ end
163
+ end
110
164
  end
111
165
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsGoogleMap
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -14,6 +14,9 @@ module RailsGoogleMap
14
14
  attr_accessor width: String | Integer | nil
15
15
  attr_accessor height: String | Integer | nil
16
16
  attr_accessor language: String?
17
+ attr_accessor wrapper_class: String?
18
+ attr_accessor map_class: String?
19
+ attr_accessor partial: String
17
20
 
18
21
  def initialize: () -> void
19
22
  def api_key?: () -> bool
@@ -27,7 +30,8 @@ module RailsGoogleMap
27
30
  EMBED_API_URL: String
28
31
  KEYLESS_EMBED_URL: String
29
32
 
30
- def google_map_for: (?untyped query, ?width: untyped, ?height: untyped, ?zoom: Integer?, ?map_type: String?, ?language: String?, ?api_key: String?, **untyped) -> untyped
33
+ def google_map_for: (?untyped query, ?wrapper: untyped, ?width: untyped, ?height: untyped, ?zoom: Integer?, ?map_type: String?, ?language: String?, ?api_key: String?, **untyped) -> untyped
34
+ def render_google_map: (?untyped query, ?partial: String?, ?title: String?, ?wrapper_class: String?, ?map_class: String?, ?width: untyped, ?height: untyped, ?zoom: Integer?, ?map_type: String?, ?language: String?, ?api_key: String?, **untyped) -> untyped
31
35
  def google_map_embed_url: (untyped query, ?zoom: Integer?, ?map_type: String?, ?language: String?, ?api_key: String?) -> String?
32
36
  def embed_google_map: (?Hash[untyped, untyped] options) -> untyped
33
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_google_map
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bikash Shrestha
@@ -46,6 +46,10 @@ files:
46
46
  - LICENSE.txt
47
47
  - README.md
48
48
  - Rakefile
49
+ - app/views/rails_google_map/_map.html.erb
50
+ - lib/generators/rails_google_map/views/templates/_map.html.erb
51
+ - lib/generators/rails_google_map/views/templates/_map.html.slim
52
+ - lib/generators/rails_google_map/views/views_generator.rb
49
53
  - lib/rails_google_map.rb
50
54
  - lib/rails_google_map/configuration.rb
51
55
  - lib/rails_google_map/engine.rb
@@ -58,7 +62,7 @@ licenses:
58
62
  - MIT
59
63
  metadata:
60
64
  homepage_uri: https://github.com/sthaB-kash/rails_google_map
61
- source_code_uri: https://github.com/sthaB-kash/rails_google_map/tree/v0.1.0
65
+ source_code_uri: https://github.com/sthaB-kash/rails_google_map/tree/v0.2.0
62
66
  changelog_uri: https://github.com/sthaB-kash/rails_google_map/blob/master/CHANGELOG.md
63
67
  bug_tracker_uri: https://github.com/sthaB-kash/rails_google_map/issues
64
68
  documentation_uri: https://github.com/sthaB-kash/rails_google_map#readme