I have found a Ruby plugin for Jekyll to obfuscate an email address like this in a Jekyll webpage with Liquid
{{ site.email | mailObfuscate }}
However, I would like to pass multiple params to mailObfuscate
I have tried the following
{{ email=site.email, linkText='foo bar' | mailObfuscate }}
However, this gives an error when building my site
Liquid Warning: Liquid syntax error (line 89): Unexpected character = in "{{ email=site.email, linkText='foo bar' | mailObfuscate }}" in privacy.html Liquid Exception: undefined method
gsub' for nil:NilClass in privacy.html Error: undefined method
gsub' for nil:NilClass Error: Run jekyll build --trace for more information.
Running the trace gives the following error
1: from D:/Ruby26-x64/lib/ruby/2.6.0/uri/common.rb:103:in
escape' D:/Ruby26-x64/lib/ruby/2.6.0/uri/rfc2396_parser.rb:305:in
escape': undefined method `gsub' for nil:NilClass (NoMethodError)
The complete trace can be found at Pastebin
How can I pass multiple variables?
You need to modify the method to take a 2nd argument, then you can use it as the link text. Try this:
require "base64"
require "uri"
module ObfuscateMailAddress
def mailObfuscate(email_address, link_text )
base64Mail = Base64.strict_encode64(URI::encode(email_address))
# See http://techblog.tilllate.com/2008/07/20/ten-methods-to-obfuscate-e-mail-addresses-compared/
output = "<a href=\"#\" "
output += "data-contact=\"#{base64Mail}\" target=\"_blank\" "
output += "onfocus=\"this.href = 'mailto:' + atob(this.dataset.contact)\">"
output += "<script type=\"text/javascript\">document.write(atob(\"#{base64Mail}\"));</script>#{link_text}</a>"
return output
end
end
Liquid::Template.register_filter(ObfuscateMailAddress)
To pass multiple arguments in your liquid template, the syntax is a bit strange, see documentation. The string on the left side of the pipe automatically get's passed as the first argument to your ruby method, while additional arguments get passed with a colon.
{{ '[email protected]' | mailObfuscate:'myLinkText' }}
But you also, if you are on Ruby >= 2.3, you can make your method more readable with no need for all the escape characters and better syntax highlighting in your editor if you change your method to use SQUIGGLY HEREDOC for your string definition, explicit return
is not required in anycase. For Ruby < 2.3 you can still use regular HEREDOC just replace ~
with -
but you just have extra indentation in your string, which is no problem anyway for rendered html.
def mailObfuscate(email_address, link_text )
base64Mail = Base64.strict_encode64(URI::encode(email_address))
ouput = <<~HTML
<a href="#" data-contact="#{base64Mail}" target="_blank"
onfocus="this.href = 'mailto:' + atob(this.dataset.contact)" >
<script type="text/javascript">
document.write(atob("#{base64Mail}"));
</script>
#{link_text}
</a>
HTML
end
And when it is called like this:
puts mailObfuscate('[email protected]', 'foobar')
It will render:
<a href="#" data-contact="Zm9vQGJhci5jb20=" target="_blank"
onfocus="this.href = 'mailto:' + atob(this.dataset.contact)" >
<script type="text/javascript">
document.write(atob("Zm9vQGJhci5jb20="));
</script>
foobar
</a>
As a side note, ruby style guide recommends we use snake_case
for method names so you might wanna use mail_obfuscate
for your method name instead.