piano_templates 1.0.3 copy "piano_templates: ^1.0.3" to clipboard
piano_templates: ^1.0.3 copied to clipboard

Piano Templates SDK for Flutter.

Piano Templates SDK for Flutter #

Display Piano templates, forms, and recommendations returned by Piano Composer. Each type is shown in a WebView, either as a modal or inline.

Installation #

Add the dependency to your pubspec.yaml:

dependencies:
  piano_templates: ^1.0.3

Getting Started #

piano_templates builds on piano_common and piano_composer, so you need a Piano instance first:

import 'package:piano_common/piano_common.dart';
import 'package:piano_templates/piano_templates.dart';

final piano = await Piano.init(
  endpoint: PianoEndpoint.production,
  aid: '<AID>',
  language: 'en_US', // optional, defaults to 'en_US'
);

The language code you pass to Piano.init is forwarded to Piano as the lang URL parameter for every template and form shown by this package, so their content is localized accordingly.

Get a client via piano.templates():

final templates = piano.templates();

It creates three controllers, one for each kind of Composer show event:

Controller Type Handles event
templates.template() PianoShowTemplateController PianoComposerShowTemplate
templates.form() PianoShowFormController PianoComposerShowForm
templates.recommendations() PianoShowRecommendationsController PianoComposerShowRecommendations

The factory methods take no arguments. All per-show options are passed to show via a typed parameters object:

Future<R?> show(
  PianoComposerEvent<T> event,
  BuildContext context, [
  P? params,
]);

The params you pass are retained on controller.params, so callbacks (such as JS-bridge listeners or the form's signIn) keep working after show returns. A later show call that omits params reuses the last ones.

Templates #

Create a controller, then call show with the event and a BuildContext:

final controller = templates.template();

// When a PianoComposerShowTemplate event arrives:
await controller.show(event, context);

Listening to template events #

A template can send events over the JavaScript bridge (for example, when the user logs in or closes it). Pass a PianoTemplateListener via PianoShowTemplateParams to handle them:

final controller = templates.template();

await controller.show(
  event,
  context,
  PianoShowTemplateParams(
    listener: PianoTemplateListener(
      onClose: (data) => print('Closed'),
      onCloseAndRefresh: (data) => print('Closed, refresh the page'),
      onRegister: (data) => print('User registered'),
      onLogin: (data) => print('User logged in'),
      onLogout: (data) => print('User logged out'),
      onCustomEvent: (data) => print('Custom event: $data'),
      onTerminateSession: (session) {
        print('Terminate session: ${session.token}');
      },
    ),
  ),
);

onTerminateSession receives a PianoTerminateSession with token, sessionCount, and sessionLimit.

Reloading with a new token #

show returns a PianoShowTemplateResult you can use to reload the template with a new user token, without reloading the whole page:

final result = await controller.show(event, context);
result?.reloadWithToken('<user_token>');

Forms #

Show a Piano ID form. Pass a PianoShowFormParams with callbacks to react to its lifecycle:

final controller = templates.form();

await controller.show(
  event,
  context,
  PianoShowFormParams(
    accessToken: '<access_token>',
    onClose: () => print('Form closed'),
    signIn: (context) async {
      // Called when the form rejects the current token and needs a fresh one.
      // Return the new token, or null if the user cancelled.
      return await mySignIn(context);
    },
  ),
);

Recommendations #

Show a Cxense recommendations widget via PianoShowRecommendationsParams:

final controller = templates.recommendations();

await controller.show(
  event,
  context,
  PianoShowRecommendationsParams(
    renderTemplateUrl: 'auto', // optional, defaults to 'auto'
    userId: '<user_id>',       // optional
  ),
);

Display Modes #

show respects the display mode set on the event:

  • Modal — opens in a modal popup with an optional close button.
  • Inline — loads into a WebView you place in your own layout.

For inline mode, register a controller for the container selector before the event arrives, and use the returned WebViewController in your widget tree:

final controller = templates.template();

// Register the container selector ahead of time, so the WebViewController
// exists before the show event for it arrives.
late final _templateView = controller.inline('template');

// Use it in your layout.
Container(
  // ...
  child: WebViewWidget(controller: _templateView),
),

// Later, when the event arrives:
await controller.show(event, context);

The string passed to inline must exactly match the event's event.eventData.containerSelector — that's how show looks up which WebViewController to load the template into. If no controller was registered for that selector, show returns null and nothing is loaded.

Call inline once per container selector you expect to receive events for; each call returns (or creates) a distinct WebViewController, so a single controller instance can drive several inline placements at once:

final headerView = controller.inline('#header-template');
final sidebarView = controller.inline('#sidebar-template');

When the owning widget is disposed, release the inline controllers:

@override
void dispose() {
  controller.dispose();
  super.dispose();
}
0
likes
140
points
145
downloads

Documentation

API reference

Publisher

verified publisherpiano.io

Weekly Downloads

Piano Templates SDK for Flutter.

Homepage

License

Apache-2.0 (license)

Dependencies

flutter, meta, piano_common, piano_composer, url_launcher, webview_flutter

More

Packages that depend on piano_templates