I decided to go through the issue thoroughly and address all the attempts that were made here. If you want a quick answer, look at the currently accepted one.
Working solution
To use a text in mailto:
URL body
parameter, percent-encode it. In PHP, use rawurlencode()
. Subject should be encoded, too.
$subj = "Whatever subject";
$body = "Multi-\r\nline\r\nbody";
printf(
"mailto:?subject=%s&body=%s",
rawurlencode($subj),
rawurlencode($body)
);
mailto:?subject=Whatever%2Osubject&body=Multi-%0D%0Aline%0D%0Abody
To use it as a target of a HTML link, replace characters that have special meaning in HTML with entity references – htmlspecialchars()
is used for that in PHP, and Wordpress has a fancier (and filtrable) esc_html()
.
$subj = "Whatever subject";
$body = "Multi-\r\nline\r\nbody";
printf(
'<a href="%s">mailto: URL with multi-line body</a>',
htmlspecialchars(sprintf(
"mailto:?subject=%s&body=%s",
rawurlencode($subj),
rawurlencode($body)
), ENT_QUOTES)
);
<a href="mailto:?subject=Whatever%2Osubject&Multi-%0D%0Aline%0D%0Abody">mailto: URL with multi-line body</a>
I am sure that by now, you know how to modify your PHP code to produce such a link.
Debugging the issue
You have to deal with several levels of technologies, each having its own escaping scheme:
PHP (e.g. "\n"
is a string with a newline, not with a backslash and the letter n; you would need to escape the backslash if you wanted that – "\\n"
)
(s)printf (e.g. to print a literal %
, you have to write %%
)
HTML (e.g. &
starts an entity reference; to be taken literally, it should be encoded as the entity reference &
)
URL (e.g. space is not a valid part of a URL and it must be percent-encoded as %20
)
This is too much to do manually and be sure it is correct without examining the intermediate steps. If you get any of the intermediate steps wrong, it is broken as a whole.
- Did you verify that the PHP code is saved exactly as you wrote it?
- Did you look at the HTML it produces?
- And did you try to copy the URL by right-clicking the link in the browser and choosing “Copy Email Address”?
The safe approach is to manually construct the product of last step, and only once it works, proceed and try to produce it programmatically. In this case, such a product is the URL that once pasted into the browser’s location bar opens mail composer with multi-line body pre-filled. You can begin with a simple working example and make it more and more complex, till it meets your needs. When manual construction is too tedious, you have probably chosen a product that is too complex – choose the simplest one that still works the way you want, you can add complexity later.
If you get stuck even with manually building the URL, you are out of luck. Either you have to read more on the topic, reach out for help, or give up. If it is not just you, the problem is somewhere between your browser and your email client. At least one of them has a bug. In my experience with mailto: URLs, this is not uncommon. Even if you get it to work for you, the visitors of your blog may not be so lucky with their setup.
Aside: HTML spec on presented attempts
I took the time to look at what HTML spec says about the issues I see in the attempts that were presented in other answers and in the question itself. Specifically:
- unencoded ampersand in attribute value
- newline in attribute value
- unencoded
<
and >
in HTML markup (<br>
) in attribute value
Syntactic level
HTML implementations are pretty robust these days and even the HTML spec became very permissive regarding encoding ampersands (&
) into entity references (&
; called character references in HTML5), therefore you will usually get away with not doing that. (HTML 4 spec required the encoding, though.)
At the level of actual bytes in the HTML file, quoted attribute values in HTML5 are free to contain almost* any characters, except the quote that is used to quote them (which must be replaced by a character reference).
* For details, see Preprocessing the input stream and ambiguous ampersand in HTML5 spec.
This is why even newline and unencoded <br>
are OK inside quoted attribute values. But actually, they are not OK in href
(unlike in e.g. title
), because…
Semantic level
At the semantic level, when everything is parsed, any string (including empty string) is allowed as attribute value, but specific attributes add further constraints.
This is where HTML bites you – href
is specified to contain a valid URL potentially surrounded by spaces, which cannot contain
- newlines and other space characters in the middle and
<
, >
, and many other characters at all.
These characters have to be percent-encoded. For the actual definition of URL and its syntax, HTML spec defers to other specifications.
Handling invalid URLs is implementation-defined, these machanisms may not be consistent across browsers. Just respect the specifications. My Firefox ignores newlines and preserves spaces – spaces are not allowed in URLs either, but Firefox encodes them before it does anything else with the URL.
mailto:?subject=%s&body=%s
– Durable