Uh oh! We couldn’t find any match.

Please try other search keywords.

Bixby Developer Center

Guides

Dialog Macros

Dialog Macros

Dialog can often contain complex logic that you may want to factor out. You can use dialog macros to avoid having to duplicate dialog logic.

Take, for example, this common pattern within a capsule:

if (exists(concept)) {
template ("#{concept} and #{value(string2)}")
} else {
template ("#{value(string2)}")
}

Often, this logic can be even more complicated. If you have to repeat it across hundreds of dialog files, it would be tedious, especially if design changes call for rendering that string differently.

With a dialog macro, you can define that pattern using the template-macro-def key in this way:

template-macro-def (id1) {
content {
template (ID1 text)
}
}

Here is another example:

template-macro-def (id2) {
params {
param (x) {
type (viv.testNamedDialog.TestConcept)
min (Required)
max (One)
}
param (t) {
type (Text)
}
}
content {
if (exists(t)) {
template ("#{t} : #{value(x)}")
} else {
template ("#{value(x)}")
}
}
}

You can invoke this dialog macro by calling the template-macro with the ID you specified in your template-macro-def:

dialog (Result) {
match: viv.testNamedDialog.TestConcept (this)
template-macro (id2) {
param (x) {
expression (this)
}
param (t) {
literal ("some text")
}
}
}
Note

You cannot have a macro with the same ID if the macro is defined in the same resource bucket. For example, if you have a macro with the ID "this-test-macro" in the bixby-mobile-en-US target, you cannot have another different macro with the same name in that target.

However, if the macro's target is in a higher level resource bucket, the more specific target will override the more general target. For example, say you have a macro in bixby-mobile-en and another macro in bixby-mobile-en-US, both with the ID "this-test-macro". The macro in the bixby-mobile-en-US target will render for the bixby-mobile-en-US target, but the bixby-mobile-en macro will render for the bixby-mobile-en-GB target.

Macros with the same ID but in different targets (for example, bixby-mobile-ko-KR and bixby-mobile-en-US) are allowed and are encouraged when localizing.

If later you need to change this complex logic, you only need to change it in the macro definition once.

You can use template macros anywhere you can use a template, including layouts:

<layout mode="Details">
<match>
viv.testNamedDialog.TestConcept (this)
</match>
<content>
<template-macro id="id2"><x>{{this}}</x><t>some text</t></template-macro>
</content>
</layout>

Note that you can also use macros without any parameters, and you can declare more than one in a single dialog file:

template-macro-def (HelloWorld) {
content {
template ("Hello World!")
}
}

template-macro-def (WelcomeMessage) {
content {
template ("Welcome to the wonderful world of Bixby!")
}
}

Not only is this feature useful for composing complicated dialog, but it also useful for localization. When a capsule is multi-locale, you can factor out strings into macros in separate files, which can then be translated by translation services. You can then place the translated versions in the appropriate resources locale folder. If you do so, ensure that the resulting composed strings work properly in the locale you are targeting.

Here is an example for a recipe capsule in which you declare three dialog macros:

template-macro-def (Bookmarks) {
params {
param( number) {
type (viv.recipe.TotalTries)
max (One) min (Required)
}
}
content: templat e("#{value(number)} bookmarks")
}
template-macro-def (CaloriesPerServing) {
params {
param (calories) {
type (viv.nutrition.Calories)
max (One) min (Required)
}
}
content: template ("#{integer(calories)} Cal/serving")
}
template-macro-def (CookingTime) {
params {
param (number) {
type (viv.recipe.TotalTime)
max (One) min (Required)
}
}
content: template ("Ready in #{value(number)}")
}

Each dialog macro includes related parameters, which consist of a parameter name param, associated type, and cardinality rules (min and max).

There is also corresponding content, which is where you include the text of the dialog.

And this is how you can invoke dialog macros in the recipe capsule within layout, which uses dialog macros within the subtitle to show how many people have looked at a recipe, cooking time, and calorie count:

<layout-macro id="summary-item">
<type>recipe</type>
<image>{{#try}}{{ thumbnail.url }}{{/try}}</image>
<title>{{this.name}}</title>
<subtitle>
{{#if exists(totalTries) || exists(totalTime) || (exists(nutritionInfo) && exists(nutritionInfo.calories))}}
<div class="info">
{{#if exists(totalTries)}}<div><template-macro id="Bookmarks"><number>{{totalTries}}</number></template-macro></div>{{/if}}
{{#if exists(totalTime)}}<div><template-macro id="CookingTime"><number>{{totalTime}}</number></template-macro></div>{{/if}}
{{#if exists(nutritionInfo) && exists(nutritionInfo.calories)}}<div><template-macro id="CaloriesPerServing"><calories>{{nutritionInfo.calories}}</calories></template-macro></div>{{/if}}
</div>
{{/if}}
</subtitle>
<action></action>
</layout-macro>

You must qualify macros that you import, but not those that are local to your capsule. Put simply, you must follow the same name-spacing rules that apply to model references.

Take, for example, a capsule called viv.capsule1 that defines template macro template1. If you want to import template1 into another capsule called viv.capsule2, you must fully qualify it as shown here:

template-macro(viv.capsule1:template1)

However, if you want to use that same macro within viv.capsule1 itself, you can use the unqualified notation:

template-macro(template1)

You can also use an alias to qualify template macros. For example, if viv.capsule2 imports viv.capsule1 as aliasedcapsule, you can then invoke a macro within it using the alias:

template-macro(aliasedcapsule:template1)