Each help center theme consists of a collection of editable page templates and custom pages. You can use the help center templating language, Curlybars, to access help center data and manipulate the content in your pages.
This article provides a list of recipes with code snippets you can use. Keep in mind that, some of the functionality in these recipes might already be in your help center, depending on whether you are using a standard theme or a customized theme and the date you enabled your help center.
Trial users are given the Professional plan, which includes code editing options, but they will no longer be able to access that feature if they purchase Suite Team.
- About the Curlybars templating language
- Customize page templates for specific categories, sections, or articles
- Customize the language names in the language selector
- Hide one or more languages in the language selector
- Let users sort article comments by date or votes
- Add a formatting toolbar to the article comment editor
- Enable users to vote on article comments
- Add Instant Search (autocomplete) results to your help center
- Add Federated Search to include external content in help center search
- Add sorting for subscription types in the My Activities Following page
- Add sorting options “created at” and “updated at” for requests in My Activities
- Add Follow/Unfollow for users in a shared organization
- Add ability for users to CC other users on support requests
- Add a link on follow-up requests to the parent request
- Enable CSAT for solved tickets on the Customer Portal
- Add voting buttons to articles
- Add content tags to articles and posts
- Add badges to your custom help center theme
- Enable users to view user profiles to your help center
- Enable subsections in your help center theme
- Add sidebar filters and results for multiple help centers to the search results page
About the Curlybars templating language
Your help center is built on a theming framework that includes its own templating language for advanced customizations. Each help center theme consists of a collection of editable templates and optional custom pages.
Editable page templates define the layout of each
page. For example, there's a template for knowledge base articles, a template for the list
of requests, and so on. A template is simply a text file to be rendered into an HTML page
when a user wants to see it. Each template consists of a mix of HTML markup and expressions
identifiable by double curly brackets such as {{post.title}}
.
Custom pages are built into the code base of your help center theme and have a specific URL that you can link from anywhere in your help center. You can use custom pages to create and code pages from scratch that meet your individual requirements. For example, you can use custom pages to create special landing pages for your help center or even create new pages to embed content from sources outside of Zendesk.
The templating language is named Curlybars and implements a large subset of the Handlebars language. But unlike Handlebars which renders on the client-side, Curlybars renders on the server-side.
You can use the help center templating language to access help center data and manipulate the content in your pages. In the following example, help center renders a list of names and avatars of all the people who left comments on the page:
{{#each comments}}
<li>
<div class="comment-avatar">
<img src="{{author.avatar_url}}" alt="Avatar" />
</div>
<div class="comment-author">
{{author.name}}
</div>
</li>
{{/each}}
Previously you could use components to customize help center, but you could not customize the components themselves, except for manipulating them with Javascript. With Curlybars you can get access to the HTML that was previously hidden inside component and edit it.
Customize page templates for specific categories, sections, or articles
You can customize the Category, Section, and Article templates for specific categories, sections, and articles respectively.
- Category
- Section
- Article
- Specify the category, section, or article id in a
is
block:{{#is id 200646205}} ... {{/is}}
Example
Inserting the following block in the Section template customizes the template for sections 200646205 and 203133596:
{{#is section.id 200646205}}
<p><strong>This is important security information! Pay attention!</strong></p>
{{/is}}
{{#is section.id 203133596}}
<p>Videos available at <a href="https://www.somelink.com">Learning to fly</a></p>
{{/is}}
Reference
Customize the language names in the language selector
You can customize the language names in the language selector on every page of help center. This is useful if you want to use one language variant, such as "English (U.S.)", for all the language's variants, such as "English".
- Header
{{#if alternative_locales}}...{{/if}}
- Replace the
{{current_locale.name}}
expression with the following conditional expression:{{#is current_locale.name 'English (US)'}} English {{else}} {{current_locale.name}} {{/is}}
Also replace the alternative locale
{{name}}
expression with the following conditional expression:{{#is name 'English (US)'}} English {{else}} {{name}} {{/is}}
Example
{{#if alternative_locales}}
<div class="dropdown language-selector" aria-haspopup="true">
<a class="dropdown-toggle">
{{#is current_locale.name 'English (US)'}}
English
{{else}}
{{current_locale.name}}
{{/is}}
</a>
<span class="dropdown-menu dropdown-menu-end" role="menu">
{{#each alternative_locales}}
<a href="{{url}}" dir="{{direction}}" rel="nofollow" role="menuitem">
{{#is name 'English (US)'}}
English
{{else}}
{{name}}
{{/is}}
</a>
{{/each}}
</span>
</div>
{{/if}}
Reference
Hide one or more languages in the language selector
Hiding a language in the language selector can be useful if the content in that language isn't ready for release.
- Header
{{#each alternative_locales}}...{{/each}}
- Replace the
<a href="{{url}}" dir="{{direction}}" rel="nofollow" role="menuitem"> {{name}} </a>
expression with the following conditional expression:{{#is name 'Français'}} {{! do nothing }} {{else}} <a href="{{url}}" dir="{{direction}}" rel="nofollow" role="menuitem"> {{name}} </a> {{/is}}
Example
{{#each alternative_locales}}
{{#is name 'Français'}}
{{! do nothing }}
{{else}}
<a href="{{url}}" dir="{{direction}}" rel="nofollow" role="menuitem">
{{name}}
</a>
{{/is}}
{{/each}}
Reference
Let users sort article comments by date or votes
By default, article comments are sorted by date from the most recent to the least. You can add Date and Votes links that users can click to sort the comments by date or by the number of votes.
- Article
<section class="article-comments">...</section>
- Insert the following div tag after the comment section's heading tag,
<h2>{{t 'comments'}}</h2>
, preferably after the{{#if comments}}
expression, if any, to ensure the sorters don't appear if nobody left comments yet:<div class="comment-sorter"> Sort by: {{#each comment_sorters}} <a aria-selected="{{selected}}" href="{{url}}">{{name}}</a> {{/each}} </div>
Example
<section class="article-comments">
<h2>{{t 'comments'}}</h2>
{{#if comments}}
<div class="comment-sorter">
Sort by:
{{#each comment_sorters}}
<a aria-selected="{{selected}}" href="{{url}}">{{name}}</a>
{{/each}}
</div>
<ul class="comment-list">
{{#each comments}}
...
Reference
Add a formatting toolbar to the article comment editor
You can add a formatting toolbar to the editor for article comments. Users can add bold and italics, unordered or ordered lists, images, and links.
- Article
{{#form 'comment'}}...{{/form}}
- Find and replace the
{{textarea 'body'}}
expression in the form object with{{wysiwyg 'body'}}
Example
{{#form 'comment' class='comment-form'}}
<div class="comment-avatar">
{{user_avatar class='user-avatar'}}
</div>
<div class="comment-container">
{{wysiwyg 'body'}}
<div class="comment-form-controls">
{{input type='submit'}}
</div>
</div>
{{/form}}
Reference
Enable users to vote on article comments
By default, users can vote on articles. You can also let them vote on article comments.
- Article
{{#each comments}}...{{/each}}
- Insert the following div tag after the
<li id="{{anchor}}">
tag:<div class="comment-vote vote"> {{vote 'up' class="article-vote-up" selected_class="vote-voted"}} {{vote 'sum' class="article-vote-sum"}} {{vote 'down' class="article-vote-down" selected_class="vote-voted"}} </div>
The vote helpers above borrow the CSS classes for articles votes to style the comment vote links. You can define your own classes to style the comment votes.
Example
{{#each comments}}
<li id="{{anchor}}" class="comment">
<div class="comment-vote vote">
{{vote 'up' class="article-vote-up" selected_class="vote-voted"}}
{{vote 'sum' class="article-vote-sum"}}
{{vote 'down' class="article-vote-down" selected_class="vote-voted"}}
</div>
<div class="comment-avatar {{#if author.agent}} comment-avatar-agent {{/if}}">
<img src="{{author.avatar_url}}" alt="Avatar">
</div>
...
Reference
Add Instant Search (autocomplete search) results to your custom help center theme
You can display links to suggested articles as the user types in the Search box by adding Instant Search to your custom theme.
When Instant Search is enabled, a maximum of six suggested articles appear as the user types their search term in the Search box. Articles are matched for Instant Search based on the article title only. The user can select matched articles directly from the Search box without going to the search results page first.
- Whichever template contains your Search expression (most often it's the Header or Home page template)
Applicable expression
- {{search}}
- Add
instant=true
to the Search expression.{{search instant=true}}
Example
<div class="search-box">
<h1 class="help-center-name">{{help_center.name}}</h1>
{{search instant=true}}
</div>
Add Federated Search to include external content in help center search
There are two parts to enabling Federated Search in your help center Search Results template:
Adding sidebar filters
You need to update the search results template by updating the properties used in the sidebar filters.
<div
class="search-results">
.<section class="search-results-sidebar">
{{#if source_filters}}
<section class="filters-in-section collapsible-sidebar" aria-expanded="false">
<button type="button" class="collapsible-sidebar-toggle" aria-expanded="false">
</button>
<h3 class="collapsible-sidebar-title sidenav-title">{{t 'filter_source'}}</h3>
<ul class="multibrand-filter-list multibrand-filter-list--collapsed">
{{#each source_filters}}
<li>
{{#if selected}}
<a href="{{url}}" class="sidenav-item current" aria-current="page">
{{else}}
<a href="{{url}}" class="sidenav-item">
{{/if}}
<span class="sidenav-subitem filter-name">{{name}}</span>
<span class="sidenav-subitem doc-count">({{count}})</span>
</a>
</li>
{{/each}}
<buttonclass="see-all-filters"aria-hidden="true"aria-label="{{t'show_more_sources'}}">{{t'show_more_sources'}}</button> </ul>
</section>
{{/if}}
{{#if type_filters}}
<section class="filters-in-section collapsible-sidebar" aria-expanded="false">
<button type="button" class="collapsible-sidebar-toggle" aria-expanded="false">
</button>
<h3 class="collapsible-sidebar-title sidenav-title">{{t 'filter_type'}}</h3>
<ul class="multibrand-filter-list multibrand-filter-list--collapsed">
{{#each type_filters}}
<li>
{{#if selected}}
<a href="{{url}}" class="sidenav-item current" aria-current="page">
{{else}}
<a href="{{url}}" class="sidenav-item">
{{/if}}
<span class="sidenav-subitem filter-name">{{name}}</span>
<span class="sidenav-subitem doc-count">({{count}})</span>
</a>
</li>
{{/each}}
</ul>
</section>
{{/if}}
{{#if subfilters}}
<section class="filters-in-section collapsible-sidebar" aria-expanded="false">
<button type="button" class="collapsible-sidebar-toggle" aria-expanded="false">
</button>
{{#is current_filter.identifier 'knowledge_base'}}
<h3 class="collapsible-sidebar-title sidenav-title">{{t 'filter_by_category'}}</h3>
{{/is}}
{{#is current_filter.identifier 'community'}}
<h3 class="collapsible-sidebar-title sidenav-title">{{t 'filter_by_topic'}}</h3>
{{/is}}
<ul class="multibrand-filter-list multibrand-filter-list--collapsed">
{{#each subfilters}}
<li>
{{#if selected}}
<a href="{{url}}" class="sidenav-item current" aria-current="page">
{{else}}
<a href="{{url}}" class="sidenav-item">
{{/if}}
<span class="sidenav-subitem filter-name">{{name}}</span>
<span class="sidenav-subitem doc-count">({{count}})</span>
</a>
</li>
{{/each}}
{{#is current_filter.identifier 'knowledge_base'}}
<button class="see-all-filters" aria-hidden="true" aria-label="{{t 'show_more_categories'}}">{{t 'show_more_categories'}}</button>
{{/is}}
{{#is current_filter.identifier 'community'}}
<button class="see-all-filters" aria-hidden="true" aria-label="{{t 'show_more_topics'}}">{{t 'show_more_topics'}}</button>
{{/is}}
</ul>
</section>
{{/if}}
</section>
Looping through the results
This snippet is an example of how you can use the {{results}}
helper to
loop through the Federated Search results:
{{#if results}}
<ul class="search-results-list">
{{#each results}}
<li class="search-result-list-item result-{{type}}">
<h2 class="search-result-title">
<a href="{{url}}" class="results-list-item-link"{{#if is_external}}
target=”_blank” {{/if}}>
{{title}}
{{#if is_external}}
<svg viewBox="0 0 24 24" width="12px" height="12px" id="zd-svg-icon-12-new-window-fill"><path d="M 19.980469 2.9902344 A 1.0001 1.0001 0 0 0 19.869141 3 L 15 3 A 1.0001 1.0001 0 1 0 15 5 L 17.585938 5 L 8.2929688 14.292969 A 1.0001 1.0001 0 1 0 9.7070312 15.707031 L 19 6.4140625 L 19 9 A 1.0001 1.0001 0 1 0 21 9 L 21 4.1269531 A 1.0001 1.0001 0 0 0 19.980469 2.9902344 z M 5 3 C 3.9069372 3 3 3.9069372 3 5 L 3 19 C 3 20.093063 3.9069372 21 5 21 L 19 21 C 20.093063 21 21 20.093063 21 19 L 21 13 A 1.0001 1.0001 0 1 0 19 13 L 19 19 L 5 19 L 5 5 L 11 5 A 1.0001 1.0001 0 1 0 11 3 L 5 3 z"/></svg>
{{/if}}
</a>
</h2>
<article>
<div class="search-result-icons">
{{#if vote_sum}}
<span class="search-result-votes">{{vote_sum}}</span>
{{/if}}
{{#if comment_count}}
<span class="search-result-meta-count">
{{comment_count}}
</span>
{{/if}}
</div>
<ul class="meta-group">
<li>
<ol class="breadcrumbs search-result-breadcrumbs">
{{#each path_steps}}
<li title="{{name}}"><a href="{{url}}" target="{{target}}">{{name}}</a></li>
{{/each}}
</ol>
</li>
<li class="meta-data">{{author.name}}</li>
<li class="meta-data">{{date created_at}}</li>
</ul>
<div class="search-results-description">{{text}}</div>
</article>
</li>
{{/each}}
</ul>
{{else}}
<p>
{{t 'no_results_unified'}}
{{#link 'help_center'}}
{{t 'browse_help_center'}}
{{/link}}
</p>
{{/if}}
Add sorting for subscription types in the My Activities Following page
You can make it easier for users to view their subscriptions by enabling them to sort subscriptions by type in the My Activities > Following page.
- Following page
- Under the
<nav>
tag, insert the following code:<div class="my-activities-following-header"> <span class="dropdown"> <span class="dropdown-toggle"> {{current_filter.label}} </span> <span class="dropdown-menu" role="menu"> {{#each filters}} <a href="{{url}}" aria-selected="{{selected}}" role="menuitem"> {{name}} </a> {{/each}} </span> </span> </div>
Add sorting options “created at” and “updated at” for requests in My Activities
You can add the sorting options “created at” and “updated at” for end-users on the request page in My Activities.
- Request list page
Recipe
- Replace
{{t 'created'}}
with:{{#link 'requests' sort_by='created_at'}}{{t 'created'}}{{/link}}
- Replace
{{t 'last_activity'}}
with:{{#link 'requests' sort_by='updated_at'}}{{t 'last_activity'}}{{/link}}
Add Follow/Unfollow for users in a shared organization
You can enable users to receive email notifications for requests in their shared organization. The {{subscribe}} helper inserts a "follow" button that users can click if they want to receive email notifications when requests are created or updated in their shared organization. Users also have the option to unfollow if they no longer want to receive updates.
- Request list page
{{#form 'requests_filter'}}...{{/form}}
- Add the
{{subscribe}}
helper to the form object.
Example
{{#form 'requests_filter' class='request-table-toolbar'}}
{{input 'query' id='quick-search' type='search' class='requests-search'}}
<div class="request-table-filters">
{{label 'organization' for='request-organization-select' class='request-filter'}}
{{select 'organization' id='request-organization-select' class='request-filter'}}
{{subscribe}}
{{label 'status' for='request-status-select' class='request-filter'}}
{{select 'status' id='request-status-select' class='request-filter'}}
</div>
{{/form}}
Reference
Add ability for signed-in users to CC other users on support requests
You can add the ability for signed-in users to add CCs to new and existing support requests in your help center. When a CC is added to a support request, the copied user will receive email notifications for ticket updates.
After you add the code to your custom theme, you must enable the feature (see Setting CC permissions).
- Request page
{{#form 'comment' class='comment-form'}}...{{/form}}
- Insert the following snippet inside
the comment form.
{{#if help_center.request_ccs_enabled}} <div class="comment-ccs"> {{token_field 'ccs' class="ccs-input"}} </div> {{/if}}
Add a link on follow-up requests to the parent request
You can display a link in a follow-up request to the parent request, if there is one.
- Request page
Recipe
- Add the following snippet to the Request page template where you want to display the
link to the parent ticket, if one is present:
{{#if request.followup_source_id}} <dl class="request-details"> <dt>{{t 'followup'}}</dt> <dd>{{link 'request' id=request.followup_source_id}} </dd> </dl> {{/if}}
Enable CSAT for solved tickets on the Customer Portal
- Request page
- Add a
{{#with satisfaction_response}}...{{/with}}
block to the request_page.hbs template.
-
See the Copenhagen theme request page.hbs on GitHub.
- Add the following template
code:
{{#with satisfaction_response}} {{#with rating}} <dl class="request-details"> <dt>{{t 'rating'}}</dt> <dd> <div> {{#is scale_type 'numeric'}} {{t 'numerical_rating' value=value max_value=max_value}} {{else}} {{scale_value}} {{/is}} </div> {{#link 'survey_response' id=../id}} {{#if ../editable}} {{t 'edit_feedback'}} {{else}} {{t 'view_feedback'}} {{/if}} {{/link}} </dd> </dl> {{else}} {{#if editable}} <dl class="request-details"> <dt>{{t 'rating'}}</dt> <dd> {{#link 'survey_response' id=id}} {{t 'add_feedback'}} {{/link}} </dd> </dl> {{/if}} {{/with}} {{/with}}
Add voting buttons to articles
The vote buttons on articles are part of the standard Copenhagen theme. But if you don't see the option to vote on your articles, you might have removed the buttons from your theme.
The code to add voting buttons can vary from theme to theme, but this is the code from the standard Copenhagen theme, in case you need it.
- Article
- Add the following code to the Article Page template:
{{#with article}} <div class="article-votes"> <span class="article-votes-question">{{t 'was_this_article_helpful'}}</span> <div class="article-votes-controls" role='radiogroup'> {{vote 'up' role='radio' class='button article-vote article-vote-up'}} {{vote 'down' role='radio' class='button article-vote article-vote-down'}} </div> <small class="article-votes-count"> {{vote 'label' class='article-vote-label'}} </small> </div> {{/with}}
Add content tags to articles and posts
The standard Copenhagen theme displays content tags on article, community post, and search pages by default. If you're using a custom or marketplace theme, you may need to update your theme to display content tags on these pages. To get started, you can use the following template files from the Copenhagen theme as a guide:
Once you're comfortable, you can add content tags to other pages. For example, the following snippet adds a list of content tags to the community topic page template.
{{#each posts}}
...
{{#if (compare content_tags.length ">" 0)}}
<ul class="content-tag-list">
{{#each content_tags}}
<li class="content-tag-item">
{{#link "search_result" content_tag_id=id}}
{{name}}
{{/link}}
</li>
{{/each}}
</ul>
{{/if}}
...
{{/each}}
Add badges to your custom help center theme
This topic covers:
Adding the new user profile actions helper
You must add the Award badge option if you want to award badges for agents. However, before you can do this, you must add the new actions helper.
To add the actions helper declaration
- Open the theme online code editor, go to an agent's user profile
page.
Page filename: user_profile_page.hbs
- Find the edit helper declaration.
{{edit}}
- Replace the edit helper declaration with the new actions helper declaration
instead.
{{actions}}
Now agents will be able to award badges. The new button will be styled with CSS according to your preferences. For more inspiration see the Zendesk example theme.
Showing Title badges on the post listings page
You can add Title badges as labels that sit next to the name of the author in the post listing page. This looks similar to post status labels because, for the sake of simplicity, the styling class is being reused.
To show Title badges on a post listings page
- Open the theme online code editor, and go
to
Page filename: community_topic_page.hbs
- Find the author name declaration. In the Copenhagen theme the line looks like
this:
<li class="meta-data">{{author.name}}</li>
- Add this snippet to the line after
it:
{{#each author.badges}} <li class="meta-data"> {{#is category_slug "titles"}} <span class="status-label">{{name}}</span> {{/is}} </li> {{/each}}
For advanced users - do not (re)use thestatus-label
CSS class for this
scenario, instead create a new specialized CSS class that you can modify independently of
the status label's style.
Here is an example of a Title badge for a Community Member
Showing Title badges on a post and comments page
To show Title badges on a post listings page
- Open the theme online code editor, and go
to
Page filename: community_post_page.hbs
- Find the author name declaration. In the Copenhagen theme the line looks like
this:
<li class="meta-data">{{author.name}}</li>
- Add this snippet to the line after
it:
{{#each author.badges}} <li class="meta-data"> {{#is category_slug "titles"}} <span class="status-label">{{name}}</span> {{/is}} </li> {{/each}}
Showing Title and Achievements badges on a user profile page
On a user profile page you will likely want to add more than just Title badges, for example, you can also add the user's achievements. The following example assumes that there is a graphical icon for each Achievement badge. Based on the Copenhagen theme, your Achievement badges may look like this:
To show Title and Achievement badges on a user's profile page
- Open the theme online code editor, and go
to
Page filename: user_profile_page.hbs
- Find the lines in the file where the user's name is rendered. For
example:
<h1 class="name"> {{#if user.url}} <a href="{{user.url}}" target="_zendesk_lotus" title="{{t 'open_user_in_support'}}">{{user.name}}</a> {{else}} {{user.name}} {{/if}} </h1>
- Replace that snippet with the
following:
<h1 class="name"> {{#if user.url}} <a href="{{user.url}}" target="_zendesk_lotus" title="{{t 'open_user_in_support'}}">{{user.name}}</a> {{else}} {{user.name}} {{/if}} {{#each user.badges}} {{#is category_slug "titles"}} <span class="status-label">{{name}}</span> {{/is}} {{/each}} </h1> <div style="margin-top: 1em;"> {{#each user.badges}} {{#is category_slug "achievements"}} <div style="float: left; text-align: center; padding: 0.5em; margin: 0.5em; background: white; border-radius: 0.2em;"> <img src="{{icon_url}}" height="40"><br> <span style="font-size: 0.8em;">{{name}}</span> </div> {{/is}} {{/each}} </div>
In this example all of the CSS styling is inlined to keep the example simple. For best practices, use these examples for inspiration, but spend time ensuring that the styling fits your theme
Enable users to view user profiles to your help center
This section describes how to update the necessary templates so that users in your help center can click the author name or avatar and view the user's profile.
link
helper
in the help center templating language. See link helper in the templating documentation to
update the following templates:
ArticlesMake the following updates to the Article page template.
Updating the article's author nameReplace the following
if
block:
{{#if article.author.url}} <a href="{{article.author.url}}" target="_zendesk_lotus"> {{article.author.name}} </a> {{else}} {{article.author.name}} {{/if}}
with
the following link
helper:
{{#link "user_profile" id=article.author.id class="user-profile"}} {{article.author.name}} {{/link}}Updating comment author names
Replace the following if
block:
{{#if author.url}} <a href="{{author.url}}" target="_zendesk_lotus">{{author.name}}</a> {{else}} {{author.name}} {{/if}}
with
the following link
helper:
{{#link "user_profile" id=author.id class="user-profile"}} {{author.name}} {{/link}}Updating the avatar of the article and comment authors
Replace the following image tag:
<img src="{{article.author.avatar_url}}" alt="Avatar"/>
with
the following link
helper:
{{#link "user_profile" id=article.author.id class="user-profile"}} <img src="{{article.author.avatar_url}}" alt="Avatar" /> {{/link}}Community posts
Make the following updates to the Community Post page template.
Updating the names of post authorsReplace the following if
block:
{{#if post.author.url}} <a href="{{post.author.url}}" target="_zendesk_lotus"> {{post.author.name}} </a> {{else}} {{post.author.name}} {{/if}}
with
the following link
helper:
{{#link "user_profile" id=post.author.id class="user-profile"}} {{post.author.name}} {{/link}}Updating the names of comment authors
Replace the following if
block:
{{#if author.url}} <a href="{{author.url}}" target="_zendesk_lotus">{{author.name}}</a> {{else}} {{author.name}} {{/if}}
with
the following link
helper:
{{#link "user_profile" id=author.id class="user-profile"}} {{author.name}} {{/link}}Updating the avatars of post authors
Replace the following image tag:
<img src="{{post.author.avatar_url}}" alt="Avatar"/>
with the
following link
helper:
{{#link "user_profile" id=post.author.id class="user-profile"}} <img src="{{post.author.avatar_url}}" alt="Avatar" /> {{/link}}Updating the avatars of the comment authors
Replace the following image tag:
<img src="{{author.avatar_url}}" alt="Avatar"/>
with the
following link
helper:
{{#link "user_profile" id=author.id class="user-profile"}} <img src="{{author.avatar_url}}" alt="Avatar" /> {{/link}}Search results
Make the following updates to the Search results template.
Updating the author names of articles in the resultsReplace the following
if
block in the {{#each article_results}}
block:
{{#if author.url}} <a href="{{author.url}}" target="_zendesk_lotus">{{author.name}}</a> {{else}} {{author.name}} {{/if}}
with
the following link
helper:
{{#link "user_profile" id=author.id class="user-profile"}} {{author.name}} {{/link}}Updating the author names of posts in the results
Replace the following if
block in the {{#each post_results}}
block:
{{#if author.url}} <a href="{{author.url}}" target="_zendesk_lotus">{{author.name}}</a> {{else}} {{author.name}} {{/if}}
with
the following link
helper:
{{#link "user_profile" id=author.id class="user-profile"}} {{author.name}} {{/link}}Updating the search results in older themes
If you have an older theme, the search results
might use the {{meta}}
helper instead. In that case you can use the code
described in this section to link author names to profile pages in your help
center.
You may need to update your CSS styling for the search results page to look uniform.
Updating the author names of articles in the resultsReplace the following div tags:
<div class="search-result-meta">{{meta}}</div> <div class="search-result-description">{{text}}</div>
With the following:
<ol class="breadcrumbs"> {{#each path_steps}} <li title="{{name}}"><a href="{{url}}">{{name}}</a></li> {{/each}} </ol> <div class="search-result-description"> {{text}} </div> <div class="search-result-meta"> <span dir="auto" class="search-result-meta-name"> {{#link "user_profile" id=author.id class="user-profile"}} {{author.name}} {{/link}} </span> <span class="search-result-meta-time">{{date created_at}}</span> </div>
For end result:
{{#each article_results}} <li class="search-result"> <a href="{{url}}" class="search-result-link">{{title}}</a> {{#if vote_sum}} <span class="search-result-votes">{{vote_sum}}</span> {{/if}} <ol class="breadcrumbs"> {{#each path_steps}} <li title="{{name}}"><a href="{{url}}">{{name}}</a></li> {{/each}} </ol> <div class="search-result-description"> {{text}} </div> <div class="search-result-meta"> <span dir="auto" class="search-result-meta-name"> {{#link "user_profile" id=author.id class="user-profile"}} {{author.name}} {{/link}} </span> <span class="search-result-meta-time">{{date created_at}}</span> </div> </li> {{/each}}Updating the author names of posts in the results
Add:
<ol class="breadcrumbs"> {{#each path_steps}} <li title="{{name}}"><a href="{{url}}">{{name}}</a></li> {{/each}} </ol>
For end result:
{{#each post_results}} <li class="search-result"> <a href="{{url}}" class="search-result-link">{{title}}</a> <ol class="breadcrumbs"> {{#each path_steps}} <li title="{{name}}"><a href="{{url}}">{{name}}</a></li> {{/each}} </ol> <div class="search-result-description"> {{text}} </div> <div class="search-result-meta"> <span dir="auto" class="search-result-meta-name"> {{#link "user_profile" id=author.id class="user-profile"}} {{author.name}} {{/link}} </span> <span class="search-result-meta-time">{{date created_at}}</span> <span class="search-result-meta-count"> {{t 'comments_count' count=comment_count}} </span> </div> </li> {{/each}}
Enable subsections in your help center theme
You can add subsections to your help center knowledge base to create more levels in your content hierarchy. If you are using a theme that was customized before March 29, 2019, you must add code to your help center custom theme to enable subsections. The following code comes with later versions of the Copenhagen theme.
- Section
section.sections
- Insert the following snippet into the Zendesk section page template,
section_page.hbs, after the header tag (
<header class="page-header">...</header>
) and before the pagination tag ({{pagination}}
) :{{#if section.sections}} <ul class="section-list section-list--collapsed"> {{#each section.sections}} <li class="section-list-item"> <a href="{{url}}"> <span>{{name}}</span> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" focusable="false" viewBox="0 0 16 16" aria-hidden="true"> <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M5 14.5l6.1-6.1c.2-.2.2-.5 0-.7L5 1.5"/> </svg> </a> </li> {{/each}} <a tabindex="0" class="see-all-sections-trigger" aria-hidden="true" id="see-all-sections-trigger" title="{{t 'see_all_sections'}}">{{t 'see_all_sections'}}</a> </ul> {{/if}} {{#if section.articles}} <ul class="article-list"> {{#each section.articles}} <li class="article-list-item {{#if promoted}} article-promoted{{/if}}"> {{#if promoted}}<span data-title="{{t 'promoted'}}" class="icon-star"></span>{{/if}} <a href="{{url}}" class="article-list-link">{{title}}</a> </li> {{/each}} </ul> {{else}} <i class="section-empty"> <a href="{{section.url}}">{{t 'empty'}}</a> </i> {{/if}}
Add sidebar filters and results for multiple help centers to the search results page
The help center search enables users to search across help centers, if you have multiple help centers, and presents the search results from help centers and from knowledge base and community, in a single unified feed with filters on the search results page.
If you are using a theme that was customized before March 29, 2019, you must add code to your help center custom theme to support unified search results and search across multiple help centers. If you have multiple help centers, you'll need to update your theme for each help center.
The fastest way to get the changes needed into your theme is to import the latest version of the Copenhagen theme that supports unified search results. To do so, see Adding a help center theme to Guide.
help_center_filters
, filters
, and
subfilters
helpers in the Curlybars templating language to update the
following files:
Updating the search results template to add sidebar filters
You need to update the search results template to add sidebar filters and to loop through the results.
Adding sidebar filters
This snippet is an example of how you can implement search facets in the search results page sidebar using the new filter helpers.
Insert the following code in <div class="search-results">
in the
search results template:
<section class="search-results-sidebar">
{{#if help_center.community_enabled}}
<section class="filters-in-section collapsible-sidebar">
<h3 class="collapsible-sidebar-title sidenav-title">{{t 'filter_by_type'}}</h3>
<ul>
{{#each filters}}
<li>
<a href="{{url}}" class="sidenav-item" aria-selected="{{selected}}">{{name}} ({{count}})</a>
</li>
{{/each}}
</ul>
</section>
{{/if}}
{{#if subfilters}}
<section class="filters-in-section collapsible-sidebar">
{{#is current_filter.identifier 'knowledge_base'}}
<h3 class="collapsible-sidebar-title sidenav-title">{{t 'filter_by_category'}}</h3>
{{/is}}
{{#is current_filter.identifier 'community'}}
<h3 class="collapsible-sidebar-title sidenav-title">{{t 'filter_by_topic'}}</h3>
{{/is}}
<ul>
{{#each subfilters}}
<li>
<a href="{{url}}" class="sidenav-item" aria-selected="{{selected}}">{{name}} ({{count}})</a>
</li>
{{/each}}
</ul>
</section>
{{/if}}
</section>
This snippet is an example of how you can use the {{results}} helper to loop through the unified search results.
Replace both
the {{article_results}}
and {{post_results}}
helpers
and their associated search-results-subheading H3s
in the search results template with the following:
{{#if results}} <ul class="search-results-list"> {{#each results}} <li class="search-result-list-item result-{{type}}"> <h2 class="search-result-title"> <a href="{{url}}" class="results-list-item-link">{{title}}</a> </h2> <article> <div class="search-result-icons"> {{#if vote_sum}} <span class="search-result-votes">{{vote_sum}}</span> {{/if}} {{#if comment_count}} <span class="search-result-meta-count"> {{comment_count}} </span> {{/if}} </div> <ul class="meta-group"> <li> <ol class="breadcrumbs search-result-breadcrumbs"> {{#each path_steps}} <li title="{{name}}"><a href="{{url}}">{{name}}</a></li> {{/each}} </ol> </li> <li class="meta-data">{{author.name}}</li> <li class="meta-data">{{date created_at}}</li> </ul> <div class="search-results-description">{{text}}</div> </article> </li> {{/each}} </ul> {{else}} <p> {{t 'no_results_unified'}} {{#link 'help_center'}} {{t 'browse_help_center'}} {{/link}} </p> {{/if}}
Updating CSS styling for the sidebar filters in the search results page
You can add CSS styling for the sidebar filters. The following example is based on the Copenhagen theme.
Make sure the following CSS rules are included in your style.css file:
/***** Search results *****/ .search-results { display: flex; flex-direction: column; flex-wrap: wrap; justify-content: space-between; } @media (min-width: 1024px) { .search-results { flex-direction: row; } } .search-results-column { flex: 1; } @media (min-width: 1024px) { .search-results-column { flex: 0 0 75%; } } .search-results-sidebar { border-top: 1px solid #ddd; flex: 1 0 auto; margin-bottom: 20px; padding: 0; } @media (min-width: 1024px) { .search-results-sidebar { border: 0; flex: 0 0 20%; height: auto; } } .search-results-sidebar .sidenav-item[aria-selected="true"] { background-color: $brand_color; color: $brand_text_color; text-decoration: none; } .search-results-subheading { font-size: 18px; font-weight: 600; } .search-results-list { margin-bottom: 25px; } .search-results-list > li { padding: 20px 0; } .search-results-list > li:first-child { border-top: 1px solid #ddd; } .search-results-list > li h2 { margin-bottom: 0; } .search-result-title { font-size: 16px; } .search-result-description { margin-top: 15px; word-break: break-word; } .search-result-votes, .search-result-meta-count { color: lighten($text_color, 20%); display: inline-block; font-size: 13px; font-weight: 300; padding: 4px 5px; position: relative; } .search-result-votes::before, .search-result-meta-count::before { color: $brand_color; } [dir="ltr"] .search-result-votes, [dir="ltr"] .search-result-meta-count { margin-left: 5px; } [dir="ltr"] .search-result-votes::before, [dir="ltr"] .search-result-meta-count::before { margin-right: 3px; } [dir="rtl"] .search-result-votes, [dir="rtl"] .search-result-meta-count { margin-right: 5px; } [dir="rtl"] .search-result-votes::before, [dir="rtl"] .search-result-meta-count::before { margin-left: 3px; } .search-result-votes::before { content: "\1F44D"; } .search-result-meta-count::before { content: "\1F4AC"; } .search-result .meta-group { align-items: center; } .search-result-breadcrumbs { margin: 0; } .search-result-breadcrumbs li:last-child::after { content: "·"; display: inline-block; margin: 0 5px; } /* Non-latin search results highlight */ /* Add a yellow background for Chinese */ html[lang|="zh"] .search-result-description em { font-style: normal; background: yellow; } /* Use bold to highlight for the rest of supported non-latin languages */ html[lang|="ar"] .search-result-description em, html[lang|="bg"] .search-result-description em, html[lang|="el"] .search-result-description em, html[lang|="he"] .search-result-description em, html[lang|="hi"] .search-result-description em, html[lang|="ko"] .search-result-description em, html[lang|="ja"] .search-result-description em, html[lang|="ru"] .search-result-description em, html[lang|="th"] .search-result-description em { font-style: bold; }
Updating JavaScript for the collapsible sidebar in the search results page
You can add JavaScript for the collapsible sidebar in the search results page. The following example is based on the Copenhagen theme.
Replace the following block in the script.js file in the custom theme:
// Toggles expanded aria to collapsible elements Array.prototype.forEach.call(document.querySelectorAll('.collapsible-nav, .collapsible-sidebar'), function(el) { el.addEventListener('click', function(e) { e.stopPropagation(); var isExpanded = this.getAttribute('aria-expanded') === 'true'; this.setAttribute('aria-expanded', !isExpanded); }); });
with the following code snippet:
// Toggles expanded aria to collapsible elements var collapsible = document.querySelectorAll('.collapsible-nav, .collapsible-sidebar'); Array.prototype.forEach.call(collapsible, function(el) { var toggle = el.querySelector('.collapsible-nav-toggle, .collapsible-sidebar-toggle'); el.addEventListener('click', function(e) { toggleNavigation(toggle, this); }); el.addEventListener('keyup', function(e) { if (e.keyCode === 27) { // Escape key closeNavigation(toggle, this); } }); });
42 comments
Catherine Michalak
Hi,
Is there anyone who could help me add subsections to my custom HC code?
I am struggling to get the section with subsections to show if it doesn't have an article in it (ie. the subsections have articles but until there's an article in the section itself, it doesn't show on the category page) and struggling to keep the layout the same on the section with subsections level as it is on the category with sections level.
TIA!
Catherine
0
Emelie Stjernquist
Hello @...,
Just so I get it right, you wish to display an "empty" section?
I'm not sure that that is possible to do (at least I've not manage to do that), however I have a suggested work-around which is to:
I usually elaborate, test back and forth in the templates until I get the result I want. You can also preview it in "Preview mode" before publishing it.
I hope this helps you to get closer to what you wish to accomplish, good luck!
//Emelie
0
Francois Spinnael
The Current_local.name trick isn't working.
I'm using this list: https://support.zendesk.com/hc/en-us/articles/203761906-Zendesk-language-support-by-product
And for some reason, the rename of the "language" is working for English (World) that is defined as a "Variant" but all the other ones, aren't working (Estonia, Lithuania, Latvia, Luxembourg,...)
0
Augusto Silva
Hey @...
Try something like this instead (language names can change):
0
blak3r
My Activities has `{{requests}}` template variable on it. The Home Page does not. Is there a simple way to expose the `{{requests}}` to the home page for signed in users?
I'd like to show them their 5 most recent requests on the homepage so it's more visible.
If that cannot be done, could a Custom Page do this? Essentially I want a landing page from our product for support that has both their requests and then knowledge base shown under it. One stop landing page from my product. We use SSO so our users are already authenticated when going there from the app.
1
Greg Katechis
Hi Blake! I thought about this for a bit to see if I could get creative, but there isn't any way that I could envision where this could be accomplished. As you noted, `{{requests}}` don't exist in the home page template and custom pages also do not contain that helper. I wish I had better news and if I think of anything, I'll drop you a line here.
0
blak3r
Greg Katechis - thanks for giving it some thought. I suppose this would need to be accomplished with custom javascript to call an api endpoint we'd host that would then use the REST api and return the data back. Blockers here: 1) simple documentation showing how to add javascript that invokes web requests to a third party server 2) Any tips on how we could authenticate on our server code that the user account is in fact authenticated... like if we had /api/getTickets?user=<emailAddress> we need to verify the user is in fact logged into zendesk somehow so they couldn't exploit the api to get other peoples tickets.
1
Greg Katechis
1) For this, you could just make an AJAX request from the custom code in your help center to initiate this call to your server/middleware. While it isn't the exact scenario that you're looking to accomplish, this article should give the basic framework that you would need and then you can just swap out your URL/endpoint.
2) This one is giving me all sorts of problems...both from a basic implementation standpoint, but especially from a security standpoint. We don't have any method of using OAuth in Guide, which would be the easiest way to accomplish this. You could also use the signed_in helper to confirm that someone is signed in and then grab the CSRF token to do...something clever? Like I mentioned, I don't feel comfortable with this, but maybe the idea would spark something in someone else to a function solution!
0
blak3r
Thanks Greg. Appreciate the link and the quick response. Maybe I can get a value that is set by the login to uniquely identify the session or something. I’ll hack around. I could provide a token in the return_to portion of the jwt flow. Then modify every page template to store that token in a cookie. And pass that along with server Ajax calls and of course have that same token stored in the user db for checking against. Or maybe just the primary entry point page and have it only work if they redirected there. I’ll sleep on it.
1
Greg Katechis
Oh that's a great idea if you use JWT! I wouldn't recommend storing the token in the DB, as that will change on each login, but you could use the shared secret from Zendesk to verify the signature on your server. The JTI might cause a problem, although if you're just storing that as a cookie and not doing any authentication/authorization in the traditional sense, this could work.
Let me know if you get this working or hit any snags with this. This could be a great tip for other users looking for a similar solution!
0
blak3r
It appears the jwt token is stored in an object in ```Session Storage.z2_sunco_widget_auth.jwt```
So, in the requests to our server we could include the users email, jwt, and the JTI. The server would take the JTI and resign the payload. If that payload matched the jwt supplied with the request then we could assume that the user was in fact the email provided to the request.
In terms of how to get the JTI, there are two approaches I see...
1. Store the JTI in our user table each time a request is built... Con here is possible synchronization issues. For example, we were planning on having links in our product just include the jwt to avoid any perceived glitchy redirect behavior from enduser standpoint. For example to go to /hc/article/103 our link would be https://subdomain.zendesk.com/jwt?jwt=<token>&return_to=https://subdomain.zendesk.com/hc/article/103
2. Pass the JTI as a GET param in the return_to and store that to a cookie with custom Javascript code on each page template. CON here is long urls look gross and add potential for user to bookmark a link with a JTI in it... Probably could mitigate this by updating the url.
3. Get our helpdesk working on a subdomain of our domain. Use https://support.mydomain.com instead of https://<zdsubdomain>.zendesk.com and have our webapp set a cookie to root domain that the zendesk code could also see. Probably the best option.
Questions for you... is this z2_sunco_widget_auth a reliable key for the JWT token? That sunco part is throwing me off. Also, I'm not a JWT security specialist, I can't see why having the JTI exposed would be that insecure... given you can't sign a payload without the shared secret but maybe i'm missing something. Feel free to DM me personally if you prefer.
0
Maxim Ageev | null | null
I need to disable search indexing on the zendesk subdomain.
To only allow it on our company domain.
I would like to add in header template the following line <meta name="robots" content="noindex">
But only if the domain is helpcenter. Is there a variable in a template that stores the current domain?
https://stackoverflow.com/q/71527073/7921383
0
Katrina Greeves
Is it possible to filter search results by label?
e.g
Article 1 is labelled A
Article 2 is labelled B
Article 3 is labelled A C
I'd like to add a sidebar filter for each label.
If I select filter A, I will only then see articles 1 and 3.
0
Dave Dyson
There isn't currently a way to filter by label, although articles with labels matching the search terms will be featured higher in the search results. If you'd like to suggest this to our product team, please post your use case to our Feedback - Help Center (Guide) topic, using this template. Thanks!
0
Taehyoung Kim
Hi, I'm trying to add the content tag feature in our customized template (Copenhagen 1.8.1) but facing some problems.
I have successfully added content tags in our knowledge base article, but still figuring out how to add them to the search result. I'm basically having a look at search_results.hbs of the recent release. But if I add the lines here to my old template, it said that 'content_tag_filters' does not exist. Does the variable name differ from version to version? Is there a way to implement this on Copenhagen 1.8.1?
Thanks in advance :)
Taehyoung
4
Beth_Borghi
I'm having the same issue as Taehyoung Kim above. Appreciate any help - thank you!
3
Christian de Heij
Having the same for my template content_tag_filters does not exists. Any help to get it in?
1
Sabine Hanna
Same here regarding the content_tag_filters. Any help would be appreciated!
0
mfg
blak3r - were you able to solve for securely getting the requests on a separate/home page without exposing tickets the authenticated user shouldn't have access to?
We are looking to have something similar (buttons for the forms at the top, [requests | article list] in a flex box beneath. Without that "{{requests}}" helper, the current solution we're considering is an iFrame / EMBED SRC= , and then style with CSS. It works - but it's not as secure as we'd like.
0
Dane
The current version of Copenhagen is Theme version 2.19.4. I have tried the content_tag_filters on search_results.hbs and it worked without any issues. Unfortunately, as customization is outside our scope the best option is to use the lates version of the Copenhagen Theme.
0
Gorka Cardona-Lauridsen
Hi All,
We are conducting research to improve our Help Center developer experience and would love to talk to any of you that have tried to edit Help Center theme code.
If you are interested please answer sign up here and answer the 3 survey questions. I will reach out to you to setup a 30 min Zoom call.
The interview will be a semi-structured interview where we would like to hear you take us through examples of what you have done or tried to do with customizations and your experience with the tools, documentation etc. you used.
Looking forward to talking to all of you.
Gorka Cardona-Lauridsen
Sr. Product Manager, Zendesk Guide
0
Tomas M. Parra
Hello!
I'm trying to add a snippet of each article's body underneath the articles' title in the category page.
This is the code as is:
<ul class="article-list">
{{#each articles}}
<li class="article-list-item{{#if promoted}} article-promoted{{/if}}">
{{#if promoted}}
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" focusable="false" viewBox="0 0 12 12" class="icon-star" title="{{t 'promoted'}}">
<path fill="currentColor" d="M2.88 11.73c-.19 0-.39-.06-.55-.18a.938.938 0 01-.37-1.01l.8-3L.35 5.57a.938.938 0 01-.3-1.03c.12-.37.45-.63.85-.65L4 3.73 5.12.83c.14-.37.49-.61.88-.61s.74.24.88.6L8 3.73l3.11.17a.946.946 0 01.55 1.68L9.24 7.53l.8 3a.95.95 0 01-1.43 1.04L6 9.88l-2.61 1.69c-.16.1-.34.16-.51.16z"/>
</svg>
{{/if}}
<a href="{{url}}" class="article-list-link">{{title}}</a>
{{#if internal}}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" focusable="false" viewBox="0 0 16 16" class="icon-lock" title="{{t 'internal'}}">
<rect width="12" height="9" x="2" y="7" fill="currentColor" rx="1" ry="1"/>
<path fill="none" stroke="currentColor" d="M4.5 7.5V4a3.5 3.5 0 017 0v3.5"/>
</svg>
{{/if}}
</li>
{{/each}}
</ul>
What I want is to add {{body}} underneath <a href="{{url}}" class="article-list-link">{{title}}</a> but I can only print the full article's body, which obviously breaks the whole layout.
I tried many things like {{body.slice 0 50}} and more, but nothing seems to work.
For the records: I am a developer, I have been through Zendesk documentation (Plus forums, stack overflow, your support, etc) and nothing seems to work.
Can you give me a hand to achieve this?
Thanks!
1
Tomas M. Parra
By the way, your console says either something like "body.slice cannot be accessed" , or something like "body doesn't accept these parameters".
1
Ryan Gilomen
Tomas M. Parra,
I use {{excerpt body characters=150}} on my section pages to achieve this.
Hope this helps!
-Ryan
1
Tomas M. Parra
Hello @Ryan!
That worked great for me. Thanks so much!
0
Casey Keefe
Hey Zendesk & Community! I am trying to use current_locale.name on home_page.hbs to change content based on selected language.
I have been able to use this in both header.hbs and footer.hbs with no problems, but getting the following error when I try to use it on home_page.hbs
I am trying to avoid using the Dynamic Content feature if at all possible (just haven't had good luck with it). Thanks!
0
Cory Waddingham
Is there a way to add metadata for a page? For example, on article pages, I want to add a <title> tag to the page header, so that page crawlers will know the title of the article without any trouble. But I can't find a way to add that page tag, either in the article_page.hbs or the document_head.hbs (adding
just results in an error.
0
Tipene Hughes
Hey, Casey Keefe!
You can access the help_center object in the home_page.hbs file. The object has the locale property available which should be what you're looking for.
Feel free to reach out with any questions!
Tipene
0
Tipene Hughes
Hi Cory Waddingham,
The article object is not accessible within the document_head.hbs file. One way you could look at going about this is by using a bit of custom Javascript to append a title to the page. Here’s an example of one way that could work:
I’m not super familiar with how crawlers interact with dynamically added meta data though so that might be something to look in to if you haven’t already.
Let me know if you have any questions!
Tipene
1
Casey Keefe
Thank you Tipene Hughes !
0