模板化时存储和访问图像文件路径(来自 cloudinary 或其他服务)
store and access image file paths when templating (from cloudinary or other service)
我正在使用 gulp 和 nunjucks 来自动执行一些基本的电子邮件模板任务。
我有一系列任务,可以在将图像添加到图像文件夹时触发这些任务,例如:
- 图片压缩
- 新图像名称和尺寸记录到 json 文件
- json 当模板任务为 运行
时,图像数据然后用于填充模板
到目前为止一切顺利。
我希望能够为每个模板定义一个通用图像文件路径,然后将其连接到每个图像名称(存储在 json 文件中)。所以像:
<img src="{{data.path}}{{data.src}}" >
如果我想指定一个不同的文件夹来包含生成的每个模板的图像,那么 cloudinary 需要在文件路径中应用一个强制性的唯一版本组件。因此,图像路径在整个模板中永远不可能保持一致。
if your public ID includes folders (elements divided by '/'), the
version component is mandatory, (but you can make it shorter. )
例如:
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
同一个文件夹。不同的路径。
所以我现在似乎需要创建一个 script/task 可以在上传或更新图像时为每个图像记录和存储每个不同的文件路径(具有由 cloudinary 生成的唯一 ID)和然后重新运行 发布它们的模板过程。
这似乎是一个相当复杂的过程,所以如果有更简单的方法我很想知道?
否则,如果这确实是必需的路线,那么如果有人能给我指出一个实现类似功能的脚本示例,那就太好了。
大概有些托管服务不会有强制性的唯一密钥,这会让生活更轻松。我花了一些时间了解 cloudinary,它是一项范围广泛的免费服务,所以我想我不愿意放弃,但愿意接受所有建议。
谢谢
请注意,对于大多数用例,版本组件(例如 v1312461204
)不再是必需的。 URL 确实可以在没有它的情况下工作,例如:
http://res.cloudinary.com/demo/image/upload/sample_email/hero_image.jpg
话虽如此,如果您想用新图像更新图像同时保持完全相同 public,强烈建议在 URL 中包含版本组件ID。在这种情况下,如果您访问完全相同的 URL,您可能会得到图像的 CDN 缓存版本,这可能是旧版本。
因此,当你上传时,你可以从 Cloudinary 的上传响应中获取 version
值,并将其存储在你的数据库中,下次更新图像时,也将 URL 更新为新版本值.
或者,您也可以要求 Cloudinary 在上传时 invalidate
图片。请注意,虽然立即将版本组件 "busts" 包含在缓存中,但失效可能需要一段时间才能通过 CDN 传播。想要查询更多的信息:
http://cloudinary.com/documentation/image_transformations#image_versions
这是我想到的解决方案。它基于调整我用来将图像从文件夹上传到 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 和 nunjucks 来自动执行一些基本的电子邮件模板任务。
我有一系列任务,可以在将图像添加到图像文件夹时触发这些任务,例如:
- 图片压缩
- 新图像名称和尺寸记录到 json 文件
- json 当模板任务为 运行 时,图像数据然后用于填充模板
到目前为止一切顺利。
我希望能够为每个模板定义一个通用图像文件路径,然后将其连接到每个图像名称(存储在 json 文件中)。所以像:
<img src="{{data.path}}{{data.src}}" >
如果我想指定一个不同的文件夹来包含生成的每个模板的图像,那么 cloudinary 需要在文件路径中应用一个强制性的唯一版本组件。因此,图像路径在整个模板中永远不可能保持一致。
if your public ID includes folders (elements divided by '/'), the version component is mandatory, (but you can make it shorter. )
例如: 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
同一个文件夹。不同的路径。
所以我现在似乎需要创建一个 script/task 可以在上传或更新图像时为每个图像记录和存储每个不同的文件路径(具有由 cloudinary 生成的唯一 ID)和然后重新运行 发布它们的模板过程。
这似乎是一个相当复杂的过程,所以如果有更简单的方法我很想知道?
否则,如果这确实是必需的路线,那么如果有人能给我指出一个实现类似功能的脚本示例,那就太好了。
大概有些托管服务不会有强制性的唯一密钥,这会让生活更轻松。我花了一些时间了解 cloudinary,它是一项范围广泛的免费服务,所以我想我不愿意放弃,但愿意接受所有建议。
谢谢
请注意,对于大多数用例,版本组件(例如 v1312461204
)不再是必需的。 URL 确实可以在没有它的情况下工作,例如:
http://res.cloudinary.com/demo/image/upload/sample_email/hero_image.jpg
话虽如此,如果您想用新图像更新图像同时保持完全相同 public,强烈建议在 URL 中包含版本组件ID。在这种情况下,如果您访问完全相同的 URL,您可能会得到图像的 CDN 缓存版本,这可能是旧版本。
因此,当你上传时,你可以从 Cloudinary 的上传响应中获取 version
值,并将其存储在你的数据库中,下次更新图像时,也将 URL 更新为新版本值.
或者,您也可以要求 Cloudinary 在上传时 invalidate
图片。请注意,虽然立即将版本组件 "busts" 包含在缓存中,但失效可能需要一段时间才能通过 CDN 传播。想要查询更多的信息:
http://cloudinary.com/documentation/image_transformations#image_versions
这是我想到的解决方案。它基于调整我用来将图像从文件夹上传到 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' }));
});