在 wagtail 中以新 window 打开外部链接
Making external links open in a new window in wagtail
我最近实现了将 target="_blank"
添加到外部链接,如下所示:
@hooks.register('after_edit_page')
def do_after_page_edit(request, page):
if hasattr(page, "body"):
soup = BeautifulSoup(page.body)
for a in soup.findAll('a'):
if hasattr(a, "href"):
a["target"] = "_blank"
page.body = str(soup)
page.body = page.body.replace("<html><head></head><body>", "")
page.body = page.body.replace("</body></html>", "")
page.body = page.body.replace("></embed>", "/>")
page.save()
@hooks.register('construct_whitelister_element_rules')
def whitelister_element_rules():
return {
'a': attribute_rule({'href': check_url, 'target': True}),
}
问题:
美丽的汤弄乱了输出,添加了 html, head & body
标签 - Don't put html, head and body tags automatically, beautifulsoup
它还与嵌入标签混淆 - How to get BeautifulSoup 4 to respect a self-closing tag?
因此我糟糕的“fix
”用空白字符串手动替换了部分输出。
问题:
执行此操作的正确和最佳方法是什么?
一直在努力解决同样的问题,无法使用 wagtailhooks 实现。我最初的解决方案是使用过滤器来处理 base.html 中的内容。用于剪切代码片段的过滤器放在内容块中时效果很好,例如:
{{ self.body|cut: ‘ href="http:’}}
上面的过滤器删除了部分内容,但不幸的是“替换”不能用作过滤器(我使用 Python 3.x)。因此,我的下一个方法是构建一个 custom_filter 来创建“替换”作为过滤器选项。长话短说:它部分起作用,但前提是内容从原始的“StreamValue”数据类型转换为“字符串”。此转换导致显示所有 html 标签的内容,因此替换没有导致工作 html。我无法再次将内容返回到 StreamValue,并且没有其他 Python 数据类型可以解决该问题。
最终 JQuery 帮我完成了工作:
$(document).ready(function(){
$('a[href^="http://"]').attr('target', '_blank');
});
此代码将“target="_blank"”添加到每个包含“http://”的 link,因此所有内部 link 都保留在现有选项卡中。它需要放在 base.html(或类似的)的末尾,当然你需要在 运行 之前加载 JQuery。
从 here 得到了我的答案。
不知道 JQuery 是否是正确和最好的方法,但它对我来说就像一个魅力,只需最少的编码。
从 Wagtail v2.5 开始,作为 Wagtail 的富文本处理的一部分,有一个 API 可以进行这样的自定义:Rewrite handlers
, with the register_rich_text_features
钩子。
下面是一个使用这个新的 API 来制作重写处理程序的示例,该处理程序将 target="_blank"
属性设置为所有外部链接:
from django.utils.html import escape
from wagtail.core import hooks
from wagtail.core.rich_text import LinkHandler
class NewWindowExternalLinkHandler(LinkHandler):
# This specifies to do this override for external links only.
# Other identifiers are available for other types of links.
identifier = 'external'
@classmethod
def expand_db_attributes(cls, attrs):
href = attrs["href"]
# Let's add the target attr, and also rel="noopener" + noreferrer fallback.
# See https://github.com/whatwg/html/issues/4078.
return '<a href="%s" target="_blank" rel="noopener noreferrer">' % escape(href)
@hooks.register('register_rich_text_features')
def register_external_link(features):
features.register_link_type(NewWindowExternalLinkHandler)
在此示例中,我还添加了 rel="noopener"
以修复 known security issue 和 target="_blank"
。
与以前解决这个问题的方法相比,这个新方法是最可靠的:它完全在服务器端,只覆盖网站前端的链接呈现方式,而不是它们的存储方式,并且只依赖于记录了 APIs 而不是内部的/实现细节。
我最近实现了将 target="_blank"
添加到外部链接,如下所示:
@hooks.register('after_edit_page')
def do_after_page_edit(request, page):
if hasattr(page, "body"):
soup = BeautifulSoup(page.body)
for a in soup.findAll('a'):
if hasattr(a, "href"):
a["target"] = "_blank"
page.body = str(soup)
page.body = page.body.replace("<html><head></head><body>", "")
page.body = page.body.replace("</body></html>", "")
page.body = page.body.replace("></embed>", "/>")
page.save()
@hooks.register('construct_whitelister_element_rules')
def whitelister_element_rules():
return {
'a': attribute_rule({'href': check_url, 'target': True}),
}
问题:
美丽的汤弄乱了输出,添加了
html, head & body
标签 - Don't put html, head and body tags automatically, beautifulsoup它还与嵌入标签混淆 - How to get BeautifulSoup 4 to respect a self-closing tag?
因此我糟糕的“
fix
”用空白字符串手动替换了部分输出。
问题:
执行此操作的正确和最佳方法是什么?
一直在努力解决同样的问题,无法使用 wagtailhooks 实现。我最初的解决方案是使用过滤器来处理 base.html 中的内容。用于剪切代码片段的过滤器放在内容块中时效果很好,例如:
{{ self.body|cut: ‘ href="http:’}}
上面的过滤器删除了部分内容,但不幸的是“替换”不能用作过滤器(我使用 Python 3.x)。因此,我的下一个方法是构建一个 custom_filter 来创建“替换”作为过滤器选项。长话短说:它部分起作用,但前提是内容从原始的“StreamValue”数据类型转换为“字符串”。此转换导致显示所有 html 标签的内容,因此替换没有导致工作 html。我无法再次将内容返回到 StreamValue,并且没有其他 Python 数据类型可以解决该问题。 最终 JQuery 帮我完成了工作:
$(document).ready(function(){
$('a[href^="http://"]').attr('target', '_blank');
});
此代码将“target="_blank"”添加到每个包含“http://”的 link,因此所有内部 link 都保留在现有选项卡中。它需要放在 base.html(或类似的)的末尾,当然你需要在 运行 之前加载 JQuery。 从 here 得到了我的答案。 不知道 JQuery 是否是正确和最好的方法,但它对我来说就像一个魅力,只需最少的编码。
从 Wagtail v2.5 开始,作为 Wagtail 的富文本处理的一部分,有一个 API 可以进行这样的自定义:Rewrite handlers
, with the register_rich_text_features
钩子。
下面是一个使用这个新的 API 来制作重写处理程序的示例,该处理程序将 target="_blank"
属性设置为所有外部链接:
from django.utils.html import escape
from wagtail.core import hooks
from wagtail.core.rich_text import LinkHandler
class NewWindowExternalLinkHandler(LinkHandler):
# This specifies to do this override for external links only.
# Other identifiers are available for other types of links.
identifier = 'external'
@classmethod
def expand_db_attributes(cls, attrs):
href = attrs["href"]
# Let's add the target attr, and also rel="noopener" + noreferrer fallback.
# See https://github.com/whatwg/html/issues/4078.
return '<a href="%s" target="_blank" rel="noopener noreferrer">' % escape(href)
@hooks.register('register_rich_text_features')
def register_external_link(features):
features.register_link_type(NewWindowExternalLinkHandler)
在此示例中,我还添加了 rel="noopener"
以修复 known security issue 和 target="_blank"
。
与以前解决这个问题的方法相比,这个新方法是最可靠的:它完全在服务器端,只覆盖网站前端的链接呈现方式,而不是它们的存储方式,并且只依赖于记录了 APIs 而不是内部的/实现细节。