fte-js-template
v3.0.0-canary.fa90532
Published
fte.js templates: syntax highlight + language server
Maintainers
Readme
fte-js-template (VS Code extension)
Language support for fte.js templates: syntax highlighting, IntelliSense (LSP), and a language-aware formatter for HTML/JS/TS/Markdown and code-generation templates.
Features
- Languages:
template-html(.nhtml),template-js(.njs),template-typescript(.nts),template-markdown(.nmd) + inline templates in JS/TS via tagged templatefte - Embedded JS blocks:
#{ ... },<# ... #>with trim modifiers, directives<#@ ... #>, and EJS-style tags<% %>,<%= %>,<%- %>,<%# %>(supports-%>/_%>trims) - Template comments:
<* ... *> - Bracket/auto-close pairs for common template delimiters
For AI agents: see
agents.mdfor a concise guide on how to author fte.js templates programmatically.
Install
- From VS Code Marketplace (after publish)
- Or manually build and install a
.vsix:npm i -g @vscode/vscevsce package- In VS Code: Extensions view → … → Install from VSIX
File associations & inline usage
- Create files with extensions:
.nhtml,.njs,.nts,.nmd - Inline in JS/TS:
const html = fte`<div>
<# if (cond) { #>
#{ value }
<# } #>
</div>`Examples
Basic Template Structure
<!-- page.nhtml -->
<#@ context 'data' #>
<!DOCTYPE html>
<html>
<head>
<title>#{data.title}</title>
</head>
<body>
<# block 'content' : #>
<p>Default content</p>
<# end #>
</body>
</html>Template Inheritance
<!-- base.nhtml -->
<#@ context 'data' #>
<!DOCTYPE html>
<html>
<body>
<# block 'header' : #>
<h1>Default Header</h1>
<# end #>
<# block 'content' : #>
<p>Default content</p>
<# end #>
</body>
</html><!-- child.nhtml -->
<#@ extend "base.nhtml" #>
<#@ context 'data' #>
<# block 'header' : #>
<h1>#{data.title}</h1>
<# end #>
<# block 'content' : #>
<#- for (const item of data.items) { #>
<div class="item">#{item.name}</div>
<#- } #>
<# end #>Trim Markers and Code Generation
<!-- api.nts -->
<#@ context 'schema' #>
<#- for (const model of schema.models) { -#>
export interface #{model.name} {
<#- for (const field of model.fields) { -#>
#{field.name}: #{field.type};
<#- } -#>
}
<#- } -#>Partials and Components
<!-- button.njs -->
<#@ context 'props' #>
<button class="btn #{props.variant || 'primary'}"
#{props.disabled ? 'disabled' : ''}>
#{props.text}
</button><!-- Usage -->
<#@ requireAs("./button.njs", "btn") #>
<div>
#{partial(context, 'btn', { text: 'Click me', variant: 'success' })}
</div>LSP capabilities
- Completions for directives,
content/partial, snippets forblock/slotwith autoend - Hover, diagnostics (parse/structure/directives), go-to-definition/references for blocks
- Formatting:
- Strict separation of concerns: template instructions and template text are formatted separately.
- Template text uses Prettier with host parser (HTML/Markdown/JS/TS) and never changes semantic output; if formatting would inject/remove whitespace, it is skipped.
- Template instructions keep delimiters intact; inner code/expressions are formatted by JS/TS rules.
- On-type: auto insert
<# end #>matching trim markers; code actions: close open blocks, remove unmatched end.
Commands
- Scaffolds: Insert Block, Insert Slot, Insert chunkStart/chunkEnd
- Partials: Create Partial and Insert Call
- Generators: Generate .nhtml Page, Generate .nts Class
- Preview: Preview Chunks (static), Preview Chunks (Live)
Configuration
ftejs.parserPath(string, optional): absolute path to localfte.js-parserwhen developing locally. If empty, the server attempts to resolve the npm packagefte.js-parserautomatically. The extension depends onfte.js-parserand installs it by default.ftejs.format.textFormatter(boolean): enable formatting of non-template text regions (default true).ftejs.format.keepBlankLines(number): max consecutive blank lines to keep in output; use -1 to disable limiting.ftejs.format.codeFormatter(boolean): enable indentation and inner formatting inside template instructions.
Formatting model
- Template instruction segments (
<# ... #>,#{...},!{...},block/slot/end):- Delimiters preserved; only inner content is formatted (JS/TS/EJS rules) where applicable.
- Trim markers
<#-and-#>are respected; on-type and code actions keep them in sync.
- Template text segments (final output):
- Prettier with host parser inferred from file extension:
.nhtml→html.nmd→markdown.nts→typescript.njs(default) →babel
- Guardrails: if formatting would change number of lines or inject trailing spaces, original text is kept.
- Prettier with host parser inferred from file extension:
Development
- Press F5 to launch VS Code Extension Host.
- Edit grammars under
syntaxes/andlanguage-configuration.json. - Quick reload: Cmd/Ctrl+R in the Extension Host window.
- Workspaces: this repo uses npm workspaces for
client/andserver/. Build both withnpm run compile. - Parser: the extension bundles
fte.js-parser(resolved from npm). For local development of parser, setftejs.parserPathto your local build.
Debugging
- Client (extension): F5 → Extension Host. Тестируйте команды/подсветку в новом окне.
- Server (LSP): сервер стартует с
--inspect=6009. Подключитесь Attach to Node Process (порт 6009) для отладки. - Логи LSP: Output → fte.js Language Server.
- Тесты:
npm test(Jest smoke‑tests вserver/).
Documentation for users and agents
- Runtime usage and API:
USAGE.md(synced from the main fte2 project). Update withnpm run docs:sync-usage(setFTE2_USAGEif needed). - AI authoring guide:
agents.md.
Publishing
- Package VSIX:
npm run compilenpx vsce package --no-yarn→.vsixв корне
- Publish to VS Code Marketplace:
- Получите
VSCE_PATи выполнитеvsce login npm run publish:vsce
- Получите
- Publish to Open VSX:
npm run publish:openvsx(требуетсяOVSX_TOKEN)
CI
- GitHub Actions workflow
.github/workflows/ci.ymlбилдит проект и собирает VSIX на каждый push/PR вmain.
Release
- Bump
versioninpackage.json. - Update
CHANGELOG.md. - Create a Git tag, CI will package and publish.
Injections into other languages
- This repo uses GitHub Actions to package and publish on tag push (e.g.
v1.2.3). - Required secrets:
VSCE_PAT: VS Code Marketplace Personal Access Token (Azure DevOps). See VS Code docs.- Optional:
OVSX_TOKENfor Open VSX publishing.
The extension injects template delimiters into Python/Swift/Ruby/Go/PHP files to highlight #{}, <# #>, EJS tags and comments inside strings or code where applicable.
Troubleshooting
Syntax Highlighting Issues
- Problem: Template delimiters not highlighted in
.njs/.nhtmlfiles - Solution: Check file extension is correct and VS Code recognized the language. Command Palette → "Change Language Mode" → select appropriate template language.
LSP Features Not Working
- Problem: No completion, hover, or formatting in template files
- Solution:
- Check VS Code output: View → Output → select "fte.js Language Server"
- Ensure language server started correctly
- Try restarting: Command Palette → "Developer: Reload Window"
Formatting Issues
- Problem: Template not formatting correctly or breaking content
- Solution:
- Check
ftejs.format.textFormattersetting (disable if problematic) - Verify Prettier configuration is valid for your file type
- Use trim markers
<#--#>to control whitespace output - Disable code formatting with
ftejs.format.codeFormatter: falseif needed
- Check
Block/Slot Navigation
- Problem: "Go to Definition" not working for
content('blockName') - Solution:
- Ensure block name exactly matches (case-sensitive)
- Check for typos in block declarations:
<# block 'name' : #> - For inherited blocks, verify parent template path in
<#@ extend "..." #>
Template Inheritance
- Problem: Child template not finding parent blocks
- Solution:
- Verify relative path in
<#@ extend "path/to/parent.nhtml" #>is correct - Check parent template exists and has proper block declarations
- Ensure both parent and child have correct file extensions
- Verify relative path in
Performance Issues
- Problem: Editor slow with large template files
- Solution:
- Disable trim visualizer: Command Palette → "fte.js: Toggle Trim Visualizer"
- Consider splitting large templates into smaller partials
- Use
ftejs.format.keepBlankLinesto limit blank line processing
Command Not Found
- Problem: Template scaffolding commands not available
- Solution:
- Ensure extension is activated (should auto-activate on template files)
- Check Command Palette shows commands starting with "fte.js:"
- Try reloading window: Command Palette → "Developer: Reload Window"
Parser Errors
- Problem: Red squiggles on valid template syntax
- Solution:
- Check for unmatched delimiters: every
<#should have#> - Verify block/slot declarations have proper syntax:
<# block 'name' : #> - Ensure
<# end #>tags match opening blocks - Check directive syntax:
<#@ directiveName param #>
- Check for unmatched delimiters: every
Getting Help
- GitHub Issues for bug reports and feature requests
- Check
USAGE.mdfor detailed template syntax reference - See
agents.mdfor AI-assisted template authoring
License
MIT
