Card Layout | Yext Hitchhikers Platform

What You’ll Learn

In this section, you will learn:

  • How to modify a card layout
  • Common changes to cards

Customizing Card Layout

Because data is inherently different customer to customer, there may be situations where you want to modify the layout and structure of our standard cards. To do this, you’ll need to fork a card, which you learned in the Adding Pages and Cards units , which allows you to override the component.js and template.hbs files.

light bulb
Note
If you change the card layout, make sure to thoroughly test across different window sizes and browsers to ensure it appears as you desire. Browser & device emulators are often helpful for this (we recommend Browserstack ). You’ll also need to keep in mind your modifications any time you update your theme.

Example 1: Adding a Third CTA

There may be cases where you want to feature a third CTA on your card; for example, you might want a ‘View Menu’ CTA in addition to ‘Call’ and ‘Get Directions’ on a Restaurant card.

Third CTA Example

This will require changes to three files:

  • component.js to add an additional CTA to the data mappings
  • template.hbs to indicate in the template to pull from this data
  • answers.scss to apply the same styling to the third CTA as the first and second CTA

component.js

Just like we have objects defining CTA1 and CTA2, we’ll add a third object, CTA3, with the same attributes.

CTA1: { // The primary call to action for the card
  iconName: 'phone', // The icon to use for the CTA
  label: 'Call', // The label of the CTA
  url: Formatter.phoneLink(profile), // The URL a user will be directed to when clicking
  target: '_top', // If the URL will be opened in a new tab, etc.
  eventType: 'TAP_TO_CALL', // Type of Analytics event fired when clicking the CTA
  eventOptions: this.addDefaultEventOptions(), // The analytics event options for CTA clicks
},
CTA2: { // The secondary call to action for the card
  label: 'Get Directions',
  iconName: 'directions',
  url: Formatter.getDirectionsUrl(profile),
  target: '_top',
  eventType: 'DRIVING_DIRECTIONS',
  eventOptions: this.addDefaultEventOptions(),
},
CTA3: { // The tertiary call to action for the card
  label: 'View Menu',
  iconName: 'info',
  url: profile.menuUrl ? profile.menuUrl.url : null,
  target: '_top',
  eventType: 'CTA_CLICK',
  eventOptions: this.addDefaultEventOptions(),
}

template.hbs

Next, you’ll add the third card CTA where the other two CTAs are referenced. By adding {{> CTA card.CTA3 ctaName="tertiaryCTA" }} in the CTAs partial, you’re indicating that a third cta be added after the primaryCTA and secondaryCTA are added, and that it should pull from the data found in card.CTA3 (which you defined in your component.js file!).

You also will need to check if the data exists in the CTA3 field before trying to place the CTA on the page - you can do this by adding (all card.CTA3 card.CTA3.url) to the if statement.

{{#*inline 'ctas'}}
{{#if (any (all card.CTA1 card.CTA1.url) (all card.CTA2 card.CTA2.url) (all card.CTA3 card.CTA3.url))}}
<div class="HitchhikerLocationStandard-ctasWrapper">
  {{> CTA card.CTA1 ctaName="primaryCTA" }}
  {{> CTA card.CTA2 ctaName="secondaryCTA" }}
  {{> CTA card.CTA3 ctaName="tertiaryCTA" }}
</div>
{{/if}}
{{/inline}}

answers.scss

Lastly, you want to make sure that the styling is consistent. The following CSS copies the styling from .HitchhikerLocationStandard-primaryCTA and .HitchhikerLocationStandard-secondaryCTA and adds .HitchhikerLocationStandard-tertiaryCTA so that those style rules apply. This may change based on the card you fork from, so always inspect the styling in order to determine the style rules you should copy.

.HitchhikerLocationStandard-primaryCTA, .HitchhikerLocationStandard-secondaryCTA, .HitchhikerLocationStandard-tertiaryCTA {
  display: flex;
  margin-top: calc(var(--hh-location-standard-base-spacing) / 2);
}

Example 2: Adding a Secondary Bulleted List

Here’s an example of adding a second list to a card. We’ll walk through adding a “Nutritional Claims” list by forking the menuitem-standard card, and moving the lists to display underneath the menu item description. Menu Lists Example

component.js

First, we’ll copy the way that we map the data for the existing list, and add listTitle2 and listItems2 to our data mappings so the field data is accessible to our template.

  listTitle2: 'Nutritional Claims',
  listItems2: profile.c_nutritionalClaims,

template.hbs

Next, we’ll update the template to accomodate this new data.

Defining the List Partial

First, we’ll copy the existing list partial, and modify it for our new list through the following actions.

  • Update the name of the partial to ‘list2’
  • Update the card. references to point to card.listTitle2 and card.listItems2
  • Add a class ‘nutritionalClaims’ in case we want to add specific styling to this list later on.

    {{#*inline 'list2'}}
    {{#if (any card.listTitle2 card.listItems2)}}
    <div class="HitchhikerMenuItemStandard-listWrapper nutritionalClaims">
    {{#if card.listTitle2}}
    <div class="HitchhikerMenuItemStandard-listTitle">
    {{card.listTitle2}}
    </div>
    <ul class="HitchhikerMenuItemStandard-listItems">
    {{#each card.listItems2}}
    <li class="HitchhikerMenuItemStandard-item">
      {{this}}
    </li>
    {{/each}}
    </ul>
    {{/if}}
    </div>
    {{/if}}
    {{/inline}}
Referencing the new Partial

Afterwards, we’ll reference the partial {{> list2 }} in order to display this on the card. In order to style the lists separately, we’re containing these two lists in a div with a class of HitchhikerMenuItemStandard-lists. We also can move the {{> details }} partial above our new Lists container so it displays above the lists.

<div class="HitchhikerMenuItemStandard {{cardName}}">
  {{> image }}
  <div class="HitchhikerMenuItemStandard-body">
    {{> title }}
    {{> subtitle }}
    <div class="HitchhikerMenuItemStandard-contentWrapper">
      <div class="HitchhikerMenuItemStandard-content">
          {{> details }}
        <div class="HitchhikerMenuItemStandard-lists">
          {{> list }}
          {{> list2 }}
        </div>
      </div>
      {{#if (any (all card.CTA1 card.CTA1.url) (all card.CTA2 card.CTA2.url))}}
      <div class="HitchhikerMenuItemStandard-ctasWrapper">
        {{#with card.CTA1}}
        {{> CTA ctaName="primaryCTA" }}
        {{/with}}
        {{#with card.CTA2}}
        {{> CTA ctaName="secondaryCTA" }}
        {{/with}}
      </div>
      {{/if}}
    </div>
  </div>
</div>

answers.scss

The below CSS accomplishes a few things:

  • Adds styling for .HitchhikerMenuItemStandard-detailsText to add some space below the details and above the lists
  • Adds styling for .HitchhikerMenuItemStandard-lists to display the two lists next to eachother on larger breakpoints, and stacked on top of eachother for smaller breakpoints (under 768px)
  • Adds a margin to .HitchhikerMenuItemStandard-listWrapper to space out the two lists
  • Adds styling to the list in .nutritionalClaims to change the bullets to square instead of disc.

    .HitchhikerMenuItemStandard-detailsText {
    margin-bottom: 1rem;
    } 
    
    .HitchhikerMenuItemStandard-lists {
    display: flex;
    }
    
    @media only screen and (max-width: 768px) {
    .HitchhikerMenuItemStandard-lists {
    display: block;
    }
    }
    
    .HitchhikerMenuItemStandard-listWrapper {
    margin-right: 2em;
    }
    
    .nutritionalClaims ul {
    list-style-type: square;
    }

Example 3: Adding an Icon next to the Distance Label

You can also add any HTML you want to the card itself, without updating the data mappings. One example might be adding a pin icon next to the distance listed on a location card.

Location Pins

template.hbs

To add the pin, we’ll add in an SVG to the template, containing it in a div with a class of HitchhikerLocationStandard-distanceIcon so we can apply styling later.

{{#*inline 'distance'}}
{{#if card.distance}}
<div class="HitchhikerLocationStandard-distance">
  <div class="HitchhikerLocationStandard-distanceIcon">
    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 14 20"><path d="M7 0C3.13 0 0 3.13 0 7c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5C5.62 9.5 4.5 8.38 4.5 7S5.62 4.5 7 4.5 9.5 5.62 9.5 7 8.38 9.5 7 9.5z"></path></svg>
  </div>
  {{card.distance}}
</div>
{{/if}}
{{/inline}}

answers.scss

Below, we’ll add some styling to ensure the location label and the pin display the in the same line, and add specific styling to the icon itself to make sure it displays as we want it to.

.HitchhikerLocationStandard-distance {
  display: flex;
}

.HitchhikerLocationStandard-distanceIcon {
  height: 1em;
  width: 1em;
  margin-top: .1rem;
  fill: var(--yxt-color-brand-primary);
  margin-right: .25rem;
}
unit Quiz
+20 points
Daily Quiz Streak Daily Quiz Streak: 0
Quiz Accuracy Streak Quiz Accuracy Streak: 0
    Error Success Question 1 of 3

    What files would you need to change if you'd like to add a third CTA using data from the Knowledge Graph to a card?

    Error Success Question 2 of 3

    True or False: You must fork a card in order to change the layout.

    Error Success Question 3 of 3

    Select the examples where you would edit a card's template.hbs file.

    Climbing that leaderboard! 📈

    You've already completed this quiz, so you can't earn more points.You completed this quiz in 1 attempt and earned 0 points! Feel free to review your answers and move on when you're ready.
1st attempt
0 incorrect
Feedback