prettier-plugin-smarty
v0.1.0
Published
Prettier plugin for Smarty templates with configurable delimiters (defaults to <{ ... }>).
Maintainers
Readme
prettier-plugin-smarty
A Prettier plugin for Smarty templates with configurable delimiters — defaults to <{ ... }> for codebases that override the standard {...} syntax.
Status: 0.1.0 — MVP. The plugin treats Smarty tags as opaque tokens, formats the surrounding HTML/CSS/JS with Prettier's built-in HTML formatter, then restores the tags. It does not reformat code inside Smarty tags. See Limitations before depending on it.
Why
Prettier doesn't have a Smarty parser. Projects that use custom delimiters like <{ ... }> (e.g. 6rooms/live_frontend) can't even use Prettier's HTML mode as a workaround, because <{ is invalid HTML and the parser rejects it.
This plugin works around that by replacing each Smarty construct with an HTML-shaped placeholder before formatting, then swapping the originals back in afterwards. Block tags (<{if}>...<{/if}>, <{foreach}>...<{/foreach}>, …) become <div> placeholders so HTML indentation tracks block boundaries correctly. Inline output (<{$var}>, <{include …}>) becomes an HTML comment so it stays on the same line as the surrounding text.
Install
npm install --save-dev prettier prettier-plugin-smartyThen add to your .prettierrc (or .prettierrc.json):
{
"plugins": ["prettier-plugin-smarty"]
}Format a file:
npx prettier --write path/to/file.tplOptions
| Option | Default | Description |
|--------|---------|-------------|
| smartyOpenDelimiter | <{ | Opening delimiter for Smarty tags. |
| smartyCloseDelimiter | }> | Closing delimiter for Smarty tags. |
Example .prettierrc.json for a project that uses the stock {...} delimiters:
{
"plugins": ["prettier-plugin-smarty"],
"smartyOpenDelimiter": "{",
"smartyCloseDelimiter": "}"
}Note: with stock
{...}delimiters there is more ambiguity (JS object literals, CSS rules, etc. all use braces). The plugin is primarily tested with<{ ... }>. Use stock delimiters at your own risk for now.
All standard Prettier options (printWidth, tabWidth, useTabs, singleQuote, htmlWhitespaceSensitivity, etc.) are forwarded to the underlying HTML formatter.
What gets formatted
- HTML markup outside Smarty tags is reformatted by Prettier's HTML printer.
- Indentation, tag wrapping, attribute placement follow standard Prettier HTML rules.
- Block boundaries (
<{if}>…<{/if}>, etc.) are preserved and the body is indented under them. - Embedded
<script>and<style>are formatted by Prettier's JS / CSS printers (Prettier default behaviour).
What does NOT get formatted (limitations)
- Anything inside Smarty tags.
<{if $x eq "y" }>stays exactly like that. The plugin sees Smarty constructs as opaque strings. - Middle tags (
<{else}>,<{elseif …}>,<{foreachelse}>) end up at the same indent as the block body, not at the block opener. The difference is one indent level — left as a v0.1 trade-off. }>inside a Smarty tag is only recognized as a tag terminator when it appears outside single/double-quoted attribute strings. Edge cases like<{include file="x}>y"}>are handled, but exotic constructs may confuse the tokenizer.- Stock
{...}delimiters are technically supported via options but not extensively tested. False positives on JS object literals or CSS braces are likely. - The plugin forces
htmlWhitespaceSensitivity: "ignore"internally regardless of your config. This is required for clean block layout. Other Prettier options (printWidth, tabWidth, etc.) are honoured.
What will fail (you need a real Smarty parser for these)
Because the plugin sees Smarty tags as opaque, anything that uses Smarty to emit partial HTML breaks Prettier's HTML parser. Common patterns that won't format:
<{if $rank == 1}>
<li class="number one">
<{else}>
<li class="number">
<{/if}>
...content...
</li>Each branch opens part of an <li>; the placeholder substitution produces unbalanced HTML and Prettier rejects it. Similarly:
<{if $logged}><body class="user"><{else}><body class="guest"><{/if}>Conditional opening of <body>, <head>, <script>, etc. all run into the same issue. Embedded PHP heredocs (<<<EOD) also break the HTML parser.
When the plugin can't format a file it throws Prettier's HTML error pointing at the offending tag. Add such files to your .prettierignore until a real Smarty parser is implemented.
Measured rate on 6rooms/live_frontend (1667 .tpl files): 63% format cleanly, 37% require .prettierignore. The failures cluster on a handful of legacy templates that use the partial-HTML pattern above.
Why placeholder approach instead of a real parser
Writing a real Smarty parser + printer is 1–2 weeks of work. The placeholder approach gets 80% of the practical value at a fraction of the cost. A future version may swap in a real parser if there's demand.
License
MIT
