Module: Decidim::MapHelper

Overview

This helper include some methods for rendering resources static and dynamic maps.

Instance Method Summary collapse

Instance Method Details

#dynamic_map_for(options_or_markers = {}, html_options = {}, &block) ⇒ Object


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'decidim-core/app/helpers/decidim/map_helper.rb', line 62

def dynamic_map_for(options_or_markers = {}, html_options = {}, &block)
  return unless map_utility_dynamic

  options = {
    popup_template_id: "marker-popup"
  }
  if options_or_markers.is_a?(Array)
    options[:markers] = options_or_markers
  else
    options = options.merge(options_or_markers)
  end

  builder = map_utility_dynamic.create_builder(self, options)

  # The map snippets are stored to the snippets utility in order to ensure
  # that they are only loaded once during each page load. In case they were
  # loaded multiple times, the maps would break. We store the map assets to
  # a special "map" snippets category in order to avoid displaying them
  # multiple times. Then we inject them to the "head" category during the
  # first load which will actually display them in the <head> section of the
  # view.
  #
  # Ideally we would use Rails' native content_for here (which is exactly
  # for this purpose) but unfortunately it does not work in the cells which
  # also need to display maps.
  unless snippets.any?(:map)
    snippets.add(:map, builder.stylesheet_snippets)
    snippets.add(:map, builder.javascript_snippets)

    # This will display the snippets in the <head> part of the page.
    snippets.add(:head, snippets.for(:map))
  end

  map_html_options = { id: "map", class: "google-map" }.merge(html_options)
  bottom_id = "#{map_html_options[:id]}_bottom"

  help = (:div, class: "map__help") do
    sr_content = (:p, t("screen_reader_explanation", scope: "decidim.map.dynamic"), class: "show-for-sr")
    link = link_to(t("skip_button", scope: "decidim.map.dynamic"), "##{bottom_id}", class: "skip")

    sr_content + link
  end
   :div, class: "row column" do
    map = builder.map_element(map_html_options, &block)
    bottom = (:div, "", id: bottom_id)

    help + map + bottom
  end
end

Renders a link to openstreetmaps with the resource latitude and longitude. The link's content is a static map image.

resource - A geolocalizable resource options - An optional hash of options (default: { zoom: 17 })

* zoom: A number to represent the zoom value of the map

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'decidim-core/app/helpers/decidim/map_helper.rb', line 12

def static_map_link(resource, options = {}, map_html_options = {}, &block)
  return unless resource.geocoded_and_valid?
  return unless map_utility_static || map_utility_dynamic

  address_text = resource.try(:address)
  address_text ||= t("latlng_text", latitude: latitude, longitude: longitude, scope: "decidim.map.static")
  map_service_brand = t("map_service_brand", scope: "decidim.map.static")

  if map_utility_static
    map_url = map_utility_static.link(
      latitude: resource.latitude,
      longitude: resource.longitude,
      options: options
    )

    # Check that the static map utility actually returns a URL before
    # creating the static map utility. If it does not, the image would be
    # otherwise blank.
    if map_utility_static.url(latitude: resource.latitude, longitude: resource.longitude)
      return link_to map_url, target: "_blank", rel: "noopener" do
        image_tag decidim.static_map_path(sgid: resource.to_sgid.to_s), alt: "#{map_service_brand} - #{address_text}"
      end
    end
  end

  # Fall back to the dynamic map utility in case static maps are not
  # provided.
  builder = map_utility_dynamic.create_builder(self, {
    type: :static,
    latitude: resource.latitude,
    longitude: resource.longitude,
    zoom: 15,
    title: "#{map_service_brand} - #{address_text}",
    link: map_url
  }.merge(options))

  unless snippets.any?(:map)
    snippets.add(:map, builder.stylesheet_snippets)
    snippets.add(:map, builder.javascript_snippets)

    # This will display the snippets in the <head> part of the page.
    snippets.add(:head, snippets.for(:map))
  end

  builder.map_element(
    { class: "static-map", tabindex: "0" }.merge(map_html_options),
    &block
  )
end