💋

parslips

Template editor for Parsley templates, forked from WOOgnl

Version
v5.6.0
Updated
Sep 3

The dev server grows up

v5.6.0 Sep 2 on GitHub ↗

The dev server grows up

A summer of work on the built-in dev server (localhost:9485) — the HTTP surface that lets external tools and AI agents drive Eclipse. It now reports what actually happened, not just that a command was relayed: /status (what's running, per launch config), /console (a launch's output, kept after the process dies), /launch with preflight refusals and waitForPort, /restart, /openProject (a project plus its workspace dependencies), /problems, /breakpoints, and a self-describing index at /. /refreshProject returns a build report instead of ok when the build produced errors.

Ask the editor what a tag can do

/elementApi returns any element's resolved binding API as JSON — types, direction, required, defaults, cross-binding rules with their plain-English messages — the editor's hover, as data. Validation also gained a check for the $-on-a-plain-tag trap. Paired with runtime-side eval and problems endpoints in ng-objects and wonder-slim.

Trustworthy markers

Revalidate All Templates (a preference-page button and /revalidate) re-runs template validation over a project or the whole workspace, and Purge Stale Markers (/purgeMarkers) deletes orphaned markers left by validators that no longer exist. /problems labels every marker with its source. Along the way: the standalone JS/CSS editors and their ancient validation engines are gone (Eclipse owns those files; inline blocks in templates keep highlighting and completion), and the plugin's embedded libraries were brought current.

Watch your agent work, live

The dev server records every request it handles, and /watch turns that into a live, narrated feed (“Validated Main — clean”, “Launched MyApp — ready in 4.2s”) with a running tally. /activity serves the same record as JSON — an audit trail of what an agent actually did to your workspace.

Launches that can't stop the world

Eclipse's “Errors exist in required project(s). Proceed?” dialog can no longer strand an agent: /launch checks the app and every project it depends on, refuses with the broken projects and the fix, and launches with Eclipse's prompting switched off. For every other modal, /dialogs lists them and can press a button — and a launch that's waiting for the app returns at once if one appears.

From the changelog, August 29, 2026.

Every standard WebObjects element, richly described

v5.5.1 Jul 4 on GitHub ↗

Every standard WebObjects element, richly described

The template editor now ships a full .apiext description for every one of the standard WebObjects dynamic elements — all 39 of them, from WOString and WORepetition to WOForm, WOPopUpButton and the rest. Until now these built-in elements were described by the old, thin .api files, which knew a binding’s name but little else. The new descriptions are far richer, and they light up everywhere the editor already helps you.

For each element and each of its bindings you now get:

  • Real documentation — a written description of what the element does and what every binding is for, shown in the hover and the Element Reference.
  • Typed bindings with direction — each binding declares the Java type it accepts, and whether the element reads it (pull ↓), writes it back (push ↑), or both. So you can see at a glance that a checkbox’s checked reads any value by truthiness but pushes back a real Boolean.
  • Cross-binding rules — the “exactly one of these” and “if you bind this, you must bind that” constraints are now typed and checked, so the editor flags a mis-bound element as you write it.
  • Sensible defaults and deprecations — default values are shown where they exist, and genuinely obsolete elements (WOApplet, WOVBScript, WOQuickTime…) are marked deprecated and struck through in the Element Reference, so it’s obvious what not to reach for.

The descriptions are grounded in the published WebObjects element reference and the elements’ documented binding behavior, so what the editor tells you matches what the framework actually does. This is also the largest body of real .apiext yet — a solid, practical proving ground for the format as it grows toward a full tag library.

From the changelog, July 4, 2026.

Jump to any part of a keypath

v5.5.0 Jul 1 on GitHub ↗

Jump to any part of a keypath

Editing a template and want to jump to the Java behind a binding? Put your cursor in a keypath and hit F3 — the same “Open Declaration” shortcut you already use in Java code. It now works in the template editor too, on element tags, binding names, and binding values, so you can navigate without reaching for the mouse.

The nice part is how it treats a keypath. Eclipse normally sees $activeUser.address.city as one thing and, on Cmd+click, jumps to the very end — the city method. But often you want a segment in the middle. Now both F3 and Cmd+click open the segment your cursor is actually on:

  • On activeUser → opens activeUser
  • On address → opens address
  • On city → opens city

And when you hold Cmd and hover, the underline now highlights just the segment you’re pointing at — so what lights up is exactly what a click will open.

From the changelog, July 1, 2026.

One source of truth for what a tag means

v5.4.4 Jun 26 on GitHub ↗

One source of truth for what a tag means

Phew. I've wanted this for so long: Eclipse/the template editor and the WO runtime now share a single, declarative tag registry — so the editor and the application will interpret tags through a single mechanism.

Until now, the template editor carried its own built-in "tag shortcut" registry for tags like and really had no idea whether it matched what WO would actually render at runtime. It usually did — but “usually” is where subtle, maddening mismatches live. The classic example: WebObjects frameworks *substitute* elements at runtime. Bind a and ERExtensions quietly swaps in its own ERXWOString when the page renders. That substitution lived only in framework code that ran at startup — completely invisible to the editor.

Now element tags are declared by frameworks and applications. A framework or application drops a simple parsley-tag-aliases.properties file on its classpath:

A tag shortcut and an element replacement are pretty much the same thing — an alias from one name to another — so they share one mechanism. Resolution is recursive: strWOStringERXWOString, following the chain to whatever your app really renders. The Parsley runtime reads this file to build pages; the editor reads the very same files from your project’s classpath.

What you get, across the whole editor:

  • Autocomplete offers the tags your project actually defines.

  • Hover and binding completion resolve the full chain. Hovering `` shows str → WOString → ERXWOString — the truth of what renders.

  • The Element Reference marks overridden elements in orange and a dedicated “Overridden by” column, so you can see at a glance which built-in elements are replaced in your project, and with what.

It is opt-in and per-project: a project that contains no alias files behaves exactly as before. And it’s the first step and foundation for something larger — a proper tag library, where a framework fully describes its own tags to the tooling.

From the changelog, June 26, 2026.

Added element reference view

v5.4.3 Jun 24 on GitHub ↗

Added element reference view

A new Element Reference view (Window → Show View → Parsley) lists every element available to your project — searchable, sortable, with each one’s full API documentation a click away. The Origin column shows which framework an element comes from, and a double-click opens it.

From the template editor, Cmd+Opt+9 reveals the element under your cursor in the view — without moving focus, so your editing flow isn’t interrupted.

Hide wod editor if wod is empty

When a component’s .wod file is empty — as it always is for inline-binding templates — the WOD editor no longer takes up half the editor. It collapses to a thin bar, giving the template the full height; click the bar any time you want the WOD editor back.

From the changelog, June 24, 2026.

Detailed element documentation on hover

v5.4.2 Jun 23 on GitHub ↗

Detailed element documentation on hover

Hovering a `` tag now shows detailed information about an element’s API — some documentation, its bindings, which bindings are required, and so on.

  • A real description. Elements and individual bindings can carry Markdown documentation (a role summary up top, a note per binding), rendered inline — so the hover explains what a binding is for, not just its name.
  • Binding direction and type. Each binding shows whether the element reads it (a grey ↓ “pull”), writes it back (an orange ↑ “push”), or both (a red ↔ two-way), along with the accepted Java type. When a binding reads one type and writes another — like a checkbox that reads any value by truthiness but writes back a Boolean — the two are shown separately.
  • Status badges. Container elements and binding-passthrough elements are flagged with a badge in the header, and a small marker shows whether the documentation came from a project’s own definition or a richer bundled one.
  • Read it comfortably. The popup opens at a generous size, scrolls when an element has a lot of bindings, and stays open when you move into it so you can select and copy text.

This richer documentation is driven by an experimental .apiext format. The editor uses it when a parsable definition is available (today for a small set of built-in elements and for AjaxSlim’s components) and falls back to the classic definition otherwise — so existing projects keep working unchanged while the format settles.

From the changelog, June 23, 2026.

A full dev loop for AI-assisted work on a running app

v5.4.1 Jun 8 on GitHub ↗

A full dev loop for AI-assisted work on a running app

Building on /refreshProject, the dev server gained a handful of endpoints that together let an external tool — most usefully an AI coding assistant working in your repo — drive the whole edit→build→run loop on a live WebObjects/Parsley application, without you relaying anything by hand. Everything is localhost-only, with no setup.

  • Validate a template without rendering it/validate?component=NAME runs Parsley’s template validator on a component and returns the problems (line, position, message) as JSON. Templates are long, error-prone strings whose mistakes usually don’t surface until the page renders; now they can be caught up front. (Eclipse’s own validation is editor-driven, so a plain refresh never checked templates — this fills that gap.)
  • Read the running app’s console over HTTP — the app (via wonder-slim’s ERExtensions, in development) serves its recent log at …/App.woa/log, with contains= and tail= filters. No more copy-pasting the Eclipse console to share what the app printed.
  • Discover what’s running — apps announce themselves at startup, so /apps lists each running app, its port, and which of its dependencies have source open in your workspace (with paths). A tool can find an app by name — no guessing ports — and knows which libraries it can actually read and edit versus jar-only ones.
  • Start and stop apps/launch starts a launch configuration (listing them, and deliberately preferring a local/dev config so it never accidentally fires Production), and /stop shuts one down (cleanly, or with force=true for a JVM that a big hot-reload has wedged).

Why this matters. Each piece removes a manual hand-off. The result is that an assistant can launch your app, edit source and templates, validate them, refresh the running instance, read back the console to confirm, and restart when a change needs it — closing the loop end to end. There’s a short guide for setting this up with an agent in the repo’s AGENTS.md.

From the changelog, June 5, 2026.

Dev server can now refresh & rebuild a whole project on demand

v5.4.0 Jun 1 on GitHub ↗

Dev server can now refresh & rebuild a whole project on demand

The dev server has a new endpoint — /refreshProject?project=NAME — that refreshes a project from disk and rebuilds it, all in one call. It’s the programmatic equivalent of closing and reopening the project in Eclipse: it picks up file changes made outside the Eclipse editor and recompiles them. Add &build=false to refresh without building, or omit project to refresh every open project.

Why this matters: Eclipse only notices edits it made itself. When something else changes your source on disk — a code generator, a script, or an AI coding assistant working in the repo — Eclipse doesn’t know, so your running app keeps using the old compiled classes and the change seems to do nothing. You’d normally fix that by manually closing and reopening the project. Now a single HTTP call does it.

Why this is useful. It turns out to be the missing piece for working with an AI assistant on a live WebObjects/Parsley app. The assistant edits your source, calls /refreshProject, and the running app hot-swaps the change in immediately — so it can load a page and actually see the result of what it just wrote. No build/redeploy/restart cycle in between. The loop goes from “edit, then a human babysits a rebuild” to “edit, refresh, observe” — in seconds. The same applies to any external tool that edits your project and wants the running app to reflect it.

From the changelog, June 1, 2026.

Components now open to the HTML template by default

v5.3.3 May 29 on GitHub ↗

Components now open to the HTML template by default

When you open a component, the editor now lands on the HTML template instead of the WOD editor. Opening a component is almost always about working on the template — and for inline-syntax components the WOD sidecar is usually empty — so HTML-first is the sensible default.

If you specifically open a .wod file (or .woo / .api), the editor still reveals that part — only the “no specific request” case (opening the component itself, via Open Component, double-clicking the .wo folder, or jumping in from an exception page) defaults to HTML.

Dev server now enabled by default

The dev server — which lets your running application drive Eclipse, most usefully so that clicking a stack-trace line on an exception page in the browser opens that source line in Eclipse — is now on by default and needs no setup. The feature has always existed (it came over from WOLips); it’s just far more accessible now.

What changed:

  • No password. The server listens only on localhost, which is its security boundary — anything that could reach it is already running on your machine. It previously required a shared password between the IDE and the app; that friction is gone, on both sides.
  • On by default. Nothing to enable. Wonder’s ERXExceptionPage (and ng-objects’ equivalent) already generate the links, so for most projects this simply starts working.
  • Fails quietly on a port conflict. If port 9485 is already taken — most commonly because a second Eclipse window already owns it — the server just doesn’t start in that instance and notes it calmly in the log. The first window owns the port, which is the one your app talks to anyway.
  • Configurable. Enable/disable and port live under Preferences → Parsley → Dev Server; changes apply immediately without restarting Eclipse.

From the changelog, May 29, 2026.

Fix: `$application` and `$session` keypaths now resolve against user subclasses in NG projects

v5.3.2 May 14 on GitHub ↗

Fix: $application and $session keypaths now resolve against user subclasses in NG projects

In ng-objects projects, keypaths like $application.formatters or $session.currentUser were producing false “There is no key” validation errors, even though the runtime resolves them correctly. The validator was checking the bare NGApplication / NGSession class instead of walking down to the user’s Application / Session subclass where the actual keys live.

The mechanism for “when this is the declared type, look at subclasses in the current project instead” has been in place for years for the classic WebObjects equivalents (WOApplication, WOSession, WODirectAction) — the ng-objects classes were just missing from the list. Now added: NGApplication, NGSession, NGDirectAction.

Detection is purely name-based and works regardless of which framework the project targets — the validator picks up whichever class appears in the supertype chain.

From the changelog, May 14, 2026.

Fix: problem markers now appear on pulled-up source folders

v5.3.1 May 6 on GitHub ↗

Fix: problem markers now appear on pulled-up source folders

Files with errors inside src/main/components, src/main/woresources, or any pulled-up ng-style resource folder were propagating their error markers up to the project, but the pulled-up folders themselves at the project root showed no marker — even though the error was clearly inside them. So you’d see the red error decorator on the project, then nothing on any of its visible children, with no easy way to drill down to where the error actually was.

The cause was an icon-overlay slot collision: the small “wo”/“ng” badge that marks pulled-up source folders was using the same image overlay slot as Eclipse’s standard problem-marker decorator. The badge was applied first, blocking the marker. The badge has been moved to the top-right corner of the folder icon, leaving the bottom-left slot free for the problem marker.

Fix: false validation errors on methods whose names start with an uppercase letter

Action methods and other unprefixed methods whose names start with an uppercase letter — for example HttpServerUpdateClicked() or HTTPServerUpdateClicked() — were producing false “There is no key ‘X’” errors when bound from a template, even though valueForKey("HttpServerUpdateClicked") finds the method correctly at runtime.

The editor was lowercasing the first character of every method name to derive the binding key, which produced names like hTTPServerUpdateClicked or httpServerUpdateClicked. The runtime never finds methods by those keys (literal-method lookup is case-sensitive), so the editor's “Did you mean...?” suggestion was actually pointing at a key that wouldn't have worked.

The fix follows the standard Cocoa / WebObjects KVC convention:

  • For methods without a get/set/is prefix, the binding key is the method name preserved exactly. HttpServerUpdateClicked() → key HttpServerUpdateClicked; title() → key title.
  • For methods with a bean-style prefix, the prefix is stripped and the first letter is lowercased — unless the first two characters are both uppercase, which preserves acronyms. getURL()URL; getTitle()title; getHttpServer()httpServer.

The same fix applies to the rename refactoring — renaming HttpServerUpdateClicked() on a Java class now correctly updates HttpServerUpdateClicked in bound templates.

From the changelog, May 6, 2026.

Dark mode readability and new color preference pages

v5.3.0 May 4 on GitHub ↗

Dark mode readability and new color preference pages

Two improvements aimed at users running Eclipse in a dark theme:

Plain text now follows Eclipse’s editor theme. The HTML, embedded JavaScript, and embedded CSS scanners used to set the default text color to a hardcoded value (pure black by default), which made plain content — HTML body text, CSS selectors and braces, JavaScript identifiers — render black on a dark background and effectively disappear. These scanners now defer to Eclipse’s standard editor foreground color, which is theme-aware. In dark mode the same text shows up in light gray; in light mode it stays dark, exactly as before.

As part of this change, the “Foreground Color” field in Preferences → Parsley has been removed — it was the setting that previously hardcoded the black default and is no longer needed. To customize the editor’s default text color, use the standard Eclipse setting at Preferences → General → Editors → Text Editors → Colors and Fonts.

New “Embedded CSS” and “Embedded JavaScript” preference pages under Preferences → Parsley, exposing color settings that previously had no UI:

  • Embedded CSS: Comment, Property, Value
  • Embedded JavaScript: Comment, String, Keyword

If you’ve been irritated by the dark-blue CSS property color on a dark editor background, this is where to fix it.

This is a first readability pass. The remaining tag/attribute/binding colors and the `` background tint are still tuned for light themes — theme-aware defaults for those are next.

From the changelog, May 4, 2026.

Updated project template versions

v5.2.2 May 1 on GitHub ↗

Updated project template versions

The New Project wizard now generates projects using the latest released dependency versions:

  • wonder-slim: 8.0.0 (released, replacing the previous 8.0.0.slim-SNAPSHOT; the group id is now is.rebbi.slim)
  • ng-objects: 0.1.1 (was 0.1.0)
  • vermilingua-maven-plugin: 1.1.4 (was 1.0.5)

Existing projects are unaffected — this only impacts new projects created via the wizard.

From the changelog, April 30, 2026.

Validate duplicate attributes

v5.2.1 Apr 12 on GitHub ↗

Validate duplicate attributes

Tags with duplicate attributes — e.g. `` — now produce a validation error. The first occurrence wins (per the HTML spec) and the duplicate is highlighted in the editor and Problems view. Detection is case-insensitive, so class and Class are correctly flagged as duplicates.

From the changelog, April 12, 2026.

Fix: extraneous close tags are now reported

v5.2.0 Apr 10 on GitHub ↗

Fix: extraneous close tags are now reported

Templates with stray close tags — e.g. `` with more closes than opens — now correctly report each dangling close tag as a validation error (

start tag is not found.”) in the Problems view and inline in the editor.

This was a long-standing bug inherited from the original WOLips parser: the FuzzyXML close-tag handler had a defensive early return whenever the open-tag stack was empty, which silently swallowed the exact case the validation was meant to catch. An empty stack on a close tag is precisely an extraneous close tag.

Fix: close-tag completion after self-closing tag with parentheses in attribute

Fixed a bug where close-tag completion (Ctrl+Space) would suggest the wrong tag after a self-closing tag whose attribute value started with a delimiter character — typically a parenthesis, like ``. The scanner’s quoted-value tracking lost state when the first character inside the quote was a delimiter, which in turn broke the self-closing pop and left the tag sitting on the unclosed-tag stack. Subsequent close-tag completions would incorrectly suggest closing the stale tag.

Also affects values starting with other delimiter characters (;, +, etc.), not just (.

From the changelog, April 10, 2026.

Find References includes template references

v5.1.8 Mar 9 on GitHub ↗

Find References includes template references

Eclipse’s Find References (Ctrl+Shift+G) now surfaces template references in the standard Search view, right alongside Java callers.

Binding keys: Search for references to a method like name() in your component class and the Search view shows hits from inline HTML bindings (value="$name") and WOD binding values (value = name;). KVC getter/setter prefixes are handled automatically — searching for getTitle() finds references to key title.

Element types: Search for references to a component or element class and the Search view shows every template that uses it — `` tags in HTML and : MyComponent { declarations in WOD files. The scan covers the element’s own project and all projects that depend on it, so library components show usages from consuming applications.

Double-click any match to jump straight to the reference in the template file.

From the changelog, March 9, 2026.

WOLips coexistence preference

v5.1.7 Mar 8 on GitHub ↗

WOLips coexistence preference

New setting in Preferences → Parsley → WOLips Coexistence: “Let Parsley handle all elements by default.”

By default, when WOLips is installed alongside Parsley, Parsley only activates for projects that have project.base set in their build.properties. This new preference flips that default — when enabled, Parsley handles editors, decorators, and keyboard shortcuts for all recognized WebObjects and ng-objects projects, even those without project.base.

Useful if you need WOLips installed for non-template-editing features but want Parsley to handle all template editing.

From the changelog, March 8, 2026.

Usages tab — “Who uses this component?”

v5.1.6 Mar 8 on GitHub ↗

Usages tab — “Who uses this component?”

A new Usages tab in the component editor answers the question every developer eventually asks: “which other components use this one?”

Click the tab and it scans all open workspace projects for templates that reference the current component as an element — both inline `` tags in HTML and : ComponentName { declarations in WOD files. Results appear in a two-column table showing the using component’s name and its project. Double-click any row to jump straight to that component’s template.

The scan runs in the background on first tab activation, so it never blocks your editing. Hit Refresh to re-scan after making changes. Works for both standalone and bundle templates, and catches cross-project references.

Extract Wrapper

A new refactoring that is the inverse of Extract Component. Select the content that should stay in the current component, press Cmd+2, X (or Edit > Refactor > Extract Wrapper…), and enter a name. Everything around the selection — the surrounding page chrome — is extracted into a new wrapper component with `` where the selection was. The original template becomes just the selection wrapped in the new component tag.

Typical use case: extracting a page layout (navigation, header, footer) into a reusable wrapper, leaving only the page-specific content in the original component.

Extract Component and Extract Wrapper: standalone template support

Both Extract Component (Cmd+2, E) and Extract Wrapper (Cmd+2, X) now correctly handle ng-objects projects — creating standalone .html template files instead of .wo bundles, and placing them in the correct resource folder.

From the changelog, March 7, 2026.

Convert between template formats

v5.1.5 Mar 6 on GitHub ↗

Convert between template formats

Bundle → standalone: Right-click a .wo folder and select “Convert to Standalone Template” to convert it to a standalone template. The action replaces all tags with their inline equivalents () using the WOD definitions, moves the HTML file out of the .wo folder, and deletes it. Supports multi-selection and recursive conversion of entire folder trees.

Standalone → bundle: Right-click a standalone .html template and select “Convert to Bundle Template” to wrap it in a .wo folder with an empty .wod file. Also supports multi-selection.

The bundle-to-standalone conversion respects the “Spaces around equals” formatting preference and the project’s configured inline binding prefix/suffix. Missing WOD entries are left unchanged with a warning dialog.

Convert WOD to Inline (single tag)

Cmd+2, I converts a single tag to inline syntax. Place the cursor on the tag, invoke the action, and the tag is rewritten with the correct element type and bindings from the WOD file. The WOD declaration is removed automatically. The reverse of the existing Cmd+2, W (Convert Inline to WOD).

From the changelog, March 6, 2026.

Full WOLips coexistence

v5.1.4 Mar 5 on GitHub ↗

Full WOLips coexistence

Parsley now coexists cleanly with WOLips in the same Eclipse installation. Install both plugins and everything just works — no manual configuration needed. Parsley’s editors, menus, and actions use the 🌿 parsley icon, so you can always tell at a glance which plugin’s UI you’re looking at.

To activate Parsley for an existing WebObjects project, add project.base=wo to the project’s build.properties. Projects without this property continue to use WOLips.

Fix: unparseable CSS in style tags no longer crashes editor

Opening a component whose template contained a `` tag with CSS the parser couldn’t handle (e.g. @import("...")) would throw a NullPointerException and prevent the editor from loading. The CSS class-name completion processor now handles unparseable stylesheets gracefully.

From the changelog, March 5, 2026.