Pack Object Model

Overview

The Pack is the main construct that API clients will deal with. It describes all the customer data required to create their printed product. The diagram below shows the basic relationships between the various different objects within the Pack object model:

Pack Data Model Diagram

Inspecting Pack data from the MOO Flash Canvas

As our new design canvas is using the API, we have developed a GreaseMonkey script to add a "Show API JSON" button to Canvas display page (/create/design.php). First, make sure you have GreaseMonkey (Firefox) or Tampermonkey (Chrome) installed, and then install the user script. You can then begin any product (e.g. Business Cards) and you can start inspecting the Pack data provided by clicking the "Show API JSON button"

The Pack instance

  • Each Pack instance has references to multiple Side instances, and multiple Card instances
  • A Pack has an ID and product code to describe the type of pack being designed
  • It contains a numCards property which defines the number of Card's required to be created in order for this Pack to be complete. This is based on the product information - i.e. a Business Card Pack requires 50, while a Postcard pack requires 20.

The Side instances

  • A Side instance is a unique design for one specified side of a physical card (e.g. "details" side, using template "businesscard_left_image_landscape", with 5 text lines)
  • There can be multiple Side instances for each specified side type (e.g. multiple "image" Side's for each image to be used on the Pack) - supporting MOO's printfinity technology. Note that the data model explicitly supports printfinity on all side types including the details sides of cards (which the MOO UI doesn't support at the time of writing).
  • The Side instance references the individual data elements as a list, tied to the template content elements by their linkId property values
  • A Side instance has both a type and a sideNum property, specified by the user. The reason for having the sideNum is to allow users to give Side instances their own internal unique ID so that they can easily be referenced within CardSide instances. This will be used by API clients who want to create an completely populated Pack (including Card's and CardSide's in one call.
  • If you don't provide your own fully populated cards array, then we will generate one for you. When doing so, it is assumed (and we ensure) that Sides have numerically ordered sideNums by sideType which we will sort per sideType before printing (i.e., "image" Side's sent to us in the order: sideNum 3, 2, 1 will be printed in the order: sideNum 1, 2, 3).

The Card instances

  • The Cards array is OPTIONAL within a Pack. If not provided, then an automatic evenly distributed Pack will be generated. If provided, it must be complete in order to validate.
  • A Card defines a unique printed card ordered within the pack
  • It contains references to N CardSide instances, which allow us to control which specific Side instance should be used on each side of the printed card.
  • Note that the data model explicitly allows for non-even distributions of different designs (e.g. you can have 40 cards with type "image" and sideNum "1", and the remaining 10 with type "image" and sidenum "2")

The CardSide instance

  • A CardSide simply is a link table to allow m-n mappings between Card instances and Side instances by physical side name.
  • Each Card will have exactly the right number of CardSide instances to populate all the physical sides of the card (e.g. 2 for a Business Card, Minicard, Postcard; 1 for a Sticker pack)

Pack Definition

The pack object is the container for the pack data model. A populated pack object can be passed to the moo.pack.createPack and moo.pack.updatePack methods and is returned from the moo.pack.getPack method. The Pack object has the following properties:

  • numCards - int - this contains the number of cards in the pack. This value and the size of the cards array (see below) must be the same.
  • productCode - string - one of 'businesscard', 'minicard', 'postcard', or 'sticker' depending on what product is being described.
  • productVersion - int - currently this must always be set to 1.
  • sides - Side[] - an array describing the type and content of each unique side within the pack. See the Sides Array documentation.
  • cards - Card[] - OPTIONAL - an array describing the distribution of sides to physical card surfaces in the pack. See the Cards Array documentation.
  • extras - Extra[] - an array of extra information required for Square Stickers in order to add to cart.
  • imageBasket - ImageBasket - an object containing information about all the images used in the Pack. This is only required for the MOO UI to be able to provide the ordered packs, or be able to drop-in a pack to the UI for completion by the customer on the MOO website.

Example empty Pack Object

"pack":{
    "numCards":50,
    "productCode":"businesscard",
    "productVersion":1,
    "sides":[
    ]
}

Sides

The sides array is a unordered list of Side objects. Each Side describes content of an abstract side for use on physical cards. The sides in array are abstract in as much as they are not attributed to a physical side of a card. The attribution of sides to card sides is described below in the cards array. Each side specifies the template to be used, along with all the Pack user data items to be merged with the Template definition. This is modelled as the user data providing a set of overrides on top of the template definition (unless the Template specifies constraints on what can be overridden within the user data).

Each Side object has the following properties:

  • type - string - the type of Side for use on the product (e.g. "image" or "details")
  • sideNum - int - a unique side number for the side type being described.
  • templateCode - string - the code of the template in effect for this side. See the Template Object Model documentation for more information about templates.
  • data - Datum[] - array of user data elements to appear on this side. Each item in the data array is linked back to the template by its linkId property. Each element must be of the correct type for the Template definition with the relevant linkId. If the template provides all the data required for a particular content item, and you don't wish to override this (e.g. leaving a text line blank), then you don't need to provide a data item for this content element. The possible types and format for the user data elements is covered in the Side Data Object Models

Example Side Array Element

"sides":[
    {
        "type": "image",
        "sideNum":1,
        "templateCode":"minicard_full_image_landscape",
        "data":[
        ]
    }
]

Cards

The cards array describes the distribution of sides to the printable surfaces of each card in the pack. The cardNum element represents a unique card in the pack. The elements in the cardSides array define which abstract Side object should be used on each printable face of the Card. The numbers of elements in the cardSides array must be consistent for the product type (e.g. 'image' and 'details' sideTypes for Minicards, Business Cards or Postcards with just 'image' for stickers).

Parameters

  • cardNum - int - Integer the number of the card in the pack. MUST satisfy 0 <= cardNum < pack.numCards (i.e. it's a 0-indexed array with pack.numCards elements)
  • cardSides - CardSide[] - array of CardSide objects, each of which links to a item in the Side array. Together, the sideType + sideNum properties must match a Side with the same type and sideNum properties.
    • sideType - string - The type of Side being rendered (and used to match the type of a Side from the sides array)
    • sideNum - int - The sideNum of the Side to be rendered here.

Example Card Array Element

"cards":[
    {
        "cardNum":0,
        "cardSides":[
            {
                "sideNum":1,
                "sideType":"image"
            },
            {
                "sideNum":1,
                "sideType":"details"
            }
        ]
    },
    {
        "cardNum":1,
        "cardSides":[
            {
                "sideNum":2,
                "sideType":"image"
            },
            {
                "sideNum":1,
                "sideType":"details"
            }
        ]
    }
],

The example above creates 2 cards - one with "image" side 1 and "details" side 1, and the second with "image" side 2, and "details" side 1 again.

Extras

The extras array is required only for Sticker products to specify extra information about the pack. The properties that each Extra object provides are:

  • key - string - the key for the Extra object
  • value - string - the value for the Extra object

For Stickers, there must be exactly one Extra item with a key of "pack_colour" and a value in "black", "blue", "green", "orange", "pink", "purple", "white", "yellow"

Example Extras Array Element

"extras": [
    {
        "key": "pack_colour",
        "value": "black"
    }
]

Image Basket Object

The Image Basket object holds information about every image used in the Pack user data elements on all Side objects. Given that often, imageData items have resourceUri properties such as filestore://image_original/someFileWeUploaded.jpeg , those URIs cannot be used on the MOO website to provide features such as preview. Instead, we need to have a way to generate browser accessible URLs over HTTP to represent these images in the UI. This is the purpose that the image basket fulfills.

The Image Basket holds an array of items each of which is an ImageBasketItem object.

The ImageBasketItem object has the following properties:

  • resourceUri - string - this is used to link up the resourceUri specified in a Side's user data with the image basket item so that the UI can then lookup the browser visible versions of the image for use in previews, crops and so on.
  • name - string - the name of the image
  • source - string - the source of the image
  • imageBox - null - RESERVED
  • removable - bool - RESERVED. Must be "true"
  • croppable - bool - RESERVED. Must be "true"
  • cacheId - string - this will be generated as part of the response to the moo.image.uploadImage and moo.image.importImage calls. Suffice to say, don't play with it :)
  • imageItems - ImageBasketItemImage[] - map of the browser visible images that can be used for previewing etc. The array MUST contain objects for the types: "thumbnail", "preview", and "print". Each ImageBasketItemImage has the following properties:
    • type - string - must be one of "thumbnail", "print", "preview"
    • resourceUri - string - must be an HTTP resource URI
    • width - int - the number of pixels wide that the image is. Failure to accurately supply this information may result in odd previews for customers
    • height - int - the number of pixels high that the image is. Failure to accurately supply this information may result in odd previews for customers
    • rotation - int - whether the print image has been rotated differently to the preview image. This is for the cases (such as Flickr images) where the high resolution version of an image can be in a different rotation from the preview. In order to accurately render the image as the customer designed it, we need to know if this is the case. Please contact MOO if you think you require this feature.

Example populated ImageBasket object:

"imageBasket":{
    "items":[
        {
            'shouldEnhance' : false,
            'copyrightOwner' : '',
            'cacheId' : 'partner_interface_uploader:7b83fe35-75ba-c0a802e8-4c754942-4de8.png',
            'type' : 'front',
            'resourceUri' : 'filestore://image_original/7b83fe35-75ba-c0a802e8-4c754942-4de8.png',
            'removable' : true,
            'croppable' : true,
            'imageBox' : {
            },
            'imageItems' : [
                '0' : {
                    'type' : 'print',
                    'resourceUri' : 'http://www.moo.com/is/o/7b83fe35-75ba-c0a802e8-4c754942-4de8.png',
                    'width' : 940,
                    'height' : 330,
                    'rotation' : 0
                },
                '1' : {
                    'type' : 'preview',
                    'resourceUri' : 'http://www.moo.com/is/r/1024/7b83fe35-75ba-c0a802e8-4c754942-4de8.png',
                    'width' : 1024,
                    'height' : 359,
                    'rotation' : 0
                },
                '2' : {
                    'type' : 'thumbnail',
                    'resourceUri' : 'http://www.moo.com/is/t/75/7b83fe35-75ba-c0a802e8-4c754942-4de8.png',
                    'width' : 75,
                    'height' : 75,
                    'rotation' : 0
                }
            ]
        }
    ],
    "type":null,
    "name":null,
    "immutable":false
}

Appendix - JSON Pack Data Pseudo Schema

"pack" => object(
    "numCards" => "string",
    "productCode" => "string",
    "productVersion" => "integer",
    "sides" => array(
        object (
            "sideNum" => "integer",
            "templateCode" => "string",
            "type" => "string",
            "data" => array(
                object(
                "type" => string,
                "linkId" => string,
                << Depending on type, other properties:
                    "textData" => See Side Object Model
                    "multiLineTextData" => See Side Object Model
                    "imageData" => See Side Object Model
                    "fixedImageData" => See Side Object Model
                    "boxData" => See Side Object Model
                >>
            )
        )
    ),
    "cards" => array(
        object(
            "cardNum" => "integer",
            "cardSides" => array(
                object(
                    "sideNum" => "integer",
                    "sideType" => "string",
                )
            )
        )
    ),
    "extras" => array(
        object(
            "key" => "string",
            "value" => "string"
        )
    ),
    "imageBasket" => array(
        "items" => array(
            object(
                "resourceUri" => "string",
                "name" => "string",
                "source" => "string",
                "imageBox" => "string",
                "removable" => "string",
                "croppable" => "string",
                "cacheId" => "string",
                "imageItems" => array(
                   object(
                        "type" => "string",
                        "resourceUri" => "string",
                        "width" => "integer",
                        "height" => "integer",
                        "rotation" => "float"
                    )
                ),
                "copyrightOwner" => "string",
                "shouldEnhance" => "boolean",
                "type" => "string"
            ),
        ),
        "type" => "string",
        "name" => "string",
        "immutable" => "boolean"
    )
)