Skip to content

Commit eb2cdba

Browse files
committed
feat: Enhance Twig template handling with addClass support and improve formatting consistency
- Added support for `attributes.addClass()` in Drupal Twig templates. - Updated test cases to validate new `addClass` functionality. - Improved formatting consistency in TypeScript code for better readability. - Added .DS_Store to .gitignore to prevent unnecessary files from being tracked.
1 parent 63c22de commit eb2cdba

File tree

3 files changed

+102
-56
lines changed

3 files changed

+102
-56
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
/dist
3+
.DS_Store

src/index.ts

Lines changed: 71 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ function transformLiquid(ast: any, { env }: TransformerContext) {
356356
}) {
357357
return Array.isArray(node.name)
358358
? node.name.every(
359-
(n) => n.type === 'TextNode' && staticAttrs.has(n.value),
360-
)
359+
(n) => n.type === 'TextNode' && staticAttrs.has(n.value),
360+
)
361361
: staticAttrs.has(node.name)
362362
}
363363

@@ -549,18 +549,18 @@ function sortTemplateLiteral(
549549
quasi.value.cooked = same
550550
? quasi.value.raw
551551
: sortClasses(quasi.value.cooked, {
552-
env,
553-
ignoreFirst: i > 0 && !/^\s/.test(quasi.value.cooked),
554-
ignoreLast:
555-
i < node.expressions.length && !/\s$/.test(quasi.value.cooked),
556-
collapseWhitespace: collapseWhitespace && {
557-
start: collapseWhitespace && collapseWhitespace.start && i === 0,
558-
end:
559-
collapseWhitespace &&
560-
collapseWhitespace.end &&
561-
i >= node.expressions.length,
562-
},
563-
})
552+
env,
553+
ignoreFirst: i > 0 && !/^\s/.test(quasi.value.cooked),
554+
ignoreLast:
555+
i < node.expressions.length && !/\s$/.test(quasi.value.cooked),
556+
collapseWhitespace: collapseWhitespace && {
557+
start: collapseWhitespace && collapseWhitespace.start && i === 0,
558+
end:
559+
collapseWhitespace &&
560+
collapseWhitespace.end &&
561+
i >= node.expressions.length,
562+
},
563+
})
564564

565565
if (
566566
quasi.value.raw !== originalRaw ||
@@ -846,6 +846,23 @@ function transformTwig(ast: any, { env, changes }: TransformerContext) {
846846

847847
StringLiteral(node, path, meta) {
848848
if (!meta.sortTextNodes) {
849+
// Check for .addClass() calls in Drupal Twig templates
850+
const isAddClassCall = path.some((entry) => {
851+
return (
852+
entry.parent &&
853+
entry.parent.type === 'CallExpression' &&
854+
entry.parent.callee &&
855+
entry.parent.callee.type === 'MemberExpression' &&
856+
entry.parent.callee.property &&
857+
entry.parent.callee.property.name === 'addClass'
858+
)
859+
})
860+
861+
if (isAddClassCall) {
862+
node.value = sortClasses(node.value, { env })
863+
return
864+
}
865+
849866
return
850867
}
851868

@@ -952,12 +969,12 @@ function transformSvelte(ast: any, { env, changes }: TransformerContext) {
952969
value.data = same
953970
? value.raw
954971
: sortClasses(value.data, {
955-
env,
956-
ignoreFirst: i > 0 && !/^\s/.test(value.data),
957-
ignoreLast: i < attr.value.length - 1 && !/\s$/.test(value.data),
958-
removeDuplicates: false,
959-
collapseWhitespace: false,
960-
})
972+
env,
973+
ignoreFirst: i > 0 && !/^\s/.test(value.data),
974+
ignoreLast: i < attr.value.length - 1 && !/\s$/.test(value.data),
975+
removeDuplicates: false,
976+
collapseWhitespace: false,
977+
})
961978
} else if (value.type === 'MustacheTag') {
962979
visit(value.expression, {
963980
Literal(node) {
@@ -1135,58 +1152,58 @@ export const parsers: Record<string, Parser> = {
11351152

11361153
...(base.parsers.svelte
11371154
? {
1138-
svelte: createParser('svelte', transformSvelte, {
1139-
staticAttrs: ['class'],
1140-
}),
1141-
}
1155+
svelte: createParser('svelte', transformSvelte, {
1156+
staticAttrs: ['class'],
1157+
}),
1158+
}
11421159
: {}),
11431160
...(base.parsers.astro
11441161
? {
1145-
astro: createParser('astro', transformAstro, {
1146-
staticAttrs: ['class', 'className'],
1147-
dynamicAttrs: ['class:list', 'className'],
1148-
}),
1149-
}
1162+
astro: createParser('astro', transformAstro, {
1163+
staticAttrs: ['class', 'className'],
1164+
dynamicAttrs: ['class:list', 'className'],
1165+
}),
1166+
}
11501167
: {}),
11511168
...(base.parsers.astroExpressionParser
11521169
? {
1153-
astroExpressionParser: createParser(
1154-
'astroExpressionParser',
1155-
transformJavaScript,
1156-
{
1157-
staticAttrs: ['class'],
1158-
dynamicAttrs: ['class:list'],
1159-
},
1160-
),
1161-
}
1170+
astroExpressionParser: createParser(
1171+
'astroExpressionParser',
1172+
transformJavaScript,
1173+
{
1174+
staticAttrs: ['class'],
1175+
dynamicAttrs: ['class:list'],
1176+
},
1177+
),
1178+
}
11621179
: {}),
11631180
...(base.parsers.marko
11641181
? {
1165-
marko: createParser('marko', transformMarko, {
1166-
staticAttrs: ['class'],
1167-
}),
1168-
}
1182+
marko: createParser('marko', transformMarko, {
1183+
staticAttrs: ['class'],
1184+
}),
1185+
}
11691186
: {}),
11701187
...(base.parsers.twig
11711188
? {
1172-
twig: createParser('twig', transformTwig, {
1173-
staticAttrs: ['class'],
1174-
}),
1175-
}
1189+
twig: createParser('twig', transformTwig, {
1190+
staticAttrs: ['class'],
1191+
}),
1192+
}
11761193
: {}),
11771194
...(base.parsers.pug
11781195
? {
1179-
pug: createParser('pug', transformPug, {
1180-
staticAttrs: ['class'],
1181-
}),
1182-
}
1196+
pug: createParser('pug', transformPug, {
1197+
staticAttrs: ['class'],
1198+
}),
1199+
}
11831200
: {}),
11841201
...(base.parsers['liquid-html']
11851202
? {
1186-
'liquid-html': createParser('liquid-html', transformLiquid, {
1187-
staticAttrs: ['class'],
1188-
}),
1189-
}
1203+
'liquid-html': createParser('liquid-html', transformLiquid, {
1204+
staticAttrs: ['class'],
1205+
}),
1206+
}
11901207
: {}),
11911208
}
11921209

tests/plugins.test.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ let tests: PluginTest[] = [
134134
plugins: ['@zackad/prettier-plugin-twig'],
135135
options: {
136136
twigAlwaysBreakObjects: false,
137+
tailwindFunctions: ['addClass'],
137138
},
138139
tests: {
139140
twig: [
@@ -162,6 +163,33 @@ let tests: PluginTest[] = [
162163
`<div class="{{ ' flex ' + ' underline ' + ' block ' }}"></div>`,
163164
`<div class="{{ 'flex ' + ' underline' + ' block' }}"></div>`,
164165
],
166+
167+
// Drupal attributes.addClass() tests
168+
[
169+
`<div {{ attributes.addClass("sm:p-0 p-0") }}></div>`,
170+
`<div {{ attributes.addClass('p-0 sm:p-0') }}></div>`,
171+
],
172+
[
173+
`{{ attributes.addClass("sm:p-0 p-0") }}`,
174+
`{{ attributes.addClass('p-0 sm:p-0') }}`,
175+
],
176+
[
177+
`{% set className = "p-0 sm:p-0" %}
178+
{{ attributes.addClass(className) }}`,
179+
`{% set className = 'p-0 sm:p-0' %}
180+
{{ attributes.addClass(className) }}`,
181+
],
182+
[
183+
`{{ attributes.addClass("sm:p-0 " ~ variant ~ " p-0") }}`,
184+
`{{ attributes.addClass('sm:p-0' ~ variant ~ 'p-0') }}`,
185+
],
186+
[
187+
`{{ attributes
188+
.addClass("sm:p-0 p-0")
189+
.addClass("flex block")
190+
.addClass("underline") }}`,
191+
`{{ attributes.addClass('p-0 sm:p-0').addClass('block flex').addClass('underline') }}`,
192+
],
165193
],
166194
},
167195
},
@@ -207,7 +235,7 @@ let tests: PluginTest[] = [
207235
import './three'
208236
import '@one/file'
209237
import '@two/file'
210-
export default function Foo() { return <div className="sm:p-0 p-4"></div> }
238+
export default function Foo() { return <div className="p-4 sm:p-0"></div> }
211239
`,
212240
`import '@one/file'\nimport '@two/file'\n\nimport './three'\n\nexport default function Foo() {\n return <div className="p-4 sm:p-0"></div>\n}`,
213241
],
@@ -219,7 +247,7 @@ let tests: PluginTest[] = [
219247
tests: {
220248
babel: [
221249
[
222-
`/**\n * @param { string } param0 description\n */\n export default function Foo(param0) { return <div className="sm:p-0 p-4"></div> }`,
250+
`/**\n * @param { string } param0 description\n */\n export default function Foo(param0) { return <div className="p-4 sm:p-0"></div> }`,
223251
`/** @param {string} param0 Description */\nexport default function Foo(param0) {\n return <div className="p-4 sm:p-0"></div>\n}`,
224252
],
225253
],

0 commit comments

Comments
 (0)