<ismodule> turns a template into a tag. The plugin reads every declaration from the index, so a custom tag completes with its attributes, opens its template on Cmd+Click and shows where it's used, like the built-in tags
Cmd+Click on the tag opens the module template, where the attributes arrive as pdict membersDeclaring a custom tag
An <ismodule> declaration maps a tag name to a template and lists the attributes the tag takes:
<ismodule template="product/loyaltyBadge"
name="loyaltybadge"
attribute="product"
attribute="size"
/>This declares <isloyaltybadge>. Its attributes reach product/loyaltyBadge.isml as pdict.product and pdict.size, in lower case. A template includes the modules file before it uses the tag:
<isinclude template="util/modules" />
<isloyaltybadge product="${product}" />A declaration can span several lines, and single-quoted or unquoted values count too. A declaration inside <iscomment> doesn't
Which declarations a template sees
This template
Its own <ismodule> declarations before the usage, the nearest first
Included templates
Declarations in the templates it includes before the usage, following includes up to 512 templates deep
Modules files
The declarations in the modules files of the linked cartridges, in cartridge order. These are visible in every template
Modules files are the templates named modules.isml or module.isml. Change the names in Settings › Languages & Frameworks › ISML › Modules files. When the field is empty, the plugin reads intellij-sfcc.isml.modules.files from .vscode/settings.json, so a team that shares the VS Code setting gets the same list. A file named modules.isml shows the icon in the Project view
Changes to a modules file, to a declaration or to the cartridge path reach open editors at once, without a restart
Completion and navigation
| Where | What you get |
|---|---|
After < | is plus each declared name, such as isloyaltybadge, with the module template as grey type text |
| Inside the tag | The declared attributes, typed isloyaltybadge, skipping the ones already written |
| On the tag name | Cmd+Click or Go to Declaration (Cmd+B, Ctrl+B) on the start or end tag opens the module template |
| On an attribute | Go to Declaration opens the attribute line of the <ismodule> |
| Go to Symbol | Custom tags are listed as isloyaltybadge, so Cmd+Alt+O (Ctrl+Alt+Shift+N) finds a declaration by its tag name |
Renaming the name value of a declaration renames every usage of the tag and keeps the is prefix. Inside the module template the attributes are pdict members with the types the @param lines give them, see Scripting in ISML
Usages
| Marker | Where | Shows | Click |
|---|---|---|---|
The name of an <ismodule> | <isloyaltybadge> is used in 3 templates | Usages of <isloyaltybadge> lists the templates | |
| 4 usages | Above each <ismodule> | How many times the tag is used | Lists the templates |
| A custom tag in a template | Open the template of <isloyaltybadge> | Opens the module template |
The marker on custom tag usages is off by default, turn it on in Settings › Editor › General › Gutter Icons. The usage count is part of the ISML group of Settings › Editor › Inlay Hints › Code vision. Find Usages on a template lists its custom tag declarations as Declared as custom tag and their usages as Custom tag usage
@param check
A module template documents its attributes with @param lines in its first <iscomment>, written like @pdict lines. The Custom tag @param does not match the ismodule attributes inspection compares them with the declaration and reports a weak warning on each side:
| Message | Where | Fixes |
|---|---|---|
<isloyaltybadge> does not declare attribute 'size' | The @param name | Add 'size' to the <ismodule> declaration, Remove '@param size' |
No @param for attribute 'size' of <isloyaltybadge> | The <iscomment> | Add '@param' for 'size', which writes @param {*} size |
Unknown custom tags
Unknown ISML custom tag reports a tag the template can't see:
| Message | Fixes |
|---|---|
Unknown custom tag <isloyaltybage>: no <ismodule> declares it | Change to <isloyaltybadge> for a close name, Declare <isloyaltybage> in a modules file, Declare <isloyaltybage> and create components/loyaltybage.isml |
<isloyaltybadge> is used before its <ismodule> declaration | None. Move the <ismodule> above the first use |
<isloyaltybadge> is declared in util/badges.isml, which this template does not include | Include 'util/badges' |
Custom tag declared only in an including template is off by default. It reports a tag declared only in a template that includes this one, with the message <isloyaltybadge> is declared only in product/productTile.isml, which includes this template, and offers Declare <isloyaltybadge> in this template
Extract Custom Tag
Select template text and choose Refactor › Extract › Custom Tag... (or Refactor This, Ctrl+T, Ctrl+Alt+Shift+T). The dialog asks for the tag name and the template, and where the declaration goes:
| Field | Default |
|---|---|
| Tag name | newtag. The template calls it as <isnewtag> |
| Template | components/newtag, following the tag name until you edit it. The path is relative to templates/<locale> of this cartridge, without .isml |
| Declare in | Modules file, the cartridge's modules file or a new util/modules.isml. This template declares the tag at the top of the current file |
The preview shows the call that replaces the selection, the declaration and the new template. The variables the selection reads become attributes, named in lower case in the order they're first used, and inside the new template they read pdict.<attribute>:
<isset name="title" value="${pdict.title}" scope="page" />
<isloop items="${pdict.products}" var="product" status="loopState">
<div class="tile ${loopState.first ? 'first' : ''}">
<span>${product.name}</span>
<span>${pdict.currencyCode} ${title}</span>
</div>
</isloop><isset name="title" value="${pdict.title}" scope="page" />
<isloop items="${pdict.products}" var="product" status="loopState">
<isproducttile loopstate="${loopState}" product="${product}" currencycode="${pdict.currencyCode}" title="${title}"/>
</isloop><div class="tile ${pdict.loopstate.first ? 'first' : ''}">
<span>${pdict.product.name}</span>
<span>${pdict.currencycode} ${pdict.title}</span>
</div><ismodule template="components/producttile" name="producttile" attribute="loopstate" attribute="product" attribute="currencycode" attribute="title"/>Page variables and loop variables become attributes. Request-scoped variables stay as they are, because the new template sees them anyway. Refactor › Extract › Include File... works the same way for a plain <isinclude>, and Refactor › Inline on an <isinclude> puts the included template back
Completion, links, usage counts, the @param and unknown tag checks and Extract Custom Tag need a license. Highlighting works without one. Renaming a declaration doesn't rename the declarations of the same tag in other cartridges