Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/hungry-ravens-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@shopify/prettier-plugin-liquid': minor
'@shopify/liquid-html-parser': minor
'@shopify/theme-check-common': minor
---

Introducing `doc` tags inside the new `snippet` tag, as well as making the theme check more rigorous with where the `doc` tag is placed
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Module: UnsupportedDocTag', () => {

expect(offenses).to.have.length(1);
expect(offenses[0].message).to.equal(
'The `doc` tag can only be used within a snippet or block.',
'The `doc` must be placed directly within an inline snippet tag, not nested inside other tags',
);
});

Expand Down Expand Up @@ -42,4 +42,39 @@ describe('Module: UnsupportedDocTag', () => {

expect(offenses).to.be.empty;
});

it('should not report an error when `doc` tag is used inside inline snippet', async () => {
const layoutSourceCode = `
{% snippet %}
${sourceCode}
{% endsnippet %}
`;

const offenses = await runLiquidCheck(
UnsupportedDocTag,
layoutSourceCode,
'file://layout/theme.liquid',
);

expect(offenses).to.be.empty;
});

it('should report an error when `doc` tag is nested inside a block within a snippet file', async () => {
const nestedSourceCode = `
{% if true %}
${sourceCode}
{% endif %}
`;

const offenses = await runLiquidCheck(
UnsupportedDocTag,
nestedSourceCode,
'file://snippets/file.liquid',
);

expect(offenses).to.have.length(1);
expect(offenses[0].message).to.equal(
'The `doc` tag cannot be nested inside any Liquid tags in a snippet or block file',
);
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { isSnippet, isBlock } from '../../to-schema';
import { LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
import { filePathSupportsLiquidDoc } from '../../liquid-doc/utils';
import { LiquidRawTag, NodeTypes, LiquidHtmlNode } from '@shopify/liquid-html-parser';

export const UnsupportedDocTag: LiquidCheckDefinition = {
meta: {
Expand All @@ -19,18 +20,30 @@ export const UnsupportedDocTag: LiquidCheckDefinition = {

create(context) {
const docTagName = 'doc';

if (filePathSupportsLiquidDoc(context.file.uri)) {
return {};
}
const snippetTagName = 'snippet';

return {
async LiquidRawTag(node) {
async LiquidRawTag(node: LiquidRawTag, ancestors: LiquidHtmlNode[]) {
if (node.name !== docTagName) {
return;
}

const isInSnippetOrBlockFile = filePathSupportsLiquidDoc(context.file.uri);
const immediateParent = ancestors.at(-1);
const isTopLevelInFile = immediateParent?.type === NodeTypes.Document;
const isDirectChildOfSnippetTag =
immediateParent?.type === NodeTypes.LiquidTag && immediateParent.name === snippetTagName;

if ((isInSnippetOrBlockFile && isTopLevelInFile) || isDirectChildOfSnippetTag) {
return;
}

const message = isInSnippetOrBlockFile
? `The \`${docTagName}\` tag cannot be nested inside any Liquid tags in a snippet or block file`
: `The \`${docTagName}\` must be placed directly within an inline snippet tag, not nested inside other tags`;

context.report({
message: `The \`${docTagName}\` tag can only be used within a snippet or block.`,
message,
startIndex: node.position.start,
endIndex: node.position.end,
suggest: [
Expand Down