Skip to content

Commit fc9243a

Browse files
committed
Fixes #236
1 parent a6db210 commit fc9243a

File tree

3 files changed

+75
-35
lines changed

3 files changed

+75
-35
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"scripts": {
1313
"pretest": "eslint img.js src/**.js test/**.js",
1414
"test": "ava --no-worker-threads",
15+
"watch": "ava --no-worker-threads --watch",
1516
"sample": "cd sample && node sample.js"
1617
},
1718
"repository": {

src/transform-plugin.js

+54-31
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,65 @@ function assignAttributes(rootTargetNode, newNode) {
3131
}
3232
}
3333

34+
function getOutputLocations(originalSource, outputDirectoryFromAttribute, pageContext, options) {
35+
let projectOutputDirectory = options.directories.output;
36+
37+
if(outputDirectoryFromAttribute) {
38+
if(path.isAbsolute(outputDirectoryFromAttribute)) {
39+
return {
40+
outputDir: path.join(projectOutputDirectory, outputDirectoryFromAttribute),
41+
urlPath: outputDirectoryFromAttribute,
42+
};
43+
}
44+
return {
45+
outputDir: path.join(projectOutputDirectory, pageContext.url, outputDirectoryFromAttribute),
46+
urlPath: path.join(pageContext.url, outputDirectoryFromAttribute),
47+
};
48+
}
49+
50+
if(options.urlPath) {
51+
// do nothing, user has specified directories in the plugin options.
52+
return {};
53+
}
54+
55+
if(path.isAbsolute(originalSource)) {
56+
// if the path is an absolute one (relative to the content directory) write to a global output directory to avoid duplicate writes for identical source images.
57+
return {
58+
outputDir: path.join(projectOutputDirectory, "/img/"),
59+
urlPath: "/img/",
60+
};
61+
}
62+
63+
// If original source is a relative one, this colocates images to the template output.
64+
let dir = path.dirname(pageContext.outputPath);
65+
66+
// filename is included in url: ./dir/post.html => /dir/post.html
67+
if(pageContext.outputPath.endsWith(pageContext.url)) {
68+
// remove file name
69+
let split = pageContext.url.split("/");
70+
split[split.length - 1] = "";
71+
72+
return {
73+
outputDir: dir,
74+
urlPath: split.join("/"),
75+
};
76+
}
77+
78+
// filename is not included in url: ./dir/post/index.html => /dir/post/
79+
return {
80+
outputDir: dir,
81+
urlPath: pageContext.url,
82+
};
83+
}
84+
3485
function transformTag(context, sourceNode, rootTargetNode, opts) {
3586
let originalSource = getSourcePath(sourceNode, rootTargetNode);
3687

3788
if(!originalSource) {
3889
return sourceNode;
3990
}
4091

41-
let { inputPath, outputPath, url } = context.page;
92+
let { inputPath } = context.page;
4293

4394
sourceNode.attrs.src = Util.normalizeImageSource({
4495
input: opts.directories.input,
@@ -51,36 +102,8 @@ function transformTag(context, sourceNode, rootTargetNode, opts) {
51102
sourceNode.attrs[ATTRS.ORIGINAL_SOURCE] = originalSource;
52103
}
53104

54-
let instanceOptions = {};
55-
56-
let outputDirectory = getOutputDirectory(sourceNode);
57-
if(outputDirectory) {
58-
if(path.isAbsolute(outputDirectory)) {
59-
instanceOptions = {
60-
outputDir: path.join(opts.directories.output, outputDirectory),
61-
urlPath: outputDirectory,
62-
};
63-
} else {
64-
instanceOptions = {
65-
outputDir: path.join(opts.directories.output, url, outputDirectory),
66-
urlPath: path.join(url, outputDirectory),
67-
};
68-
}
69-
} else if(opts.urlPath) {
70-
// do nothing, user has specified directories in the plugin options.
71-
} else if(path.isAbsolute(originalSource)) {
72-
// if the path is an absolute one (relative to the content directory) write to a global output directory to avoid duplicate writes for identical source images.
73-
instanceOptions = {
74-
outputDir: path.join(opts.directories.output, "/img/"),
75-
urlPath: "/img/",
76-
};
77-
} else {
78-
// If original source is a relative one, this colocates images to the template output.
79-
instanceOptions = {
80-
outputDir: path.dirname(outputPath),
81-
urlPath: url,
82-
};
83-
}
105+
let outputDirectoryFromAttribute = getOutputDirectory(sourceNode);
106+
let instanceOptions = getOutputLocations(originalSource, outputDirectoryFromAttribute, context.page, opts);
84107

85108
// returns promise
86109
return imageAttributesToPosthtmlNode(sourceNode.attrs, instanceOptions, opts).then(newNode => {

test/transform-test.mjs

+20-4
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,6 @@ test("Using the transform plugin, <img> to <picture>, keeps slot attribute #241"
420420
elev.disableLogger();
421421

422422
let results = await elev.toJSON();
423-
// TODO how to add independent class to <picture>
424423
t.is(results[0].content, `<picture><source type="image/webp" srcset="/virtual/KkPMmHd3hP-1280.webp 1280w"><img src="/virtual/KkPMmHd3hP-1280.jpeg" alt="My ugly mug" slot="image-1" width="1280" height="853"></picture>`);
425424
});
426425

@@ -437,7 +436,6 @@ test("#234 Use existing `width` attribute for `widths` config", async t => {
437436
elev.disableLogger();
438437

439438
let results = await elev.toJSON();
440-
// TODO how to add independent class to <picture>
441439
t.is(results[0].content, `<picture><source type="image/webp" srcset="/virtual/KkPMmHd3hP-200.webp 200w"><img src="/virtual/KkPMmHd3hP-200.jpeg" alt="My ugly mug" width="200" height="133"></picture>`);
442440
});
443441

@@ -454,7 +452,6 @@ test("#234 Use existing `width` attribute for `widths` config (huge width uses m
454452
elev.disableLogger();
455453

456454
let results = await elev.toJSON();
457-
// TODO how to add independent class to <picture>
458455
t.is(results[0].content, `<picture><source type="image/webp" srcset="/virtual/KkPMmHd3hP-1280.webp 1280w"><img src="/virtual/KkPMmHd3hP-1280.jpeg" alt="My ugly mug" width="1280" height="853"></picture>`);
459456
});
460457

@@ -471,6 +468,25 @@ test("#234 Use existing `width` attribute for `widths` config (comma separated w
471468
elev.disableLogger();
472469

473470
let results = await elev.toJSON();
474-
// TODO how to add independent class to <picture>
475471
t.is(results[0].content, `<picture><source type="image/webp" srcset="/virtual/KkPMmHd3hP-1280.webp 1280w"><img src="/virtual/KkPMmHd3hP-1280.jpeg" alt="My ugly mug" width="1280" height="853"></picture>`);
472+
});
473+
474+
test("#236 Use with permalink with file name", async t => {
475+
let elev = new Eleventy( "test", "test/_site", {
476+
config: eleventyConfig => {
477+
eleventyConfig.addTemplate("virtual.md", `![alt text](./bio-2017.jpg)`, {
478+
permalink: "blog/posts/blog-post.html"
479+
});
480+
481+
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
482+
formats: ["auto"],
483+
dryRun: true, // don’t write image files!
484+
});
485+
}
486+
});
487+
elev.disableLogger();
488+
489+
let results = await elev.toJSON();
490+
491+
t.is(results[0].content.trim(), `<p><img src="/blog/posts/KkPMmHd3hP-1280.jpeg" alt="alt text" width="1280" height="853"></p>`);
476492
});

0 commit comments

Comments
 (0)