Silverstripe Language Support
VSCode extension providing intelligent Silverstripe template (.ss) language support with PHPActor integration. Judging by the number of emojis, you've probably guessed it - this is a vibe-coded project. It's an experiment to integrate PHPActor, annotations & caching into a VSCode plugin.
Features
- ✅ Syntax Highlighting: Rich syntax highlighting for
.ss template files, including embedded JS and CSS
- ✅ Emmet Support: Full Emmet abbreviation expansion inside
.ss files
- ✅ Go to Definition: Navigate from
<% include MyTemplate %> to the template file
- ✅ Control-Tag Keyword Completion: Suggests
if, loop, with, include, end_if, etc. right after typing <%
- ✅ Template Autocomplete: Suggests available templates when typing
<% include %>
- ✅ Variable Completion:
$Title, $Content, etc. — sourced from $db, $has_one, $has_many, @property docblocks, and PHPActor methods
- ✅
<%t ... %> Translation Keys: Completion for existing i18n translation keys
- ✅ Dot-chain Completion:
$Image.Fill(300,200). resolves the return type and offers its members
- ✅ Loop/With Scope Tracking: Completions reflect the correct class inside
<% loop %> and <% with %> blocks
- ✅
$Up / $Top Navigation: Scope traversal completions across nested loops
- ✅ PHPActor Integration: Queries
phpactor class:reflect for inherited and annotated methods
- ✅ Status Bar: Shows the mapped PHP class (FQN) for the active template file
- ✅ Diagnostics: Flags unclosed/mismatched block tags (
if/loop/with/cached/uncached), variables missing their $ prefix in <% if %>/<% else_if %> conditions, and unresolved <% include %> targets
For DDEV + Devcontainer Projects
This extension is designed to work within DDEV devcontainer environments.
Installation
Install from the Visual Studio Marketplace:
code --install-extension lerni.silverstripe-actor
Or search for "Silverstripe Language Support" in the VS Code Extensions view.
Add to a Devcontainer
Add the extension ID to .devcontainer/devcontainer.json so it's installed automatically:
{
"customizations": {
"vscode": {
"extensions": [
"lerni.silverstripe-actor"
// ... other extensions
]
}
}
}
Then rebuild the devcontainer (Cmd/Ctrl + Shift + P → "Dev Containers: Rebuild Container").
Building from source is only needed if you want to contribute to the extension itself — see CONTRIBUTING.md.
Development
Initial Setup
cd ss-vscode-actor
npm install
Build Commands
Compile Once
npm run compile
Compiles TypeScript to JavaScript in the dist/ folder.
Watch Mode (auto-compile on save)
npm run watch
Automatically recompiles when you save TypeScript files. Keep this running during development.
Debug/Test the Extension
- Open the
ss-vscode-actor folder in VSCode
- Press
F5 to launch Extension Development Host (runs the "Run Extension" launch config)
- Open a Silverstripe project in the new window
- Test with
.ss files
The preLaunchTask will automatically compile before debugging.
Package for Distribution
npx vsce package
Creates a .vsix matching the version in package.json (e.g. silverstripe-actor-0.1.1.vsix)
Install Packaged Extension
In VS Code:
- Press
Cmd/Ctrl + Shift + P
- Type "Extensions: Install from VSIX"
- Select the generated
.vsix file
- Reload VS Code when prompted
Or via command line:
code --install-extension silverstripe-actor-0.1.1.vsix
See CONTRIBUTING.md for how releases to the Marketplace are published.
Architecture
How it works
The extension combines three strategies for completions:
- Direct PHP source parsing — reads
$db, $has_one, $has_many, $many_many, $belongs_many_many arrays and @property/@method docblock annotations directly from the PHP file.
- PHPActor CLI — calls
phpactor class:reflect --format=json 'FQN' to enumerate inherited and annotated public methods. Results are cached per file with mtime invalidation.
- Composer and Silverstripe module discovery — parses Composer metadata and mirrors Silverstripe's manifest rules (
_config/, _config.php, and _manifest_exclude) to discover module template directories.
For template includes, the extension uses this Silverstripe-style manifest discovery to find templates in vendor packages and local modules, in addition to app and theme templates.
Template-to-class mapping follows Silverstripe conventions:
templates/App/Elements/ElementHero.ss → App\Elements\ElementHero
templates/Layout/Page.ss → Page (strips Layout/ sub-type)
templates/App/Includes/Header.ss → no class (includes are excluded)
ElementPage_produkt.ss → ElementPage (strips _suffix variants)
Project Structure
ss-vscode-actor/
├── src/
│ ├── extension.ts # Entry point, registers all providers
│ └── providers/
│ ├── templateDefinitionProvider.ts # Go-to-definition for <% include %> and vite assets
│ ├── templateCompletionProvider.ts # Autocomplete for template paths
│ ├── templateKeywordCompletionProvider.ts # Keyword completion right after <%
│ ├── templateDiagnosticsProvider.ts # Unclosed blocks, missing $, unresolved includes
│ ├── templateClassMapper.ts # Maps .ss file → PHP class FQN
│ ├── phpClassInspector.ts # Reads PHP source + queries PHPActor
│ ├── variableCompletionProvider.ts # $Variable and dot-chain completions
│ ├── translationCompletionProvider.ts # <%t ... %> translation key completion
│ ├── translationKeyProvider.ts # Loads/caches available translation keys
│ └── moduleDiscovery.ts # Finds vendor/local modules with templates/
├── syntaxes/
│ ├── silverstripe.tmLanguage.json # Main grammar
│ └── silverstripe-injection.tmLanguage.json
├── dist/ # Compiled output (gitignored)
├── package.json # Extension manifest
├── tsconfig.json # TypeScript config
└── .vscode/
├── launch.json # Debug config
└── tasks.json # Build tasks
Known limitations / still to do
- PSR-4 cache is not invalidated when
composer install/update runs (requires reload)
- Signature help for methods not yet implemented
- The missing-
$-prefix diagnostic is a regex heuristic, not a real parser — it can misfire on unusual conditions (e.g. helper calls with bare-word arguments)
Customizing Syntax Highlighting
The extension provides rich syntax highlighting for Silverstripe templates using TextMate scopes. You can customize the colors to match your preferred theme.
Inspecting Scopes
- Open any
.ss file
- Press
Cmd/Ctrl + Shift + P → "Developer: Inspect Editor Tokens and Scopes"
- Click on any Silverstripe syntax element to see its scope
Example Customizations
Add to your VSCode settings.json (Preferences → Settings → {} icon):
"editor.tokenColorCustomizations": {
"textMateRules": [
{
// <% %> brackets
"scope": "punctuation.definition.silverstripe",
"settings": {
"foreground": "#30afae"
}
},
{
// Keywords: if, loop, with, include, etc.
"scope": "keyword.silverstripe",
"settings": {
"foreground": "#559ad1"
}
},
{
// Control structure names: end_if, end_loop
"scope": "entity.name.type.silverstripe",
"settings": {
"foreground": "#C695C6",
"fontStyle": "italic"
}
},
{
// Variables: $Title, $Content
"scope": "entity.name.silverstripe variable.silverstripe",
"settings": {
"foreground": "#f6ac81"
}
},
{
// Method calls: .Fill(), .URL
"scope": "entity.name.function.silverstripe",
"settings": {
"foreground": "#dcc665"
}
},
{
// Comments: <%-- comment --%>
"scope": "comment.block.silverstripe",
"settings": {
"foreground": "#9E9E9E",
"fontStyle": "italic"
}
}
]
}
Available Scopes
punctuation.definition.silverstripe - <% and %> delimiters
keyword.silverstripe - Control keywords (if, loop, include, etc.)
entity.name.type.silverstripe - Type names and end tags
entity.name.silverstripe - Variable names
entity.name.function.silverstripe - Method calls
comment.block.silverstripe - Template comments
string.quoted.double.silverstripe - Double-quoted strings
string.quoted.single.silverstripe - Single-quoted strings
punctuation.separator.silverstripe - Commas and separators
License
MIT