This is the second in a series of posts on the different elements we use in creating and supporting our Help Center customizations. If you haven't read Zendesk theme customization part 1: How we use Zendesk features yet, it's best to start with that post, as this one builds on the first. The goal is to provide enough information that anyone could build similar customizations on their own. These posts are a starting place; we aim to provide more code examples in the future.
Now let’s examine some open source tools we use to leverage the data and construct modules.
Reusable theme modules and third party modules with Node.js
Our Guide theme makes a large number of UI features into self contained modules that:
- Promote code reuse and maintainability.
- Make it easier to see where the code for a specific feature resides.
- Open the door to unit testing for module logic.
Handlebars & jQuery
Handlebars and jQuery provide the display and functional layers for our modular theme. They are well documented and are compatible with the legacy code we still need to support.
The similarity between Handlebars and Curlybars syntax also helps provide a consistent syntax between the server templates and the client side templates.
However, some of our modules are written in a manner that closely resemble the structure of React components (https://reactjs.org/). We’ll likely be adopting React in the future to use the suite of Zendesk Garden components. See https://garden.zendesk.com/react-components/.
Webpack allows us to process all the module code and package it into just three production-ready files.
Each of the modules has the option of specifying an arbitrary number of *.hbs files which are concatenated together to form footer.hbs. Concatenating files together allows us to simulate having an arbitrary number of server templates to better segment our code.
Some of our routine tasks were greatly simplified by using Gulp to script them. Some examples include:
- Running Webpack
- Linting the module code with ESLint (https://eslint.org/)
- Transpiling with Babel (https://babeljs.io/)
- Concatenating the footer templates with gulp-concat (https://github.com/gulp-community/gulp-concat)
- Programmatically generating a theme ZIP file with gulp-zip (https://github.com/sindresorhus/gulp-zip)
Overview of our theme’s architecture
Next let’s see how these pieces fit together.
Anatomy of a theme module
In this example, you can see our “community-posts” module consists of 4 files:
- community-posts.hbs - contains Curlybars template code to be processed on the server side, the result of which will be output to the client’s browser. This is where dynamic content strings and JSON blobs get dumped for the display modules to use on page load. It gets concatenated with all the other *.hbs files in the other modules to become to the footer.hbs file.
- index.js - represents the module code which may take the form of an Node.js module or simple HTML <script> definition to be run inline in the head of the page.
- partials.js - this file contains all client side Handlebars templates used by this module.
- style.scss - contains all the SASS (https://sass-lang.com/) style definitions for this module.
After the modules are built, they are merely included in the document_head.hbs server template like any other theme assets:
This leads us to our next topic.
Some modules run inline, but our more complex modules load after the document ready event to prevent locking the page. We merely need to instantiate a single new instance of each module in our webpack entry script and the modules handle the rest themselves:
Here is the constructor used for the CommunityPosts module:
The following two examples showcase our Gulp and Webpack configurations for reference:
Please post your questions in the comments section below.
Disclaimer: Zendesk provides this article for informational purposes only. Zendesk does not provide support for the content. Zendesk also cannot provide support for third-party technologies such as Webpack and Gulp.
Bitte melden Sie sich an, um einen Kommentar zu hinterlassen.