Multilanguage Mod 2 Final Assessment

Hi Team, I keep getting one section wrong in Multi-language Mod 2…Update the config/restaurants.json file to use the new multilang-restaurant custom card
Add translation override for Features in the multilang-restaurant card

Here is my code for the restaurants.json
{
“verticalKey”: “restaurants”, // The vertical key from your search configuration
“pageTitle”: “Restaurant Search”, // !!!REPLACE THIS VALUE!!! The contents of the title tag and meta open graph tag for title
// “metaDescription”: “”, // The meta tag for open graph description
// “canonicalUrl”: “”, // The link tag for canonical URL as well as the meta tag for open graph url
// “keywords”: “”, // The meta tag for keywords
“pageSettings”: {
/**
“search”: {
“verticalKey”: “restaurants”, // The vertical key from your search configuration
“defaultInitialSearch”: “” // Enter a default search term
}
/
},
“componentSettings”: {
/

“QASubmission”: {
“entityId”: “”, // Set the ID of the entity to use for Q&A submissions, must be of entity type “Organization”
“privacyPolicyUrl”: “” // The fully qualified URL to the privacy policy
},
**/
“Facets”: {
“title”: “”, // The title to display above the facets
“expand”: false, // Allow the user to expand and collapse the facets
“showMore”: true, // Display a link to see more facet options within a facet
“searchOnChange”: true, // Will automatically run a search as facets are selected or unselected. Set to false to only trigger updates with an Apply button.
“showMoreLimit”: 3,
“fields”: {
“c_restaurantFeatures”: {
“searchable”: true,
“searchLabelText”: “Search for our features”,
“placeholderText”: “Search”
}
}
// Additional options are available in the documentation
},
“FilterLink”: {
“changeFiltersText”: “filters”, // Text that displays by default
“resetFiltersText”: “reset filters”, // Text when filters are applied
“clearSearchText”: “clear search” // Text when there are no results, conducts an empty search
},
“AppliedFilters”: {
“removable”: true
},
“VerticalResults”: {
“noResults”: {
“displayAllResults”: true // Optional, whether to display all results in the vertical when no results are found.
},
“hideResultsHeader”: true
},
“SearchBar”: {
“placeholderText”: “Search”, // The placeholder text in the answers search bar
“allowEmptySearch”: true // Allows users to submit an empty search in the searchbar
},
“Pagination”: {
“noResults”: {
“visible”: true
}
}
},
// Configuration used to define the look and feel of the vertical, both on this page and, by default,
// on the universal page.
“verticalsToConfig”: {
“restaurants”: { // The vertical key from your search configuration
// “label”: “”, // The name of the vertical in the section header and the navigation bar
// “verticalLimit”: 15, // The result count limit for vertical search
// “universalLimit”: 5, // The result count limit for universal search
“cardType”: “multilang-restaurant”, // The name of the card to use - e.g. accordion, location, customcard
“icon”: “pin”, // The icon to use on the card for this vertical
“mapConfig”: {
“enablePinClustering”: true, // Cluster pins on the map that are close together. Defaults false
“mapProvider”: “MapBox”, // The name of the provider (e.g. Mapbox, Google)
“noResults”: {
“displayAllResults”: false // Set to FALSE to hide results on the map when a search returns no results
},
“pin”: {
“default”: { // The pin in its normal state
“backgroundColor”: “#009347”, // Enter a hex value or color for the pin background
“strokeColor”: “#2a446b”,
“labelColor”: “white”
},
“hovered”: { // The pin when it is hovered
“backgroundColor”: “#efefd4”,
“strokeColor”: “#172638”,
}
“labelColor”: “white”
},
“selected”: { // The pin when it is selected by mouse click or through a card click
“backgroundColor”: “#2f4d71”,
“strokeColor”: “#172638”,
“labelColor”: “white”
}
}
},
“universalSectionTemplate”: “standard”
}
}

and then this is my code for the multi-lanaguage template.json

{! Some partials here use the result.ordinal parameter, a reserved value automatically provided to
any card template. This value contains the ordinal of the card.
}}

{{> image }}
{{#if (any card.title card.distance)}}
{{> ordinalAndTitle displayOrdinal=(all card.showOrdinal result.ordinal) }}
{{> closeCardButton }} {{> distance }}
{{/if}} {{#if card.subtitle}}
{{card.subtitle}}
{{/if}}
{{> contactInfo }} {{> details }}
{{> ctas }}
{{#*inline 'address'}} {{#if card.address}}
{{{card.address}}}
{{/if}} {{/inline}} {{#*inline 'phone'}} {{#if card.phone}}
{{card.phone}}
{{card.phone}}
{{/if}} {{/inline}} {{#*inline 'image'}} {{#if card.image}}
{{#if card.altText}}{{card.altText}}{{/if}}
{{/if}} {{/inline}} {{#*inline 'distance'}} {{#if card.distance}}
{{card.distance}}
{{/if}} {{/inline}} {{#*inline 'ctas'}} {{#if (any (all card.CTA1 card.CTA1.url) (all card.CTA2 card.CTA2.url))}}
{{> CTA card.CTA1 ctaName="primaryCTA" }} {{> CTA card.CTA2 ctaName="secondaryCTA" }}
{{/if}} {{/inline}} {{#*inline 'CTA'}} {{#if (all url label)}}
{{#if (any iconName iconUrl)}}
{{> icons/iconPartial iconName=iconName iconUrl=(relativePathHandler url=iconUrl relativePath=@root.relativePath) }}
{{/if}}
{{label}}
{{/if}} {{/inline}} {{#* inline "ordinalAndTitle"}} {{#if (any displayOrdinal card.title)}}
{{#if displayOrdinal}}
{{result.ordinal}}
{{/if}} {{> title }}
{{/if}} {{/inline}} {{#* inline "contactInfo"}}
{{#if (any card.phone card.address)}}
{{> address }} {{> phone }}
{{/if}} {{#if (any card.hours card.services)}}
{{#if card.hours}}
{{{card.hours}}}
{{/if}} {{#if card.services}}
{{ translate phrase='Features:' }} {{#each card.services~}}{{this}}{{#unless @last}}, {{/unless}}{{~/each}}
{{/if}}
{{/if}}
{{/inline}} {{#* inline "title"}} {{#if card.title}}
{{#if card.url}} {{{card.title}}} {{else}} {{{card.title}}} {{/if}}
{{/if}} {{/inline}} {{! Displays the details for the card. If showMoreDetails has been configured, this partial handles the show more toggle, show less toggle, truncated details, and full details. If showMoreDetails has not been configured, it will display the the regular card details. }} {{#*inline 'details'}} {{#if card.details}}
{{#if showExcessDetailsToggle}}
{{truncatedDetails}}
{{/if}}
{{card.details}}
{{#if showExcessDetailsToggle}} {{card.showMoreDetails.showMoreText}} {{> icons/builtInIcon iconName='chevron' classNames='Icon--sm Icon--collapseDown' }} {{card.showMoreDetails.showLessText}} {{> icons/builtInIcon iconName='chevron' classNames='Icon--sm Icon--collapseUp' }} {{/if}}
{{/if}} {{/inline}} {{#*inline 'closeCardButton'}} {{ close-card-svg }} {{translate phrase='Close Card' context='Close is a verb'}} {{/inline}}

AND component.json

{{> cards/card_component componentName=‘multilang-restaurant’ }}
class multilang_restaurantCardComponent extends BaseCard[‘multilang-restaurant’] {
constructor(config = {}, systemConfig = {}) {
super(config, systemConfig);
}
onMount() {
const onVerticalFullPageMap = !!document.querySelector(‘.js-answersVerticalFullPageMap’);
onVerticalFullPageMap && registerVerticalFullPageMapCardListeners(this);
super.onMount();
}
/**

  • This returns an object that will be called card
  • in the template. Put all mapping logic here.
  • @param {Object} profile of the entity in the card
    /
    dataForRender(profile) {
    const linkTarget = AnswersExperience.runtimeConfig.get(‘linkTarget’) || ‘_top’;
    return {
    title: profile.name, // The header text of the card
    url: profile.website || profile.landingPageUrl, // If the card title is a clickable link, set URL here
    target: linkTarget, // If the title’s URL should open in a new tab, etc.
    titleEventOptions: this.addDefaultEventOptions(), // The event options for title click analytics
    // subtitle: ‘’, // The sub-header text of the card
    hours: Formatter.openStatus(profile),
    services: profile.c_restaurantFeatures, // Used for a comma delimited list of services for the location
    address: Formatter.address(profile), // The address for the card
    phone: Formatter.nationalizedPhoneDisplay(profile), // The phone number for the card
    phoneEventOptions: this.addDefaultEventOptions(), // The analytics event options for phone clicks
    distance: Formatter.toLocalizedDistance(profile), // Distance from the user’s or inputted location
    // details: profile.description, // The description for the card, displays below the address and phone
    // altText: ‘’, // The alt-text of the displayed image
    // image: ‘’, // The URL of the image to display on the card
    showOrdinal: true, // Show the map pin number on the card. Only supported for universal search
    CTA1: { // The primary call to action for the card
    label: {{ translateJS phrase=‘Call’ context=‘Call is a verb’ }}, // The label of the CTA
    iconName: ‘phone’, // The icon to use for the CTA
    url: Formatter.phoneLink(profile), // The URL a user will be directed to when clicking
    target: linkTarget, // 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
    // ariaLabel: ‘’, // Accessible text providing a descriptive label for the CTA
    },
    CTA2: { // The secondary call to action for the card
    label: {{ translateJS phrase=‘Get Directions’ }},
    iconName: ‘directions’,
    url: Formatter.getDirectionsUrl(profile),
    target: linkTarget,
    eventType: ‘DRIVING_DIRECTIONS’,
    eventOptions: this.addDefaultEventOptions(),
    // ariaLabel: ‘’,
    }
    };
    }
    /
    *
  • The template to render
  • @returns {string}
  • @override
    */
    static defaultTemplateName (config) {
    return ‘cards/multilang-restaurant’;
    }
    }
    ANSWERS.registerTemplate(
    ‘cards/multilang-restaurant’,
    {{{stringifyPartial (read ‘cards/multilang-restaurant/template’) }}}
    );
    ANSWERS.registerComponentType(multilang_restaurantCardComponent);

Hey Claire,

This was a tricky one! You actually do pass the rule on updating the config/restaurants.json rile to use the new multilang-restaurant custom card. However, there is an extra bracket in this file that is throwing an error, so the code editor can’t actually read it!

In the screenshot below, you can see there is an extra closing bracket on line 85. The labelColor property is underlined in red because it can’t come immediately after }. When you delete the } on line 85, you’ll notice the last } on line 97 will have a red underline because the number of }'s doesn’t line up with the number of {'s. Add one on line 98. (Looks like somehow the } on line 98 was moved to line 85.)

Yay that worked! Thank you so much!!