class Jekyll::Newsletter

Constants

CONFIG

Attributes

site[R]

Public Class Methods

new(site) click to toggle source
   # File lib/jekyll/newsletter.rb
17 def initialize(site)
18   @site = site
19 end

Public Instance Methods

config() click to toggle source

TODO: Refactor this mess

   # File lib/jekyll/newsletter.rb
66 def config
67   @config ||= Jekyll::Utils.deep_merge_hashes(CONFIG,
68                                               (site.config['newsletter'] || {}).transform_keys(&:to_sym)).tap do |config|
69 
70     config[:from] ||= ENV['JEKYLL_NEWSLETTER_FROM']
71     config[:to] = [config[:to]].flatten
72     config[:to].concat(ENV['JEKYLL_NEWSLETTER_TO']&.split(',')&.map(&:strip) || [])
73     config[:to].compact!
74 
75     %i[to from].each do |o|
76       raise Jekyll::Errors::InvalidConfigurationError, "Missing `newsletter.#{o}` in _config.yml" if config[o].nil? || config[o].empty?
77     end
78 
79     config[:delivery_method] = config[:delivery_method].to_sym
80     config[:options].transform_keys!(&:to_sym)
81     config[:options][:user_name] ||= config[:from].scan(/<([^>]+)>/)&.flatten&.first || config[:from]
82     config[:options][:domain] ||= config[:from].split('@').last
83     config[:options][:address] ||= "smtp.#{config[:options][:domain]}"
84     config[:delivery_method] = :logger unless production?
85   end.freeze
86 end
deliver() click to toggle source
   # File lib/jekyll/newsletter.rb
21 def deliver
22   return false unless post
23 
24   Jekyll.logger.info "Sending #{post.data['title']} as newsletter"
25 
26   return false unless mail.deliver
27 
28   Jekyll.logger.info 'Newsletter sent'
29 
30   cache[key_for_post(post)] = Time.now if production?
31 
32   true
33 end
mail() click to toggle source
   # File lib/jekyll/newsletter.rb
47 def mail
48   @mail ||= begin
49     mail = Mail.new
50     mail.from      = config[:from]
51     mail.to        = config[:to]
52     mail.subject   = post.data['title']
53     mail.html_part = post.content
54     # TODO: We don't have access to Markdown on post_write because
55     # Jekyll replaces the contents with the rendered output, but we
56     # could keep *some* formatting.
57     mail.text_part = post.content.gsub(/<[^>]+>/m, '')
58 
59     mail.delivery_method config[:delivery_method], **config[:options]
60 
61     mail
62   end
63 end
post() click to toggle source

Select the newest Post that hasn't been sent already. Jekyll::Collection doesn't guarantee order so we convert to a Liquid drop to get the ordered Posts.

   # File lib/jekyll/newsletter.rb
38 def post
39   @post ||= site.to_liquid['site']['posts'].find do |post|
40     !cache[key_for_post(post)]
41   rescue StandardError
42     # When the post isn't in the cache
43     true
44   end
45 end

Private Instance Methods

cache() click to toggle source
    # File lib/jekyll/newsletter.rb
 98 def cache
 99   @cache ||= Jekyll::Cache.new(self.class.to_s)
100 end
key_for_post(post) click to toggle source
   # File lib/jekyll/newsletter.rb
94 def key_for_post(post)
95   post.data['uuid'] || post.relative_path
96 end
production?() click to toggle source
   # File lib/jekyll/newsletter.rb
90 def production?
91   Jekyll.env == 'production'
92 end