Object Display
A creator or a builder who owns a Publisher
object can use the sui::display
module to define display properties for their objects. To get a Publisher object check out the Publisher page.
Display<T>
is an object that specifies a set of named templates for the type T
(for example, for a type 0x2::capy::Capy
the display would be Display<0x2::capy::Capy>
). All objects of the type T
will be processed in the Sui Full Node RPC through the matching Display
definition and will have processed result attached when an object is queried.
Description
Sui Object Display is a template engine which allows for on-chain display configuration for type to be handled off-chain by the ecosystem. It has the ability to use an object's data for substitution into a template string.
There's no limitation to what fields can be set, all object properties can be accessed via the {property}
syntax and inserted as a part of the template string (see examples for the illustration).
Example
For the following Hero module, the Display would vary based on the "name", "id" and "image_url" properties of the type "Hero". The template defined in the init function can be represented as:
{
"name": "{name}",
"link": "https://sui-heroes.io/hero/{id}",
"image_url": "ipfs://{img_url}",
"description": "A true Hero of the Sui ecosystem!",
"project_url": "https://sui-heroes.io",
"creator": "Unknown Sui Fan"
}
/// Example of an unlimited "Sui Hero" collection - anyone is free to
/// mint their Hero. Shows how to initialize the `Publisher` and how
/// to use it to get the `Display<Hero>` object - a way to describe a
/// type for the ecosystem.
module examples::my_hero {
use std::string::String;
// The creator bundle: these two packages often go together.
use sui::package;
use sui::display;
/// The Hero - an outstanding collection of digital art.
public struct Hero has key, store {
id: UID,
name: String,
img_url: String,
}
/// One-Time-Witness for the module.
public struct MY_HERO has drop {}
/// In the module initializer we claim the `Publisher` object
/// to then create a `Display`. The `Display` is initialized with
/// a set of fields (but can be modified later) and published via
/// the `update_version` call.
///
/// Keys and values are set in the initializer but could also be
/// set after publishing if a `Publisher` object was created.
fun init(otw: MY_HERO, ctx: &mut TxContext) {
let keys = vector[
b"name".to_string(),
b"link".to_string(),
b"image_url".to_string(),
b"description".to_string(),
b"project_url".to_string(),
b"creator".to_string(),
];
let values = vector[
// For `name` we can use the `Hero.name` property
b"{name}".to_string(),
// For `link` we can build a URL using an `id` property
b"https://sui-heroes.io/hero/{id}".to_string(),
// For `image_url` we use an IPFS template + `img_url` property.
b"ipfs://{img_url}".to_string(),
// Description is static for all `Hero` objects.
b"A true Hero of the Sui ecosystem!".to_string(),
// Project URL is usually static
b"https://sui-heroes.io".to_string(),
// Creator field can be any
b"Unknown Sui Fan".to_string()
];
// Claim the `Publisher` for the package!
let publisher = package::claim(otw, ctx);
// Get a new `Display` object for the `Hero` type.
let mut display = display::new_with_fields<Hero>(
&publisher, keys, values, ctx
);
// Commit first version of `Display` to apply changes.
display.update_version();
transfer::public_transfer(publisher, ctx.sender());
transfer::public_transfer(display, ctx.sender());
}
/// Anyone can mint their `Hero`!
public fun mint(name: String, img_url: String, ctx: &mut TxContext): Hero {
let id = object::new(ctx);
Hero { id, name, img_url }
}
}
Methods description
Display is created via the display::new<T>
call, which can be performed either in a custom function (or a module initializer) or as a part of a programmable transaction.
module sui::display {
/// Get a new Display object for the `T`.
/// Publisher must be the publisher of the T, `from_package`
/// check is performed.
public fun new<T>(pub: &Publisher): Display<T> { /* ... */ }
}
Once acquired, the Display can be modified:
module sui::display {
/// Sets multiple fields at once
public fun add_multiple(
self: &mut Display,
keys: vector<String>,
values: vector<String
) { /* ... */ }
/// Edit a single field
public fun edit(self: &mut Display, key: String, value: String) { /* ... */ }
/// Remove a key from Display
public fun remove(self: &mut Display, key: String ) { /* ... */ }
}
To apply changes and set the Display for the T, one last call is required: update_version
publishes version by emitting an event which Full Node listens to and uses to get a template for the type.
module sui::display {
/// Update the version of Display and emit an event
public fun update_version(self: &mut Display) { /* ... */ }
}