Transit Pass Template

Transit passes support template rendering. If no template is defined, the default one is used.

Template definition

A pass template is defined at the class level and it is used to display any object that's associated with the class. The template defines which fields to display in different sections of the pass.

The template is divided into the following sections:

Android

Template overview

Web

Template overview

Card title

Android

Card title elements Default card title
  1. class.logo
  2. class.localizedIssuerName
    or class.issuerName
  3. object.ticketLeg.originName
  4. object.ticketLeg.destinationName
  5. object.ticketLeg.originStationCode
  6. object.ticketLeg.destinationStationCode
  7. object.tripType
  8. object.hexBackgroundColor
    or class.hexBackgroundColor

Wide-logo card title
  1. class.wideLogo
  2. object.ticketLeg.originName
  3. object.ticketLeg.destinationName
  4. object.ticketLeg.originStationCode
  5. object.ticketLeg.destinationStationCode
  6. object.tripType
  7. object.hexBackgroundColor
    or class.hexBackgroundColor

Web

Card title elements
  1. class.logo
  2. class.localizedIssuerName
    or class.issuerName
  3. object.ticketLeg.originName
  4. object.ticketLeg.destinationName
  5. object.ticketLeg.originStationCode
  6. object.ticketLeg.destinationStationCode
  7. object.tripType
  8. object.hexBackgroundColor
    or class.hexBackgroundColor

The card title section displays the logo, name of the transit operator, and journey summary. All of these three elements are required and neither the field references used to populate them nor their position can be changed.

However, the rendering logic allows for some flexibility for the top row. The top row of the pass, which represents a journey summary, is controlled by the following fields in the TransitObject for a single-leg journey:

  • object.tripType
  • object.ticketLeg.originName
  • object.ticketLeg.destinationName
  • object.ticketLeg.originStationCode
  • object.ticketLeg.destinationStationCode

How the pass is rendered depends on which fields are non-empty. It can be rendered in the following ways:

  • Origin name only: The origin name is the only information displayed. This is particularly useful for tickets that cover an area instead of a specific journey.
  • Origin and destination: The origin is on the left-hand side and the destination is on the right-hand side. The symbol in between the two depends on the type of the trip. Origin and destination are shown as one of the following:
    • Names and station codes: We show the station codes with the names as smaller text on top.
    • Names only: We show the names.
    • Station codes only: We show the station codes.

Multi-leg TransitObject objects work very similarly. In this case, do not use object.ticketLeg. Instead, you have to use the object.ticketLegs[] list. Both origins and destinations must be defined. Names or station codes, or both, must be used consistently in each leg. The origin displayed is the origin of the first element in the array, while the destination displayed is the destination of the last element in the array.

The background color of the pass isn't a required field and can be defined at both the class level and the object level. The object field has higher priority and can be used to override the class field.

When the wide logo field is set, on Android devices the default template header with the logo and issuer name is replaced with the wide logo.

Please follow the wide logo image guidelines when creating your wide header logo to optimally display your image on your passes.

Card template

Android

Template overview

Web

Template overview

The card template section is used to display extra rows. These rows can contain text-based structured data fields or text module fields.

You can specify the number of rows that define the number of objects in the class.classTemplateInfo.cardTemplateOverride.cardRowTemplateInfos[] list. The list requires at least one element and we recommed to use at most two elements. Each element must be of one of the following types:

  • oneItem, which accepts one item:
    • item
  • twoItems, which accepts two items:
    • startItem
    • endItem
  • threeItems, which accepts three items:
    • startItem
    • middleItem
    • endItem

Each item can be defined as either a single field selector (.firstValue), two field selectors (.firstValue and .secondValue), or a predefined item (.predefinedItem). Both the selected field’s values and their respective labels are displayed. When you define two field selectors, the values of the selected fields are displayed with a "/" separator. The same goes for the labels of the selected fields. Predefined items are used to define more complex rendering.

The following code sample shows how to override the card template card row sections to specify two rows. Each row includes three items that each reference six class-level textModuleData custom fields and their headers as labels:

Python

 {
   ... //Rest of class
   "textModulesData": [
        {
            "header": "Label 1",
            "body": "Some info 1",
            "id": "myfield1"
        },
        {
            "header": "Label 2",
            "body": "Some info 2",
            "id": "myfield2"
        },
        {
            "header": "Label 3",
            "body": "Some info 3",
            "id": "myfield3"
        },
        {
            "header": "Label 4",
            "body": "Some info 4",
            "id": "myfield4"
        },
        {
            "header": "Label 5",
            "body": "Some info 5",
            "id": "myfield5"
        },
        {
            "header": "Label 6",
            "body": "Some info 6",
            "id": "myfield6"
        }
    ],
   "classTemplateInfo": {
        "cardTemplateOverride": {
            "cardRowTemplateInfos": [{
                "threeItems": {
                    "startItem": {
                        "firstValue": {
                            "fields": [{
                                "fieldPath": "class.textModulesData['myfield1']"
                            }]
                        }
                    },
                    "middleItem": {
                        "firstValue": {
                            "fields": [{
                                "fieldPath": "class.textModulesData['myfield2']"
                            }]
                        }
                    },
                    "endItem": {
                        "firstValue": {
                            "fields": [{
                                "fieldPath": "class.textModulesData['myfield3']"
                            }]
                        }
                    },
                }
            },{
                "threeItems": {
                    "startItem": {
                        "firstValue": {
                            "fields": [{
                                "fieldPath": "class.textModulesData['myfield4']"
                            }]
                        }
                    },
                    "middleItem": {
                        "firstValue": {
                            "fields": [{
                                "fieldPath": "class.textModulesData['myfield5']"
                            }]
                        }
                    },
                    "endItem": {
                        "firstValue": {
                            "fields": [{
                                "fieldPath": "class.textModulesData['myfield6']"
                            }]
                        }
                    },
                }
            }]
        }
    }
}
    

Java

// Rest of class
  .setTextModulesData((new ArrayList<TextModuleData>() {
    {
      add((new TextModuleData()).setHeader("Label 1")
        .setBody("Some info 1")
        .setId("myfield1"));
      add((new TextModuleData()).setHeader("Label 2")
        .setBody("Some info 1")
        .setId("myfield2"));
      add((new TextModuleData()).setHeader("Label 3")
        .setBody("Some info 3")
        .setId("myfield3"));
      add((new TextModuleData()).setHeader("Label 4")
        .setBody("Some info 4")
        .setId("myfield4"));
      add((new TextModuleData()).setHeader("Label 5")
        .setBody("Some info 5")
        .setId("myfield5"));
      add((new TextModuleData()).setHeader("Label 6")
        .setBody("Some info 5")
        .setId("myfield6"));
    }
  }))
  .setClassTemplateInfo((new ClassTemplateInfo())
    .setCardTemplateOverride((new CardTemplateOverride())
      .setCardRowTemplateInfos(new ArrayList<CardRowTemplateInfo>() {
        {
          add((new CardRowTemplateInfo()).setThreeItems((new CardRowThreeItems())
            .setStartItem((new TemplateItem()).setFirstValue((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
              {
                add((new FieldReference()).setFieldPath("class.textModulesData['myfield1']"));
              }
            })))
            .setMiddleItem((new TemplateItem()).setFirstValue((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
              {
                add((new FieldReference()).setFieldPath("class.textModulesData['myfield2']"));
              }
            })))
            .setEndItem((new TemplateItem()).setFirstValue((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
              {
                add((new FieldReference()).setFieldPath("class.textModulesData['myfield3']"));
              }
            })))
          ));
          add((new CardRowTemplateInfo()).setThreeItems((new CardRowThreeItems())
            .setStartItem((new TemplateItem()).setFirstValue((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
              {
                add((new FieldReference()).setFieldPath("class.textModulesData['myfield4']"));
              }
            })))
            .setMiddleItem((new TemplateItem()).setFirstValue((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
              {
                add((new FieldReference()).setFieldPath("class.textModulesData['myfield5']"));
              }
            })))
            .setEndItem((new TemplateItem()).setFirstValue((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
              {
                add((new FieldReference()).setFieldPath("class.textModulesData['myfield6']"));
              }
            })))
          ));
          }
  })))
    

PHP

// Rest of class
    $textModulesData1 = new Google_Service_Walletobjects_TextModuleData();
    $textModulesData1->setBody("Some info 1");
    $textModulesData1->setHeader("Label 1");
    $textModulesData1->setId("myfield1");

    $textModulesData2 = new Google_Service_Walletobjects_TextModuleData();
    $textModulesData2->setBody("Some info 2");
    $textModulesData2->setHeader("Label 2");
    $textModulesData2->setId("myfield2");

    $textModulesData3 = new Google_Service_Walletobjects_TextModuleData();
    $textModulesData3->setBody("Some info 3");
    $textModulesData3->setHeader("Label 3");
    $textModulesData3->setId("myfield3");

    $textModulesData4 = new Google_Service_Walletobjects_TextModuleData();
    $textModulesData4->setBody("Some info 4");
    $textModulesData4->setHeader("Label 4");
    $textModulesData4->setId("myfield4");

    $textModulesData5 = new Google_Service_Walletobjects_TextModuleData();
    $textModulesData5->setBody("Some info 5");
    $textModulesData5->setHeader("Label 5");
    $textModulesData5->setId("myfield5");

    $textModulesData6 = new Google_Service_Walletobjects_TextModuleData();
    $textModulesData6->setBody("Some info 6");
    $textModulesData6->setHeader("Label 6");
    $textModulesData6->setId("myfield6");

    $textModulesDatas = array($textModulesData1, $textModulesData2, $textModulesData3,
                  $textModulesData4, $textModulesData5, $textModulesData6);

    $startItemField = new Google_Service_Walletobjects_FieldReference();
    $startItemField->setFieldPath("class.textModulesData['myfield1']");

    $startItemFirstValue = new Google_Service_Walletobjects_FieldSelector();
    $startItemFirstValue->setFields(array($startItemField));

    $startItem = new Google_Service_Walletobjects_TemplateItem();
    $startItem->setFirstValue($startItemFirstValue);

    $middleItemField = new Google_Service_Walletobjects_FieldReference();
    $middleItemField->setFieldPath("class.textModulesData['myfield2']");

    $middleItemFirstValue = new Google_Service_Walletobjects_FieldSelector();
    $middleItemFirstValue->setFields(array($middleItemField));

    $middleItem = new Google_Service_Walletobjects_TemplateItem();
    $middleItem->setFirstValue($middleItemFirstValue);

    $endItemField = new Google_Service_Walletobjects_FieldReference();
    $endItemField->setFieldPath("class.textModulesData['myfield3']");

    $endItemFirstValue = new Google_Service_Walletobjects_FieldSelector();
    $endItemFirstValue->setFields(array($endItemField));

    $endItem = new Google_Service_Walletobjects_TemplateItem();
    $endItem->setFirstValue($endItemFirstValue);

    $cardRowTemplate = new Google_Service_Walletobjects_CardRowThreeItems();
    $cardRowTemplate->setStartItem($startItem);
    $cardRowTemplate->setMiddleItem($middleItem);
    $cardRowTemplate->setEndItem($endItem);

    $cardRowTemplateInfo1 = new Google_Service_Walletobjects_CardRowTemplateInfo();
    $cardRowTemplateInfo1->setThreeItems($cardRowTemplate);

    $startItemField2 = new Google_Service_Walletobjects_FieldReference();
    $startItemField2->setFieldPath("class.textModulesData['myfield4']");

    $startItemFirstValue2 = new Google_Service_Walletobjects_FieldSelector();
    $startItemFirstValue2->setFields(array($startItemField2));

    $startItem2 = new Google_Service_Walletobjects_TemplateItem();
    $startItem2->setFirstValue($startItemFirstValue2);

    $middleItemField2 = new Google_Service_Walletobjects_FieldReference();
    $middleItemField2->setFieldPath("class.textModulesData['myfield5']");

    $middleItemFirstValue2 = new Google_Service_Walletobjects_FieldSelector();
    $middleItemFirstValue2->setFields(array($middleItemField2));

    $middleItem2 = new Google_Service_Walletobjects_TemplateItem();
    $middleItem2->setFirstValue($middleItemFirstValue2);

    $endItemField2 = new Google_Service_Walletobjects_FieldReference();
    $endItemField2->setFieldPath("class.textModulesData['myfield6']");

    $endItemFirstValue2 = new Google_Service_Walletobjects_FieldSelector();
    $endItemFirstValue2->setFields(array($endItemField2));

    $endItem2 = new Google_Service_Walletobjects_TemplateItem();
    $endItem2->setFirstValue($endItemFirstValue2);

    $cardRowTemplate2 = new Google_Service_Walletobjects_CardRowThreeItems();
    $cardRowTemplate2->setStartItem($startItem2);
    $cardRowTemplate2->setMiddleItem($middleItem2);
    $cardRowTemplate2->setEndItem($endItem2);

    $cardRowTemplateInfo2 = new Google_Service_Walletobjects_CardRowTemplateInfo();
    $cardRowTemplateInfo2->setThreeItems($cardRowTemplate2);

    $cardTemplateOverride = new Google_Service_Walletobjects_CardTemplateOverride();
    $cardTemplateOverride->setCardRowTemplateInfos(array($cardRowTemplateInfo1,
                  $cardRowTemplateInfo2));

    $classTemplateInfo = new Google_Service_Walletobjects_ClassTemplateInfo();
    $classTemplateInfo->setCardTemplateOverride($cardTemplateOverride);

    $payload->setTextModulesData($textModulesDatas);
    $payload->setClassTemplateInfo($classTemplateInfo);
    

The code creates a pass with the following code template section format:

Example of a label override.

If an item is empty, it isn't displayed. For more details, see Field References. If all items in a row are empty, the row isn't displayed. If some but not all items in a row are empty, the non-empty items are re-arranged and displayed as a row with fewer items.

If you don't override the card template, the default number of rows, the default number of items, and the default field references are used. For more details, see Default template.

After you define a Hero Image, it can appear after the first row, if there are multiple rows in the cardRowTemplateInfos list, or above the row, if there is only one.

Card barcode

Android

Card barcode elements
  1. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstTopDetail
  2. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .secondTopDetail
  3. object.barcode.type and object.barcode.value
    or object.ticketNumber
  4. object.barcode.alternateText
  5. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstBottomDetail

Web

Card barcode elements
  1. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstTopDetail
  2. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .secondTopDetail
  3. object.barcode.type and object.barcode.value
    or object.ticketNumber
  4. object.barcode.alternateText
  5. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstBottomDetail

The card barcode section is used to display extra text or images above and below the barcode. None of the fields in this section are required.

There are three field selectors that can be used to define two side-by-side fields above and one below the barcode. These are displayed with no label and can either be text-based structured data fields, text module fields, or image module fields. If you use images, these should follow the brand guidelines.

The barcode is defined by a type and a value. For a list of supported barcode types, see Reference. Furthermore, a text can be shown right underneath the barcode. This text can make it easier to scan barcodes, among other uses.

The following code sample shows how to override the barcode section of a pass to display an image above the barcode:

Python

#... rest of class
    "imageModulesData": [
        {
            "mainImage": {
                "sourceUri": {
                    "uri":  "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
                    "description": "Coffee"
                }
            },
            "Id": "myimage"
        }
    ],
    "classTemplateInfo": {
        "cardBarcodeSectionDetails": {
            "firstTopDetail": {
                "fieldSelector": {
                    "fields": [
                        {
                        "fieldPath": "class.imageModulesData['myimage'].mainImage"
                        }
                    ]
                }
            }
        }
    }
}
    

Java

//... rest of class
  .setImageModulesData((new ArrayList<ImageModuleData>() {
    {
      add((new ImageModuleData())
        .setId("myimage")
        .setMainImage((new Image()).setSourceUri((new ImageUri()).setDescription("Coffee beans")
          .setUri("http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"))));
        }
      }))
      .setClassTemplateInfo((new ClassTemplateInfo())
        .setCardBarcodeSectionDetails((new CardBarcodeSectionDetails())
          .setFirstTopDetail((new BarcodeSectionDetail())
            .setFieldSelector((new FieldSelector())
              .setFields((new ArrayList<FieldReference>(){
                {
                  add((new FieldReference()).setFieldPath("class.imageModulesData['myimage'].mainImage"));
                }
            })))))
      }
    

PHP

//... rest of class
    $imageUri = new Google_Service_Walletobjects_ImageUri();
    $imageUri->setUri("https://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg");
    $imageUri->setDescription("Baconrista flights image");
    $image = new Google_Service_Walletobjects_Image();
    $image->setSourceUri($imageUri);
    $imageModulesData = new Google_Service_Walletobjects_ImageModuleData();
    $imageModulesData->setMainImage($image);
            $imageModulesData->setId("myimage");

    $cardBarcodeFieldReference = new Google_Service_Walletobjects_FieldReference();
    $cardBarcodeFieldReference->setFieldPath("class.imageModulesData['myimage'].mainImage");

    $cardBarcodeFieldSelector = new Google_Service_Walletobjects_FieldSelector();
    $cardBarcodeFieldSelector->setFields(array($cardBarcodeFieldReference));

    $cardBarcodeDetail = new Google_Service_Walletobjects_BarcodeSectionDetail();
    $cardBarcodeDetail->setFieldSelector($cardBarcodeFieldSelector);

    $cardBarcodeSectionDetails = new Google_Service_Walletobjects_CardBarcodeSectionDetails();
    $cardBarcodeSectionDetails->setFirstTopDetail($cardBarcodeDetail);

    $classTemplateInfo = new Google_Service_Walletobjects_ClassTemplateInfo();
    $classTemplateInfo->setCardBarcodeSectionDetails($cardBarcodeSectionDetails);

    $payload->setClassTemplateInfo($classTemplateInfo);
            $payload->setImageModuleData($imageModulesData);
    

The code creates a pass with the following barcode section format:

Example of a card barcode override.

If you don't override the barcode section, the default barcode fields are used. For more information, see Default template.

Details template

Android

Details template sections
  • Multi leg itinerary
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[0].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[1].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[2].item
  • ...

Web

Details template sections
  • Multi leg itinerary
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[0].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[1].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[2].item
  • ...

The details template section is a list of items class.classTemplateInfo.detailsTemplateOverride.detailsItemInfos[]. The items can contain any kind of structured data fields, text module fields, link module fields, image module fields, or messages.

Each item can be defined as either a single field selector (.firstValue), two field selectors (.firstValue and .secondValue), or a predefined item (.predefinedItem). Both the selected field’s values and their respective labels are displayed. When you define two field selectors, the values of the selected fields are displayed with a "/" separator. The same goes for the labels of the selected fields. Predefined items are used to define more complex rendering. Image module fields are rendered at full-width without a label.

The following code sample shows how to override the detail section of the pass to show a single linksModuleData field with its label:

Python

//... rest of class
   "linksModuleData": {
        "uris": [
            {
                "uri": "http://maps.google.com/",
                "description": "Nearby Locations",
                "id":"mylink"
            }
        ]
    },
   "classTemplateInfo": {
        "detailsTemplateOverride": {
            "detailsItemInfos": [
                {
                    "item":{
                        "firstValue": {
                            "fields": [{
                                "fieldPath": "class.linksModuleData.uris['mylink']"
                            }]
                        }
                    }
                }
            ]
        }
     }
//... rest of class
    

Java

 //... rest of class
  .setLinksModuleData((new ArrayList<LinksModuleData>() {
    {
      add((new LinksModuleData()).setDescription("Nearby Locations")
        .setUri("http://maps.google.com/")
        .setId("mylink"));
      }))
      .setClassTemplateInfo((new ClassTemplateInfo())
        .setDetailsTemplateOverride((new DetailsTemplateOverride())
          .setDetailsItemInfos(new ArrayList<DetailsItemInfo>(){
            {
              add((new DetailsItemInfo())
                .setItem((new TemplateItem()).setFirstValue((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
                  {
                    add((new FieldReference()).setFieldPath("class.linksModuleData.uris['mylink']"));
                  }
                }))));
              }
            }))
//... rest of class
    

PHP



    //... rest of class building
    $locationUri = new Google_Service_Walletobjects_Uri();
    $locationUri->setUri("http://maps.google.com/");
    $locationUri->setDescription("Nearby Locations");
    $locationUri->setId("mylink");

    $linksModuleData = new Google_Service_Walletobjects_LinksModuleData();
    $linksModuleData->setUris(array($locationUri));

    $detailItemFieldReference = new Google_Service_Walletobjects_FieldReference();
    $detailItemFieldReference->setFieldPath("class.linksModuleData.uris['mylink']");
    $detailItemFieldSelector = new Google_Service_Walletobjects_FieldSelector();
    $detailItemFieldSelector->setFields(array($detailItemFieldReference));

    $detailItem = new Google_Service_Walletobjects_TemplateItem();
    $detailItem->setFirstValue($detailItemFieldSelector);

    $detailsItemInfo = new Google_Service_Walletobjects_DetailsItemInfo();
    $detailsItemInfo->setItem($detailItem);

    $cardDetailsTemplateOverride = new Google_Service_Walletobjects_DetailsTemplateOverride();
    $cardDetailsTemplateOverride->setDetailsItemInfos(array($detailsItemInfo));

    $classTemplateInfo = new Google_Service_Walletobjects_ClassTemplateInfo();
    $classTemplateInfo->setDetailsTemplateOverride($cardDetailsTemplateOverride);

    $payload->setClassTemplateInfo($classTemplateInfo);
    $payload->setLinksModuleData($linksModuleData);
    //... rest of class
    

The code creates a pass with the following detail section format:

Example of a detail
                                                                             override.

If an item is empty, it isn't displayed. For more details, see Field References.

If you don't override the details template, the default list of reference fields in the default order is displayed. For more information, see Default template.

If the journey includes multiple legs, a simple itinerary is displayed at the top of the section and can't be moved. If the journey only includes a single leg, a simple itinerary can be shown by setting class.enableSingleLegItinerary.

Multi Leg Itinerary
  1. class.tranistType
  2. object.ticketLegs[i].originName
    or object.ticketLegs[i].originStationCode
  3. object.ticketLegs[i].departureDateTime (time only)
  4. object.ticketLegs[i].transitOperatorName
  5. COACH or class.customCoachLabel
  6. object.ticketLegs[i].ticketSeat.coach
    or object.ticketLegs[i].ticketSeats[*].coach
  7. SEAT or class.customSeatLabel
  8. object.ticketLegs[i].ticketSeat.seat
    or object.ticketLegs[i].ticketSeat.seatAssignment
    or object.ticketLegs[i].ticketSeats[*].seat
    or object.ticketLegs[i].ticketSeats[*].seatAssignment
    or NO SPECIFIC SEAT
  9. object.hexBackgroundColor
    or class.hexBackgroundColor
  10. object.ticketLegs[i].destinationName
    or object.ticketLegs[i].destinationStationCode
  11. object.ticketLegs[i].arrivalDateTime (time only)
  12. TRANSFER TO: PLATFORM
    or TRANSFER TO: class.customPlatformLabel
    or TRANSFER (if no platform is defined)
  13. object.ticketLegs[i+1].platform

List template

List template elements
  1. class.classTemplateInfo.listTemplateOverride
      .firstRowOption.fieldOption.fields[]
  2. object.ticketLeg.departureDateTime (grouped)
    or class.classTemplateInfo.listTemplateOverride
      .secondRowOption.fields[]
  3. class.logo
  4. object.hexBackgroundColor
    or class.hexBackgroundColor
  5. <# passes> (grouped)

The list template section is used to select what field to display in the "Passes" view of the Google Wallet app. The pass is represented in the list with the logo, background color, and three rows.

The following code sample shows how to override the list template of a pass to show a single passes’ object expiration date field in the first row of the list template:

Python


#... rest of class definition
   "classTemplateInfo": {
        "listTemplateOverride":{
            "firstRowOption": {
                "fieldOption":{
                    "fields": [{
                        "fieldPath": "object.validTimeInterval.end"
                    }]
                }
            }
        }
   }
}
    

Java

//... rest of class
  .setClassTemplateInfo((new ClassTemplateInfo())
    .setListTemplateOverride((new ListTemplateOverride())
      .setFirstRowOption((new FirstRowOption())
        .setFieldOption((new FieldSelector()).setFields(new ArrayList<FieldReference>(){
          {
            add((new FieldReference()).setFieldPath("object.validTimeInterval.end"));
          }
        }))))
//... rest of class
    

PHP

    //... rest of class
    $fieldReference = new Google_Service_Walletobjects_FieldReference();
    $fieldReference->setFieldPath("object.validTimeInterval.end");

    $fieldOption = new Google_Service_Walletobjects_FieldSelector();
    $fieldOption->setFields(array($fieldReference));

    $firstRowOption = new Google_Service_Walletobjects_FirstRowOption();
    $firstRowOption->setFieldOption($fieldOption);

    $listTemplateOverride = new Google_Service_Walletobjects_ListTemplateOverride();
    $listTemplateOverride->setFirstRowOption($firstRowOption);

    $classTemplateInfo = new Google_Service_Walletobjects_ClassTemplateInfo();
    $classTemplateInfo->setListTemplateOverride($listTemplateOverride);

    $payload->setClassTemplateInfo($classTemplateInfo);
    //... rest of class
    

The code creates a pass with the following list template rendition:

Example of a list
                                                                           override.

The first row can be defined with a field selector or it shows the journey summary. The format of the summary can be one of the following:

  • originAndDestinationCodes
  • originAndDestinationNames
  • originName

The second and third rows can only be defined with a field selector. The fields are displayed with no label. For grouped passes, the second row always shows the departure date and the third row always shows the number of grouped passes.

Labels

All structured data fields have a label provided by Google. Google is responsible for providing a translation for each of these labels in all the supported languages.

You can customize some of these labels using one of the class.custom<name_of_the_field>Label fields. When you customize a label, you become responsible for providing translations for that specific label in all the languages that you wish to support.

Field references

Field references are used in different parts of the template with the form class.classTemplateInfo.*.fields[]. A field reference contains a list of paths to structured data fields, text module fields, link module fields, image module fields, or messages.

Not all types of paths are allowed in every field reference. For example, some field references only allow paths to text-based structured data fields or text module fields. Text-based structured fields are structured data fields of type string, localized string, date, or money.

The list can be used to implement a fallback logic. This means that if the first path in the list resolves to an empty field, the next path is evaluated. The fallback logic is mainly targeted at text-based structured data fields or text module fields. Do not mix different types of fields in the same list. Use the fallback logic with caution and only in specific situations when you expect a consistent pattern of fields that exist in some objects but not others. Most of the time, it's easier to create separate classes for separate use cases.

If all paths in a field reference list resolve to empty fields, the item that uses the field reference isn't displayed. If you want the item that uses the field reference to always be present, make sure that at least one path isn't empty. We recommend that you set a field to a special character, such as ‘-’, to represent a null value, even if some fields allow strings with just a space.

In order to reference a field contained in a list, you can use the index of the field in the list or, in most cases, you can use a reference ID. Items of a list that can be referenced by ID have a .id field. We recommend that you use a reference ID over the index of the field in the list when available.

Here is an example of how to reference fields contained in a list.

  • object.imageModulesData[0].id = my-first-id
  • object.imageModulesData[1].id = my-second-id
  • class.detailsTemplateOverride.detailsItemInfos[0].item.firstValue.fields[0].fieldPath = object.imageModulesData[‘my-second-id’]
  • class.detailsTemplateOverride.detailsItemInfos[1].item.firstValue.fields[0].fieldPath = object.imageModulesData[0]

In this case, the first item in the details section of the pass is the second image declared in the object. While, the second item in the details section of the pass is the first image declared in the object.

Default template

Android

Default template elements
  1. class.logo
  2. class.localizedIssuerName
    or class.issuerName
  3. See Card title
  4. DEPARTURE or VALID FROM
  5. object.ticketLeg.departureDateTime (date and time)
    or object.validTimeInterval.start.date
  6. ARRIVING AT or VALID UNTIL
  7. object.ticketLeg.arrivalDateTime (time only)
    or object.validTimeInterval.end.date
  8. PASSENGER
  9. object.passengerNames
  10. CARRIAGE or class.customCarriageLabel
  11. object.ticketLeg.carriage
  12. COACH or class.customCoachLabel
  13. object.ticketLeg.ticketSeat.coach
  14. SEAT or class.customSeatLabel
  15. object.ticketLeg.ticketSeat.seat
    or object.ticketLeg.ticketSeat.seatAssignment
  16. object.barcode.type and object.barcode.value
    or object.ticketNumber
  17. object.barcode.alternateText
  18. object.hexBackgroundColor
    or class.hexBackgroundColor
  19. Multi leg itinerary
  20. TICKET NUMBER or class.customTicketNumberLabel
  21. object.ticketNumber
  22. TICKET STATUS
  23. object.ticketStatus or object.customTicketStatus
  24. DEPARTURE
  25. object.ticketLeg.departureDateTime
  26. ARRIVAL
  27. object.ticketLeg.arrivalDateTime
  28. FARE NAME or class.customFareNameLabel
  29. object.ticketLeg.fareName
  30. PLATFORM or class.customPlatformLabel
  31. object.ticketLeg.platform
  32. ZONE or class.customZoneLabel
  33. object.ticketLeg.zone
  34. FARE CLASS or class.customFareClassLabel
  35. object.ticketLeg.ticketSeat.fareClass
    or object.ticketLeg.ticketSeat.customFareClass
  36. CONCESSION CATEGORY
    or class.customConcessionCategoryLabel
  37. object.concessionCategory
    or object.customConcessionCategory
  38. ROUTE RESTRICTIONS
    or class.customRouteRestrictionsLabel
  39. object.ticketRestrictions.routeRestrictions
  40. ROUTE RESTRICTIONS DETAILS
    or class.customRouteRestrictionsDetailsLabel
  41. object.ticketRestrictions.routeRestrictionsDetails
  42. TIME RESTRICTIONS
    or class.customTimeRestrictionsLabel
  43. object.ticketRestrictions.timeRestrictions
  44. OTHER RESTRICTIONS
    or class.customOtherRestrictionsLabel
  45. object.ticketRestrictions.otherRestrictions
  46. RECEIPT NUMBER
    or class.customPurchaseReceiptNumberLabel
  47. object.purchaseDetails.purchaseReceiptNumber
  48. PURCHASE DATE
  49. object.purchaseDetails.purchaseDateTime
  50. ACCOUNT ID
  51. object.purchaseDetails.accountId
  52. CONFIRMATION CODE
    or class.customConfirmationCodeLabel
  53. object.purchaseDetails.confirmationCode
  54. FACE VALUE or class.customPurchaseFaceValueLabel
  55. object.purchaseDetails.ticketCost.faceValue
  56. PRICE or class.customPurchasePriceLabel
  57. object.purchaseDetails.ticketCost.purchasePrice
  58. DISCOUNT MESSAGE
    or class.customDiscountMessageLabel
  59. object.purchaseDetails.ticketCost.discountMessage
  60. class.imageModulesData[0].mainImage
  61. object.imageModulesData[0].mainImage
  62. class.messages[].header
  63. class.messages[].body
  64. object.messages[].header
  65. object.messages[].body
  66. class.textModulesData[0..9].header
  67. class.textModulesData[0..9].body
  68. object.textModulesData[0..9].header
  69. object.textModulesData[0..9].body
  70. class.linksModuleData.uris[].description
  71. object.linksModuleData.uris[].description

Web

Default template elements
  1. class.logo
  2. class.localizedIssuerName
    or class.issuerName
  3. See Card title
  4. DEPARTURE or VALID FROM
  5. object.ticketLeg.departureDateTime (date and time)
    or object.validTimeInterval.start.date
  6. ARRIVING AT or VALID UNTIL
  7. object.ticketLeg.arrivalDateTime (time only)
    or object.validTimeInterval.end.date
  8. PASSENGER
  9. object.passengerNames
  10. CARRIAGE or class.customCarriageLabel
  11. object.ticketLeg.carriage
  12. COACH or class.customCoachLabel
  13. object.ticketLeg.ticketSeat.coach
  14. SEAT or class.customSeatLabel
  15. object.ticketLeg.ticketSeat.seat
    or object.ticketLeg.ticketSeat.seatAssignment
  16. object.barcode.type and object.barcode.value
    or object.ticketNumber
  17. object.barcode.alternateText
  18. object.hexBackgroundColor
    or class.hexBackgroundColor
  19. Multi leg itinerary
  20. TICKET NUMBER or class.customTicketNumberLabel
  21. object.ticketNumber
  22. TICKET STATUS
  23. object.ticketStatus or object.customTicketStatus
  24. DEPARTURE
  25. object.ticketLeg.departureDateTime
  26. ARRIVAL
  27. object.ticketLeg.arrivalDateTime
  28. FARE NAME or class.customFareNameLabel
  29. object.ticketLeg.fareName
  30. PLATFORM or class.customPlatformLabel
  31. object.ticketLeg.platform
  32. ZONE or class.customZoneLabel
  33. object.ticketLeg.zone
  34. FARE CLASS or class.customFareClassLabel
  35. object.ticketLeg.ticketSeat.fareClass
    or object.ticketLeg.ticketSeat.customFareClass
  36. CONCESSION CATEGORY
    or class.customConcessionCategoryLabel
  37. object.concessionCategory
    or object.customConcessionCategory
  38. ROUTE RESTRICTIONS
    or class.customRouteRestrictionsLabel
  39. object.ticketRestrictions.routeRestrictions
  40. ROUTE RESTRICTIONS DETAILS
    or class.customRouteRestrictionsDetailsLabel
  41. object.ticketRestrictions.routeRestrictionsDetails
  42. TIME RESTRICTIONS
    or class.customTimeRestrictionsLabel
  43. object.ticketRestrictions.timeRestrictions
  44. OTHER RESTRICTIONS
    or class.customOtherRestrictionsLabel
  45. object.ticketRestrictions.otherRestrictions
  46. RECEIPT NUMBER
    or class.customPurchaseReceiptNumberLabel
  47. object.purchaseDetails.purchaseReceiptNumber
  48. PURCHASE DATE
  49. object.purchaseDetails.purchaseDateTime
  50. ACCOUNT ID
  51. object.purchaseDetails.accountId
  52. CONFIRMATION CODE
    or class.customConfirmationCodeLabel
  53. object.purchaseDetails.confirmationCode
  54. FACE VALUE or class.customPurchaseFaceValueLabel
  55. object.purchaseDetails.ticketCost.faceValue
  56. PRICE or class.customPurchasePriceLabel
  57. object.purchaseDetails.ticketCost.purchasePrice
  58. DISCOUNT MESSAGE
    or class.customDiscountMessageLabel
  59. object.purchaseDetails.ticketCost.discountMessage
  60. class.imageModulesData[0].mainImage
  61. object.imageModulesData[0].mainImage
  62. class.messages[].header
  63. class.messages[].body
  64. object.messages[].header
  65. object.messages[].body
  66. class.textModulesData[0..9].header
  67. class.textModulesData[0..9].body
  68. object.textModulesData[0..9].header
  69. object.textModulesData[0..9].body
  70. class.linksModuleData.uris[].description
  71. object.linksModuleData.uris[].description

For image module fields, we show one and only one image module field from the class and one and only one image module field from the object. If you need more than one image module field at either level, override the default template.

For text module fields, we only show a maximum of 20 text module fields from the class and 20 text module fields from the object. The fields are displayed in the same order in which they are defined in the array. If you need more than 20 text module fields at either level, override the default template.

For messages, we only show a maximum of 20 messages from the class and 20 messages from the the object. We don't guarantee the order of the messages. If you need more than 20 messages at either level, or a guarantee for any orders, override the default template.

For the links module field, there is no limit on the number of uris you can define. Uris are diplayed grouped in the following order for each level (class or object):

  1. Map coordinates
  2. Telephone numbers
  3. Email addresses
  4. Web pages

For each group, URIs are displayed in the same order in which they are defined in the array. If you need a different ordering, override the default template.

Default list template elements
  1. (object.ticketLeg.originName
      and object.ticketLeg.destinationName)
    or (object.ticketLeg.originStationCode
      and object.ticketLeg.destinationStationCode)
    or object.ticketLeg.originName
  2. object.ticketLeg.departureDateTime
    or object.validTimeInterval.end.date
  3. class.logo
  4. object.hexBackgroundColor
    or class.hexBackgroundColor
  5. <# passes> (grouped)