Module: Consently::TagsHelper

Defined in:
app/helpers/consently/tags_helper.rb

Overview

The three helpers a host application calls: the tags in , the noscript fallbacks right after , and the banner anywhere on the page.

Instance Method Summary collapse

Instance Method Details

#consently_banner(policy_url: nil) ⇒ Object

The banner, the preferences panel, and the JavaScript that releases the blocked tags. Render it once per page, ideally at the end of the body.

The container stays in the DOM after a choice is made so that consently_preferences_link has something to reopen.



44
45
46
47
48
49
50
51
# File 'app/helpers/consently/tags_helper.rb', line 44

def consently_banner(policy_url: nil)
  return "".html_safe unless consently_enabled? && Consently.consent_required?(request)

  render "consently/banner",
    consent: consently_consent,
    policy_url: policy_url || consently_policy_url,
    categories: Consently.config.optional_categories
end


66
67
68
69
70
71
72
73
# File 'app/helpers/consently/tags_helper.rb', line 66

def consently_consent
  @consently_consent ||= if Consently.consent_required?(request)
    Consent.from_cookie(cookies[Consently.config.cookie_name], version: Consently.config.consent_version)
  else
    # Nobody to ask, so nothing is held back.
    Consent.new(categories: Consently.config.categories, version: Consently.config.consent_version)
  end
end

#consently_data_layer_push(event, category: :analytics, **payload) ⇒ Object

Push an event onto the dataLayer from a view, respecting consent: with no analytics consent the event is simply not emitted.

<%= consently_data_layer_push("purchase", value: 120, currency: "EUR") %>


79
80
81
82
83
84
# File 'app/helpers/consently/tags_helper.rb', line 79

def consently_data_layer_push(event, category: :analytics, **payload)
  return "".html_safe unless consently_enabled? && consently_consent.granted?(category)

  payload = payload.merge(event: event)
  consently_inline_script "window.dataLayer = window.dataLayer || []; window.dataLayer.push(#{payload.to_json});"
end

#consently_log_urlObject

Where the banner POSTs the decision, when consent logging is on and the engine is mounted. Nil otherwise, and the banner skips the request.



104
105
106
107
108
109
110
# File 'app/helpers/consently/tags_helper.rb', line 104

def consently_log_url
  return nil unless Consently.config.log_consents

  consently.consents_path
rescue NoMethodError, NameError
  nil
end

#consently_noscript_tagsObject

Goes directly after - Google Tag Manager and Meta both still ship a noscript fallback. Only rendered for categories already granted: there is no way to hold an iframe back and release it later.



26
27
28
29
30
31
32
33
34
35
36
37
# File 'app/helpers/consently/tags_helper.rb', line 26

def consently_noscript_tags
  return "".html_safe unless consently_enabled?

  fallbacks = Consently.tags_for(request).filter_map do |provider|
    next unless consently_consent.granted?(provider.category)

    provider.noscript&.html_safe
  end
  return "".html_safe if fallbacks.empty?

  (:noscript, safe_join(fallbacks, "\n"))
end

#consently_policyObject

A complete cookie policy for the tags this request would load: every category, every vendor, every cookie it sets and for how long, plus whether the visitor has agreed to it right now.

Drop it into your own policy page under your own heading and legal text.



91
92
93
# File 'app/helpers/consently/tags_helper.rb', line 91

def consently_policy
  render "consently/policy", tags: Consently.tags_for(request), consent: consently_consent
end

A "Cookie settings" link for the footer. Reopens the panel.

Marked rather than wired: the link lives outside the banner element, so a data-action on it would never bind. The controller watches the whole document for a click on anything carrying this attribute, which also means your own markup can reopen the panel just by wearing it.



59
60
61
62
63
64
# File 'app/helpers/consently/tags_helper.rb', line 59

def consently_preferences_link(name = nil, **options, &block)
  name ||= t("consently.preferences_link")
  options[:data] = { consently_open: true }.merge(options[:data] || {})

  link_to(name, "#consently", options, &block)
end

#consently_stylesheet_tagObject

The banner brings its own plain CSS - no framework, no build step. The look is driven by custom properties, so overriding a few variables is usually enough; rails g consently:views is there for the rest.



98
99
100
# File 'app/helpers/consently/tags_helper.rb', line 98

def consently_stylesheet_tag
  stylesheet_link_tag "consently", media: "all"
end

#consently_tagsObject

Every tag configured for this request. Tags whose category the visitor has not agreed to are rendered inert (type="text/plain") and the banner turns them into real scripts the moment consent is given - so a visitor who accepts does not have to reload to be counted.



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'app/helpers/consently/tags_helper.rb', line 9

def consently_tags
  return "".html_safe unless consently_enabled?

  parts = []
  parts << consently_stylesheet_tag if Consently.config.stylesheet
  parts << consently_consent_mode_tag if Consently.config.google_consent_mode
  Consently.tags_for(request).each do |provider|
    granted = consently_consent.granted?(provider.category)
    provider.scripts.each { |script| parts << consently_script_tag(script, provider, granted) }
  end

  safe_join(parts, "\n")
end