python - 在 wagtail 的新窗口中打开外部链接

标签 python html django hook 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}),
    }

问题:

  1. 漂亮的汤弄乱了输出,添加了 html、head 和 body 标签 - Don't put html, head and body tags automatically, beautifulsoup

  2. 它还与嵌入标签混淆 - How to get BeautifulSoup 4 to respect a self-closing tag?

  3. 因此我糟糕的“fix”手动将部分输出替换为空白字符串。

问题:

执行此操作的正确和最佳方法是什么?

最佳答案

从 Wagtail v2.5 开始,有一个 API 可以像这样作为 Wagtail 富文本处理的一部分进行自定义:Rewrite handlers , 与 register_rich_text_features钩子(Hook)。

下面是一个使用这个新 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"


与之前针对此问题的解决方案相比,这种新方法是最可靠的:它完全是服务器端的,只覆盖链接在站点前端的呈现方式而不是它们的存储方式,并且只依赖于文档化的 API而不是内部的/实现细节。

关于python - 在 wagtail 的新窗口中打开外部链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33300941/

相关文章:

django admin - 访问 BaseInlineFormSet 中的 request.user

python - render 和 render_to_string 有什么区别?

Python 线程和 GIL

HTML5 Canvas save()和restore()性能

javascript - 如何更改自己定义的属性

python - 我可以删除迁移目录中的 django 迁移文件吗

python - 使用 couchdb-python 处理嵌套对象

python - 你如何从 python 中做一个简单的 "chmod +x"?

python - 如何为makerbot/s3g设置虚拟环境

javascript - 未定义 onclick 事件的函数 -HTML5 canvas