【问题标题】:store and access image file paths when templating (from cloudinary or other service)模板时存储和访问图像文件路径(来自 cloudinary 或其他服务)
【发布时间】:2026-01-21 23:30:01
【问题描述】:

我正在使用 gulp 和 nunjucks 来自动化一些基本的电子邮件模板任务。

我有一个任务链,可以在将图像添加到图像文件夹时触发,例如:

  1. 图片压缩
  2. 记录到 json 文件的新图像名称和尺寸
  3. json 图像数据然后在模板任务运行时用于填充模板

到目前为止一切顺利。

我希望能够为每个模板定义一个通用图像文件路径,然后将其连接到每个图像名称(存储在 json 文件中)。所以像:

<img src="{{data.path}}{{data.src}}" >

如果我想指定一个不同的文件夹来包含生成的每个模板的图像,那么 cloudinary 需要在文件路径中应用强制的唯一版本组件。因此,整个模板中的图像路径永远不会保持一致。

如果您的公共 ID 包括文件夹(以“/”分隔的元素),则 版本组件是强制性的,(但您可以将其缩短。)

例如: http://res.cloudinary.com/demo/image/upload/v1312461204/sample_email/hero_image.jpg

http://res.cloudinary.com/demo/image/upload/v1312461207/sample_email/footer_image.jpg

同一个文件夹。不同的路径。

所以看来我现在需要创建一个脚本/任务,该脚本/任务可以在任何时候上传或更新图像时记录和存储每个图像的每个不同文件路径(其唯一 ID 由 cloudinary 生成),然后重新运行模板发布它们的过程。

这似乎是一个相当复杂的过程,所以如果有更简单的方法我很想知道?

否则,如果这确实是所需的路线,那么如果有人能指出一个实现类似功能的脚本示例,那就太好了。

大概一些托管服务不会有强制性的唯一密钥,这让生活更轻松。我花了一些时间来了解 cloudinary,它是一项覆盖范围很广的免费服务,所以我想我不愿意放弃这艘船,但对所有建议持开放态度。

谢谢

【问题讨论】:

    标签: javascript image path hosting cloudinary


    【解决方案1】:

    请注意,对于大多数用例,版本组件(例如,v1312461204)不再是强制性的。没有它,URL 确实可以工作,例如: http://res.cloudinary.com/demo/image/upload/sample_email/hero_image.jpg

    话虽如此,如果您想用新的图像更新图像同时保持完全相同的公共 ID,我们强烈建议您在 URL 中包含版本组件。在这种情况下,如果您访问完全相同的 URL,您可能会获得图像的 CDN 缓存版本,这可能是旧版本。 因此,当您上传时,您可以从 Cloudinary 的上传响应中获取 version 值,并将其存储在您的 DB 中,下次更新图像时,也将 URL 更新为新的版本值。

    或者,您也可以在上传图片时要求 Cloudinary invalidate。请注意,虽然包含版本组件会立即“破坏”缓存,但失效可能需要一段时间才能通过 CDN 传播。了解更多信息: http://cloudinary.com/documentation/image_transformations#image_versions

    【讨论】:

    • 非常感谢您将我放在版本组件 Itay 上。我从这个post 中取得领先,因为它是最近的,所以没有注意到无效选项。考虑到您的建议,我尝试生成脚本以存储更新的文件路径,然后生成修改后的 json 数据文件以将托管的 src 详细信息发布到模板。我对实现这一目标不是很有信心,但管理了一些对我有用的东西,并将其作为答案发布。谢谢!
    【解决方案2】:

    这是我想出的解决方案。它基于调整我用来将图像从文件夹上传到 cloudinary 的通用脚本,现在存储来自 cloudinary 的更新文件路径并生成一个 json 数据文件以将托管的 src 详细信息发布到模板。

    我相信它在语义上可能会更好,所以如果有人偶然发现它,欢迎提供任何修订,但它似乎可以完成这项工作:

    // points to the config file where we are defining file paths
    var path = require('./gulp.path')();
    // IMAGE HOSTING
    var fs = require('fs'); // !! not installed !! Not required?? 
    var cloudinary = require('cloudinary').v2;
    var uploads = {};
    var dotenv = require('dotenv');
    dotenv.load();
    // Finds the images in a specific folder and retrurns an array
    var read = require('fs-readdir-recursive');
    // Set location of images
    var imagesInFolder = read(path.images);
    
    // The array that will be populated with image src data
    var imgData = new Array();
    
    (function uploadImages(){
    
    // Loop through all images in folder and upload
    for(var i = 0; i < imagesInFolder.length;i++){
           cloudinary.uploader.upload(path.images + imagesInFolder[i], {folder: path.hosted_folder, use_filename: true, unique_filename: false, tags: 'basic_sample'}, function(err,image){
              console.log();
              console.log("** Public Id");
              if (err){ console.warn(err);}
              console.log("* Same image, uploaded with a custom public_id");
              console.log("* "+image.public_id);
    
              // Generate the category title for each image. The category is defined within the image name. It's the first part of the image name i.e. anything prior to a hyphen:
              var title = image.public_id.substr(image.public_id.lastIndexOf('/') + 1).replace(/\.[^/.]+$/, "").replace(/-.*$/, "");
    
              console.log("* "+title); 
              console.log("* "+image.url);
    
              // Add the updated src for each image to the output array 
              imgData.push({ 
                            [title] : {"src" : image.url}
                          });
    
                // Stringify data with no spacing so .replace regex can easily remove the unwanted curly braces
                var imgDataJson = JSON.stringify(imgData, null, null);
    
                // Remove the unwanted [] that wraps the json imgData array
               var imgDataJson = imgDataJson.substring(1,imgDataJson.length-1);
    
               // Delete unwanted braces "},{" replace with "," otherwise what is output is not valid json
               var imgDataJson =  imgDataJson.replace(/(},{)/g, ',');
    
              var outputFilename = "images2-hosted.json"
    
            // output the hosted image path data to a json file
            // (A separate gulp task is then run to merge and update the new 'src' data into an existing image data json file)
            fs.writeFile(path.image_data_src + outputFilename, imgDataJson, function(err) {
              if(err) {
                console.log(err);
              } else {
                console.log("JSON saved to " + outputFilename);
              }
             });
    
            });
          }
     })();
    

    然后使用 gulp 任务合并新生成的 json 以覆盖现有的 json 数据文件:

    // COMPILE live image hosting data
    var merge = require('gulp-merge-json');
    gulp.task('imageData:comp', function() {
      gulp
        .src('src/data/images/*.json')
        .pipe(merge('src/data/images.json'))
        .pipe(gulp.dest('./'))
        .pipe(notify({ message: 'imageData:comp task complete' }));
    });
    

    【讨论】:

    • 如果它对你仍然有用,我有一个 gulp plugin 可以做类似的事情。
    最近更新 更多