loading

Defining New Cards| Hitchhikers Platform

What You’ll Learn

In this section, you will learn:

  • How to fork and create your own card
  • How to leverage formatters to make data mapping easy

Forking a Card

You learned how to add a new card in the Adding Cards unit in Core Frontend - Global Settings, Pages & Cards.

After you follow the steps to add a new card, you’ll see two new files added to your repo in your cards directory - cards/[cardname]/component.js and cards/[cardname]/template.hbs. Look familiar? These are the same two files that define the theme’s built-in cards, except this time, you get to modify these files! We’ll be working primarily with JavaScript and Handlebars templates - the Introduction to Javascript will be good background to understand how data mappings work in this module, and Introduction to Handlebars will give you the context for updating the card structure in later, advanced modules.

For example, let’s say that we wanted to create a card for a “Press Release” vertical. The Standard card is very close, but we want to be able to add an ‘Author’ field as the subtitle of the card.

You would first add a new card using Jambo Commands, using Standard as the template, and name it pressrelease.

Then, you would navigate to cards > pressrelease > component.js.

The only thing in the file you would need to change is the line containing the ‘subtitle’.

dataForRender(profile) {
  ...
  return {
    ...
    subtitle: profile.c_author, // The sub-header text of the card
    ...
  }
}

How to Define Data Mappings

At a high level, the dataForRender function accepts an object parameter profile, which is all the data associated with an individual entity. For each of the card sections (ex. ‘title’, ‘subtitle’, and ‘details’), we are defining the data from the profile object to pass the right information from an Entity profile to the card.

In a statement like the above - subtitle: profile.c_author, we are setting the value of the subtitle property to the contents of the c_author field on an entity profile.

So, what does this actually mean for you? A few things:

  • Because we’re defining an object, you’ll have to ensure there is a comma separating every property. In our previous example, we have a comma after the subtitle.
  • To define the content, you’ll just need to refer to the right property of the profile. Typically, this will be as simple as profile.[api name of field].
  • If you want to access the subfield of an entity field that is a struct, you can access that subfield by appending it to the end, separated by a period - profile.[api name of field].[subfield api name]

Null Checking

We briefly talked about the importance of nullchecking in Introduction to Javascript. We don’t want our data mappings to fail if a field is empty. Instead, we’ll check if the field has content (or if it’s empty, aka null) before doing any actions with that field. Constructing a null check is simple - just follow this pattern: condition ? action if true : action if false

To check if a field has data, you simply refer to the field itself. If it has data, it will return ‘true’; if it doesn’t, it will return false.

For example, if I wanted to default the details on my Locations card if the description field isn’t filled out, I could construct the details like so:

details: profile.description ? profile.description : "This is my fallback description for my locations.",

You’ll see this pattern frequently in the built-in cards, so you’ll be able to easily repurpose in your custom cards to pull the fields you’d like.

light bulb
Tip

Generally, our mappings will handle nullchecking if you’re mapping a singular field (ex. subtitle: profile.c_author). You’ll usually need to use nullchecking if you’re using a function to transform the data or if you’re constructing a string.

For example, if I wanted the subtitle to have ‘Author: ‘ hardcoded before the author, I’d first want to check if the author field is populated. I’d construct my data mapping like below:

subtitle: profile.c_author ? 'Author: ' + profile.c_author : null

Common Formatters

You might be wondering - what if I want to add more complex formatting to a field? Good news! We have a bunch of functions, referred to as formatters, that will make this much easier for you. You can see the whole list of Formatter functions available to you in the theme. Navigate to themes > answers-hitchhiker-theme > static > js > formatters.js, and you’ll see the functions at your disposal.

To use a formatter in your data mappings, you’ll just need to add Formatter. to the beginning of the function name.

We’ll walk through the most commonly used formatters here.

This will return the mailto link for the first email in the Emails profile field.

Example Use Case

url: Formatter.emailLink(profile)

getDirectionsUrl(profile)

We can use this formatter to construct a Get Directions URL to Google Maps based on the address field on an entity.

Example Use Case

url: Formatter.getDirectionsUrl(profile)

joinList(list, separator)

This is an incredibly helpful formatter that will return a list field on an entity with whatever separator you indicate. For example, on a Jobs card, you could add a subtitle with a comma-separated list for text list field called Positions Available (Part Time, Full Time), and a description with a - separated list of the locations a job is available at (text list field called Locations Available).

If there is no separator defined, it will default to ,.

Example Use Case

subtitle: Formatter.joinList(profile.c_positionsAvailable),
details: Formatter.joinList(profile.c_locationsAvailable, "-"),

Note: if you are mapping a list field to a section on the card that already accepts a list (ex. Services), you don’t need to use this formatter.

image(profile.field)

The image formatter handles some important behavior for images that help it render appropriately on the card at the right size. It returns an object with a url and alternateText, so you’ll want to specify the URL field when you map this to the image on a template.

To use the image formatter, you’ll use null-checking. Here, we’re checking to see if the Job Photo field is filled out for a Job entity - if it is, we’ll use our formatter and grab the URL returned. Otherwise, we won’t show an image.

image: profile.c_jobPhoto ? Formatter.image(profile.c_jobPhoto).url : null,

This formatter is essential if you are using a field of type Call To Action.

Because you are able to add different types of links via this field (ex. mailto: for email, tel: for phone, as well as regular URLs), we need a formatter to be able to correctly construct the link for all these use cases.

You’ll see this in the standard card mappings for the links of CTAs.

url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA),
unit Quiz
+20 points
Daily Quiz Streak Daily Quiz Streak: 0
Quiz Accuracy Streak Quiz Accuracy Streak: 0
    Error Success Question 1 of 3

    For a custom field called Department, what is the correct way to map this to the subtitle of the card?

    Error Success Question 2 of 3

    How do you determine how you reference a field from entity profile?

    Error Success Question 3 of 3

    What formatter would you use to add a list of Allergens to the details section of your card?

    You're a star! ⭐️

    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
Splash Loading