LOADING

加载过慢请开启缓存 浏览器默认开启

Anzhiyu_Flink_Encrypt

Anzhiyu_Flink_Encrypt - 基于anzhiyu主题实现友链页面加密功能

前言: 为了反社工侦察,博主独创的友链加密功能,以防信息搜集者通过你的博客定位到你朋友的博客(bushi
s

(其实只是一个形式了

ps:本站友链密码:Q3liZXJTZWN1cml0eUAxMTQ1MTQ= 你不是来社工的对吧!👀

v1.1

更新内容: 添加控制加密功能,可在_config.yml文件中设置encrypted_friends的参数来控制网站是否启用友链加密功能

//- includes/page/flink.pug

//- 检查是否开启友链加密功能
//- 逻辑:当 encrypted_friends 为 false 时关闭加密,否则需要 page.password 才加密
- const encrypted_friends_setting = theme.encrypted_friends
- const enableEncryption = encrypted_friends_setting !== false && page.password

if enableEncryption
  #hexo-blog-encrypt
    .hbe-input-container
      input(type="password" id="hbePass" placeholder=page.message || "请输入密码查看友链")
      button(onclick="decryptFriends()") 解密查看
    #hbeError(style="display:none;color:red;margin-top:10px;")= page.wrong_pass_message || '密码错误!'

  #encrypted-content(style="display:none;")
    #article-container
      if theme.linkPageTop && theme.linkPageTop.enable
        #flink-banners
          .banner-top-box
            .flink-banners-title
              .banners-title-small 友情链接
              .banners-title-big=theme.linkPageTop ? theme.linkPageTop.title : "与数百名博主无限进步"
            .banner-button-group
              if (theme.friends_vue.apiurl)
                a.banner-button.secondary.no-text-decoration(onclick="friendChainRandomTransmission()")
                  i.anzhiyufont.anzhiyu-icon-paper-plane1
                  span.banner-button-text 随机访问
              if theme.linkPageTop.addFriendPlaceholder && theme.comments.use == 'Twikoo' && theme.twikoo.envId
                a.banner-button.no-text-decoration(onclick="anzhiyu.addFriendLink()")
                  i.anzhiyufont.anzhiyu-icon-arrow-circle-right
                  span.banner-button-text 申请友链
          #skills-tags-group-all
            .tags-group-wrapper
              - function getAvatarWithoutExclamationMark(url) {
              -   const index = url.indexOf('!');
              -   return index !== -1 ? url.substring(0, index) : url;
              - }
              each y in [1,2]
                each i, index in site.data.link.slice(0, 15)
                  - const link_list = i.link_list.slice()
                  - const hundredSuffix = i.hundredSuffix ? i.hundredSuffix : ""
                  - const evenNum = link_list.filter((x, index) => index % 2 === 0);
                  - const oddNum = link_list.filter((x, index) => index % 2 === 1);
                  each item, index2 in link_list.slice(0, Math.min(evenNum.length, oddNum.length))
                    - const index = index2 * 2
                    if (index <= 15 && typeof evenNum[index] !== 'undefined' && typeof oddNum[index] !== 'undefined')
                      - let oddNumAvatar = getAvatarWithoutExclamationMark(oddNum[index].avatar);
                      - let evenNumAvatar = getAvatarWithoutExclamationMark(evenNum[index].avatar);
                      .tags-group-icon-pair
                        a.tags-group-icon.no-text-decoration(href=url_for(evenNum[index].link), title=evenNum[index].name)
                          img.no-lightbox(title=evenNum[index].name, src=url_for(evenNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=evenNum[index].name)
                        a.tags-group-icon.no-text-decoration(href=url_for(oddNum[index].link), title=oddNum[index].name)
                          img.no-lightbox(title=oddNum[index].name, src=url_for(oddNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=oddNum[index].name)
      if theme.friends_vue && theme.friends_vue.enable
        .title-h2-a
          .title-h2-a-left
            h2(style='padding-top:0;margin:.6rem 0 .6rem') 🎣 钓鱼
            a.random-post-start.no-text-decoration(href='javascript:fetchRandomPost();')
              i.anzhiyufont.anzhiyu-icon-arrow-rotate-right
          .title-h2-a-right
            a.random-post-all.no-text-decoration(href='/link/') 全部友链
        #random-post
        script(defer data-pjax src=url_for(theme.asset.random_friends_post_js))
      
      .flink
        if site.data.link
          each i in site.data.link
            if i.class_name
              h2!= i.class_name + "(" + i.link_list.length + ")"
            if i.class_desc
              .flink-desc!=i.class_desc
            if i.flink_style === 'anzhiyu'
              div(class=i.lost_contact ? 'anzhiyu-flink-list cf-friends-lost-contact' : 'anzhiyu-flink-list')
                if i.link_list
                  each item in i.link_list
                    - let color = item.color || ""
                    - let tag = item.tag || ""
                    
                    .flink-list-item
                      if color == "vip" && tag
                        span.site-card-tag.vip #[=tag]
                          i.light
                      else if color == "speed" && tag
                        span.site-card-tag.speed #[=tag]
                      else if tag
                        span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                      else if item.recommend
                        span.site-card-tag 荐
                      if i.lost_contact
                        a.cf-friends-link(href=url_for(item.link) title=item.name target="_blank")
                          if theme.lazyload.enable
                            img.no-lightbox(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          else
                            img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          .flink-item-info
                            .flink-item-name.cf-friends-name-lost-contact= item.name
                      else
                        a.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) title=item.name target="_blank")
                          if theme.lazyload.enable
                            img.cf-friends-avatar.no-lightbox(data-lazy-src=url_for(item.avatar), cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          else
                            img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          .flink-item-info
                            .flink-item-name.cf-friends-name= item.name
                            .flink-item-desc(title=item.descr)= item.descr
            
            else if i.flink_style === 'telescopic'
              .telescopic-site-card-group
                each item in i.link_list
                  - let color = item.color || ""
                  - let tag = item.tag || ""
                  - let siteshot = item.siteshot || `https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/${item.link}` || theme.default_img
                  .site-card
                    if color == "vip" && tag
                      span.site-card-tag.vip #[=tag]
                        i.light
                    else if color == "speed" && tag
                      span.site-card-tag.speed #[=tag]
                    else if tag
                      span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                    else if item.recommend
                      span.site-card-tag 荐
                    a.img.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, rel='external nofollow')
                      img.flink-avatar(data-lazy-src=siteshot, onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, style="pointer-events: none;", src=`${siteshot}`)
                    a.info.cf-friends-link.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, cf-href=url_for(item.link), rel='external nofollow')
                      .site-card-avatar
                        img.flink-avatar.cf-friends-avatar.no-fancybox(data-lazy-src=item.avatar, cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, src=item.avatar)
                      .site-card-text
                        span.title.cf-friends-name #[=item.name]
                        span.desc(title=`${item.descr}`) #[=item.descr]
            else if i.flink_style === 'flexcard'
              .flexcard-flink-list
                each item in i.link_list
                  a.flink-list-card.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) target='_blank' data-title=item.descr)
                    .wrapper.cover
                      - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
                      if theme.lazyload.enable
                        img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )
                      else
                        img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )    
                    .info
                      if theme.lazyload.enable
                        img.cf-friends-avatar.no-lightbox.flink-avatar(data-lazy-src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                      else
                        img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                      span.flink-sitename.cf-friends-name= item.name
      != page.content

else
  //- 非加密模式:直接显示内容
  #article-container
    if theme.linkPageTop && theme.linkPageTop.enable
      #flink-banners
        .banner-top-box
          .flink-banners-title
            .banners-title-small 友情链接
            .banners-title-big=theme.linkPageTop ? theme.linkPageTop.title : "与数百名博主无限进步"
          .banner-button-group
            if (theme.friends_vue.apiurl)
              a.banner-button.secondary.no-text-decoration(onclick="friendChainRandomTransmission()")
                i.anzhiyufont.anzhiyu-icon-paper-plane1
                span.banner-button-text 随机访问
            if theme.linkPageTop.addFriendPlaceholder && theme.comments.use == 'Twikoo' && theme.twikoo.envId
              a.banner-button.no-text-decoration(onclick="anzhiyu.addFriendLink()")
                i.anzhiyufont.anzhiyu-icon-arrow-circle-right
                span.banner-button-text 申请友链
        #skills-tags-group-all
          .tags-group-wrapper
            - function getAvatarWithoutExclamationMark(url) {
            -   const index = url.indexOf('!');
            -   return index !== -1 ? url.substring(0, index) : url;
            - }
            each y in [1,2]
              each i, index in site.data.link.slice(0, 15)
                - const link_list = i.link_list.slice()
                - const hundredSuffix = i.hundredSuffix ? i.hundredSuffix : ""
                - const evenNum = link_list.filter((x, index) => index % 2 === 0);
                - const oddNum = link_list.filter((x, index) => index % 2 === 1);
                each item, index2 in link_list.slice(0, Math.min(evenNum.length, oddNum.length))
                  - const index = index2 * 2
                  if (index <= 15 && typeof evenNum[index] !== 'undefined' && typeof oddNum[index] !== 'undefined')
                    - let oddNumAvatar = getAvatarWithoutExclamationMark(oddNum[index].avatar);
                    - let evenNumAvatar = getAvatarWithoutExclamationMark(evenNum[index].avatar);
                    .tags-group-icon-pair
                      a.tags-group-icon.no-text-decoration(href=url_for(evenNum[index].link), title=evenNum[index].name)
                        img.no-lightbox(title=evenNum[index].name, src=url_for(evenNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=evenNum[index].name)
                      a.tags-group-icon.no-text-decoration(href=url_for(oddNum[index].link), title=oddNum[index].name)
                        img.no-lightbox(title=oddNum[index].name, src=url_for(oddNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=oddNum[index].name)
    if theme.friends_vue && theme.friends_vue.enable
      .title-h2-a
        .title-h2-a-left
          h2(style='padding-top:0;margin:.6rem 0 .6rem') 🎣 钓鱼
          a.random-post-start.no-text-decoration(href='javascript:fetchRandomPost();')
            i.anzhiyufont.anzhiyu-icon-arrow-rotate-right
        .title-h2-a-right
          a.random-post-all.no-text-decoration(href='/link/') 全部友链
      #random-post
      script(defer data-pjax src=url_for(theme.asset.random_friends_post_js))
    
    .flink
      if site.data.link
        each i in site.data.link
          if i.class_name
            h2!= i.class_name + "(" + i.link_list.length + ")"
          if i.class_desc
            .flink-desc!=i.class_desc
          if i.flink_style === 'anzhiyu'
            div(class=i.lost_contact ? 'anzhiyu-flink-list cf-friends-lost-contact' : 'anzhiyu-flink-list')
              if i.link_list
                each item in i.link_list
                  - let color = item.color || ""
                  - let tag = item.tag || ""
                  
                  .flink-list-item
                    if color == "vip" && tag
                      span.site-card-tag.vip #[=tag]
                        i.light
                    else if color == "speed" && tag
                      span.site-card-tag.speed #[=tag]
                    else if tag
                      span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                    else if item.recommend
                      span.site-card-tag 荐
                    if i.lost_contact
                      a.cf-friends-link(href=url_for(item.link) title=item.name target="_blank")
                        if theme.lazyload.enable
                          img.no-lightbox(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        else
                          img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        .flink-item-info
                          .flink-item-name.cf-friends-name-lost-contact= item.name
                    else
                      a.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) title=item.name target="_blank")
                        if theme.lazyload.enable
                          img.cf-friends-avatar.no-lightbox(data-lazy-src=url_for(item.avatar), cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        else
                          img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        .flink-item-info
                          .flink-item-name.cf-friends-name= item.name
                          .flink-item-desc(title=item.descr)= item.descr
          
          else if i.flink_style === 'telescopic'
            .telescopic-site-card-group
              each item in i.link_list
                - let color = item.color || ""
                - let tag = item.tag || ""
                - let siteshot = item.siteshot || `https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/${item.link}` || theme.default_img
                .site-card
                  if color == "vip" && tag
                    span.site-card-tag.vip #[=tag]
                      i.light
                  else if color == "speed" && tag
                    span.site-card-tag.speed #[=tag]
                  else if tag
                    span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                  else if item.recommend
                    span.site-card-tag 荐
                  a.img.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, rel='external nofollow')
                    img.flink-avatar(data-lazy-src=siteshot, onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, style="pointer-events: none;", src=`${siteshot}`)
                  a.info.cf-friends-link.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, cf-href=url_for(item.link), rel='external nofollow')
                    .site-card-avatar
                      img.flink-avatar.cf-friends-avatar.no-fancybox(data-lazy-src=item.avatar, cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, src=item.avatar)
                    .site-card-text
                      span.title.cf-friends-name #[=item.name]
                      span.desc(title=`${item.descr}`) #[=item.descr]
          else if i.flink_style === 'flexcard'
            .flexcard-flink-list
              each item in i.link_list
                a.flink-list-card.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) target='_blank' data-title=item.descr)
                  .wrapper.cover
                    - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
                    if theme.lazyload.enable
                      img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )
                    else
                      img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )    
                  .info
                    if theme.lazyload.enable
                      img.cf-friends-avatar.no-lightbox.flink-avatar(data-lazy-src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                    else
                      img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                    span.flink-sitename.cf-friends-name= item.name
    != page.content

//- 只在启用加密功能时才加载JavaScript
if enableEncryption
  script.
    // 页面加载时立即检查加密状态
    document.addEventListener('DOMContentLoaded', function() {
      const encryptedContent = document.getElementById('encrypted-content');
      const encryptContainer = document.getElementById('hexo-blog-encrypt');
      
      // 强制显示加密界面,隐藏内容
      if (encryptContainer) encryptContainer.style.display = 'block';
      if (encryptedContent) encryptedContent.style.display = 'none';
      
      // 检查保存的密码
      const savedPass = localStorage.getItem('friends-page-pass');
      const correctPass = '#{page.password}';
      
      if (savedPass === correctPass) {
        // 密码正确,显示内容
        if (encryptedContent) encryptedContent.style.display = 'block';
        if (encryptContainer) encryptContainer.style.display = 'none';
      } else {
        // 密码错误或未保存,清除可能存在的错误缓存
        localStorage.removeItem('friends-page-pass');
        if (encryptedContent) encryptedContent.style.display = 'none';
        if (encryptContainer) encryptContainer.style.display = 'block';
      }
    });

    function decryptFriends() {
      const inputPass = document.getElementById('hbePass').value;
      const correctPass = '#{page.password}';
      const encryptedContent = document.getElementById('encrypted-content');
      const errorElement = document.getElementById('hbeError');
      const encryptContainer = document.getElementById('hexo-blog-encrypt');
      
      if (inputPass === correctPass) {
        encryptedContent.style.display = 'block';
        encryptContainer.style.display = 'none';
        errorElement.style.display = 'none';
        // 保存密码
        localStorage.setItem('friends-page-pass', inputPass);
      } else {
        errorElement.style.display = 'block';
        // 清除错误的保存
        localStorage.removeItem('friends-page-pass');
      }
    }

控制器配置:

在站点配置文件or主题配置文件中添加:

encrypted_friends: false

或者:

encrypted_friends: true

之后进行hexo三连;

v1.0

效果图

image-20251103215515074

部署教程

前置:

部署好你的博客(本站使用的是基于hexo框架anzhiyu主题的部署)且配置好anzhiyu独有的友链页面

步骤:

  1. 找到\themes\anzhiyu\layout\includes\page\flink.pug文件,将其替换为以下内容:
//- includes/page/flink.pug

if page.password
  #hexo-blog-encrypt
    .hbe-input-container
      input(type="password" id="hbePass" placeholder=page.message || "请输入密码查看友链")
      button(onclick="decryptFriends()") 解密查看
    #hbeError(style="display:none;color:red;margin-top:10px;")= page.wrong_pass_message || '密码错误!'

  #encrypted-content(style="display:none;")
    #article-container
      if theme.linkPageTop && theme.linkPageTop.enable
        #flink-banners
          .banner-top-box
            .flink-banners-title
              .banners-title-small 友情链接
              .banners-title-big=theme.linkPageTop ? theme.linkPageTop.title : "与数百名博主无限进步"
            .banner-button-group
              if (theme.friends_vue.apiurl)
                a.banner-button.secondary.no-text-decoration(onclick="friendChainRandomTransmission()")
                  i.anzhiyufont.anzhiyu-icon-paper-plane1
                  span.banner-button-text 随机访问
              if theme.linkPageTop.addFriendPlaceholder && theme.comments.use == 'Twikoo' && theme.twikoo.envId
                a.banner-button.no-text-decoration(onclick="anzhiyu.addFriendLink()")
                  i.anzhiyufont.anzhiyu-icon-arrow-circle-right
                  span.banner-button-text 申请友链
          #skills-tags-group-all
            .tags-group-wrapper
              - function getAvatarWithoutExclamationMark(url) {
              -   const index = url.indexOf('!');
              -   return index !== -1 ? url.substring(0, index) : url;
              - }
              each y in [1,2]
                each i, index in site.data.link.slice(0, 15)
                  - const link_list = i.link_list.slice()
                  - const hundredSuffix = i.hundredSuffix ? i.hundredSuffix : ""
                  - const evenNum = link_list.filter((x, index) => index % 2 === 0);
                  - const oddNum = link_list.filter((x, index) => index % 2 === 1);
                  each item, index2 in link_list.slice(0, Math.min(evenNum.length, oddNum.length))
                    - const index = index2 * 2
                    if (index <= 15 && typeof evenNum[index] !== 'undefined' && typeof oddNum[index] !== 'undefined')
                      - let oddNumAvatar = getAvatarWithoutExclamationMark(oddNum[index].avatar);
                      - let evenNumAvatar = getAvatarWithoutExclamationMark(evenNum[index].avatar);
                      .tags-group-icon-pair
                        a.tags-group-icon.no-text-decoration(href=url_for(evenNum[index].link), title=evenNum[index].name)
                          img.no-lightbox(title=evenNum[index].name, src=url_for(evenNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=evenNum[index].name)
                        a.tags-group-icon.no-text-decoration(href=url_for(oddNum[index].link), title=oddNum[index].name)
                          img.no-lightbox(title=oddNum[index].name, src=url_for(oddNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=oddNum[index].name)
      if theme.friends_vue && theme.friends_vue.enable
        .title-h2-a
          .title-h2-a-left
            h2(style='padding-top:0;margin:.6rem 0 .6rem') 🎣 钓鱼
            a.random-post-start.no-text-decoration(href='javascript:fetchRandomPost();')
              i.anzhiyufont.anzhiyu-icon-arrow-rotate-right
          .title-h2-a-right
            a.random-post-all.no-text-decoration(href='/link/') 全部友链
        #random-post
        script(defer data-pjax src=url_for(theme.asset.random_friends_post_js))
      
      .flink
        if site.data.link
          each i in site.data.link
            if i.class_name
              h2!= i.class_name + "(" + i.link_list.length + ")"
            if i.class_desc
              .flink-desc!=i.class_desc
            if i.flink_style === 'anzhiyu'
              div(class=i.lost_contact ? 'anzhiyu-flink-list cf-friends-lost-contact' : 'anzhiyu-flink-list')
                if i.link_list
                  each item in i.link_list
                    - let color = item.color || ""
                    - let tag = item.tag || ""
                    
                    .flink-list-item
                      if color == "vip" && tag
                        span.site-card-tag.vip #[=tag]
                          i.light
                      else if color == "speed" && tag
                        span.site-card-tag.speed #[=tag]
                      else if tag
                        span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                      else if item.recommend
                        span.site-card-tag 荐
                      if i.lost_contact
                        a.cf-friends-link(href=url_for(item.link) title=item.name target="_blank")
                          if theme.lazyload.enable
                            img.no-lightbox(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          else
                            img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          .flink-item-info
                            .flink-item-name.cf-friends-name-lost-contact= item.name
                      else
                        a.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) title=item.name target="_blank")
                          if theme.lazyload.enable
                            img.cf-friends-avatar.no-lightbox(data-lazy-src=url_for(item.avatar), cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          else
                            img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                          .flink-item-info
                            .flink-item-name.cf-friends-name= item.name
                            .flink-item-desc(title=item.descr)= item.descr
            
            else if i.flink_style === 'telescopic'
              .telescopic-site-card-group
                each item in i.link_list
                  - let color = item.color || ""
                  - let tag = item.tag || ""
                  - let siteshot = item.siteshot || `https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/${item.link}` || theme.default_img
                  .site-card
                    if color == "vip" && tag
                      span.site-card-tag.vip #[=tag]
                        i.light
                    else if color == "speed" && tag
                      span.site-card-tag.speed #[=tag]
                    else if tag
                      span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                    else if item.recommend
                      span.site-card-tag 荐
                    a.img.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, rel='external nofollow')
                      img.flink-avatar(data-lazy-src=siteshot, onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, style="pointer-events: none;", src=`${siteshot}`)
                    a.info.cf-friends-link.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, cf-href=url_for(item.link), rel='external nofollow')
                      .site-card-avatar
                        img.flink-avatar.cf-friends-avatar.no-fancybox(data-lazy-src=item.avatar, cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, src=item.avatar)
                      .site-card-text
                        span.title.cf-friends-name #[=item.name]
                        span.desc(title=`${item.descr}`) #[=item.descr]
            else if i.flink_style === 'flexcard'
              .flexcard-flink-list
                each item in i.link_list
                  a.flink-list-card.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) target='_blank' data-title=item.descr)
                    .wrapper.cover
                      - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
                      if theme.lazyload.enable
                        img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )
                      else
                        img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )    
                    .info
                      if theme.lazyload.enable
                        img.cf-friends-avatar.no-lightbox.flink-avatar(data-lazy-src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                      else
                        img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                      span.flink-sitename.cf-friends-name= item.name
      != page.content

else
  #article-container
    if theme.linkPageTop && theme.linkPageTop.enable
      #flink-banners
        .banner-top-box
          .flink-banners-title
            .banners-title-small 友情链接
            .banners-title-big=theme.linkPageTop ? theme.linkPageTop.title : "与数百名博主无限进步"
          .banner-button-group
            if (theme.friends_vue.apiurl)
              a.banner-button.secondary.no-text-decoration(onclick="friendChainRandomTransmission()")
                i.anzhiyufont.anzhiyu-icon-paper-plane1
                span.banner-button-text 随机访问
            if theme.linkPageTop.addFriendPlaceholder && theme.comments.use == 'Twikoo' && theme.twikoo.envId
              a.banner-button.no-text-decoration(onclick="anzhiyu.addFriendLink()")
                i.anzhiyufont.anzhiyu-icon-arrow-circle-right
                span.banner-button-text 申请友链
        #skills-tags-group-all
          .tags-group-wrapper
            - function getAvatarWithoutExclamationMark(url) {
            -   const index = url.indexOf('!');
            -   return index !== -1 ? url.substring(0, index) : url;
            - }
            each y in [1,2]
              each i, index in site.data.link.slice(0, 15)
                - const link_list = i.link_list.slice()
                - const hundredSuffix = i.hundredSuffix ? i.hundredSuffix : ""
                - const evenNum = link_list.filter((x, index) => index % 2 === 0);
                - const oddNum = link_list.filter((x, index) => index % 2 === 1);
                each item, index2 in link_list.slice(0, Math.min(evenNum.length, oddNum.length))
                  - const index = index2 * 2
                  if (index <= 15 && typeof evenNum[index] !== 'undefined' && typeof oddNum[index] !== 'undefined')
                    - let oddNumAvatar = getAvatarWithoutExclamationMark(oddNum[index].avatar);
                    - let evenNumAvatar = getAvatarWithoutExclamationMark(evenNum[index].avatar);
                    .tags-group-icon-pair
                      a.tags-group-icon.no-text-decoration(href=url_for(evenNum[index].link), title=evenNum[index].name)
                        img.no-lightbox(title=evenNum[index].name, src=url_for(evenNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=evenNum[index].name)
                      a.tags-group-icon.no-text-decoration(href=url_for(oddNum[index].link), title=oddNum[index].name)
                        img.no-lightbox(title=oddNum[index].name, src=url_for(oddNumAvatar + hundredSuffix) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=oddNum[index].name)
    if theme.friends_vue && theme.friends_vue.enable
      .title-h2-a
        .title-h2-a-left
          h2(style='padding-top:0;margin:.6rem 0 .6rem') 🎣 钓鱼
          a.random-post-start.no-text-decoration(href='javascript:fetchRandomPost();')
            i.anzhiyufont.anzhiyu-icon-arrow-rotate-right
        .title-h2-a-right
          a.random-post-all.no-text-decoration(href='/link/') 全部友链
      #random-post
      script(defer data-pjax src=url_for(theme.asset.random_friends_post_js))
    
    .flink
      if site.data.link
        each i in site.data.link
          if i.class_name
            h2!= i.class_name + "(" + i.link_list.length + ")"
          if i.class_desc
            .flink-desc!=i.class_desc
          if i.flink_style === 'anzhiyu'
            div(class=i.lost_contact ? 'anzhiyu-flink-list cf-friends-lost-contact' : 'anzhiyu-flink-list')
              if i.link_list
                each item in i.link_list
                  - let color = item.color || ""
                  - let tag = item.tag || ""
                  
                  .flink-list-item
                    if color == "vip" && tag
                      span.site-card-tag.vip #[=tag]
                        i.light
                    else if color == "speed" && tag
                      span.site-card-tag.speed #[=tag]
                    else if tag
                      span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                    else if item.recommend
                      span.site-card-tag 荐
                    if i.lost_contact
                      a.cf-friends-link(href=url_for(item.link) title=item.name target="_blank")
                        if theme.lazyload.enable
                          img.no-lightbox(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        else
                          img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        .flink-item-info
                          .flink-item-name.cf-friends-name-lost-contact= item.name
                    else
                      a.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) title=item.name target="_blank")
                        if theme.lazyload.enable
                          img.cf-friends-avatar.no-lightbox(data-lazy-src=url_for(item.avatar), cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        else
                          img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
                        .flink-item-info
                          .flink-item-name.cf-friends-name= item.name
                          .flink-item-desc(title=item.descr)= item.descr
          
          else if i.flink_style === 'telescopic'
            .telescopic-site-card-group
              each item in i.link_list
                - let color = item.color || ""
                - let tag = item.tag || ""
                - let siteshot = item.siteshot || `https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/${item.link}` || theme.default_img
                .site-card
                  if color == "vip" && tag
                    span.site-card-tag.vip #[=tag]
                      i.light
                  else if color == "speed" && tag
                    span.site-card-tag.speed #[=tag]
                  else if tag
                    span.site-card-tag(style=`background-color: ${color}`) #[=tag]
                  else if item.recommend
                    span.site-card-tag 荐
                  a.img.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, rel='external nofollow')
                    img.flink-avatar(data-lazy-src=siteshot, onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, style="pointer-events: none;", src=`${siteshot}`)
                  a.info.cf-friends-link.no-text-decoration(target='_blank', title=`${item.name}`, href=`${item.link}`, cf-href=url_for(item.link), rel='external nofollow')
                    .site-card-avatar
                      img.flink-avatar.cf-friends-avatar.no-fancybox(data-lazy-src=item.avatar, cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='${theme.default_img}'`, alt=item.name, src=item.avatar)
                    .site-card-text
                      span.title.cf-friends-name #[=item.name]
                      span.desc(title=`${item.descr}`) #[=item.descr]
          else if i.flink_style === 'flexcard'
            .flexcard-flink-list
              each item in i.link_list
                a.flink-list-card.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) target='_blank' data-title=item.descr)
                  .wrapper.cover
                    - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
                    if theme.lazyload.enable
                      img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )
                    else
                      img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='cover' )    
                  .info
                    if theme.lazyload.enable
                      img.cf-friends-avatar.no-lightbox.flink-avatar(data-lazy-src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                    else
                      img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='cover' )
                    span.flink-sitename.cf-friends-name= item.name
    != page.content

if page.password
  script.
    function decryptFriends() {
      const inputPass = document.getElementById('hbePass').value;
      const correctPass = '#{page.password}';
      const encryptedContent = document.getElementById('encrypted-content');
      const errorElement = document.getElementById('hbeError');
      const encryptContainer = document.getElementById('hexo-blog-encrypt');
      
      if (inputPass === correctPass) {
        encryptedContent.style.display = 'block';
        encryptContainer.style.display = 'none';
        errorElement.style.display = 'none';
        localStorage.setItem('friends-page-pass', inputPass);
      } else {
        errorElement.style.display = 'block';
      }
    }

    document.addEventListener('DOMContentLoaded', function() {
      const savedPass = localStorage.getItem('friends-page-pass');
      if (savedPass === '#{page.password}') {
        document.getElementById('encrypted-content').style.display = 'block';
        document.getElementById('hexo-blog-encrypt').style.display = 'none';
      }
    });
  1. 在你创建友链页面而生成的\source\link\index.md文件的Front-matter部分,添加以下参数:
password: your_password # 设置你的访问密码
message: 请输入密码查看友链
wrong_pass_message: 密码错误,请重试!
abstract: 这里是加密的友链页面,只有知道密码的朋友才能看到哦~
  1. 创建CSS样式并引入配置文件进行美化:
/* 加密界面样式 */
#hexo-blog-encrypt {
  background: var(--anzhiyu-card-bg);
  border: var(--style-border);
  border-radius: 12px;
  padding: 3rem 2rem;
  margin: 2rem 0;
  box-shadow: var(--anzhiyu-shadow-border);
  text-align: center;
}

.hbe-input-container {
  margin-bottom: 1rem;
}

#hbePass {
  padding: 10px 15px;
  border: var(--style-border);
  border-radius: 8px;
  width: 200px;
  margin-right: 10px;
  background: var(--anzhiyu-background);
  color: var(--anzhiyu-fontcolor);
}

#hexo-blog-encrypt button {
  padding: 10px 20px;
  background: var(--anzhiyu-theme);
  color: var(--anzhiyu-white);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
}

#hexo-blog-encrypt button:hover {
  background: var(--anzhiyu-theme);
  transform: translateY(-2px);
  box-shadow: var(--anzhiyu-shadow-theme);
}

完成后进行hexo 三连即可应用

附: 该功能初步实现,如有隐藏bug或安全漏洞请联系,感激不尽

注: 本功能与文章加密插件不兼容