HTML hooks

Plugster reads its inputs from the DOM via a small, fixed set of data-* attributes. This page is the reference for each one: what it does, where it goes, and what the framework does with it at init() and plug() time. Most of these have already appeared in earlier pages — this is the consolidated quick lookup.

data-controller-name #

Marks an HTML element as a Plugster view and binds it to a controller class of the same name. The attribute value is the PascalCase class name, matched exactly.

        
            <div data-controller-name="ExchangeRatesPlugster">
                <!-- this region is owned by ExchangeRatesPlugster -->
            </div>
        
    

The framework scans the document for these attributes once, when the first Plugster of the page calls Plugster.plug(). Any element type works — <div>, <form>, even <body>. Multiple views can share the same class name only if you also provide an explicit controllerName as the second constructor argument; otherwise the class-to-view mapping is one-to-one.

data-outlet-id #

Declares an element as an outlet of its surrounding view. The attribute value is the outlet's identifier, used by the controller as this._.<identifier>. Outlet identifiers are camelCase and unique within their owning view.

        
            <div data-controller-name="SignInPlugster">
                <input data-outlet-id="emailInput" type="email">
                <button data-outlet-id="submitButton">Sign in</button>
            </div>
        
    

Outlets that sit inside a nested view belong to that nested view's controller, not to the outer one. The boundary is strict — an outer controller cannot reach into an inner view's outlets through this._. See Core concepts → The view for the nesting rule in detail.

data-child-templates #

Marks an outlet as list-enabled. The attribute value is a JSON array of one or more URLs pointing to static HTML files that the framework will load and cache. Each URL is a row template; the controller picks which one to use per item via the first argument to buildListItem.

        
            <div data-outlet-id="ratesList"
                 data-child-templates='["rate-row-template.html"]'>
            </div>
        
    

The framework fetches each template URL once and caches the response in Plugster.childTemplateHtmlCache for the lifetime of the page; concurrent requests for the same URL share a single in-flight jqXHR via Plugster.childTemplateRequestCache. Multiple Plugsters declaring the same template URL pay the network cost once.

Child templates are static HTML — they are not rendered by the server template engine, so server helpers like _() or render_snippet() are not available inside them. They use data-child-outlet-id instead of data-outlet-id for their inner outlets; List outlets covers the full pattern.

data-on-{publisher}-{event} #

Declares an HTML-level subscription: this view's controller wants to listen for a named event coming from another Plugster. The attribute value is the name of the handler method on the subscribing class.

The naming rule for the attribute itself is mechanical:

  • Publisher name: the publisher Plugster's class name, lowercased entirely.
  • Event name: the published event name, lowercased entirely.
  • Separator: single hyphens between on, publisher and event.
        
            <div data-controller-name="DataLoaderPlugster"
                 data-on-workspaceplugster-bucketpresenterready="setup"
                 data-on-themetogglerplugster-themechanged="handleThemeChanged">
                ...
            </div>
        
    

In this example, DataLoaderPlugster listens to two publishers — WorkspacePlugster's bucketPresenterReady event (mapped to its own setup method) and ThemeTogglerPlugster's themeChanged event (mapped to handleThemeChanged).

The framework wires these subscriptions at Plugster.plug() time. The handler method MUST exist on the subscriber class — if it does not, the framework throws. Subscriptions are bidirectional in the registration sense (both publisher and subscriber must be plugged in for events to flow), but the wiring is one-way: publisher dispatches, subscriber receives.

For Plugsters that do not exist in the page at load time — typically because they are instantiated dynamically from inside another controller — use the explicit listenTo API instead. See Events.

data-lang #

Carries the active language code onto the view element, so the controller can pick it up at runtime. The attribute is typically set by the server template that renders the page:

        
            <div data-controller-name="SignInPlugster"
                 data-lang="{{ lang_code }}">
                ...
            </div>
        
    

Inside the controller, read it through the implicit root outlet:

        
            afterInit() {
                this.lang = this._.root.data('lang');
                this._.titleLabel.text(this.translateTo(this.lang, 'Welcome'));
            }
        
    

The framework itself does nothing with data-lang — it is a convention, not a feature. The reason it has a dedicated entry on this page is that the localization helpers (setLocales / translateTo, covered in Localization) expect this.lang to be set, and reading it from data-lang is the standard way to do that.

Reserved attributes inside child templates #

Static HTML files used as child templates use a parallel set of attributes — covered fully in List outlets:

  • data-child-outlet-id — outlet declared inside a child template.
  • data-key — per-item key, written by the framework when an item is built via buildListItem.

These are read-only from the page author's perspective; you declare them in the template but never set them from outside.

At a glance #

        
            data-controller-name="PascalCaseName"          → binds view to controller class
            data-outlet-id="camelCaseId"                   → declares an outlet
            data-child-templates='["url.html", ...]'       → makes the outlet list-enabled
            data-on-{pubname}-{eventname}="handler"        → HTML-declared subscription
            data-lang="{{ lang_code }}"                    → carries active language onto view

            (inside child template files only)
            data-child-outlet-id="camelCaseId"             → outlet inside a list item
            data-key                                       → per-item key, framework-managed
        
    
Content