我最近实施了将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
”用空字符串手动替换部分输出。
问题:
这样做的正确和最佳方式是什么?
答案 0 :(得分:7)
一直在努力解决同样的问题,并且无法使用wagtailhooks来实现它。我最初的解决方案是使用过滤器操纵base.html中的内容。当放置在内容块中时,用于剪切代码片段的过滤器非常有效,例如:
{{ self.body|cut: ‘ href="http:’}}
上面的过滤器会删除部分内容,但遗憾的是“替换”不能用作过滤器(我使用的是Python 3.x)。因此,我的下一个方法是构建一个custom_filter来创建'replace'作为过滤选项。长话短说:它部分有效,但前提是内容从原始的'StreamValue'数据类型转换为'string'。此转换导致显示所有html标记的内容,因此替换不会导致工作html。我无法再将内容恢复到StreamValue,没有其他Python数据类型可以解决问题。 最终JQuery为我完成了工作:
$(document).ready(function(){
$('a[href^="http://"]').attr('target', '_blank');
});
此代码将'target =“_ blank”'添加到包含'http://'的每个链接,因此所有内部链接都保留在现有标签中。它需要放在base.html(或类似的)的末尾,当然你需要在运行它之前加载它。 得到了here的答案。 不知道JQuery是否是正确的,最好的方法,但它对我来说就像是一个很少编码的魅力。
答案 1 :(得分:3)
从Wagtail v2.5开始,作为Wagtail富文本处理的一部分,有一个API可以像这样进行自定义:Rewrite handlers
,带有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"
,用target="_blank"
修复了known security issue。
与以前解决此问题的方法相比,此新方法最可靠:完全在服务器端仅覆盖链接在网站前端上的呈现方式,而不是链接的存储方式,而仅依赖于已记录的API内部细节/实施细节。