邮件收件人:链接正文中的换行符



我想在博客文章下方创建一个"将此转发给朋友"链接,该博客文章打开我的电子邮件客户端并带有准备好的消息。我可以让它适用于单行消息,但我希望能够中断消息正文内的行。我该怎么做?

<?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())
);
?>

如何在新行上以空行开始"祝你有美好的一天!"?

链接:...

祝你有美好的一天!

斯蒂芬

我的博客使用带有创世纪主题的WordPress,我将我的代码放入启用PHP的genesis_footer_entry钩中(见屏幕截图 - 电子邮件文本是荷兰语)。

您不能在邮件正文中使用 HTML 标记

根据 RFC 2368,这是不可能的:

特殊的 hname "body" 表示关联的 hvalue 是 消息的正文。"body"hname 应包含以下内容 消息的第一个文本/纯正文部分。邮件收件人网址是 主要用于生成以下短文本消息: 实际上是自动处理的内容(如"订阅" 邮件列表的消息),而不是一般的 MIME 机构。

因此,任何依赖于HTML标签的解决方案都是不可能的。 我建议的解决方案是使用 \r和 PHP 函数rawurlencode

所以这是代码

<?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.rnThis is the link: %s.rnHave a great day!rnStefaan", get_the_permalink()))
);
?>

注意:我尝试将get_the_permalink()替换为变量携带 http://example.com/test.php

引用:

带有 HTML 正文的邮件收件人

在PHP中,JavaScript的encodeURI组件相当于什么?

解释

a mailto:是电子邮件地址的 URI 方案,与所有其他 URI 一样,字符需要转换为可以通过 Internet 传输的格式。

采用原始代码的简化形式来说明以下几点

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

代码按以下顺序运行

  1. get_the_permalink()获取页面的网址
  2. sprintf()$content%s替换为步骤 1 的结果
  3. 然后print_f()替换
    i) 第一个%s,即subject=%sthe_title_attribute( 'echo=0' )的获取结果,我假设 是页面或网站的标题,然后 ii) 第二%sbody=%s与步骤 2 的结果一起形成完整的a mailto链接

为了保留换行符,您应该在输出之前将$content字符串转换为 URL 编码形式。

在PHP中,这是通过使用rawurlencode()函数完成的,它将字符串中的换行符rn转换为%0D%0A,根据RFC 3986

由于百分号%sprint_f()中用于转换规范,因此在字符串被sprint_f()格式化后,你应该将字符串传递给rawurlencode(),因此使用rawurlencode(sprint_f($string, $arg))

解决方案

我已经完整地整理了解决方案
,供您复制并粘贴到您的小部件中,以避免由于错误实施而导致的漏报。

格式 1和格式 2 包含基本相同的代码,这两种格式可以向您说明如何插入换行符,要么按 1)pressing enterOR 2) 通过typing in rn需要换行符的地方。

我已将$content一个单独的字符串,以便于编辑和代码的可读性。

格式 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()))
);
?>

格式 2

<?php
//Start new line by adding rn
//IMPORTANT NOTE: do not remove the %s 
$content="Hi there, this might be interesting for yournThis is the link: %srnHave a great day!rnStefaan";
//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()))
);              
?>

演示

<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>

根据电子邮件规范,每行电子邮件都需要以旧的<CR><LF>对结尾 - 因此您需要在sprintf()字符串中使用rn

"This is the link: %s.rn Have a great day!rn Stefaan"

如果rn不起作用,那么您就有了源语言的限制。鉴于:

  • r是 ASCII13(十六进制0D)
  • n是 ASCII10(十六进制0A)

也许你可以使用"&#13;&#10;"

对 CR/LF 使用 urlencoding 字符串

%0D%0A

你想休息的地方。

在示例中

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

将另一个%s参数添加到您的sprintf()调用中,并向其传递换行字符%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" )
);

编辑: 此外,您也可以将%0A添加到字符串本身,但您必须记住通过在它之前添加一个额外的字符来转义%字符:

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" )
);

我决定彻底解决这个问题并解决这里所做的所有尝试。如果您想要快速答案,请查看当前接受的答案。

工作解决方案

若要在 URLbody参数中使用文本mailto:请对其进行百分比编码。在 PHP 中,使用rawurlencode()。主题也应该被编码。

$subj = "Whatever subject";
$body = "Multi-rnlinernbody";
printf(
"mailto:?subject=%s&body=%s",
rawurlencode($subj),
rawurlencode($body)
);
mailto:?subject=Whatever%2Osubject&body=Multi-%0D%0Aline%0D%0Abody

要将其用作HTML链接的目标,请将HTML中具有特殊含义的字符替换为实体引用 -htmlspecialchars()用于PHP中的字符,而Wordpress具有更高级(和可过滤)的esc_html()

$subj = "Whatever subject";
$body = "Multi-rnlinernbody";
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>

我相信到目前为止,您知道如何修改PHP代码以生成这样的链接。

调试问题

您必须处理多个级别的技术,每个技术都有自己的转义方案:

  • PHP(例如"n"是带有换行符的字符串,而不是带有反斜杠和字母 n 的字符串;如果你想要,你需要转义反斜杠 -"\n"

    )
  • (
  • s)printf(例如,要打印文字%,你必须写%%)

  • 网页(例如&启动实体引用;从字面上理解,它应该编码为实体引用&amp;)

  • URL
  • (例如,空格不是URL的有效部分,必须按百分比编码为%20)

手动执行此操作太多,并且无需检查中间步骤即可确保其正确。如果你弄错了任何中间步骤,它就会作为一个整体被破坏。

  • 您是否验证了 PHP 代码是否完全按照您编写的方式保存?
  • 你看过它产生的 HTML 吗?
  • 您是否尝试通过右键单击浏览器中的链接并选择"复制电子邮件地址"来复制 URL?

安全的方法是手动构造最后一步的产品,并且只有在它起作用后,才继续并尝试以编程方式生成它。在这种情况下,这样的产品是一旦粘贴到浏览器的地址栏中就会打开预填充多行正文的邮件编辑器的 URL。您可以从一个简单的工作示例开始,然后使其变得越来越复杂,直到它满足您的需求。当手动构造太繁琐时,您可能选择了太复杂的产品 - 选择最简单的仍然按照您想要的方式工作的产品,您可以稍后增加复杂性。

如果您即使手动构建 URL 也陷入困境,那么您就不走运了。要么你必须阅读更多关于这个话题的信息,寻求帮助,要么放弃。如果不仅仅是您,则问题出在您的浏览器和电子邮件客户端之间。其中至少有一个有错误。根据我对mailto:URL的经验,这种情况并不少见。即使您让它为您工作,您博客的访问者也可能对他们的设置不那么幸运。


旁白:关于呈现的尝试的 HTML 规范

我花时间查看了HTML规范对我在尝试中看到的问题的看法,这些问题在其他答案和问题本身中提出。具体说来:

  • 属性值中未编码的与号和
  • 属性值中的换行符
  • 属性值中 HTML 标记 (<br>) 中的未编码<>

句法级别

如今,HTML实现非常健壮,甚至HTML规范也变得非常宽容地将与号(&)编码为实体引用(&amp;;在HTML5中称为字符引用),因此您通常会侥幸不这样做。(不过,HTML 4规范需要编码。

在 HTML 文件中的实际字节级别,HTML5 中带引号的属性值可以自由包含几乎*任何字符,但用于引号的引号除外(必须替换为字符引用)。

* 有关详细信息,请参阅 HTML5 规范中的输入流和不明确的与号预处理。

这就是为什么即使是换行符和未编码<br>也可以在引号属性值内使用的原因。但实际上,它们在href是不行的(不像例如title),因为...

语义级别

在语义级别,当解析所有内容时,允许任何字符串(包括空字符串)作为属性值,但特定属性会添加进一步的约束。

这是 HTML 咬你的地方 -href被指定为包含一个可能被空格包围的有效 URL,而空格不能包含

  • 中间的换行符和其他空格字符和
  • <>和许多其他角色。

这些字符必须进行百分比编码。对于 URL 及其语法的实际定义,HTML 规范遵循其他规范。

处理无效 URL 是实现定义的,这些机制在浏览器之间可能不一致。只需遵守规格即可。我的 Firefox 忽略换行符并保留空格 - URL 中也不允许空格,但 Firefox 会在对 URL 执行任何其他操作之前对其进行编码。

您可以在 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() )

编辑:

如果要纯文本邮件,请使用rn和双引号:

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

你可能会把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 )
);

最新更新