The default Protocol directory structure looks something like this:
protocol
├── dist
├── docs
├── gulp
│ ├── tasks
│ ├── utils
│ ├── config.js
├── src
│ ├── assets
│ ├── data
│ ├── pages
│ ├── patterns
│ ├── static
│ └── templates
└── gulpfile.js
File | Description |
---|---|
dist | Where Protocol builds are output |
src/assets | Where Protocol source files live |
src/data | Where shared template data files live |
src/pages | Where Page content and templates live |
src/patterns | Where Pattern templates live |
src/static | Where generic root assets live |
src/templates | Where Page Layout and Protocol UI templates live |
gulp/config.js | The Gulp task configuration module |
gulp/tasks | Individual Gulp task files |
gulp/utils | Common Gulp task utility files and helpers |
gulpfile.js | The Gulp task initialization script |
A Pattern is a grouping of markup templates representing a distinct interface element. Patterns are probably the most substantial and relevant part of the Protocol design system.
The default project structure is as follows:
src/patterns
├── atoms
├── molecules
├── organisms
└── templates
A Pattern Collection is any folder within src/patterns that is the parent to one or more template files. The files can be named anything with a .hbs or .html extension, and will be concatenated into a single file during the build process.
Example input:
src/patterns/molecules
├── card
├── extra-small-card.hbs
├── large-card.hbs
├── medium-card.hbs
└── small-card.hbs
Example output:
dist/patterns/molecules
└── card.html
It's common for patterns to consist of multiple variations of the same general piece of markup. For example, the pattern collection for a button component could be structured as:
src/patterns/atoms/buttons
├── basic.hbs
|── primary.hbs
└── secondary.hbs
These pattern variations are accessible from other templates as partials:
And for more complex cases, the {{#extend}} and {{#embed}} helpers can be used:
Pages can be used to present Patterns, or to supplement them with examples or additional documentation. They can be authored as Markdown, Handlebars, or standard HTML.
Example input:
src/pages
├── demos
│ ├── article.hbs
│ ├── card-layout.hbs
│ └── index.hbs
├── docs
│ └── index.hbs
├── fundamentals
│ ├── color.hbs
│ └── typography.hbs
└── index.hbs
Example output:
dist
├── demos
│ ├── article.html
│ ├── card-layout.html
│ └── index.html
├── docs
│ └── index.html
├── fundamentals
│ ├── color.html
│ └── typography.html
└── index.html
By default, Pages will include the surrounding Protocol UI elements in their layout:
To use a different layout template, you can assign one in the Page front-matter:
title: Demo Page
layout: blank
Refer to the Layouts section for more information on the default layout templates.
To share common data across all Page and Pattern templates, you can define data files in JSON or YAML format.
Common data files are include:
src/data
├── articles.yaml
├── colors.yaml
├── items.yaml
├── project.yaml
└── specimens.yaml
Accessing values from these files can be done with the {{data}}
template helper. For example:
# src/data/team.yaml
- name: Pete
photo: pete.jpg
- name: Paul
photo: paul.jpg
- name: Mary
photo: mary.jpg
Results in:
<!-- dist/team.html -->
<img src="pete.jpg" alt="Pete">
<img src="paul.jpg" alt="Paul">
<img src="mary.jpg" alt="Mary">
Patterns and Pages can leverage YAML front-matter for local template data:
---
name: Basic Button
notes: This is _just_ a **basic** button.
---
<button class="mzp-c-button">
{{name}}
</button>
These values can be accessed directly within their own template (e.g. {{name}}
). From outside templates, the values can be accessed via the data
property:
Front-matter can also be applied to Pattern Collections by using a collection.yaml file at the root of the directory:
src/patterns/atoms/buttons
├── collection.yaml
├── basic.hbs
└── download.hbs
While any arbitrary data can be added and referenced, there are some special property definitions that affect how things are displayed:
Property | Type | Description |
---|---|---|
name | string | Override the default name for Patterns and Collections. Example: name: My Page |
order | number | Override the default sort position for Patterns and Collections. Example: order: 1 |
hidden | boolean | Hide a Pattern variation from listings. |
notes | string | Annotate details about a Pattern variation with Markdown formatting. |
links | object | Provide a menu of additional documentation links for a Pattern. |
sourceless | boolean | Prevent the HTML source of a Pattern from being displayed. |
layout | string | Associate a Layout template to be used for wrapping Page content. Example: layout: blank |
Templates in the src/templates directory are intended for the surrounding Protocol docs UI.
src/templates
├── drizzle
├── blank.hbs
├── collection.hbs
└── default.hbs
The templates in this directory differ from Patterns and Pages in a few ways:
- They are for presenting content (opposed to being content).
- They do not utilize front-matter data.
- They cannot be iterated over in any way.
Files at the top-level of the templates directory are assumed to be layout templates for Pages:
Layout | Description |
---|---|
default.hbs | This is for standard pages that do require the presence of the Protocol docs UI. Example |
blank.hbs | This is used for special standalone pages that don't require the presence of the Protocol docs UI. Example |
collection.hbs | This is used for concatenating Pattern collections into a single page. Example |
Files deeper than the top-level of the templates directory are intended to be used as partials for the Protcol docs UI:
src/templates/drizzle
├── item.hbs
├── labelheader.hbs
├── nav.hbs
└── swatch.hbs
A handful of helpers are included by default to assist with looking up and listing Data, Pages, and Patterns.
{{data}} provides access to Data:
{{pages}} provides access to Page listings:
{{collections}} provides access to Pattern collection listings:
{{#extend}}, {{#embed}}, {{#block}} and {{#content}}:
The handlebars-layouts helper suite is included to provide extensible "layout" behavior to all templates:
<html>
<body>
Final content
</body>
</html>
Pattern templates can also benefit from these helpers:
<button class="mzp-c-button mzp-t-dark">
Primary Button
</button>
Protocol CSS files are compiled from Sass source files. Both source files and compiled CSS files are included in the output dist
directory for convenience.
Example input:
assets/sass
├── demos
│ ├── article.scss
│ ├── card.scss
│ └── newsletter.scss
├── docs
│ └── site.scss
├── protocol
│ ├── base
│ ├── components
│ ├── includes
│ ├── templates
│ └── protocol.scss
Example output:
dist/assets
├── docs
| |── css
| |── article.css
| |── article.scss
| |── card.css
| |── card.scss
| |── newsletter.css
| |── newsletter.scss
| |── site.css
| └── site.scss
├── protocol
| |── protocol
| |── css
│ ├── base
│ ├── components
│ ├── includes
│ ├── templates
│ ├── protocol.css
│ └── protocol.scss
Note: that both demos
and docs
source files are copied to the same directory for use in the docs site.
JavaScript files are also processed using a similar structure.
Example input:
src/assets/js
├── docs
│ ├── vendor
│ └── global.js
├── protocol
│ ├── protocol-base.js
│ └── protocol-sidemenu.js
Example output:
dist/assets
├── docs
| |── js
| |── vendor
| └── global.js
├── protocol
| |── protocol
| |── js
│ ├── protocol-base.js
│ └── protocol-sidemenu.js
The build sequence consists of a small set of Gulp tasks. While you'll probably only need gulp
and gulp --dev
most of the time, the other tasks can be called independently to process only a subset of your source files:
Task | Description |
---|---|
gulp |
Build everything and start the development server. |
gulp --dev |
Do everything gulp does, but with file watching. |
gulp build |
Just build everything. |
To start the build process and then run front-end JS tests against the processed files:
npm test
Protocol is published to NPM under the @mozilla-protocol/core
namespace/package name. To publish a release to NPM, use the following steps:
- Before you start make sure the project's CHANGELOG.md is up to date.
- Update the package
version
number in src/assets/package/package.json (use Semantic Versioning to determine what the new version number should be). - Update the package README assets/package/README.md.
- Run
npm install
to update the package-lock.json file. - Submit a pull request with your changes (or commit directly to
master
if you have permission). Once the changes have been merged to master: - Tag a new release. You can do this either using Git tag, or directly on the GitHub website.
- Run
npm test
to run the build script and front-end tests. The package contents will be located in./dist/assets/protocol/
. - If the build is successful and all tests pass, publish to NPM using
npm publish ./dist/assets/protocol/
.
Note: the following instructions assume the mozilla reporitory is the remote called origin
.
Each time an updated package is published to NPM, https://protocol.mozilla.org/ should also be updated so the documentation site matches the NPM package features.
- Verify all is good on the staging site.
- Make sure your local
master
branch is up to date - Push the
master
branch to theprod
branch:git push origin master:prod
.
A notice will be posted in #www-notify on Slack when the push has completed.
For previewing new components before they are merged to master
, two demo instances are available.
- Push your branch to the
demo1
ordemo2
branches e.g.git push -f origin my-branch-name:demo1
- Your branch will be published:
A notice will be posted in #www-notify on Slack when the push has completed.
Protocol started out life as a fork of Drizzle, by Cloud Four: