惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog RSS Feed
宝玉的分享
宝玉的分享
腾讯CDC
博客园_首页
T
Tailwind CSS Blog
月光博客
月光博客
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
SecWiki News
SecWiki News
美团技术团队
P
Privacy International News Feed
H
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
D
DataBreaches.Net
Project Zero
Project Zero
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
S
Schneier on Security
G
GRAHAM CLULEY
博客园 - 三生石上(FineUI控件)
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
Forbes - Security
Forbes - Security
D
Docker
T
Tenable Blog
S
Secure Thoughts
雷峰网
雷峰网
S
Security @ Cisco Blogs
T
The Exploit Database - CXSecurity.com
The Cloudflare Blog
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
阮一峰的网络日志
阮一峰的网络日志

元视角

.NET 生态下的 Agent 框架选型:从 ReAct 到原生推理 - 元视角 从「能用」到「好用」:LLM 流式响应实现方式的探索之路 - 元视角 当我用 2000 条聊天记录,让 AI 为我画一幅自画像 - 元视角 基于 Supabase 的 AI 应用开发探索 - 元视角 微博 × MCP:社交媒体新玩法解锁 - 元视角 四点钟海棠花未眠 - 元视角 Semantic Kernel × MCP:智能体的上下文增强探索 - 元视角 基于 K-Means 聚类分析实现人脸照片的快速分类 - 元视角 容器技术驱动下的代码沙箱实践与思考 - 元视角 温故而知新:后端通用查询方案的再思考 - 元视角 浅议 CancellationToken 在前后端协同取消场景中的应用 - 元视角 Semantic Kernel 视角下的 Text2SQL 实践与思考 - 元视角 关于 ChatGPT 的流式传输,你需要知道的一切 - 元视角 RAG 的是与非、Rewrite 和 Rerank - 元视角 使用 EFCore 和 PostgreSQL 实现向量存储及检索 - 元视角 基于 LLaMA 和 LangChain 实践本地 AI 知识库 - 元视角 使用 llama.cpp 在本地部署 AI 大模型的一次尝试 - 元视角 如何为 Git 配置多个 SSH Key - 元视角 C# 使用 LibUsbDotNet 实现 USB 设备检测 - 元视角 基于 C# 实现样式与数据分离的打印方案 - 元视角 基于 SVG 的图形交互方案实践 - 元视角 前端视频播放技术概览 - 元视角 温故而知新,再话 Python 动态导入 - 元视角 后 GPT 时代,NLP 不存在了? - 元视角 视频是不能 P 的系列:使用 Milvus 实现海量人脸快速检索 - 元视角 GDI+下字体大小自适应方案初探 - 元视角 小爱音箱集成 ChatGPT 的不完全教程 - 元视角 程序员视角下的三体世界随想 - 元视角 关于 Docker 容器配置信息的渐进式思考 - 元视角 在 Docker 容器内集成 Crontab 定时任务 - 元视角 为你的服务器集成 LDAP 认证 - 元视角 似花还似非花 - 元视角 视频是不能 P 的系列:使用 Dlib 实现人脸识别 - 元视角 浅议分布式链路追踪与日志的整合 - 元视角 关于 Git 大文件上传这件小事 - 元视角 .NET 进程内队列 Channel 的入门与应用 - 元视角 使用 Fody 实现 .NET 的静态编织 - 元视角 .NET Core + ELK 搭建可视化日志分析平台(下) - 元视角 聊一聊前端图片懒加载背后的故事 - 元视角 支持外部链接跳转的 Vue Router 扩展实现 - 元视角 视频是不能 P 的系列:OpenCV 和 Dlib 实现表情包 - 元视角 不得不说的 ASP.NET Core 集成测试 - 元视角 再议 DDD 视角下的 EFCore 与 领域事件 - 元视角 Vue.js 前端项目容器化部署实践极简教程 - 元视角 再见,人间四月天 - 元视角 Python 图像风格化迁移助力画家梦想 - 元视角 利用 ASP.NET Core 中的标头传播实现分布式链路追踪 - 元视角 利用 gRPC 实现文件的上传与下载 - 元视角 七种武器:延迟队列的原理和实现总结 - 元视角 gRPC 流式传输极简入门指南 - 元视角 Envoy 集成 Jaeger 实现分布式链路追踪 - 元视角 浅议非典型 Web 应用场景下的身份认证 - 元视角 gRPC 借助 Any 类型实现接口的泛化调用 - 元视角 分布式丛林探险系列之 Redis 集群模式 - 元视角 分布式丛林探险系列之 Redis 主从复制模式 - 元视角 通过 Python 预测 2021 年双十一交易额 - 元视角 gRPC 搭配 Swagger 实现微服务文档化 - 元视角 SSL/TLS 加密传输与数字证书的前世今生 - 元视角 使用 Python 自动识别防疫健康码 - 元视角 你不可不知的容器编排进阶技巧 - 元视角 ASP.NET Core 搭载 Envoy 实现 gRPC 服务代理 - 元视角 再话 AOP,从简化缓存操作说起 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT) - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的监控预警 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的反向代理 - 元视角 ASP.NET Core gRPC 打通前端世界的尝试 - 元视角 EFCore 实体命名约定库:EFCore.NamingConventions - 元视角 ASP.NET Core gRPC 集成 Polly 实现优雅重试 - 元视角 ASP.NET Core gRPC 健康检查的探索与实现 - 元视角 ASP.NET Core gRPC 拦截器的使用技巧分享 - 元视角 SnowNLP 使用自定义语料进行模型训练 - 元视角 使用 HttpMessageHandler 实现 HttpClient 请求管道自定义 - 元视角 ABP vNext 的实体与服务扩展技巧分享 - 元视角 ABP vNext 对接 Ant Design Vue 实现分页查询 - 元视角 源代码探案系列之 .NET Core 跨域中间件 CORS - 元视角 源代码探案系列之 .NET Core 限流中间件 AspNetCoreRateLimit - 元视角 源代码探案系列之 .NET Core 并发限制中间件 ConcurrencyLimiter - 元视角 通过 EmbededFileProvider 实现 Blazor 的静态文件访问 - 元视角 低代码,想说爱你不容易 - 元视角 记一次失败的 ThoughtWorks 面试经历 - 元视角 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览 - 元视角 通过 Python 分析 2020 年全年微博热搜数据 - 元视角 基于 Python 和 Selenium 实现 CSDN 一键三连自动化 - 元视角 使用多线程为你的 Python 爬虫提速的 N 种姿势,你会几种? - 元视角 实现网页长截图的常见思路总结 - 元视角 温故而知新,由 ADO.NET 与 Dapper 所联想到的 - 元视角 视频是不能 P 的系列:OpenCV 人脸检测 - 元视角 作为技术宅的我,是这样追鬼滅の刃的 - 元视角 使用 Python 抽取《半泽直树》原著小说人物关系 - 元视角 厉害了!打工人用 Python 分析西安市职位信息 - 元视角 使用 dotTrace 对 .NET 应用进行性能分析与优化 - 元视角 一道 HashSet 面试题引发的蝴蝶效应 - 元视角 基于选项模式实现.NET Core 的配置热更新 - 元视角 Dapper.Contrib 在 Oracle 环境下引发 ORA-00928 异常问题的解决 - 元视角 .NET Core 中对象池(Object Pool)的使用 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(下):EventBus 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(中):RabbitMQ 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(上):基础篇 - 元视角 记一次从已损坏的 Git 仓库中找回代码的经历 - 元视角 .NET Core 原生 DI 扩展之属性注入实现 - 元视角
为 Hexo 开发一个网易云音乐的文章插件 - 元视角
飞鸿踏雪 · 2015-03-24 · via 元视角

当你打开这篇文章的时候,你听到一首熟悉的旋律,那是因为在你的心里始终装着一张泛黄的 CD,你从来不愿意打开它,即使外表早已积满了灰尘,你依然视它如新的一般,我们喜欢把它叫做时光或者说是青春。正如你所看到的,我在博客文章中插入了网易云音乐的播放器。这是一个基于 Flash 技术实现的组件。因为博主特别喜欢网易云音乐这个音乐产品,所以博主想将这个播放器带入到我的博客。在博客中使用这个播放器,只要在文章中添加如下代码:

<embed src="http://music.163.com/style/swf/widget.swf?sid=29713754&type=2&auto=1&width=278&height=32" width="298" height="52"  allowNetworking="all"></embed>

可是这样的结构对于一个写博客的人来说还是显得臃肿了,能不能让这个结构更简单写呢?简单到这样:

因为在这段代码中真正和音乐有关的只有 sid 这个参数,所以我们我们只需要关注这个参数就好了。那么,现在我们其实就是在做这样一件事情,我们在文章中插入这样一个[key:value]的结构,然后通过程序将它替换成相应的 HTML 结构,这样就实现了在 Hexo 的文章中使用[key:value]结构来编写简单插件的功能,如果经历过使用 wordpress 建站的朋友一定知道,在 wordpress 中存在许多这样的类似插件,可以帮助写作者简化某些输入内容。好了,那么今天我们就来试着为 hexo 编写这样一个小插件吧!为了避免将插件写到网页里的时候出现错误,我们首先在 NodeJS 中测试,测试程序如下:

   //定义测试内容
   var str = "这是一条测试内容以测试这个程序是否能够正确运行,现在让我们来听一首《匆匆那年》[music:29713754]";
   //获得匹配内容
   var dicts = str.match(/\[(.*?):(.*?)\]/g);
   if(dicts.length == 0) return;
   //对每一个匹配项进行处理
   for(var i = 0; i < dicts.length; i++)
   {
         //对匹配项进行分割,拆分结果为'[music'和'29713754]'
         //我TM就郁闷了,在这里写成'/:/'报错
         //可是写成/:/就顺利通过
         var dict = dicts[i].split(/:/);
         //获得键名
         var key = dict[0].substring(1,dict[0].length);
         //获得ID
         var id = dict[1].substring(0,dict[1].indexOf(']'));
         //判断键名的类型
         if (key == 'music')
         {
            str = str.replace(dicts[i],'<embed src="http://music.163.com/style/swf/widget.swf?sid='+ id +
            '&type=2&auto=1&width=278&height=32" width="298" height="52" allowNetworking="all"></embed>');
         }
    }
    //输出结果
    console.log(str);

这段代码主要就是通过正则表达式来匹配文章正文中所有的[key:value]结构,然后根据 key 来确定当前结构表什么类型,根据 id 来确定当前类型的参数,尽管这里只提到了一个 music 的类型,不过我相信只要大家开动脑筋、发挥想像相信会有更好的想法产生吧!这段代码博主在本地使用 NodeJS 测试了没有不过什么问题,大家可以在截图中清楚地看到 [music:29713754] 已经被替换称了网易云音乐的 Flash 组件,这样在网页中就会显示出网易云音乐的播放器,我们就能听到这熟悉而温暖的旋律了。

NodeJS程序演示效果 NodeJS程序演示效果

不过真的想要吐槽下 JavaScript。本来 JavaScript 就是弱类型了吧,NodeJS 再给弄一个除了报错什么都不会的命令行,因此在本地调试 JavaScript 代码实在是太困难了。昨天为了写出一个正确的正则表达式奋战到三点钟,后来终于给写出来了,实在压抑不住内心的喜悦匆匆忙忙地就往模板里面放,结果刚放进去再重新生成页面地时候博客就华丽地挂了,尝试了若干次无果后,果断放弃然后用备份地主题文件进行了覆盖替换。总之,经过这次事情,我是再不想接触 Javacript 了,你不让我面向对象我可以容忍,因为 JavaScript 本来就不是一门面向对象的语言。可是你总得让我知道我写的这个变量是个什么类型吧?因为这个插件的编写涉及到 JavaScript、NodeJS、Hexo 所以整个过程中编程的效率特别低,因为在没有文档、没有语法提示的情况下来写这样一段代码,在我看来完全就是摸着石头过河啊!

好了,停止吐槽!我们接下来看看这段代码怎样和 Hexo 整个到一起。按照博主的理解既然我们要对文章的内容中的[key:value]结构进行替换,我们首先应该知道文章的内容在哪里。经过这么长时间对 Hexo 的学(zhe)习(teng),我们知道文章的内容是定义在 layout_partial 下的 article.ejs 这个文件中,在这个文件中有一个叫做 item 的变量,这个 item 的真实身份其实是 Hexo 中定义的一个全局变量 post。顾名思义,这个 post 就是我们发表的文章啦,它有一个重要的属性叫做 content,就是我们这里要用到的东西了。我们来 article.ejs 这个文件中定义的一段代码:

    <div class="entry">
      <% if (item.excerpt && index){ %>
        <%- item.excerpt %>
      <% } else { %>
         <% if (!index){ %>
                <% if (!index && item.toc){ %>
                   <%- partial('extra/toc') %>
                <% } %>
                <%- item.content %>
          <% } else { %>
            <%- item.content.substring(0,item.content.indexOf('\n')) %>
          <% } %>
      <% } %>
    </div>

这段代码是关于文章的内容的,因此我们要对文章内容进行修改的话,就要先读懂这块儿的代码。这块儿代码首先判断文章是不是处于首页位置(index),接着判断文章中有没有 ReadMore 标记(excerpt)。如果文章在首页位置(index)且存在 ReadMore 标记(excerpt),那么文章显示的是 ReadMore 标记前的内容(item.excerpt);如果文章没有 ReadMore 标记(excerpt)且文章在首页位置(index),那么文章显示的整篇文章(item.content);如果文章在首页(index)可是没有 ReadMore 标记(excerpt),那么选取文章的第一段作为文章的摘要来显示。这就是博主的博客目前采用的方案了,如果大家对这部分感兴趣的话,可以看看自己的博客使用的主题是如何定义这部分内容的,然后在此基础上做些调整以满足个性化的需求。

好了,那么在了解了这部分内容后,我们应该马上就能想到,我们需要掉正的代码应该是在第 9 行这个位置,即当文章不在首页的时候要显示的内容。好了,按照我们在测试程序中的写法,我们可以写出如下代码:

<% var dicts=item.content.match(/\[(.*?):(.*?)\]/g); %>
<% if(dicts.length==0){ %>
   <%- item.content %>
<% } else { %>
   <% for(i=0;i<dicts.length;i++) %>
   <% { %>
        <% var dict=dicts[i].split(/:/); %>
        <% var key=dict[0].substring(1,dict[0].length);  %>
        <% var id=dict[1].substring(0,dict[1].length-1); %>
        <% if(key=='music') %>
        <% { %>
             item.content=item.content.replace(dicts[i],'<embed src="http://music.163.com/style/swf/widget.swf?sid='+ id +
             '&type=2&auto=1&width=278&height=32" width="298" height="52" allowNetworking="all"></embed>')
        <% } %>
   <% } %>
   <%- item.content %>
<% } %>

相信经过博主的一番介绍,大家已经对这段代码相当熟悉了吧,这里就是先做判断,判断文章内容中是否有[key:vaule]这样的结构,如果没有就直接输出 item.content;如果有就需要对其进行替换后再输出 item.content。好了,现在我们用这段代码替换掉第 9 行代码,然后再次输出网页。可是结果让我们白忙活了一场,因为 Hexo 在输出网页的时候会报错,可能是因为博主写的 JavaScript 脚本 Hexo 无法解析吧!好了,从昨天下午开始差不多都在想着怎样解决这个问题,到现在还是没有一点头绪,文章里讲述的方法可以作为一种尝试,如果有兴趣、有精力、有能力解决这个问题的人,可以去进一步深入地探索这个问题。今天的内容就是这样了,睡觉!

2015 年 11 月 10 日更新: 昨天抽空研究了下 Hexo 的插件机制,发现在 Hexo 中提供了一种标签插件,可以帮助我们快速完成这种需求,所以就记录在这里。首先,它的原理是根据这样一个简单的标记来进行处理,当我们输入默认的这样的标记的时候它会被渲染为普通的引用标记,当我们在这个标记内传入参数后就可以利用程序进行处理。例如我们编写这样的简单的 JS 文件:

/**
* hexo-tag-cloudmusic
* https://github.com/qinyuanpei/hexo-tag-cloudmusic.git
* Copyright (c) 2015, qinyuanpei
* Licensed under the MIT license.
*/

hexo.extend.tag.register('cloudmusic', function(args){
  var sid = args[0];
  var config = hexo.config.cloudmusic || {};
  var widgetType = hexo.config.widgetType || 'flash';
  var widgetSize = config.widgetSize || 'small';
  var autoPlay = config.autoPlay || 1;
  var width = config.width || 278;
  var height = config.height || 32;

  if(widgetType == 'iframe'){
  	if(widgetSize=='small'){
  		return '<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=298 height=52 src="http://music.163.com/outchain/player?type=2&id=' + sid + '&auto=' + autoPlay +'&height=32"></iframe>';
  	}else if(widgetSize=='big'){
  		return '<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=351 height=86 src="http://music.163.com/outchain/player?type=2&id=' + sid + '&auto=' + autoPlay + '&height=66"></iframe>';
  	}else if(widgetSize=='custom'){
  		return '<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=' + width +' height=' + height +' src="http://music.163.com/outchain/player?type=2&id=' + sid + '&auto=' + autoPlay + '&height=66"></iframe>';
  	}
  }else{
  	if(widgetSize=='small'){
  		return '<embed src="http://music.163.com/style/swf/widget.swf?sid=' + sid + '&type=2&auto=' + autoPlay + '&width=278&height=32" width="298" height="52"  allowNetworking="all"></embed>';
  	}else{
  		return '<embed src="http://music.163.com/style/swf/widget.swf?sid=' + sid + '&type=2&auto=' + autoPlay + '&width=320&height=66" width="340" height="86"  allowNetworking="all"></embed>';
  	}
  }
});

大家可以看到这个 JS 文件本质上就是根据传入的 sid 来拼接生成网易云音乐的 widget 代码,这样当我们需要在博客中引用网易云音乐的时候只需要采用下面的标记:

{% cloudmusic 20744792 %}

这个项目我目前发布在我的 Github 上,欢迎大家 Start 和 Fork!