Шаблон транзитного пропуска

Проездные билеты поддерживают отрисовку шаблонов. Если шаблон не определен, используется шаблон по умолчанию.

Определение шаблона

Шаблон прохода определяется на уровне класса и используется для отображения любых объектов, связанных с этим классом. Шаблон определяет, какие поля следует отображать в различных разделах прохода.

Шаблон разделён на следующие разделы:

Android

Обзор разделов и позиций шаблона пропуска.

Веб

Обзор разделов и позиций шаблона пропуска.

Название карты

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

Веб

Элементы оформления заголовка карточки и расположение полей Название карты по умолчанию
  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 заголовок шаблона по умолчанию, содержащий логотип и название издателя, заменяется широким логотипом.

При создании широкого логотипа в заголовке следуйте рекомендациям по отображению изображений , чтобы оптимально показывать ваше изображение на ваших пропусках.

Шаблон открытки

Android

Элементы макета строк шаблона карточки и расположение полей

Веб

Элементы макета строк шаблона карточки и расположение полей

Раздел шаблонов карточек используется для отображения дополнительных строк. Эти строки могут содержать текстовые поля структурированных данных или текстовые поля модулей.

Вы можете указать количество строк, определяющих количество объектов в списке 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);
    

Данный код создает проход с использованием следующего формата раздела шаблона кода:

Пример переопределения метки.

Если элемент пуст, он не отображается. Дополнительные сведения см. в разделе «Ссылки на поля» . Если все элементы в строке пусты, строка не отображается. Если некоторые, но не все элементы в строке пусты, непустые элементы перегруппировываются и отображаются в строке с меньшим количеством элементов.

Если вы не переопределите шаблон карточки, будут использоваться значения по умолчанию: количество строк, количество элементов и ссылки на поля. Дополнительные сведения см. в разделе «Шаблон по умолчанию» .

После определения изображения-заставки (Hero Image ) оно может отображаться после первой строки, если в списке 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

Веб

Элементы и расположение штрихкода на карте
  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
  • ...

Веб

Подробные сведения о шаблоне, нижние разделы и элементы.
  • Многоэтапный маршрут
  • 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
    или НЕТ КОНКРЕТНОГО МЕСТА
  9. object.hexBackgroundColor
    или class.hexBackgroundColor
  10. object.ticketLegs[i].destinationName
    или object.ticketLegs[i].destinationStationCode
  11. object.ticketLegs[i].arrivalDateTime (только время)
  12. ПЕРЕНОС НА: ПЛАТФОРМУ
    или ПЕРЕНЕСТИ В: class.customPlatformLabel
    или ПЕРЕДАЧА (если платформа не определена)
  13. object.ticketLegs[i+1].platform

Шаблон списка

Элементы шаблона списка
  1. class.classTemplateInfo.listTemplateOverride
    .firstRowOption.fieldOption.fields[]
  2. object.ticketLeg.departureDateTime (grouped)
    или class.classTemplateInfo.listTemplateOverride
    .secondRowOption.fields[]
  3. class.logo
  4. object.hexBackgroundColor
    или class.hexBackgroundColor
  5. <# проходов> (группированные)

Раздел шаблона списка используется для выбора поля, которое будет отображаться в разделе «Пропуска» приложения Google Wallet. Пропуск отображается в списке с логотипом, цветом фона и тремя строками.

В следующем примере кода показано, как переопределить шаблон списка для пропуска, чтобы отобразить поле с датой истечения срока действия отдельного объекта пропуска в первой строке шаблона списка:

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[] . Ссылка на поле содержит список путей к полям структурированных данных, полям текстового модуля, полям модуля ссылок, полям модуля изображений или сообщениям.

Не все типы путей разрешены во всех ссылках на поля. Например, некоторые ссылки на поля допускают пути только к текстовым структурированным полям данных или текстовым полям модулей. Текстовые структурированные поля — это структурированные поля данных типа «строка», «локализованная строка», «дата» или «деньги».

Список можно использовать для реализации резервной логики. Это означает, что если первый путь в списке приводит к пустому полю, оценивается следующий путь. Резервная логика в основном предназначена для текстовых структурированных полей данных или полей текстовых модулей. Не смешивайте поля разных типов в одном списке. Используйте резервную логику с осторожностью и только в определенных ситуациях, когда вы ожидаете согласованного шаблона полей, которые существуют в одних объектах, но отсутствуют в других. В большинстве случаев проще создать отдельные классы для разных вариантов использования.

Если все пути в списке ссылок на поля указывают на пустые поля, элемент, использующий ссылку на поле, не отображается. Если вы хотите, чтобы элемент, использующий ссылку на поле, всегда присутствовал, убедитесь, что хотя бы один путь не пуст. Мы рекомендуем присваивать полю специальный символ, например, '-', для обозначения нулевого значения, даже если некоторые поля допускают строки только с пробелом.

Для ссылки на поле, содержащееся в списке, можно использовать индекс поля в списке или, в большинстве случаев, идентификатор ссылки. Элементы списка, на которые можно ссылаться по 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. ОТПРАВЛЕНИЕ или ДЕЙСТВИТЕЛЬНО С
  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. Название тарифа или class.customFareNameLabel
  29. object.ticketLeg.fareName
  30. ПЛАТФОРМА или 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. ИДЕНТИФИКАТОР УЧЕТНОЙ ЗАПИСИ
  51. object.purchaseDetails.accountId
  52. КОД ПОДТВЕРЖДЕНИЯ
    или class.customConfirmationCodeLabel
  53. object.purchaseDetails.confirmationCode
  54. НОМИНАЛЬНАЯ СТОИМОСТЬ или 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

Веб

Элементы и позиции макета шаблона прохода по умолчанию
  1. class.logo
  2. class.localizedIssuerName
    или class.issuerName
  3. См. название карточки.
  4. ОТПРАВЛЕНИЕ или ДЕЙСТВИТЕЛЬНО С
  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. Название тарифа или class.customFareNameLabel
  29. object.ticketLeg.fareName
  30. ПЛАТФОРМА или 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. ИДЕНТИФИКАТОР УЧЕТНОЙ ЗАПИСИ
  51. object.purchaseDetails.accountId
  52. КОД ПОДТВЕРЖДЕНИЯ
    или class.customConfirmationCodeLabel
  53. object.purchaseDetails.confirmationCode
  54. НОМИНАЛЬНАЯ СТОИМОСТЬ или 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. <# проходов> (группированные)