Update plugin.py

master
zxc 4 months ago
parent f83339d3eb
commit 84127fe0af

@ -6,43 +6,51 @@ from djangoblog.plugin_manage.hook_constants import ARTICLE_CONTENT_HOOK_NAME
class ExternalLinksPlugin(BasePlugin):
PLUGIN_NAME = '外部链接处理器'
PLUGIN_DESCRIPTION = '自动为文章中的外部链接添加 target="_blank" 和 rel="noopener noreferrer" 属性。'
PLUGIN_VERSION = '0.1.0'
PLUGIN_AUTHOR = 'liangliangyy'
# 插件元信息定义,用于系统识别和管理插件
PLUGIN_NAME = '外部链接处理器' # 插件名称,显示在插件管理界面
PLUGIN_DESCRIPTION = '自动为文章中的外部链接添加 target="_blank" 和 rel="noopener noreferrer" 属性。' # 功能描述
PLUGIN_VERSION = '0.1.0' # 插件版本号
PLUGIN_AUTHOR = 'liangliangyy' # 插件作者
# 注册钩子:将插件功能绑定到文章内容处理钩子
def register_hooks(self):
# 当系统触发ARTICLE_CONTENT_HOOK_NAME文章内容钩子执行process_external_links方法
hooks.register(ARTICLE_CONTENT_HOOK_NAME, self.process_external_links)
# 核心功能:处理文章中的外部链接,添加安全属性
def process_external_links(self, content, *args, **kwargs):
# 导入工具函数,获取当前网站的域名(用于判断是否为外部链接)
from djangoblog.utils import get_current_site
site_domain = get_current_site().domain
# 正则表达式查找所有 <a> 标签
# 正则表达式:匹配文章中的<a>标签,捕获 href 属性值及标签前后内容
# 匹配规则:<a ... href="链接地址" .../>,不区分大小写
link_pattern = re.compile(r'(<a\s+(?:[^>]*?\s+)?href=")([^"]*)(".*?/a>)', re.IGNORECASE)
# 替换函数:对匹配到的<a>标签进行处理
def replacer(match):
# match.group(1) 是 <a ... href="
# match.group(2) 是链接 URL
# match.group(3) 是 ">...</a>
# 解构匹配结果group(1)=<a ... href="group(2)=链接URLgroup(3)=".../a>
href = match.group(2)
full_a_tag = match.group(0)
# 如果链接已经有 target 属性,则不处理
if 'target=' in match.group(0).lower():
return match.group(0)
# 跳过已包含target属性的链接避免重复添加
if 'target=' in full_a_tag.lower():
return full_a_tag
# 解析链接
# 解析链接URL提取域名netloc
parsed_url = urlparse(href)
# 如果链接是外部的 (有域名且域名不等于当前网站域名)
# 判断是否为外部链接:有域名(非相对路径)且域名不等于当前网站域名
if parsed_url.netloc and parsed_url.netloc != site_domain:
# 添加 target 和 rel 属性
# 为外部链接添加 target="_blank"(新窗口打开)和 rel="noopener noreferrer"(安全防护)
return f'{match.group(1)}{href}" target="_blank" rel="noopener noreferrer"{match.group(3)}'
# 否则返回原样
return match.group(0)
# 内部链接(相对路径或同域名):返回原标签,不做修改
return full_a_tag
# 用replacer函数替换content中所有匹配的<a>标签,返回处理后的内容
return link_pattern.sub(replacer, content)
# 实例化插件:自动触发父类初始化,完成钩子注册,使插件生效
plugin = ExternalLinksPlugin()

Loading…
Cancel
Save