Bixby Developer Center

Guides
References

Layout Macros

Note

Both layout-macro and layout-macro-def will be deprecated in a future release. You should switch to using generic macro and macro-def files instead to create layout macros. For more information, see Reusing Content with Macros.

The same complex user interface patterns often are used in multiple places in your capsule. By turning these patterns into layout macros or macros you can easily reuse them.

Note

Be aware of which components you are adding to your layouts and layout macros, because different components are available under different views. If you call a layout or layout macro in a view and that layout specifies a component that the view does not support, Bixby Developer Studio will throw an error. Similarly, you should consider which layout macros are being called within a layout itself. The same layout macro invoked in one component might not be valid if used within a different component, as the list of supported child components could differ.

You can read the Designing with Bixby Views Design Guide and the Building Bixby Views (UI) Developers' Guide to check if your layout is using the correct components for that moment and that view.

Defining Layout Macros

Layout macros are defined with the macro-def key.

Here is an example of using a macro-def key:

macro-def (space-resort-details) {
params {
param (spaceResort) {
type (SpaceResort)
min (Required) max (One)
}
}
content {
section {
content {
image-carousel {
images (spaceResort.images)
}
title-area {
halign (Center)
slot1 {
text {
value ("#{value(spaceResort.name)}")
style (Title_L)
}
}
slot2 {
single-line {
text {
value ("#{value(spaceResort.planet)}#{value(spaceResort.gravity)}g")
style (Title_XS)
}
}
}
}
paragraph {
value ("#{value(spaceResort.description)}")
style (Detail_M)
}
partitioned {
content {
for-each (spaceResort.attributes) {
as (attribute) {
single-line {
text {
value ("#{value(attribute)}")
style (Detail_L)
}
}
}
}
}
}
}
}
}
}

This macro could be used within a larger layout or view file:

Result View - Space Resort Details

The params key starts a block that lets you specify parameters for the macro. These parameters are defined similarly to properties in structure concepts:

  • a type that matches either a primitive like Integer or Text, or a previously-defined concept, like SpaceResort
  • min to set optionality to Required or Optional
  • max to set cardinality to One or Many
Note

You cannot have a macro with the same ID if the macro is defined in the same resource folder. 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 folder, 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, especially when localizing or handling development for multiple devices.

Specifying Parameter Default Values

Your macro definition can include a default key in a param block to set a default value for that parameter. This sets a default value of false for the fromQuiz parameter in the example.movieAgent sample capsule:

    param (fromQuiz) {
type (core.Boolean)
min (Optional)
max (One)
default (false)
}

View master on GitHub

You can set default values for these types of values:

  • Text
  • Boolean
  • Integer
  • Decimal

Invoking Layout Macros

Use the macro key in the render block of your views to invoke macros. Use param blocks to pass values to the macro's parameters.

This example shows a result view that can be either a list of search results, in which case list-of is used to construct a list of space-resort-summary layouts for each resort, or a single space-resort-detail layout if only a single result has been returned.

result-view {
match: SpaceResort (result)

render {
if (size (result) > 1)) {
list-of (result) {
where-each (item) {
macro (space-resort-summary) {
param (spaceResort) {
expression(item)
}
}
}
}
} else-if (size (result) == 1) {
layout {
macro (space-resort-details) { // calling a more generic macro that defines a "section"
param (spaceResort) {
expression (result)
}
}
}
}
}
}

Here is what the layout would look like, which has the space-resort-details information displayed above:

Result view with one result

Note

Macros from capsules that you import but do not alias must include the full namespace:

macro (example.SpaceResort.space-resort-summary)

Target Model Parameters

min and max are required attributes for target-defined parameter types.

  • min: Optional or Required
  • max: One or Many

When adding parameters, you should start with less restrictive constraints such as Optional and Many so that your macro is usable in more places.

Ensure that you test if the parameter is populated when using it inside your macro template.

if (exists(targetParameter)) {
// ...
}

Layout Modes

Conditional blocks can test which, if any, layout mode is being used by using the special variable $layoutMode.

if ($layoutMode == 'Details') {
// ...
}

The conditions require one of these enums for testing:

  • Summary
  • Details
  • Confirmation
  • Input

Prompt mode can change between views, so if your macro is used across multiple layout modes, you might want to test against the $promptMode.

Why Use Macros

As mentioned previously, layout macros are useful in reusing content that can be placed in multiple places. They can aid in rendering content with complex logic. For example, in the shirt Sample Capsule walkthrough, the confirmation view varies only in the message, depending on if the order was first made or if it was updated. The use of a macro lets you reuse the majority of the layout, but with the differing messages depending on the match-pattern, which calls the appropriate confirmation view.

Macros are useful when handling various languages and locales. If you are creating a capsule that should work in different locales, you can tweak a view but still display the same components by using macros. For example, you might have a compound card that displays various flowers for order. The image card within that compound card might have the same information, no matter what region you are in: a picture of the arrangement being sent, the name of the arrangement, and a price. However, the text in the attribution-link might differ because where you punch users out to might depend on the local florists available in that region.

Additionally, macros are useful if you are developing across multiple devices. For example, when you are displaying a list of results, you might want to use image cards on devices with larger screens, but for a watch, you might want to use a thumbnail card to display content because you want to use smaller images. You can use macros here to repeat the title-area content.