Module: AlEmailProtect
- Defined in:
- lib/al_email_protect.rb,
lib/al_email_protect/version.rb
Overview
Keeps published email addresses away from harvesters.
The scraper-facing half is deliberately server-side: when the feature is on,
no mailto: string and no user@host string is present in the HTML at all.
Address harvesters read markup, not JavaScript, so an approach that ships the
plaintext and merely rewrites it on DOMContentLoaded protects nobody. The
address is emitted as two halves and only rejoined in the browser.
Defined Under Namespace
Modules: Filters Classes: AssetsGenerator, LinkTag, PluginStaticFile, ScriptsTag, StylesTag
Constant Summary collapse
- PLUGIN_ROOT =
File.("..", __dir__)
- LIB_ROOT =
Jekyll writes a StaticFile to
/ / , where is relative to the base below. That base must be lib/, not the gem root, or assets land at /lib/assets/... while every tag in this file points at /assets/... . __dir__- ASSETS_ROOT =
File.join(LIB_ROOT, "assets")
- VERSION =
"1.0.0"
Class Method Summary collapse
-
.asset_entries ⇒ Object
[relative_dir, filename] for everything this gem publishes.
-
.domain_markup(domain) ⇒ Object
Builds "example [dot] com" as alternating styled spans.
- .enabled?(site) ⇒ Boolean
- .escape(value) ⇒ Object
-
.obfuscate_text(value) ⇒ Object
"someone [at] example [dot] com", for places that show an address as text rather than as a link (CV contact blocks, for instance).
-
.split_address(value) ⇒ Object
Splits "someone@example.ac.uk" into ["someone", "example.ac.uk"].
Class Method Details
.asset_entries ⇒ Object
[relative_dir, filename] for everything this gem publishes. Exposed so the destination path can be asserted without booting a full Jekyll site.
73 74 75 76 77 |
# File 'lib/al_email_protect.rb', line 73 def asset_entries Dir.glob(File.join(ASSETS_ROOT, "**", "*")).sort.reject { |p| File.directory?(p) }.map do |source_path| [File.dirname(source_path).sub("#{LIB_ROOT}/", ""), File.basename(source_path)] end end |
.domain_markup(domain) ⇒ Object
Builds "example [dot] com" as alternating styled spans.
66 67 68 69 |
# File 'lib/al_email_protect.rb', line 66 def domain_markup(domain) separator = %(<span class="al-email-sep"> [dot] </span>) domain.split(".").map { |label| %(<span class="al-email-text">#{escape(label)}</span>) }.join(separator) end |
.enabled?(site) ⇒ Boolean
27 28 29 30 31 |
# File 'lib/al_email_protect.rb', line 27 def enabled?(site) return false unless site site.config["protect_email"] == true end |
.escape(value) ⇒ Object
61 62 63 |
# File 'lib/al_email_protect.rb', line 61 def escape(value) CGI.escapeHTML(value.to_s) end |
.obfuscate_text(value) ⇒ Object
"someone [at] example [dot] com", for places that show an address as text rather than as a link (CV contact blocks, for instance).
53 54 55 56 57 58 59 |
# File 'lib/al_email_protect.rb', line 53 def obfuscate_text(value) parts = split_address(value) return value.to_s unless parts local, domain = parts "#{local} [at] #{domain.gsub(".", " [dot] ")}" end |
.split_address(value) ⇒ Object
Splits "someone@example.ac.uk" into ["someone", "example.ac.uk"].
Splits on the LAST "@" because the local part of an address may legally contain one when quoted (RFC 5321), and getting this backwards would emit a broken address rather than a protected one. Returns nil for anything not usable as an address, so callers can fall back to rendering it verbatim instead of silently publishing a mangled contact.
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/al_email_protect.rb', line 40 def split_address(value) address = value.to_s.strip return nil if address.empty? local, _, domain = address.rpartition("@") return nil if local.empty? || domain.empty? return nil unless domain.include?(".") [local, domain] end |