{"id":16434,"library":"melody-parser","title":"Melody Twig Template Parser","description":"melody-parser is an extensible JavaScript parser specifically designed for the Twig template language, generating a detailed Abstract Syntax Tree (AST) from source code. Currently at version 1.7.5, the library maintains a steady release cadence with focus on robustness and extensibility. A key differentiator is its ability to be extended with custom parsing rules via \"extensions,\" allowing it to handle custom Twig tags or specialized template syntaxes beyond standard Twig. It also provides granular control over error handling for unknown tags, differentiating between strict parsing for code generation and lenient parsing for mere AST inspection. It is an essential component for projects requiring deep analysis, transformation, or tooling around Twig templates.","status":"active","version":"1.7.5","language":"javascript","source_language":"en","source_url":null,"tags":["javascript"],"install":[{"cmd":"npm install melody-parser","lang":"bash","label":"npm"},{"cmd":"yarn add melody-parser","lang":"bash","label":"yarn"},{"cmd":"pnpm add melody-parser","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides the type definitions for the Abstract Syntax Tree (AST) nodes generated by the parser. It's a peer dependency for type compatibility.","package":"melody-types","optional":false}],"imports":[{"note":"While CommonJS `require` is shown in some examples, modern Node.js and browser-first applications should prefer ES module `import`.","wrong":"const { parse } = require('melody-parser');","symbol":"parse","correct":"import { parse } from 'melody-parser';"},{"note":"Extensions are typically named exports, often aliased for clarity.","wrong":"import coreExtensions from 'melody-extension-core';","symbol":"coreExtensions (named import from melody-extension-core)","correct":"import { extension as coreExtensions } from 'melody-extension-core';"},{"note":"Custom extensions might be default exports or named exports depending on their implementation. Follow the extension's specific documentation.","symbol":"customExtension (default import from a custom module)","correct":"import customExtension from 'melody-extension-custom';"}],"quickstart":{"code":"import { parse } from 'melody-parser';\nimport { extension as coreExtensions } from 'melody-extension-core';\n\n// Example 1: Basic parsing\nconst twigCodeBasic = '{% spaceless %} Hello, {{ name }}! {% endspaceless %}';\nconst astBasic = parse(twigCodeBasic);\nconsole.log('Basic AST:', JSON.stringify(astBasic, null, 2));\n\n// Example 2: Parsing with options\nconst twigCodeWithOptions = '{# This is a comment #} {{ var }}';\nconst astWithOptions = parse(twigCodeWithOptions, {\n  ignoreComments: false, // Ensure comments are included in the AST\n  decodeEntities: true,\n});\nconsole.log('AST with options:', JSON.stringify(astWithOptions, null, 2));\n\n// Example 3: Parsing with extensions (core and a hypothetical custom one)\n// For a real custom extension, you'd implement its parser logic.\nconst customExtension = {\n  tags: {\n    exit: {\n      parse(parser, token) {\n        // Simplified parsing for an {% exit 404 %} tag\n        parser.advance(); // consume 'exit'\n        const parts = [parser.expression()];\n        parser.expect(token.type, 'end of tag');\n        return {\n          type: 'GenericTwigTag',\n          tagName: 'exit',\n          parts: parts,\n          sections: [],\n        };\n      }\n    }\n  }\n};\n\nconst twigCodeWithExtensions = '{% exit 404 %}';\nconst astWithExtensions = parse(\n  twigCodeWithExtensions,\n  { allowUnknownTags: true }, // Important for custom or unknown tags\n  coreExtensions,\n  customExtension\n);\nconsole.log('AST with extensions:', JSON.stringify(astWithExtensions, null, 2));","lang":"typescript","description":"Demonstrates basic parsing, parsing with configuration options, and extending the parser with custom logic using `melody-extension-core` and a hypothetical custom extension."},"warnings":[{"fix":"To allow parsing of unknown tags into `GenericTwigTag` AST nodes, set the `allowUnknownTags` option to `true` in the parse function's options object: `parse(code, { allowUnknownTags: true })`. Alternatively, provide a custom extension to explicitly handle the unknown tag.","message":"By default, `melody-parser` throws an error when it encounters an unknown Twig tag. This is strict behavior intended for scenarios where all tags must be explicitly handled (e.g., code generation).","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always install `melody-types` alongside `melody-parser`, adhering to the peer dependency version range specified (e.g., `npm install melody-types@^1.1.0`). Regularly update both packages to their latest compatible versions.","message":"Ensure `melody-types` peer dependency is installed and compatible. This package defines the AST node types, and version mismatches could lead to unexpected type errors or runtime issues, especially in TypeScript projects.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Enable the `allowUnknownTags` option: `parse(code, { allowUnknownTags: true })`. If 'mytag' is a custom tag you intend to support fully, create and pass a `melody-parser` extension that defines how to parse 'mytag'.","cause":"The parser encountered a Twig tag not recognized by its built-in rules or any provided extensions, and the `allowUnknownTags` option was not enabled.","error":"Error: Unknown tag \"mytag\""}],"ecosystem":"npm"}