vite-plugin-twig-drupal 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +39 -9
- package/tests/__snapshots__/smoke.test.js.snap +46 -2
- package/tests/fixtures/mockup.twig +4 -0
- package/tests/smoke.test.js +7 -0
- package/vite.config.js +7 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import Twig from "twig"
|
|
2
|
+
import { resolve, dirname } from "node:path"
|
|
3
|
+
import { existsSync } from "node:fs"
|
|
4
|
+
|
|
2
5
|
const { twig } = Twig
|
|
3
|
-
import { resolve } from "node:path"
|
|
4
6
|
|
|
5
7
|
const FRAMEWORK_REACT = "react"
|
|
6
8
|
const FRAMEWORK_HTML = "html"
|
|
@@ -9,6 +11,7 @@ const defaultOptions = {
|
|
|
9
11
|
namespaces: {},
|
|
10
12
|
filters: {},
|
|
11
13
|
functions: {},
|
|
14
|
+
globalContext: {},
|
|
12
15
|
framework: FRAMEWORK_HTML,
|
|
13
16
|
pattern: /\.(twig)(\?.*)?$/,
|
|
14
17
|
}
|
|
@@ -21,6 +24,13 @@ const includeTokenTypes = [
|
|
|
21
24
|
"Twig.logic.type.import",
|
|
22
25
|
]
|
|
23
26
|
|
|
27
|
+
const resolveFile = (directory, file) => {
|
|
28
|
+
if (existsSync(resolve(file))) {
|
|
29
|
+
return resolve(file)
|
|
30
|
+
}
|
|
31
|
+
return resolve(directory, file)
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
const pluckIncludes = (tokens) => {
|
|
25
35
|
return [
|
|
26
36
|
...tokens
|
|
@@ -70,7 +80,9 @@ const errorHandler =
|
|
|
70
80
|
(e) => {
|
|
71
81
|
if (isDefault) {
|
|
72
82
|
return {
|
|
73
|
-
code: `export default () => 'An error occurred whilst rendering ${id}: ${e.toString()}
|
|
83
|
+
code: `export default () => 'An error occurred whilst rendering ${id}: ${e.toString()} ${
|
|
84
|
+
e.stack
|
|
85
|
+
}';`,
|
|
74
86
|
map: null,
|
|
75
87
|
}
|
|
76
88
|
}
|
|
@@ -102,9 +114,11 @@ const plugin = (options = {}) => {
|
|
|
102
114
|
}
|
|
103
115
|
let embed,
|
|
104
116
|
embeddedIncludes,
|
|
117
|
+
functions,
|
|
105
118
|
code,
|
|
106
119
|
includes,
|
|
107
120
|
seen = []
|
|
121
|
+
|
|
108
122
|
try {
|
|
109
123
|
const result = await compileTemplate(id, id, options).catch(
|
|
110
124
|
errorHandler(id)
|
|
@@ -117,8 +131,11 @@ const plugin = (options = {}) => {
|
|
|
117
131
|
includes = result.includes
|
|
118
132
|
const includePromises = []
|
|
119
133
|
const processIncludes = (template) => {
|
|
120
|
-
const file =
|
|
121
|
-
|
|
134
|
+
const file = resolveFile(
|
|
135
|
+
dirname(id),
|
|
136
|
+
Twig.path.expandNamespace(options.namespaces, template)
|
|
137
|
+
)
|
|
138
|
+
if (!seen.includes(template)) {
|
|
122
139
|
includePromises.push(
|
|
123
140
|
new Promise(async (resolve, reject) => {
|
|
124
141
|
const { includes, code } = await compileTemplate(
|
|
@@ -132,7 +149,7 @@ const plugin = (options = {}) => {
|
|
|
132
149
|
resolve(code)
|
|
133
150
|
})
|
|
134
151
|
)
|
|
135
|
-
seen.push(
|
|
152
|
+
seen.push(template)
|
|
136
153
|
}
|
|
137
154
|
}
|
|
138
155
|
includes.forEach(processIncludes)
|
|
@@ -140,11 +157,22 @@ const plugin = (options = {}) => {
|
|
|
140
157
|
.filter((template) => template !== "_self")
|
|
141
158
|
.map(
|
|
142
159
|
(template) =>
|
|
143
|
-
`import '${
|
|
160
|
+
`import '${resolveFile(
|
|
161
|
+
dirname(id),
|
|
144
162
|
Twig.path.expandNamespace(options.namespaces, template)
|
|
145
163
|
)}';`
|
|
146
164
|
)
|
|
147
165
|
.join("\n")
|
|
166
|
+
|
|
167
|
+
functions = Object.entries(options.functions)
|
|
168
|
+
.map(([name, value]) => {
|
|
169
|
+
return `
|
|
170
|
+
const ${name} = ${value};
|
|
171
|
+
${name}(Twig);
|
|
172
|
+
`
|
|
173
|
+
})
|
|
174
|
+
.join("\n")
|
|
175
|
+
|
|
148
176
|
const includeResult = await Promise.all(includePromises).catch(
|
|
149
177
|
errorHandler(id)
|
|
150
178
|
)
|
|
@@ -161,10 +189,11 @@ const plugin = (options = {}) => {
|
|
|
161
189
|
import DrupalAttribute from 'drupal-attribute';
|
|
162
190
|
import { addDrupalExtensions } from 'drupal-twig-extensions/twig';
|
|
163
191
|
${frameworkInclude}
|
|
164
|
-
|
|
192
|
+
|
|
165
193
|
${embed}
|
|
166
194
|
|
|
167
|
-
|
|
195
|
+
${functions}
|
|
196
|
+
|
|
168
197
|
// Disable caching.
|
|
169
198
|
Twig.cache(false);
|
|
170
199
|
|
|
@@ -176,7 +205,8 @@ const plugin = (options = {}) => {
|
|
|
176
205
|
${includes ? `component.options.allowInlineIncludes = true;` : ""}
|
|
177
206
|
try {
|
|
178
207
|
return frameworkTransform(component.render({
|
|
179
|
-
|
|
208
|
+
attributes: new DrupalAttribute(),
|
|
209
|
+
...${JSON.stringify(options.globalContext)},
|
|
180
210
|
...context
|
|
181
211
|
}));
|
|
182
212
|
}
|
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
+
exports[`Basic smoke test > Should support global context and functions 1`] = `
|
|
4
|
+
"<section>
|
|
5
|
+
<h1>Include</h1>
|
|
6
|
+
<article>
|
|
7
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. At dignissimos fugiat inventore laborum maiores molestiae neque quia quo unde veniam?
|
|
8
|
+
</article>
|
|
9
|
+
</section>
|
|
10
|
+
<section>
|
|
11
|
+
<h1>Embed</h1>
|
|
12
|
+
<article>
|
|
13
|
+
Lorem ipsum dolor sit amet.
|
|
14
|
+
<button class=\\"button--primary\\">Nested include</button>
|
|
15
|
+
IT WORKS!
|
|
16
|
+
</article>
|
|
17
|
+
</section>
|
|
18
|
+
<section>
|
|
19
|
+
<h1></h1>
|
|
20
|
+
<article>
|
|
21
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. At dignissimos fugiat inventore laborum maiores molestiae neque quia quo unde veniam?
|
|
22
|
+
</article>
|
|
23
|
+
</section>
|
|
24
|
+
<section>
|
|
25
|
+
<h1>Relative include</h1>
|
|
26
|
+
<article>
|
|
27
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. At dignissimos fugiat inventore laborum maiores molestiae neque quia quo unde veniam?
|
|
28
|
+
</article>
|
|
29
|
+
</section>
|
|
30
|
+
"
|
|
31
|
+
`;
|
|
32
|
+
|
|
3
33
|
exports[`Basic smoke test > Should support includes 1`] = `
|
|
4
34
|
"<section>
|
|
5
35
|
<h1>Include</h1>
|
|
@@ -12,7 +42,8 @@ exports[`Basic smoke test > Should support includes 1`] = `
|
|
|
12
42
|
<article>
|
|
13
43
|
Lorem ipsum dolor sit amet.
|
|
14
44
|
<button class=\\"button--primary\\">Nested include</button>
|
|
15
|
-
|
|
45
|
+
IT WORKS!
|
|
46
|
+
</article>
|
|
16
47
|
</section>
|
|
17
48
|
<section>
|
|
18
49
|
<h1></h1>
|
|
@@ -20,6 +51,12 @@ exports[`Basic smoke test > Should support includes 1`] = `
|
|
|
20
51
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit. At dignissimos fugiat inventore laborum maiores molestiae neque quia quo unde veniam?
|
|
21
52
|
</article>
|
|
22
53
|
</section>
|
|
54
|
+
<section>
|
|
55
|
+
<h1>Relative include</h1>
|
|
56
|
+
<article>
|
|
57
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. At dignissimos fugiat inventore laborum maiores molestiae neque quia quo unde veniam?
|
|
58
|
+
</article>
|
|
59
|
+
</section>
|
|
23
60
|
"
|
|
24
61
|
`;
|
|
25
62
|
|
|
@@ -52,7 +89,8 @@ exports[`Basic smoke test > Should support variables 1`] = `
|
|
|
52
89
|
<article>
|
|
53
90
|
Lorem ipsum dolor sit amet.
|
|
54
91
|
<button class=\\"button--primary\\">Nested include</button>
|
|
55
|
-
|
|
92
|
+
IT WORKS!
|
|
93
|
+
</article>
|
|
56
94
|
</section>
|
|
57
95
|
<section>
|
|
58
96
|
<h1>Pickle Fixie</h1>
|
|
@@ -60,5 +98,11 @@ exports[`Basic smoke test > Should support variables 1`] = `
|
|
|
60
98
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit. At dignissimos fugiat inventore laborum maiores molestiae neque quia quo unde veniam?
|
|
61
99
|
</article>
|
|
62
100
|
</section>
|
|
101
|
+
<section>
|
|
102
|
+
<h1>Relative include</h1>
|
|
103
|
+
<article>
|
|
104
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. At dignissimos fugiat inventore laborum maiores molestiae neque quia quo unde veniam?
|
|
105
|
+
</article>
|
|
106
|
+
</section>
|
|
63
107
|
"
|
|
64
108
|
`;
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
{% block content %}
|
|
4
4
|
Lorem ipsum dolor sit amet.
|
|
5
5
|
{% include "@tests/button.twig" with {text: 'Nested include'} %}
|
|
6
|
+
{% if active_theme == 'poodles' %}
|
|
7
|
+
{{ testFunction() }}
|
|
8
|
+
{% endif %}
|
|
6
9
|
{% endblock %}
|
|
7
10
|
{% endembed %}
|
|
8
11
|
{% include "@tests/section.twig" %}
|
|
12
|
+
{% include "../fixtures/section.twig" with {title: 'Relative include'} %}
|
package/tests/smoke.test.js
CHANGED
|
@@ -9,6 +9,7 @@ describe("Basic smoke test", () => {
|
|
|
9
9
|
const markup = Markup()
|
|
10
10
|
expect(markup).toMatchSnapshot()
|
|
11
11
|
expect(markup).toContain("Nested include")
|
|
12
|
+
expect(markup).toContain("Relative include")
|
|
12
13
|
})
|
|
13
14
|
it("Should support variables", () => {
|
|
14
15
|
const markup = Markup({ title: "Pickle Fixie" })
|
|
@@ -28,4 +29,10 @@ describe("Basic smoke test", () => {
|
|
|
28
29
|
expect(markup).toContain("Contact")
|
|
29
30
|
expect(markup).toMatchSnapshot()
|
|
30
31
|
})
|
|
32
|
+
it("Should support global context and functions", () => {
|
|
33
|
+
const markup = Markup()
|
|
34
|
+
expect(markup).toMatchSnapshot()
|
|
35
|
+
expect(markup).toContain("Nested include")
|
|
36
|
+
expect(markup).toContain("IT WORKS!")
|
|
37
|
+
})
|
|
31
38
|
})
|
package/vite.config.js
CHANGED
|
@@ -18,6 +18,13 @@ export default defineConfig({
|
|
|
18
18
|
},
|
|
19
19
|
plugins: [
|
|
20
20
|
twig({
|
|
21
|
+
globalContext: {
|
|
22
|
+
active_theme: "poodles",
|
|
23
|
+
},
|
|
24
|
+
functions: {
|
|
25
|
+
testFunction: (instance) =>
|
|
26
|
+
instance.extendFunction("testFunction", () => "IT WORKS!"),
|
|
27
|
+
},
|
|
21
28
|
namespaces: {
|
|
22
29
|
tests: join(__dirname, "/tests/fixtures"),
|
|
23
30
|
},
|