Skip to content

Commit d287b7b

Browse files
committed
feat: template config and template rules.
1 parent ef2eb88 commit d287b7b

File tree

11 files changed

+104
-59
lines changed

11 files changed

+104
-59
lines changed

website/open-graph-templates/basic/template.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"font": "arial.ttf",
44
"layout": [
55
{
6-
"typse": "text",
6+
"type": "text",
77
"name": "title",
88
"fontSize": 80,
99
"fill": "white",
+9-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
{
22
"outputDir": "assets/og",
3-
"textWidthLimit": 200,
3+
"textWidthLimit": 1100,
4+
"quality": 70,
45
"rules": [
56
{
67
"name": "basic",
78
"priority": 0,
8-
"pattern": "*"
9+
"pattern": "."
910
},
1011
{
1112
"name": "gray",
1213
"priority": 1,
13-
"pattern": "*"
14+
"pattern": "^concepts*"
15+
},
16+
{
17+
"name": "gray",
18+
"priority": 2,
19+
"pattern": "^about*"
1420
}
1521
]
1622
}
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
11
{
22
"image": "preview.png",
3-
"font": "Kanit-Bold.ttf",
3+
"font": "Kanit-bold.ttf",
44
"layout": [
55
{
66
"type": "text",
7-
"name": "label",
8-
"fontSize": 20,
7+
"name": "title",
8+
"fontSize": 80,
99
"fill": "white",
1010
"stroke": "white",
11-
"top": 20,
12-
"left": 20
13-
},
14-
{
15-
"type": "text",
16-
"name": "description",
17-
"fontSize": 20,
18-
"fill": "white",
19-
"stroke": "white",
20-
"top": 40,
21-
"left": 120
11+
"top": 200,
12+
"left": 200
2213
}
2314
]
2415
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,49 @@
11
# Docusaurus OpenGraph image generator plugin
22

33

4-
Templates configuration file example:
4+
### Templates folder files listing.
5+
```sh
6+
└── website/
7+
└── open-graph-tempaltes/
8+
# required
9+
├── basic
10+
| ├── font.ttf
11+
| ├── preview.png
12+
| └── template.json
13+
|
14+
└── config.json
15+
```
16+
17+
18+
### Templates configuration file example:
519
**config.json**
620
```json
721
{
8-
"outputDir": "",
9-
"rules": {
10-
"basic": {
22+
"outputDir": "assets/og",
23+
"textWidthLimit": 1100,
24+
"quality": 70,
25+
"rules": [
26+
{
27+
"name": "basic",
1128
"priority": 0,
12-
"pattern": "*"
29+
"pattern": "."
1330
},
14-
"gray": {
31+
{
32+
"name": "gray",
1533
"priority": 1,
16-
"pattern": "*"
34+
"pattern": "^concepts*"
35+
},
36+
{
37+
"name": "gray",
38+
"priority": 2,
39+
"pattern": "^about*"
1740
}
18-
}
41+
]
1942
}
43+
2044
```
2145

22-
Template configuration example:
46+
### Template configuration example:
2347
**template.json**
2448
```json
2549
{
@@ -28,23 +52,13 @@ Template configuration example:
2852
"layout": [
2953
{
3054
"type": "text",
31-
"name": "label",
32-
"fontSize": 72,
55+
"name": "title",
56+
"fontSize": 80,
3357
"fill": "white",
3458
"stroke": "white",
35-
"top": 20,
36-
"left": 20
37-
},
38-
{
39-
"type": "text",
40-
"name": "description",
41-
"fontSize": 64,
42-
"fill": "white",
43-
"stroke": "white",
44-
"top": 40,
45-
"left": 120
59+
"top": 400,
60+
"left": 200
4661
}
4762
]
4863
}
49-
5064
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const fs = require("fs");
2+
const { objectFromBuffer, validateConfig } = require("./utils");
3+
4+
module.exports.getConfig = function (path, encode = "utf-8") {
5+
const config = objectFromBuffer(fs.readFileSync(`${path}\\config.json`, encode));
6+
if (!validateConfig(config)) {
7+
console.error("Config validation error");
8+
return;
9+
}
10+
return config;
11+
};

website/plugins/docusaurus-plugin-open-graph-image/image.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function createImageFromTemplate({ path, name, params }) {
1313
module.exports.createImagesMapFromTemplates = function (templates) {
1414
const images = new Map();
1515
templates.forEach((item) => {
16-
if (!images.has(item.params.image)) {
16+
if (!images.has(`${item.name}_${item.params.image}`)) {
1717
images.set(`${item.name}_${item.params.image}`, createImageFromTemplate(item));
1818
}
1919
});

website/plugins/docusaurus-plugin-open-graph-image/index.js

+16-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const { validateTemplate } = require("./utils");
55
const { createLayoutLayers } = require("./layout");
66
const { createFontsMapFromTemplates } = require("./font");
77
const { createImagesMapFromTemplates } = require("./image");
8+
const { getConfig } = require("./config");
9+
const { getTemplateNameByRules } = require("./rules");
810

911
module.exports = function (context, { templatesDir }) {
1012
const isProd = process.env.NODE_ENV === "production";
@@ -17,33 +19,40 @@ module.exports = function (context, { templatesDir }) {
1719

1820
const templates = getTemplates(templatesDir);
1921
if (!templates.some(validateTemplate)) {
20-
console.error("Template validation error.");
2122
return;
2223
}
2324

25+
const config = getConfig(templatesDir);
26+
if (!config) return;
27+
28+
// TODO: File not found exception?
2429
const fonts = createFontsMapFromTemplates(templates);
2530
const images = createImagesMapFromTemplates(templates);
2631

2732
async function generateImageFromDoc(doc, locale, outputDir) {
2833
const { id, title } = doc;
2934

30-
// use basic
3135
const hashFileName = sha1(id + locale);
36+
const templateName = getTemplateNameByRules(id, config.rules);
3237

33-
const template = templates.find((item) => item.name === "basic");
38+
const template = templates.find((item) => item.name === templateName);
3439

3540
const previewImage = await images.get(`${template.name}_${template.params.image}`).clone();
3641

3742
const previewFont = fonts.get(template.params.font);
3843

39-
const textLayers = createLayoutLayers(doc, template.params.layout, previewFont);
44+
const textLayers = createLayoutLayers(
45+
doc,
46+
template.params.layout,
47+
previewFont,
48+
config.textWidthLimit,
49+
);
4050

4151
try {
4252
await previewImage.composite(textLayers);
4353
await previewImage
4454
.jpeg({
45-
// TODO: Quality from config.json
46-
quality: 80,
55+
quality: config.quality,
4756
chromaSubsampling: "4:4:4",
4857
})
4958
.toFile(`${outputDir}\\${hashFileName}.jpg`);
@@ -59,7 +68,7 @@ module.exports = function (context, { templatesDir }) {
5968
(plugin) => plugin.name === "docusaurus-plugin-content-docs",
6069
);
6170

62-
const previewOutputDir = `${outDir}\\assets\\og\\`;
71+
const previewOutputDir = `${outDir}\\${config.outputDir}`;
6372
fs.mkdir(previewOutputDir, { recursive: true }, (error) => {
6473
if (error) throw error;
6574
});

website/plugins/docusaurus-plugin-open-graph-image/layout.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const { createSVGText } = require("./font");
22

3-
module.exports.createLayoutLayers = function (doc, layout, previewFont) {
3+
module.exports.createLayoutLayers = function (doc, layout, previewFont, textWidthLimit) {
44
const layers = layout.map((item) => {
55
if (!Object.prototype.hasOwnProperty.call(doc, item.name)) {
66
console.error(`Wrong template config? Doc property ${item.name} not found.`);
@@ -14,7 +14,9 @@ module.exports.createLayoutLayers = function (doc, layout, previewFont) {
1414
};
1515

1616
return {
17-
input: Buffer.from(createSVGText(previewFont, doc[item.name], layoutOptions)),
17+
input: Buffer.from(
18+
createSVGText(previewFont, doc[item.name], layoutOptions, textWidthLimit),
19+
),
1820
top: item.top,
1921
left: item.left,
2022
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports.getTemplateNameByRules = function (path, rules) {
2+
const filteredRules = rules.filter((rule) => new RegExp(rule.pattern).test(path));
3+
const sortedRules = filteredRules.sort((a, b) => b.priority - a.priority);
4+
return sortedRules[0]?.name || "basic";
5+
};

website/plugins/docusaurus-plugin-open-graph-image/utils.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,27 @@ module.exports.validateTemplate = function ({ params }) {
2626
return acc;
2727
}, true);
2828
}
29+
console.error("Template validation error.");
2930
return false;
3031
};
3132

3233
module.exports.objectFromBuffer = function objectFromBuffer(buffer) {
3334
return JSON.parse(buffer.toString());
3435
};
3536

36-
const Config = object({
37-
outputDir: string(),
38-
textWidthLimit: number(),
39-
rules: array(),
40-
});
41-
4237
const Rule = object({
4338
name: string(),
4439
priority: number(),
4540
pattern: string(),
4641
});
4742

43+
const Config = object({
44+
outputDir: string(),
45+
textWidthLimit: number(),
46+
quality: number(),
47+
rules: array(Rule),
48+
});
49+
4850
module.exports.validateConfig = function (config) {
4951
if (is(config, Config)) {
5052
return config.rules.reduce((acc, item) => {

website/src/theme/DocItem/index.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ import { OpenGraphPreview } from "../../shared/lib/open-graph-preview";
66
function DocItem(props) {
77
const { content } = props;
88
const { id, source } = content.metadata;
9-
const lang = source.match(/i18n\/(?<locale>[a-z]+)\//)?.locale;
9+
10+
const lang = source.match(/i18n\/(?<locale>[a-z]+)\//)?.groups?.locale;
11+
// No any load for static
1012
const hashFileName = sha1(id + lang);
1113

1214
return (
1315
<>
14-
<OpenGraphPreview imgUrl={hashFileName} />
16+
{/* TODO: Add and use domain from env? */}
17+
<OpenGraphPreview
18+
imgUrl={`https://feature-sliced.design/assets/og/${hashFileName}.jpg`}
19+
/>
1520
<OriginalDocItem {...props} />
1621
</>
1722
);

0 commit comments

Comments
 (0)