简体   繁体   English

mailto:link中的换行符

[英]Line break in body of mailto: link

I want to create a “Forward this to a friend” link below a blog post that opens my email client with a prepared message. 我想在博客文章下面创建一个“转发给朋友”链接,该帖子打开我的电子邮件客户端并准备好了消息。 I can get it to work for a single-line message, but I'd like to be able to break lines inside the message body. 我可以让它用于单行消息,但我希望能够在消息体内打破行。 How can I do that? 我怎样才能做到这一点?

<?php
printf(
    '<a href="mailto:?subject=%s&body=%s">Forward this to a friend</a>',
    the_title_attribute('echo=0'),
    sprintf('The link: %s Have a great day! Stefaan', get_the_permalink())
);
?>

How do I start “Have a great day!” on a new line with an empty line above? 如何在上面有空行的新行上开始“祝你有美好的一天!”

The link: ... 链接: ...

Have a great day! 祝你有美好的一天!

Stefaan 斯特凡

My blog uses WordPress with a Genesis theme and I put my code into the genesis_footer_entry hook with PHP enabled (see screenshot – email text is in Dutch). 我的博客使用带有Genesis主题的WordPress,我将我的代码放入启用PHP的genesis_footer_entry钩子中(参见截图 - 电子邮件文本是荷兰语)。

Explanation 说明

a mailto: is a URI scheme for email address, like all other URIs, characters need to be translated into a format that can be transmitted over the Internet. a mailto:是电子邮件地址的URI方案,与所有其他URI一样,字符需要转换为可以通过Internet传输的格式。

Take a simplified form of your original code to illustrate the points below 采用原始代码的简化形式来说明以下几点

printf(<href="mailto:?subject=%s&body=%s">Description</a>, the_title_attribute( 'echo=0' ) , sprintf("content link:%s more content", get_the_permalink())

The code runs in the following sequences 代码按以下顺序运行

  1. get_the_permalink() gets the URL of your page get_the_permalink()获取您网页的网址
  2. sprintf() replaces %s in $content with the result of step 1 sprintf()$content %s替换为步骤1的结果
  3. print_f() then replaces print_f()然后替换
    i) the first %s ie subject=%s with the fetched result of the_title_attribute( 'echo=0' ) , which I assume is the title of the page or your site and then ii) the second %s ie body=%s with the result of step 2 to form a complete a mailto link i)第一个%ssubject=%s带有the_title_attribute( 'echo=0' )的获取结果,我假设是页面或你的网站的标题,然后ii)第二个%sbody=%s与步骤2的结果形成一个完整a mailto链接

In order to retain the line breaks, you should convert the $content string into URL encoded form before outputting it. 为了保留换行符,您应该在输出之前将$content字符串转换为URL编码形式。

In PHP that's done by using the rawurlencode() function, it translates line breaks \\r\\n in string into %0D%0A , as per RFC 3986 . 在使用rawurlencode()函数完成的PHP中,它根据RFC 3986将字符串中的换行符\\r\\n转换为%0D%0A

Since the percentage sign % is used for conversion specification in sprint_f() , you should pass the string to rawurlencode() after the string has been formatted by sprint_f() , therefore the use of rawurlencode(sprint_f($string, $arg)) 由于百分号%被用于转换规范sprint_f()你应该把这个字符串传给rawurlencode()之后的字符串已经被格式化sprint_f()因此使用rawurlencode(sprint_f($string, $arg))


Solution
I have put together the solution in full for you to copy and paste into your widget to avoid false negative due to wrongful implementation. 我已经完整地整理了解决方案,您可以将其复制并粘贴到您的小部件中,以避免因错误实施而导致的误报。

Format 1 and format 2 contain essentially the same code, the two formats are there to illustrate to you how you can insert line break, either by 1) pressing enter OR 2) by typing in \\r\\n where line break is needed. 格式1和格式2包含基本相同的代码,这两种格式可以说明如何插入换行符,方法是1) pressing enter OR 2) typing in \\r\\n ,其中需要换行符。

I have made $content a separate string for your ease of editing and readability of code. 我已经将$content作为单独的字符串,以便于编辑和编写代码。

Format 1 格式1

 <?php
  //Start new line by pressing enter
  //IMPORTANT NOTE: do not remove the %s 
    $content="Hi there, this might be interesting for you
    This is the link: %s
    Have a great day!
    Stefaan
    ";
  //No need to amend the code below  
    printf( 
            '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s">
            <div class="label">
            <div class="dashicons dashicons-admin-plugins"></div>
            Forward this to a friend</div></a>',the_title_attribute( 'echo=0' ),
            rawurlencode(sprintf( $content,get_the_permalink()))
            );
?>

Format 2 格式2

<?php
  //Start new line by adding \r\n
  //IMPORTANT NOTE: do not remove the %s 
    $content="Hi there, this might be interesting for you\r\nThis is the link: %s\r\nHave a great day!\r\nStefaan";
 //No need to amend the code below          
    printf( 
            '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s">
            <div class="label">
            <div class="dashicons dashicons-admin-plugins"></div>
            Forward this to a friend</div></a>',the_title_attribute( 'echo=0' ),
            rawurlencode(sprintf( $content,get_the_permalink()))
            );              
?>

Demo 演示

 <a class="simple-mail-link" href="mailto:?subject=Page%20Title&amp;body=Hi%20there%2C%20this%20might%20be%20interesting%20for%20you%0D%0AThis%20is%20the%20link%3A%20http%3A%2F%2Fblahblahblah.com%0D%0AHave%20a%20great%20day%21%0D%0AStefaan"><div class="label"> <div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a></body> 

You cannot use HTML tags in body of mailto 您不能在mailto 正文中使用HTML标记

According to RFC 2368 , this is not possible: 根据RFC 2368 ,这是不可能的:

The special hname "body" indicates that the associated hvalue is the body of the message. 特殊的hname“body”表示关联的hvalue是消息的主体。 The "body" hname should contain the content for the first text/plain body part of the message. “body”hname应该包含消息的第一个text / plain正文部分的内容。 The mailto URL is primarily intended for generation of short text messages that are actually the content of automatic processing (such as "subscribe" messages for mailing lists), not general MIME bodies. mailto URL主要用于生成实际上是自动处理内容的短文本消息(例如邮件列表的“订阅”消息),而不是一般的MIME主体。

So any solution depends on HTML tags is not possible. 所以任何解决方案都取决于HTML标签是不可能的。 The solution I'm suggesting is to use \\r\\n along with PHP function rawurlencode 我建议的解决方案是使用\\ r \\ n和PHP函数rawurlencode

So here's the code 所以这是代码

<?php

     printf( 
    '<a class="simple-mail-link" href="mailto:x@y.com?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
    'My Subject',
    rawurlencode(sprintf( "Hi there, this might be interesting for you.\r\nThis is the link: %s.\r\nHave a great day!\r\nStefaan", get_the_permalink()))
    );

?>

Note: I tried the code with replacing get_the_permalink() with variable carrying http://example.com/test.php 注意:我尝试使用带有http://example.com/test.php的变量替换get_the_permalink()代码

references: 引用:

MailTo with HTML body 带有HTML正文的MailTo

What is the equivalent of JavaScript's encodeURIcomponent in PHP? 在PHP中,JavaScript的encodeURIcomponent相当于什么?

According to the e-mail specification, every e-mail line needs to end in the old <CR><LF> pair - so you need to use \\r\\n in the sprintf() string. 根据电子邮件规范,每个电子邮件行都需要以旧的<CR><LF>对结束 - 因此您需要在sprintf()字符串中使用\\r\\n

"This is the link: %s.\\r\\n Have a great day!\\r\\n Stefaan"

And if \\r\\n doesn't work, you've got a source-language limitation. 如果\\r\\n不起作用,你就有源语言限制。 Given that: 鉴于:

  • \\r is ASCII 13 (hex 0D ) \\r是ASCII 13 (十六进制0D
  • \\n is ASCII 10 (hex 0A ) \\n是ASCII 10 (十六进制0A

perhaps you could use "&#13;&#10;" 也许你可以使用"&#13;&#10;" ?

Use urlencoded string for CR/LF 使用urlencoded字符串表示CR / LF

%0D%0A

where you want a break. 你想要休息的地方。

In example 在例子中

<a 
 class="simple-mail-link" 
 href="mailto:?subject=hello&body=Hello%0D%0A%0D%0AWorld!"
>

Add another %s argument to your sprintf() call and pass it the URL-encoded version of the line-feed char %0A (twice): sprintf()调用中添加另一个%s参数,并将换行符char %0A的URL编码版本(两次)传递给它:

printf( 
        '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
        'subject',
        sprintf( 'Hi there, this might be interesting for you. This is the link: %s. %sHave a great day! Stefaan', "link-here", "%0A%0A" )
    );

Edit: Additionally, you could also just add the %0A to the string itself, but you have to remember to escape the % char by adding an extra one before it: 编辑:此外,您还可以将%0A添加到字符串本身,但您必须记住通过在它之前添加额外的一个来转义% char:

printf( 
        '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
        'subject',
        sprintf( 'Hi there, this might be interesting for you. This is the link: %s. %%0A%%0AHave a great day! Stefaan', "link-here" )
    );

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. 要在mailto: URL body参数中使用文本,请对其进行百分比编码 In PHP, use rawurlencode() . 在PHP中,使用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() . 要将它用作HTML链接的目标,请将HTML中具有特殊含义的字符替换为实体引用 - 在PHP中使用htmlspecialchars() ,并且Wordpress具有更高级的(和可过滤的) 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&amp;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. 我相信到现在为止,您知道如何修改PHP代码以生成这样的链接。

Debugging the issue 调试问题

You have to deal with several levels of technologies , each having its own escaping scheme: 您必须处理多个级别的技术 ,每个技术都有自己的转义方案:

  • PHP (eg "\\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" ) PHP(例如"\\n"是带换行符的字符串,不带反斜杠和字母n;如果你需要,你需要转义反斜杠 - "\\\\n"

  • (s)printf (eg to print a literal % , you have to write %% ) (s)printf(例如,要打印文字% ,你必须写%%

  • HTML (eg & starts an entity reference; to be taken literally, it should be encoded as the entity reference &amp; ) HTML(例如&开始实体引用;从字面上看,它应该被编码为实体引用&amp;

  • URL (eg space is not a valid part of a URL and it must be percent-encoded as %20 ) URL(例如,空格不是URL的有效部分,必须以百分比编码%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? 您是否验证了PHP代码的保存方式与您编写的完全相同?
  • Did you look at the HTML it produces? 你看过它产生的HTML了吗?
  • And did you try to copy the URL by right-clicking the link in the browser and choosing “Copy Email Address”? 您是否尝试通过右键单击浏览器中的链接并选择“复制电子邮件地址”来复制URL?

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. 在这种情况下,这样的产品是一旦粘贴到浏览器的位置栏中的URL就打开了预先填充多行体的邮件编辑器。 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. 如果即使手动构建URL也会卡住,那你就不走运了。 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. 其中至少有一个有bug。 In my experience with mailto: URLs, this is not uncommon. 根据我使用mailto:URL的经验,这并不罕见。 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 除此之外:HTML规范提出了尝试

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. 我花了很多时间来看看HTML规范中关于我在其他答案和问题本身所呈现的尝试中看到的问题。 Specifically: 特别:

  • unencoded ampersand in attribute value 属性值中未编码的&符号
  • newline in attribute value 属性值中的换行符
  • unencoded < and > in HTML markup ( <br> ) in attribute value 属性值中的HTML标记( <br> )中未编码的<>

Syntactic level 句法层面

HTML implementations are pretty robust these days and even the HTML spec became very permissive regarding encoding ampersands ( & ) into entity references ( &amp; ; called character references in HTML5), therefore you will usually get away with not doing that. HTML实现现在相当强大,甚至HTML规范也变得非常宽松,将&符号( & )编码为实体引用( &amp;在HTML5中称为字符引用 ),因此通常不会这样做。 (HTML 4 spec required the encoding, though.) (但HTML 4规范要求编码。)

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). 在HTML文件中的实际字节级别, HTML5中的引用属性值可以自由包含几乎任何字符,除了用于引用它们的引号(必须用字符引用替换)。

* For details, see Preprocessing the input stream and ambiguous ampersand in HTML5 spec. *有关详细信息,请参阅HTML5规范中的预处理输入流不明确的&符号

This is why even newline and unencoded <br> are OK inside quoted attribute values. 这就是为什么即使换行和未编码的<br>在引用的属性值中也可以。 But actually, they are not OK in href (unlike in eg title ), because… 但实际上,它们在href并不好(与title不同),因为......

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 这就是HTML咬你的地方 - 指定href包含可能由空格包围有效URL ,但不能包含空格

  • 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. 对于URL及其语法的实际定义 ,HTML规范遵循其他规范。

Handling invalid URLs is implementation-defined , these machanisms may not be consistent across browsers. 处理无效URL是实现定义的 ,这些机制可能在浏览器之间不一致。 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. 我的Firefox忽略换行符并保留空格 - URL中也不允许使用空格,但Firefox在对URL执行任何其他操作之前对其进行编码。

You could add <br> tag in your sprintf (assuming you want to display break line in for HTML): 您可以在sprintf中添加<br>标签(假设您要为HTML显示断行):

sprintf( 'Hi there, this might be interesting for you. This is the link: %s.<br> Have a great day!<br> Stefaan',get_the_permalink() )

EDIT: 编辑:

If you want plain text mail use \\r\\n and double quotes: 如果您想要纯文本邮件,请使用\\r\\n和双引号:

sprintf("Hi there, this might be interesting for you. This is the link: %s.\r\n Have a great day!\r\n Stefaan",get_the_permalink() )

You could probably chuck a PHP_EOL in there 你可能会在那里扔掉一个PHP_EOL

<?php
     printf( 
        '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
        the_title_attribute( 'echo=0' ),
        sprintf( 'Hi there, this might be interesting for you. This is the link: %s. %sHave a great day! %sStefaan',get_the_permalink(), PHP_EOL, PHP_EOL )
    );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM