公交卡模板

交通通票支持模板渲染。如果未定义任何模板,则使用默认模板。

模板定义

卡券模板在类级别定义,用于显示与该类关联的任何对象。该模板定义了要在卡券的不同部分中显示的字段。

该模板分为以下几个部分:

Android

卡券模板布局部分和位置概览

Web

卡券模板布局部分和位置概览

卡片标题

Android

卡片标题布局元素和字段位置 默认卡片标题
  1. class.logo
  2. class.localizedIssuerName
    或 class.issuerName
  3. object.ticketLeg.originName
  4. object.ticketLeg.destinationName
  5. object.ticketLeg.originStationCode
  6. object.ticketLeg.destinationStationCode
  7. object.tripType
  8. object.hexBackgroundColor
    或 class.hexBackgroundColor

宽徽标卡片标题
  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
    或 class.hexBackgroundColor

Web

卡片标题布局元素和字段位置 默认卡片标题
  1. class.logo
  2. class.localizedIssuerName
    或 class.issuerName
  3. object.ticketLeg.originName
  4. object.ticketLeg.destinationName
  5. object.ticketLeg.originStationCode
  6. object.ticketLeg.destinationStationCode
  7. object.tripType
  8. object.hexBackgroundColor
    或 class.hexBackgroundColor

宽徽标卡片标题
  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
    或 class.hexBackgroundColor

卡片标题部分会显示公交运营商的徽标、名称和行程摘要。 这三个元素都是必需的,用于填充这些元素的字段引用及其位置都不能更改。

不过,渲染逻辑允许对顶行进行一些灵活调整。卡券的第一行代表行程摘要,由单段行程的 TransitObject 中的以下字段控制:

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

卡券的呈现方式取决于哪些字段不为空。它可以通过以下方式呈现:

  • 仅显示来源名称:仅显示来源名称。这对于涵盖某个区域而非特定行程的票券特别有用。
  • 来源和目的地:来源位于左侧,目的地位于右侧。两者之间的符号取决于行程类型。出发地和目的地显示为以下其中一项:
    • 名称和车站代码:我们会显示车站代码,并在其上方以较小的文字显示名称。
    • 仅显示名称:我们会显示名称。
    • 仅显示车站代码:我们会显示车站代码。

多航段 TransitObject 对象的工作原理非常相似。在这种情况下,请勿使用 object.ticketLeg。您必须改用 object.ticketLegs[] 列表。必须同时定义起点和终点。在每个航段中,必须始终如一地使用名称或车站代码,或同时使用两者。显示的起点是数组中第一个元素的起点,而显示的目的地是数组中最后一个元素的目的地。

卡券的背景颜色不是必填字段,可以在类级别和对象级别定义。对象字段具有更高的优先级,可用于替换类字段。

设置宽徽标字段后,在移动设备上,包含徽标和颁发者名称的默认模板标题会被替换为宽徽标。

在创建宽幅标题徽标时,请遵循宽幅徽标图片指南,以便在卡券上以最佳方式显示图片。

卡片模板

Android

卡片模板行布局元素和字段位置

Web

卡片模板行布局元素和字段位置

卡片模板部分用于显示额外行。这些行可以包含基于文本的结构化数据字段或文本模块字段。

您可以指定行数,以定义 class.classTemplateInfo.cardTemplateOverride.cardRowTemplateInfos[] 列表中的对象数量。该列表至少需要一个元素,我们建议最多使用两个元素。每个元素都必须是以下类型之一:

  • oneItem,接受一个项:
    • item
  • twoItems,它接受两个项:
    • startItem
    • endItem
  • threeItems,它接受三个项:
    • startItem
    • middleItem
    • endItem

每个项都可以定义为单个字段选择器 (.firstValue)、两个字段选择器(.firstValue 和 .secondValue)或预定义项 (.predefinedItem)。所选字段的值及其各自的标签都会显示。定义两个字段选择器时,所选字段的值会以“/”分隔符显示。所选字段的标签也是如此。预定义项用于定义更复杂的呈现。

以下代码示例展示了如何替换卡片模板卡片行部分,以指定两行。每行包含三个项,每个项都引用六个类级 textModuleData 自定义字段及其标题作为标签:

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);
    

该代码会创建一个具有以下代码模板部分格式的卡券:

标签替换示例。

如果某项内容为空,则不会显示。如需了解详情,请参阅字段引用。如果某行中的所有项都为空,则该行不会显示。如果某行中的部分(而非全部)内容为空,则非空内容会重新排列,并显示为内容较少的一行。

如果您不替换卡片模板,系统会使用默认行数、默认项数和默认字段引用。如需了解详情,请参阅默认模板。

定义主打图片后,如果 cardRowTemplateInfos 列表中有多行,则主打图片可以显示在第一行之后;如果只有一行,则可以显示在该行上方。

卡条形码

Android

卡券条形码布局元素和位置
  1. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstTopDetail
  2. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .secondTopDetail
  3. object.barcode.type 和 object.barcode.value
    或 object.ticketNumber
  4. object.barcode.alternateText
  5. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstBottomDetail

Web

卡券条形码布局元素和位置
  1. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstTopDetail
  2. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .secondTopDetail
  3. object.barcode.type 和 object.barcode.value
    或 object.ticketNumber
  4. object.barcode.alternateText
  5. class.classTemplateInfo
      .cardBarcodeSectionDetails
      .firstBottomDetail

卡券条形码部分用于在条形码前后显示额外的文字或图片。此部分中的所有字段都不是必填项。

您可以使用三个字段选择器来定义条形码前面的两个并排字段和后面的一个字段。这些字段不显示标签,可以是基于文本的结构化数据字段、文本模块字段或图片模块字段。如果您使用图片,这些图片应遵循品牌推广指南。

条形码由类型和值定义。如需查看支持的条形码类型列表,请参阅参考。此外,还可以在条形码正下方显示文本。此文本可让您更轻松地扫描条形码,以及执行其他操作。

以下代码示例展示了如何替换卡券的条形码部分,以便在条形码上方显示图片:

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);
    

该代码会创建具有以下条形码部分格式的卡券:

卡券条形码替换示例。

如果您未替换条形码部分,系统将使用默认条形码字段。 如需了解详情,请参阅默认模板。

底部版块

Android

详情模板底部部分和内容
  • 多航段行程
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[0].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[1].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[2].item
  • …

Web

详情模板底部部分和内容
  • 多航段行程
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[0].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[1].item
  • class.classTemplateInfo.detailsTemplateOverride
      .detailsItemInfos[2].item
  • …

底部部分是项列表 class.classTemplateInfo.detailsTemplateOverride.detailsItemInfos[]。这些内容可以包含任何类型的结构化数据字段、文本模块字段、链接模块字段、图片模块字段或消息。

每项内容都可以定义为单个字段选择器 (.firstValue)、两个字段选择器(.firstValue 和 .secondValue)或预定义项 (.predefinedItem)。所选字段的值及其各自的标签都会显示。如果您定义了两个字段选择器,则所选字段的值会以“/”分隔符显示。所选字段的标签也是如此。预定义项用于定义更复杂的呈现。图片模块字段会以全宽呈现,不带标签。

以下代码示例展示了如何替换卡券的底部部分,以显示单个 linksModuleData 字段及其标签:

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
    

该代码会创建具有以下底部版块格式的卡券:

底部部分替换示例。

如果某项内容为空,则不会显示。如需了解详情,请参阅字段引用。

如果您不替换底部部分,系统会按默认顺序显示参考字段的默认列表。如需了解详情,请参阅默认模板。

如果行程包含多个航段,则该部分顶部会显示一个简单的行程,且无法移动。如果行程仅包含一个航段,则可以通过设置 class.enableSingleLegItinerary 来显示简单行程。

多航段行程
  1. class.tranistType
  2. object.ticketLegs[i].originName
    或 object.ticketLegs[i].originStationCode
  3. object.ticketLegs[i].departureDateTime(仅限时间)
  4. object.ticketLegs[i].transitOperatorName
  5. COACH 或 class.customCoachLabel
  6. object.ticketLegs[i].ticketSeat.coach
    或 object.ticketLegs[i].ticketSeats[*].coach
  7. SEAT 或class.customSeatLabel
  8. object.ticketLegs[i].ticketSeat.seat
    或 object.ticketLegs[i].ticketSeat.seatAssignment
    或 object.ticketLegs[i].ticketSeats[*].seat
    或 object.ticketLegs[i].ticketSeats[*].seatAssignment
    或 NO SPECIFIC SEAT
  9. object.hexBackgroundColor
    或 class.hexBackgroundColor
  10. object.ticketLegs[i].destinationName
    或 object.ticketLegs[i].destinationStationCode
  11. object.ticketLegs[i].arrivalDateTime(仅限时间)
  12. TRANSFER TO: PLATFORM
    或 TRANSFER TO: class.customPlatformLabel
    或 TRANSFER(如果未定义平台)
  13. object.ticketLegs[i+1].platform

列表模板

列出模板元素
  1. class.classTemplateInfo.listTemplateOverride
      .firstRowOption.fieldOption.fields[]
  2. object.ticketLeg.departureDateTime(已分组)
    或 class.classTemplateInfo.listTemplateOverride
      .secondRowOption.fields[]
  3. class.logo
  4. object.hexBackgroundColor
    或 class.hexBackgroundColor
  5. <# passes>(分组)

列表模板部分用于选择要在 Google 钱包应用的“卡券”视图中显示的字段。卡券在列表中以徽标、背景颜色和三行内容表示。

以下代码示例展示了如何替换卡券的列表模板,以便在列表模板的第一行中显示单个卡券对象的失效日期字段:

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
    

该代码会创建一个具有以下列表模板呈现形式的卡券:

列表替换示例。

第一行可以使用字段选择器进行定义,也可以显示历程摘要。摘要的格式可以是以下格式之一:

  • originAndDestinationCodes
  • originAndDestinationNames
  • originName

第二行和第三行只能使用字段选择器进行定义。 这些字段在显示时没有标签。 对于分组卡券,第二行始终显示出发日期,第三行始终显示分组卡券的数量。

标签

所有结构化数据字段都有 Google 提供的标签。Google 负责以所有受支持的语言提供每个标签的翻译。

您可以使用其中一个 class.custom<name_of_the_field>Label 字段自定义部分标签。自定义标签后,您需要负责以您希望支持的所有语言提供该特定标签的翻译。

字段引用

字段引用在模板的不同部分中使用,格式为 class.classTemplateInfo.*.fields[]。字段引用包含指向结构化数据字段、文本模块字段、链接模块字段、图片模块字段或消息的路径列表。

并非所有类型的路径都允许在每个字段引用中使用。例如,某些字段引用仅允许指向基于文本的结构化数据字段或文本模块字段的路径。基于文本的结构化字段是字符串、本地化字符串、日期或货币类型的结构化数据字段。

该列表可用于实现回退逻辑。这意味着,如果列表中的第一个路径解析为空字段,则系统会评估下一个路径。后备逻辑主要针对基于文本的结构化数据字段或文本模块字段。请勿在同一列表中混用不同类型的字段。请谨慎使用回退逻辑,并且仅在特定情况下使用,即您预计某些对象中存在一致的字段模式,而其他对象中不存在。在大多数情况下,为不同的用例创建不同的类会更容易。

如果字段引用列表中的所有路径都解析为空字段,则不会显示使用该字段引用的项。如果您希望使用字段引用的项始终存在,请确保至少有一个路径不为空。我们建议您将字段设置为特殊字符(例如“-”)来表示 null 值,即使某些字段允许仅包含空格的字符串。

如需引用列表中包含的字段,您可以使用该字段在列表中的索引,或者在大多数情况下,您可以使用引用 ID。可通过 ID 引用的列表项具有 .id 字段。我们建议您使用引用 ID,而不是列表中字段的索引(如果可用)。

以下示例展示了如何引用列表中包含的字段。

  • 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]

在这种情况下,卡券详细信息部分中的第一项是对象中声明的第二张图片。而卡券详细信息部分的第二项是对象中声明的第一张图片。

默认模板

Android

默认卡券模板布局元素和位置
  1. class.logo
  2. class.localizedIssuerName
    或 class.issuerName
  3. 查看卡片标题
  4. DEPARTURE 或 VALID FROM
  5. object.ticketLeg.departureDateTime(日期和时间)
    或 object.validTimeInterval.start.date
  6. 到达时间或有效期至
  7. object.ticketLeg.arrivalDateTime(仅限时间)
    或 object.validTimeInterval.end.date
  8. 乘客
  9. object.passengerNames
  10. CARRIAGE 或 class.customCarriageLabel
  11. object.ticketLeg.carriage
  12. COACH 或 class.customCoachLabel
  13. object.ticketLeg.ticketSeat.coach
  14. SEAT 或class.customSeatLabel
  15. object.ticketLeg.ticketSeat.seat
    或 object.ticketLeg.ticketSeat.seatAssignment
  16. object.barcode.type 和 object.barcode.value
    或 object.ticketNumber
  17. object.barcode.alternateText
  18. object.hexBackgroundColor
    或 class.hexBackgroundColor
  19. 多航段行程
  20. 票号或 class.customTicketNumberLabel
  21. object.ticketNumber
  22. 票卡状态
  23. object.ticketStatus 或 object.customTicketStatus
  24. 出发
  25. object.ticketLeg.departureDateTime
  26. 到达时间
  27. object.ticketLeg.arrivalDateTime
  28. FARE NAME 或 class.customFareNameLabel
  29. object.ticketLeg.fareName
  30. PLATFORM 或 class.customPlatformLabel
  31. object.ticketLeg.platform
  32. ZONE 或 class.customZoneLabel
  33. object.ticketLeg.zone
  34. 票价类型或 class.customFareClassLabel
  35. object.ticketLeg.ticketSeat.fareClass
    或 object.ticketLeg.ticketSeat.customFareClass
  36. 优惠类别
    或 class.customConcessionCategoryLabel
  37. object.concessionCategory
    或 object.customConcessionCategory
  38. 路线限制
    或 class.customRouteRestrictionsLabel
  39. object.ticketRestrictions.routeRestrictions
  40. 路线限制详情
    或 class.customRouteRestrictionsDetailsLabel
  41. object.ticketRestrictions.routeRestrictionsDetails
  42. 时间限制
    或 class.customTimeRestrictionsLabel
  43. object.ticketRestrictions.timeRestrictions
  44. 其他限制
    或 class.customOtherRestrictionsLabel
  45. object.ticketRestrictions.otherRestrictions
  46. 收据编号
    或 class.customPurchaseReceiptNumberLabel
  47. object.purchaseDetails.purchaseReceiptNumber
  48. 购买日期
  49. object.purchaseDetails.purchaseDateTime
  50. 账号 ID
  51. object.purchaseDetails.accountId
  52. 确认码
    或 class.customConfirmationCodeLabel
  53. object.purchaseDetails.confirmationCode
  54. FACE VALUE 或 class.customPurchaseFaceValueLabel
  55. object.purchaseDetails.ticketCost.faceValue
  56. 价格或class.customPurchasePriceLabel
  57. object.purchaseDetails.ticketCost.purchasePrice
  58. 折扣消息
    或 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

默认卡券模板布局元素和位置
  1. class.logo
  2. class.localizedIssuerName
    或 class.issuerName
  3. 查看卡片标题
  4. DEPARTURE 或 VALID FROM
  5. object.ticketLeg.departureDateTime(日期和时间)
    或 object.validTimeInterval.start.date
  6. 到达时间或有效期至
  7. object.ticketLeg.arrivalDateTime(仅限时间)
    或 object.validTimeInterval.end.date
  8. 乘客
  9. object.passengerNames
  10. CARRIAGE 或 class.customCarriageLabel
  11. object.ticketLeg.carriage
  12. COACH 或 class.customCoachLabel
  13. object.ticketLeg.ticketSeat.coach
  14. SEAT 或class.customSeatLabel
  15. object.ticketLeg.ticketSeat.seat
    或 object.ticketLeg.ticketSeat.seatAssignment
  16. object.barcode.type 和 object.barcode.value
    或 object.ticketNumber
  17. object.barcode.alternateText
  18. object.hexBackgroundColor
    或 class.hexBackgroundColor
  19. 多航段行程
  20. 票号或 class.customTicketNumberLabel
  21. object.ticketNumber
  22. 票卡状态
  23. object.ticketStatus 或 object.customTicketStatus
  24. 出发
  25. object.ticketLeg.departureDateTime
  26. 到达时间
  27. object.ticketLeg.arrivalDateTime
  28. FARE NAME 或 class.customFareNameLabel
  29. object.ticketLeg.fareName
  30. PLATFORM 或 class.customPlatformLabel
  31. object.ticketLeg.platform
  32. ZONE 或 class.customZoneLabel
  33. object.ticketLeg.zone
  34. 票价类型或 class.customFareClassLabel
  35. object.ticketLeg.ticketSeat.fareClass
    或 object.ticketLeg.ticketSeat.customFareClass
  36. 优惠类别
    或 class.customConcessionCategoryLabel
  37. object.concessionCategory
    或 object.customConcessionCategory
  38. 路线限制
    或 class.customRouteRestrictionsLabel
  39. object.ticketRestrictions.routeRestrictions
  40. 路线限制详情
    或 class.customRouteRestrictionsDetailsLabel
  41. object.ticketRestrictions.routeRestrictionsDetails
  42. 时间限制
    或 class.customTimeRestrictionsLabel
  43. object.ticketRestrictions.timeRestrictions
  44. 其他限制
    或 class.customOtherRestrictionsLabel
  45. object.ticketRestrictions.otherRestrictions
  46. 收据编号
    或 class.customPurchaseReceiptNumberLabel
  47. object.purchaseDetails.purchaseReceiptNumber
  48. 购买日期
  49. object.purchaseDetails.purchaseDateTime
  50. 账号 ID
  51. object.purchaseDetails.accountId
  52. 确认码
    或 class.customConfirmationCodeLabel
  53. object.purchaseDetails.confirmationCode
  54. FACE VALUE 或 class.customPurchaseFaceValueLabel
  55. object.purchaseDetails.ticketCost.faceValue
  56. 价格或class.customPurchasePriceLabel
  57. object.purchaseDetails.ticketCost.purchasePrice
  58. 折扣消息
    或 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

对于图片模块字段,我们会显示类中的一个且仅一个图片模块字段,以及对象中的一个且仅一个图片模块字段。如果您在任一级别需要多个图片模块字段,请替换默认模板。

对于文本模块字段,我们最多只能显示类中的 20 个文本模块字段和对象中的 20 个文本模块字段。这些字段的显示顺序与它们在数组中的定义顺序相同。如果您在任一级别需要 20 个以上的文本模块字段,请替换默认模板。

对于消息,我们最多只会显示来自类的 20 条消息和来自对象的 20 条消息。我们不保证消息的顺序。如果您在任一级别需要 20 条以上的消息,或者需要为任何订单提供保证,请替换默认模板。

对于链接模块字段,您可以定义的 URI 数量没有限制。URI 按以下顺序分组显示,每个级别(类或对象)对应一个分组:

  1. 地图坐标
  2. 电话号码
  3. 电子邮件地址
  4. 网页

对于每个组,URI 的显示顺序与其在数组中的定义顺序相同。 如果您需要不同的排序,请替换默认模板。

默认列表模板布局元素和位置
  1. (object.ticketLeg.originName
      和 object.ticketLeg.destinationName)
    或 (object.ticketLeg.originStationCode
      和 object.ticketLeg.destinationStationCode)
    或 object.ticketLeg.originName
  2. object.ticketLeg.departureDateTime
    或 object.validTimeInterval.end.date
  3. class.logo
  4. object.hexBackgroundColor
    或 class.hexBackgroundColor
  5. <# passes>(分组)