Module: Assistant::EmailBlocks

Defined in:
app/services/assistant/email_blocks.rb

Overview

Ruby reader for the shared WarmlyYours email block snippets — the SAME file the
Redactor email plugin uses (client/js/common/email_blocks.json). This is the
single source of truth for the branded header/footer/full-template/support-case
HTML, so Sunny-authored templates start from byte-identical markup to what the
wyemailblocks toolbar buttons and the Redactor clips insert. Edit the JSON;
never duplicate snippet HTML in Ruby or JS.

Snippets are editor-semantic body_v4 source. The final email-ready
body_v4_email is produced exclusively by Redactor's getEmail() on a human
editor save — never reconstructed server-side.

Constant Summary collapse

SOURCE_PATH =

Path to the shared snippet store (committed; read at boot, cached).

Rails.root.join('client/js/common/email_blocks.json').freeze
CONTENT_MARKER =

Placeholder in full_template where new-template content is injected.

'<!-- @@CONTENT@@ -->'

Class Method Summary collapse

Class Method Details

.allHash{String=>String}

Returns snippet key => HTML (memoized).

Returns:

  • (Hash{String=>String})

    snippet key => HTML (memoized)



26
27
28
# File 'app/services/assistant/email_blocks.rb', line 26

def all
  @all ||= load_blocks
end

.blank_templateString

Returns minimal empty-editor starter (config + empty content region,
header/hero/footer as comment markers). What the editor mounts on a blank
new template — shared with redactor4.js so the JS default can't drift.

Returns:

  • (String)

    minimal empty-editor starter (config + empty content region,
    header/hero/footer as comment markers). What the editor mounts on a blank
    new template — shared with redactor4.js so the JS default can't drift.



42
# File 'app/services/assistant/email_blocks.rb', line 42

def blank_template = all.fetch('blank_template', '')

.email_optionsString

Returns the canonical email-options config (the Redactor
email plugin config block), extracted from the full template so it stays
in lockstep with the single source. Memoized.

Returns:

  • (String)

    the canonical email-options config (the Redactor
    email plugin config block), extracted from the full template so it stays
    in lockstep with the single source. Memoized.



50
51
52
53
54
55
# File 'app/services/assistant/email_blocks.rb', line 50

def email_options
  @email_options ||= begin
    node = Nokogiri::HTML5.fragment(full_template).at_css('.email-options')
    node ? node.to_html : ''
  end
end

Returns branded footer snippet (carries {unsubscribe_url}).

Returns:

  • (String)

    branded footer snippet (carries {unsubscribe_url})



34
# File 'app/services/assistant/email_blocks.rb', line 34

def footer = all.fetch('footer')

.full_templateString

Returns full email scaffold with the CONTENT_MARKER placeholder.

Returns:

  • (String)

    full email scaffold with the CONTENT_MARKER placeholder



37
# File 'app/services/assistant/email_blocks.rb', line 37

def full_template = all.fetch('full_template')

.headerString

Returns branded header snippet.

Returns:

  • (String)

    branded header snippet



31
# File 'app/services/assistant/email_blocks.rb', line 31

def header = all.fetch('header')

.reload!Object

Test seam: drop the memoized cache.



79
80
81
82
# File 'app/services/assistant/email_blocks.rb', line 79

def reload!
  @all = nil
  @email_options = nil
end

.scaffold_with(content_html) ⇒ String

Build a complete editor-semantic body_v4 from the full scaffold by injecting
the given main-content HTML at the content marker.

The shared full_template carries a <p>Sample text</p> placeholder right
after the marker — intentional for a HUMAN clicking the Redactor "Full Email
Template" toolbar button (a fillable starter). When the ASSISTANT injects real
content we must drop that placeholder, or it leaks into the sent email (it did:
template 2407 showed a stray "Sample text" line). So replace the marker AND the
trailing sample paragraph with the authored content.

Parameters:

  • content_html (String)

Returns:

  • (String)


68
69
70
71
72
73
74
75
76
# File 'app/services/assistant/email_blocks.rb', line 68

def scaffold_with(content_html)
  tpl = full_template
  return "#{tpl}\n#{content_html}" unless tpl.include?(CONTENT_MARKER)

  # Match the marker plus an optional immediately-following <p>…Sample text…</p>
  # placeholder (whitespace-tolerant) and replace the whole thing with content.
  marker_with_placeholder = %r{#{Regexp.escape(CONTENT_MARKER)}\s*(?:<p>\s*Sample text\s*</p>)?}mo
  tpl.sub(marker_with_placeholder, content_html.to_s)
end

.support_caseString

Returns support-case full-page scaffold.

Returns:

  • (String)

    support-case full-page scaffold



45
# File 'app/services/assistant/email_blocks.rb', line 45

def support_case = all.fetch('support_case')