该页面由AI翻译并经过人工校对,你可能想要
            查看原文
          
         
        
        前言
由于 post_asset_folder 在 _config.yml 文件中的设置如下,因此每篇文章的资源都可以在与文章同名的目录中找到。
1 2 3 4
   | post_asset_folder: true marked:   prependRoot: true   postAsset: true
   | 
 
然而,在本网站支持国际化之后,冗余资源会大量积累。不同语言的文章内容应该不同,但资源应该相同。以下是源文件的目录结构。不同语言中带有 (*) 的资源目录是重复的,可以进行优化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
   | source ├── _posts │   ├── en │   │   └── 2025 │   │       ├── 07 │   │       │   ├── online-404-error-troubleshooting (*) │   │       │   └── online-404-error-troubleshooting.md │   │       └── 08 │   │           ├── exploring-multilingual-site-solutions-in-hexo (*) │   │           └── exploring-multilingual-site-solutions-in-hexo.md │   └── zh-CN │       └── 2025 │           ├── 07 │           │   ├── online-404-error-troubleshooting (*) │           │   └── online-404-error-troubleshooting.md │           └── 08 │               ├── exploring-multilingual-site-solutions-in-hexo (*) │               └── exploring-multilingual-site-solutions-in-hexo.md ├── en │   ├── 404 │   ├── about │   ├── albums │   │   ├── animal │   │   │   ├── cat (*) │   │   │   ├── cat.md │   │   │   ├── dog (*) │   │   │   ├── dog.md │   │   │   └── index.md │   │   └── index.md │   ├── categories │   └── tags └── zh-CN     ├── 404     ├── about     ├── albums     │   ├── animal     │   │   ├── cat (*)     │   │   ├── cat.md     │   │   ├── dog (*)     │   │   ├── dog.md     │   │   └── index.md     │   └── index.md     ├── categories     └── tags
   | 
 
优化
设计
首先,为了减少之前对资源引用方式的影响,我需要设计静态资源的组织方式。幸运的是,只需将所有重复的资源目录移动到 /source/images 目录(带有 (*) 的目录)即可,如下所示。之后,如果使用相对路径引用资源,只需进行少量更改即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
   | . ├── _posts │   ├── en │   │   └── 2025 │   │       ├── 07 │   │       │   └── online-404-error-troubleshooting.md │   │       └── 08 │   │           └── exploring-multilingual-site-solutions-in-hexo.md │   └── zh-CN │       └── 2025 │           ├── 07 │           │   └── online-404-error-troubleshooting.md │           └── 08 │               └── exploring-multilingual-site-solutions-in-hexo.md ├── en │   ├── 404 │   ├── about │   ├── albums │   │   ├── animal │   │   │   ├── cat.md │   │   │   ├── dog.md │   │   │   └── index.md │   │   └── index.md │   ├── categories │   └── tags ├── images │   ├── 2025 │   │   ├── 07 │   │   │   └── online-404-error-troubleshooting (*) │   │   └── 08 │   │       └── exploring-multilingual-site-solutions-in-hexo (*) │   ├── albums │   │   └── animal │   │       ├── cat (*) │   │       └── dog (*) │   ├── my_avatar.png │   └── my_favicon.png └── zh-CN     ├── 404     ├── about     ├── albums     │   ├── animal     │   │   ├── cat.md     │   │   ├── dog.md     │   │   └── index.md     │   └── index.md     ├── categories     └── tags
 
   | 
 
然后,找到一种方法来替换每篇帖子中引用的资源路径。由于资源可以通过相对路径或绝对路径(以 http、https 或 / 开头)引用,如果是绝对路径,则直接使用该路径;否则,在 /images 目录中与帖子同名的目录中查找资源。因此,只需将相对路径转换为 /images/[prefix]/[name]/[resource],其中 name 表示帖子名称,resource 表示资源名称,prefix 表示从 /source/[lang] 到帖子的路径。
例如,对于帖子 /2025/07/my-post.md,无论语言是什么。
- 如果资源引用为 ./image.png,则资源路径将转换为 /images/2025/07/my-post/image.png。在本例中,prefix 为 2025/07,name 为 my-post,resource 为 image.png。 注意 如果您使用相对路径,请确保它始终以 './' 开头。如果您使用 ../another-post/image.png,它将不会被转换为 /images/2025/07/another-post/image.png。如果您确实需要使用属于其他帖子的资源,请尝试使用绝对路径,例如 /images/2025/07/another-post/image.png。
 
- 如果资源被引用为 /images/2025/07/my-post/image.png,由于它是绝对路径,因此资源路径不会被转换。
 
- 如果资源被引用为 https://exmaple.com/image.png,资源路径也不会被转换。
 
更多示例请参见下文。
实现
在 themes/arch/scripts 目录下创建一个名为 hexo-filter.js 的文件,并输入以下代码。在 after_post_rende 的回调中,可以访问所有数据,包括原始内容、解析后的内容以及页面元信息。获取所有 <img> 的 src 值,如果 src 是相对路径,则应用上述路径转换。就是这样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
   |  const absPathRegExp = /^(https?:\/\/|\/)/i;
  function replaceRelativePath(src, prefix) {      if (absPathRegExp.test(src)) {     return src;   }         let cleanSrc = src.replace(/^(\.\/|\.\.\/)+/, "");
       return [prefix, cleanSrc].join("/"); }
 
 
 
 
 
 
 
 
 
 
  hexo.extend.filter.register("after_post_render", function (data) {   const { source, type } = data;
       if (["tags", "categories"].includes(type)) {     return data;   }
             const parts = source.split("/");
    let dirParts = !type ? parts.slice(2, -1) : parts.slice(1, -1);      if (!type || type === "album") {     dirParts = dirParts.concat(parts[parts.length - 1].replace(/\.md$/, ""));   }
    const prefix = `/images/${dirParts.join("/")}`;
          data.content = data.content.replace(     /<img\s+([^>]*?)src=["']([^"']+)["']([^>]*?)>/gi,     function (match, pre, src, post) {              if (absPathRegExp.test(src)) {         return match;       }              return `<img ${pre}src="${replaceRelativePath(src, prefix)}"${post}>`;     }   );
       if (type === "albums" && Array.isArray(data.children)) {     data.children.forEach((child) => {       if (child.cover) {         child.cover = replaceRelativePath(child.cover, prefix);       }     });   }
       if (type === "album" && Array.isArray(data.resources)) {     data.resources.forEach((resource) => {       if (resource.src) {         resource.src = replaceRelativePath(resource.src, prefix);       }     });   }      return data; });
 
  | 
 
使用方法
如果在文章中使用 <img /> 以相对路径引用资源,则无需执行任何操作。对于相册和相册类型页面,由于存在绝对路径,因此需要进行如下更改。
请注意,只有使用 <img /> 以相对路径引用资源时,才会转换资源路径。核心逻辑如下。
1 2 3 4 5 6 7 8 9 10 11
   | data.content = data.content.replace(   /<img\s+([^>]*?)src=["']([^"']+)["']([^>]*?)>/gi,   function (match, pre, src, post) {          if (absPathRegExp.test(src)) {       return match;     }          return `<img ${pre}src="${replaceRelativePath(src, prefix)}"${post}>`;   } );
   | 
 
如果您使用 Markdown 语法或 Hexo 标签使用相对路径(如下所示),资源路径将不会被转换,图片将加载失败。
1 2 3
   | 
  {% asset_img "image.png" "image.png" %}
   |