What's new in Parsley Template Editor
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 — <wo:MyComponent> 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.
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.
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 <wo:ComponentName> 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.
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 <wo:content /> 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.
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.
Bundle → standalone: Right-click a .wo folder and select “Convert to Standalone Template” to convert it to a standalone template. The action replaces all <webobject name="X"> tags with their inline equivalents (<wo:Type binding="value">) 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.
Cmd+2, I converts a single <webobject name="X"> tag to inline <wo:Type> 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).
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.
Opening a component whose template contained a <style> 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.
Renaming a method or field in a component’s Java class via Refactor > Rename now automatically updates binding key references in the component’s own template files. WOD binding values (value = title;) and inline HTML bindings (value="$title") are included in the refactoring preview alongside the Java rename.
Key paths are handled correctly — renaming title() to heading() updates value = title.length; to value = heading.length;, changing only the first segment. KVC getter/setter prefixes are stripped automatically: renaming getTitle() to getHeading() renames key title → heading. String literals, caret references, and partial matches are conservatively excluded.
The editor now reports an error when a quote character appears inside an attribute name, catching the common typo of omitting = between an attribute name and its value — e.g. negate"true" instead of negate="true". The error message identifies the attribute and suggests the correct syntax.
The parser also recovers gracefully: the attribute name and value are correctly extracted despite the missing =, so downstream tools (binding validation, autocomplete, hover) continue to work on the recovered parse tree.
The editor now reports an error when a tag is missing its closing > — e.g. <wo:if condition="$showGraphs" followed by a newline. This common typo silently corrupts the document structure: the parser consumes the next line as part of the unclosed tag, making sibling elements disappear. The error marker now points directly at the malformed tag.
Double-clicking an attribute name after the first one in a tag (e.g. item or selection in a tag with multiple bindings) previously selected the preceding whitespace, the = sign, and surrounding spaces along with the name. The editor’s quoted-string selection was too eager — it found the nearest quotes on each side without checking whether they belonged to the same attribute value. Now it verifies the selection doesn’t span across attribute boundaries before claiming a match.
A forward slash in body text (e.g. <td>Price / amount</td>) was mistakenly treated as a self-closing tag marker, popping the current tag off the autocomplete stack. This caused close-tag completion (Ctrl+Space) to suggest the wrong tag. The scanner now only treats / as a self-closing marker when inside a tag context, leaving body text slashes harmless.
JavaScript operators like < inside <script> blocks were being parsed as HTML tags, corrupting the close-tag autocomplete stack. For example, if (a < b) caused the scanner to think a <b> tag was open. The scanner now skips over <script> and <style> content entirely, jumping straight to the matching closing tag.
HTML void elements like <br>, <img>, and <input> were pushed onto the unclosed-tag stack even though they can never have children. This caused close-tag completion to suggest closing the void element instead of its parent. The scanner now recognizes all 14 HTML void elements and never pushes them onto the stack, regardless of whether they use the explicit self-closing syntax (<br />) or not (<br>).
Tag shortcuts now work seamlessly in ng-objects projects. Write <wo:if>, <wo:repetition>, <wo:str> — the editor automatically resolves them to their ng-objects equivalents (NGConditional, NGRepetition, NGString). Binding validation, keypath checking, and error markers all work correctly against the NG class hierarchy.
Binding autocomplete is fully functional for all standard dynamic elements — type <wo:if, press Ctrl+Space, and get condition and negate offered as completions with required-binding markers. This works even though NG elements declare bindings via internal association maps rather than KVC-style accessors — the editor sources binding metadata from the global API definitions, supplementing Java reflection results.
Place the cursor on a <wo:ComponentName> tag and press F3 to jump straight to the Java class declaration — the standard Eclipse “Open Declaration” shortcut, now working in templates. Same navigation as Cmd+click, without leaving the keyboard.
Rename a binding in the .api editor and update all template references in one step. Check the “Refactor on rename” checkbox (top-right of the API editor), rename one or more bindings, save — a refactoring preview shows every .html and .wod file that uses the old binding name on that component. Confirm to apply all changes atomically, or cancel to keep only the .api change.
The scan covers the source project and all projects that depend on it (transitively), so components defined in framework projects have their references updated in consuming application projects. Multiple bindings renamed in the same session are processed in a single pass per file, ensuring correct results even when several bindings appear in the same tag.
Saving an .api file now immediately revalidates all open component editors. Mark a binding as required, save — and every open template that uses that component instantly shows (or clears) the corresponding validation markers. Previously, you had to re-save each component or restart Eclipse to see updated validation.
Cmd+Alt+5 now opens the .api file for the current element, even from a standalone Java editor. For components with templates, this opens the Component Editor with the API tab active. For WOElements without an associated component template, it opens the standalone API editor. If no .api file exists yet, one is created automatically. Previously, this shortcut only worked from within the Component Editor.
Fixed a bug where unchecking “Required” or “Will Set” on a binding in the API editor would fail silently or throw an error. The root cause was a double-removal in the DOM — the validation element was removed twice, once automatically when it became empty and once explicitly. Also fixed a stale-timestamp issue that could cause the editor to unnecessarily reparse the file after saving.
Fixed a long-standing bug (inherited from WOLips) where an apostrophe in body text — e.g. <p>what’s up</p> — would break tag autocompletion for the rest of the file. The tag-stack scanner mistakenly treated the apostrophe as the start of a quoted attribute value, swallowing all subsequent content (including < characters) so Ctrl+Space could never see a tag prefix.
Tag autocomplete now inserts self-closing tags (<wo:str />) for elements that don’t accept child content, and opening+closing tag pairs (<wo:form></wo:form>) for content components. Required bindings are pre-inserted with the cursor inside the quotes — e.g. completing wo:str inserts <wo:str value="" /> so you can start typing immediately. Both behaviors are driven by the element’s .api file.
Three optimizations that together eliminate the multi-second delay when opening components or triggering tag autocomplete in large projects. Resolved element types are now cached so deprecation checks don’t re-trigger JDT lookups; exact-match type lookups skip the expensive hierarchy scope entirely; and autocomplete tag info is cached per project so repeat invocations reuse pre-loaded attribute info instead of rebuilding it each time.
The formatting preferences (Preferences > Parsley > Template Formatting) now let you choose between tabs and spaces for indentation, and set the number of spaces per indent level (1–8, default 2). These settings existed in the formatter backend since the WOLips era but were never exposed in the UI.
Also fixed the formatter converting non-ASCII characters to HTML entities — accented letters, Icelandic characters, and other valid UTF-8 text (e.g. ó, ð) would be replaced with entity references like ó and ð. They are now preserved as-is.
Fixed empty HTML elements like <th></th> being collapsed to self-closing tags (<th />), which browsers treat as unclosed tags. Now only HTML void elements (<br>, <img>, etc.) and wo: tags are rendered as self-closing when empty.
The formatter now respects the original line structure of your template — if you wrote content on a single line (e.g. <a><wo:str .../> text</a>), it stays on one line. Multi-line content is properly indented. entities are also preserved instead of being silently replaced with regular spaces.
Blank lines between elements are now preserved exactly as written. Whether you separate </style> from <div> with one blank line or two, the formatter keeps them. This works at all nesting levels — between top-level blocks, inside nested structures, and around wo: control tags.
Spaces between inline tags are preserved — e.g. <strong>text</strong> <wo:str .../> keeps the space so rendered words don’t merge together.
HTML void elements (<br>, <hr>, <img>, etc.) are now rendered without a trailing slash — <br> instead of <br /> — matching standard HTML practice. Comment content and text entities (including single quotes in <script> blocks) are preserved exactly as written, with no unwanted escaping or whitespace normalization.
The New Component wizard now lets you choose between Standalone template (ng-objects style) and Bundle template (WebObjects style). The default is auto-detected from the project type — ng-objects projects default to standalone templates, WO projects to bundle templates.
Select HTML in the template, press Cmd+2, E (or Edit > Refactor > Extract Component…), enter a name — the selected HTML is extracted into a new component. The plugin creates the .wo folder with all files (.html, .wod, .woo, .java), replaces the selection with a <wo:NewComponentName/> tag, and opens the new component for editing.
The new component is placed alongside the current component and uses the same Java package and component superclass. The extracted HTML is automatically dedented — common leading whitespace is stripped so the new template starts at column 0. The selected HTML is placed as-is — bindings are wired up manually afterward.
Hovering over a <wo:ComponentName> tag now shows the component's API documentation — accepted bindings, required/settable markers, and defaults. Works for project components (via .api files) and built-in WO components (via WebObjectDefinitions.xml). When both a validation error and documentation are available, the error appears first with documentation below.
Renaming any WOElement/NGElement subclass via Refactor > Rename now automatically updates all references across the project. Inline binding tags (<wo:OldName> → <wo:NewName>, including close tags) and WOD element type declarations (Foo : OldName { } → Foo : NewName { }) are rewritten in every template that uses the renamed type.
This applies to all element subclasses — not just components, but also custom dynamic elements. Tag shortcuts (like <wo:if> for WOConditional) are not affected, since they use the shortcut name rather than the class name.
Renaming a WOComponent/NGComponent Java class via Refactor > Rename now also renames the .wo folder, all contained template files (.html, .wod, .woo), standalone .html templates, and .api files to match.
Works in both directions: a “Rename Component…” context menu action on .wo folders renames from the template side, delegating to JDT’s rename so both the Java class and template files are renamed together.
Miscapitalized tag shortcuts are now flagged as validation errors. Writing <wo:Repetition> when the shortcut is defined as repetition now produces an error with a "Did you mean 'repetition'?" suggestion. Uses the same error format as element type errors — no distinction between shortcuts and class names. Previously, the case-insensitive matching silently accepted any capitalization. Quick-fix support via Cmd+1 and the Problems view.
Mistype an element name after <wo: and the editor now suggests corrections — "The class for 'Str' is either missing... Did you mean 'str'?". Catches capitalization errors (Str → str) and typos (WOStirng → WOString). Uses the same quick-fix infrastructure as keypath errors: Cmd+1, Problems view, and hover help.
When a line has multiple errors (e.g. <wo:Str value="$application.nme" />), Cmd+1 shows proposals for both the element name and the keypath error.
Mistype a key in a binding value and the editor now suggests corrections — "There is no key 'nme' in MyComponent. Did you mean 'name'?". Suggestions are computed using Damerau–Levenshtein string distance, which catches transpositions (vlaue → value), insertions, deletions, and substitutions.
Press Cmd+1 anywhere on the line to apply the fix instantly — no need to position the cursor on the exact error. Quick-fixes are also available from the Problems view (right-click → Quick Fix). Hovering over a squiggly-underlined error now shows the message inline.
<p:raw> and <p:comment><p:raw> treats its content as literal text — no dynamic tag processing, useful for embedding example code containing <wo:> tags. <p:comment> is a template-level comment that is stripped entirely from output. Both block types are rendered with a distinct background tint and muted text, are skipped by validation, support linked rename (Cmd+2, R), and isolate their content so broken HTML inside can't affect the rest of the document.
/ in attribute valuesFixed a long-standing bug where auto-close tag completion (Ctrl+Space) would suggest the wrong tag when an attribute value contained / — e.g. href="/". The / was mistakenly interpreted as a self-closing tag marker, corrupting the tag stack. A second bug (operator precedence) caused the same issue with single-quoted values. Both are now fixed.
Create new ng-objects or WebObjects projects from scratch — complete Maven projects with a sample Main component, ready to run. The wizard generates all source files and imports the project via m2e.
A new "Maven" preference page under NG Component Editor settings. Detects whether your settings.xml has the WOCommunity repository configured and offers a one-click button to add it — no more hand-editing XML to get WebObjects dependencies resolving.
The WOCommunity Maven archetype catalog is now registered automatically, making WO project archetypes available in Eclipse's New Maven Project wizard.
Standalone templates (.html files not inside .wo folders) now have full editor support: autocomplete, keypath validation, and build-time validation — all on par with traditional .wo components. This is a key enabler for ng-objects, where single-file templates are the primary component format.
Fixed a long-standing intermittent bug inherited from WOLips where validation would report false errors — e.g. "exactly one of 'count' or 'list' must be bound" on a WORepetition that was correctly bound. The root cause was concurrent DOM access to the shared API model.
The plugin now works with both ng-objects and WebObjects projects in the same workspace. Per-project framework detection uses build.properties (project.base=ng or project.base=wo) with automatic classpath probing as a fallback.
Parsley Template Editor — extracted from the WOLips plugin suite (~18 plugins merged into one bundle), rebuilt as a standalone Eclipse plugin with unique identifiers for coexistence with WOLips.
WebObjects and ng-objects projects are marked with framework badges in the Package Explorer, making it easy to tell at a glance which framework each project uses.
WO and ng-objects specific source folders (src/main/components, src/main/woresources, src/main/webserver-resources) are pulled up to the project root alongside standard Java source folders, and marked with badges so they stand out.
A Package Explorer variant with component-aware behavior: bundle template folders are expandable (unlike WOLips), pulled-up source folders, and project/component decorators throughout.
Component files (.html, .wod, .woo, .api) automatically open in the Parsley editor — for any file inside a .wo folder, or for component files in ng-objects projects.