Tutorial

Using assets to save links to images, videos and pdfs

The commercetools™ platform offers the common type Asset that is embedded in other endpoints like the Products. To follow this tutorial, you should have a project set up, as described in Getting Started, and have a product onto which you want to add assets.

Adding an asset

Let’s add a simple asset, a PDF, to our product variant:

POST /{projectKey}/products/<product-id> with:

#!/bin/sh
curl -sH "Authorization: Bearer ACCESS_TOKEN" https://api.sphere.io/{project-key}/products/{product-id} -d @- << EOF
{
    "version": 1,
    "actions": [{
        "action": "addAsset",
        "variantId": 1,
        "asset": {
            "sources": [
                {
                    "uri": "http://example.org/content/product-manual.pdf",
                    "contentType": "application/pdf"
                }
            ],
            "name": { "en" : "Product Manual" },
            "description": { "en" : "The manual for my product." },
            "tags": ["manual", "pdf"]
        }
    }]
}
EOF
{
  "version": 1,
  "actions": [{
    "action": "addAsset",
    "variantId": 1,
    "asset": {
      "sources": [
        {
          "uri": "http://example.org/content/product-manual.pdf",
          "contentType": "application/pdf"
        }
      ],
      "name": { "en" : "Product Manual" },
      "description": { "en" : "The manual for my product." },
      "tags": ["manual", "pdf"]
    }
  }]
}
 final AssetSource assetSource = AssetSourceBuilder.ofUri("http://example.org/content/product-manual.pdf")
         .contentType("application/pdf")
         .build();
 final AssetDraft assetDraft = AssetDraftBuilder.of(asList(assetSource), en("Product Manual"))
         .description(en("The manual for my product."))
         .tags(asSet("manual", "pdf"))
         .build();
 final AddAsset addAsset = AddAsset.ofVariantId(1, assetDraft);
 final ProductUpdateCommand productUpdateCommand = ProductUpdateCommand.of(product, addAsset);
 return client.execute(productUpdateCommand);
<?php
 $assetDraft = AssetDraft::of()
     ->setSources(
         AssetSourceCollection::of()
             ->add(
                 AssetSource::of()
                     ->setUri('http://example.org/content/product-manual.pdf')
                     ->setContentType('application/pdf')
             )
     )
     ->setName(LocalizedString::ofLangAndText('en', 'Product Manual'))
     ->setDescription(LocalizedString::ofLangAndText('en', 'The manual for my product.'))
     ->setTags(['manual', 'pdf']);

 $request = ProductUpdateRequest::ofIdAndVersion($product->getId(), $product->getVersion());
 $request->addAction(
     ProductAddAssetAction::ofVariantIdAndAsset(
         $product->getMasterData()->getCurrent()->getAllVariants()->current()->getId(),
         $assetDraft
     )
 );
 $response = $request->executeWithClient($client);
 $product = $request->mapFromResponse($response);

We’ve set a name and a description. We’ve also added tags and set the optional contentType on the source. Both can be used by your frontend to decide how to display the asset, or search for a specific one in the assets array. For example, if there is a Manual-Section on your PDP, you can search for all assets that have the tag “manual”, and based on the contentType decide whether to show the content in a PDF viewer or a video player.

Using tags

Here are a two examples for the use of tags. You can use them whenever you want to help your frontend to display the assets.

Using tags for languages

You may add a tag for the language of the asset. For example, a video may be localized into different languages. With the help of a tag, the frontend can pick the right asset to display.

{
  "assets": [
    {
      "tags": ["video", "en"],
      [...]
    }, {
      "tags": ["video", "de"],
      [...]
    }, {
      "tags": ["video", "fr"],
      [...]
    }
  ]
}

Using tags for images in different aspect ratios

Depending on the device or view, you may want to present the content in a different aspect ratio. E.g. on a desktop, the landscape version of an image is shown, but on a mobile device the portrait version is preferred.

{
  "assets": [
    {
      "tags": ["image", "primary", "landscape"],
      [...]
    }, {
      "tags": ["image", "primary", "portrait"],
      [...]
    },
    [...]
  ]
}

In this example, the primary image exists in two versions - landscape and portrait.

Using tags for 360 degree images

For 360 degree images, you will have multiple assets (e.g. you may shoot an image at every 10 degrees). With the tags, your frontend can figure out which of the assets make up the 360 degree image, and in which order.

{
  "assets": [
    {
      "tags": ["image"],
      [...]
    }, {
      "tags": ["360-image", "deg=0"],
      [...]
    }, {
      "tags": ["360-image", "deg=10"],
      [...]
    }, {
      "tags": ["360-image", "deg=20"],
      [...]
    },
    [...]
  ]
}

In this example, the first image is a regular one. The following ones belong to the 360 degree image, and indicate with a tag at which angle they’ve been shot.

Using Asset Sources

An AssetSource is a representation of an Asset in a specific format, e.g. a video in a certain encoding, or an image in a certain resolution. To pick the right source, you can optionally supply a key or the dimensions of the asset.

Using Asset Sources for offering an image in different resolutions

In this example, the image is available in three resolutions: One is a thumb to be displayed on a POP, one is a regular resolution to be displayed on a PDP, and one is a high-res version to be used when the customer zooms into the image.

{
  "assetId": "<id>",
  "name": { "en" : "My Product Image" },
  "sources": [
    {
      "uri": "http://example.org/product-full.jpg",
      "dimensions": {"w": 600, "h": 400},
      "key": "full"
    },
    {
      "uri": "http://example.org/product-thumb.jpg",
      "dimensions": {"w": 90, "h": 60},
      "key": "thumb"
    },
    {
      "uri": "http://example.org/product-zoom.jpg",
      "dimensions": {"w": 3000, "h": 2000},
      "key": "zoom"
    }
  ]
}
 final AssetSource sourceProductFull = AssetSourceBuilder.ofUri("http://example.org/product-full.jpg")
         .dimensions(AssetDimensions.ofWidthAndHeight(600, 400))
         .key("full")
         .build();
 final AssetSource sourceProductThumb = AssetSourceBuilder.ofUri("http://example.org/product-thumb.jpg")
         .dimensions(AssetDimensions.ofWidthAndHeight(90, 60))
         .key("thumb")
         .build();
 final AssetSource sourceProductZoom = AssetSourceBuilder.ofUri("http://example.org/product-zoom.jpg")
         .dimensions(AssetDimensions.ofWidthAndHeight(3000, 2000))
         .key("zoom")
         .build();
 final AssetDraft assetDraft = AssetDraftBuilder.of(asList(sourceProductFull, sourceProductThumb, sourceProductZoom), en("My Product Image"))
         .build();
<?php
 AssetSourceCollection::of()
             ->add(
                 AssetSource::of()
                     ->setUri('http://example.org/product-full.jpg')
                     ->setDimensions(
                         AssetDimension::of()->setW(600)->setH(400)
                     )
                     ->setKey('full')
             )
             ->add(
                 AssetSource::of()
                     ->setUri('http://example.org/product-thumb.jpg')
                     ->setDimensions(
                         AssetDimension::of()->setW(90)->setH(60)
                     )
                     ->setKey('thumb')
             )
             ->add(
                 AssetSource::of()
                     ->setUri('http://example.org/product-zoom.jpg')
                     ->setDimensions(
                         AssetDimension::of()->setW(3000)->setH(2000)
                     )
                     ->setKey('zoom')
             )

In this example, both the key and the dimensions are set. The frontend may use the key to find the thumbnail by finding the source for which the key is "thumb". Alternatively, one could save many resolutions, and the frontend could figure out which image is best used (e.g. a thumbnail on a retina-display would use a different resolution than on a regular display).

You can also use the dimensions field to generate the HTML srcset property:

<img src="http://example.org/product-full.jpg"
  srcset="http://example.org/product-thumb.jpg 90w, http://example.org/product-full.jpg 600w, http://example.org/product-zoom.jpg 3000w">

Using Asset Sources for offering a video in different encodings

In this example, the video is encoded for in MP4 (for Flash), WebM (for HTML5) and HLS (for mobile apps). A thumbnail is also available.

{
  "assetId": "<id>",
  "name": { "en" : "My Product Video" },
  "sources": [
    {
      "uri": "http://example.org/product-video.mp4",
      "key": "flash",
      "contentType": "video/mp4"
    },
    {
      "uri": "http://example.org/product-video.webm",
      "key": "html5",
      "contentType": "video/webm"
    },
    {
      "uri": "http://example.org/product-video.m3u8",
      "key": "mobile",
      "contentType": "application/x-mpegURL"
    },
    {
      "uri": "http://example.org/product-video-thumb.jpg",
      "key": "thumb",
      "contentType": "application/jpeg"
    }
  ]
}

The flash player or a mobile app could look for its file by the key. In HTML5, the video element supports multiple sources and the browser will pick the most suitable source:

<video controls poster="http://example.org/product-video-thumb.jpg" >
  <source src="http://example.org/product-video.mp4" type="video/mp4">
  <source src="http://example.org/product-video.webm" type="video/webm">
  <source src="http://example.org/product-video.m3u8" type="application/x-mpegURL">
</video>

Conclusion

You’ve seen how to create a simple asset like a PDF, how a frontend can select the right asset out of multiple ones based on tags, and how asset sources can be used to offer different image resolutions or video encodings.

comments powered by Disqus