Version 0.5 Last updated: Tuesday 17 January 2017
- 1. Introduction
- 2. How to build the DPL
- 3. How to add a new pattern
- 4.0 How to add an example page
Hurrah! So you want to contribute to the digital pattern library (DPL)? That's great news! This guide should get you started.
The first thing to do is to make sure you have permission to use and develop the DPL. Details may be found on the DPL homepage, along with a list of approved developers.
If you haven't already set up your development environment, see SETUP.md.
- Nothing should be in the pattern library unless it is used on a live website or web application — we don't build patterns 'just in case'. Redundant patterns should be deprecated and eventually removed.
- The pattern library should be opinionated.
Workflow is about how we branch source code, and then merge those changes back in again.
We use GitHub Flow which is a fairly simple workflow that has just enough structure. Read Scott Chacon's article about Github Flow for a good introduction. The main points are:
- All development must take place in feature branches.
- Feature branches should be branched from
master
. - Commit often in your feature branches.
- When features are near complete, submit a pull request for that feature
branch to be merged into
master
. - Code reviews are a part of the pull request. Ideally, a person (or persons
if you are doing pair QAing) other than yourself should review (at a minimum
conduct a sanity check) on all features before they are merged into
master
. - When approved by your reviewer, you should non-fast-forward merge your
feature branch into
master
and resolve any conflicts. This preserves the history of how each feature was made. - The code should then be uploaded to www.st-andrews.ac.uk/~cdn and www.st-andrews.ac.uk/dpl/ and tagged in GitHub.
Developers using the DPL must not fork the code in GitHub.
No patterns or elements (such as colours) in the DPL may be edited without liaising with the digital communications team. This is the case in both the DPL and in any content management system: patterns should not be modified in any manner. Do not use CSS to overrule DPL elements, patterns, fonts etc.
New patterns may only be created by developers working in collaboration with the digital communications team.
All code written must follow the digital communications team’s code standards. Rules on all patterns must be adhered to – if in doubt, please ask.
Commit messages must follow the commit message style guide.
The DPL follows semantic versioning. This means that every version number has three parts:
major.minor.patch
When determining the appropriate number for a new version, increment the:
- major version when you make incompatible API changes,
- minor version when you add functionality in a backwards-compatible manner, and
- patch version when you make backwards-compatible bug fixes.
See semantic versioning for more information.
Whenever you release a new version you must update the version in the source code and add a Git tag for that version.
The version number is stored in the package.json
file in the root of the DPL. You must change the version number here to your new version number and then rebuild core/
and docs/
with Grunt. When Grunt runs, the version number found in package.json
is listed at the top of all the JavaScript and CSS core assets and is also output in the title of the documentation pages, and the DPL homepage.
We follow the convention that for version 0.5.4
the Git tag would be:
v0.5.4
But the folder that is deployed to on the CDN and for the docs would simply be:
0.5.4
The reason for having the extra v
in the Git tag is that it means you can quickly find all the version tags since you may have non-version related tags in your Git repository. There's not really a strong argument for or against the v
– consistency is the main thing.
We really cannot emphasize this strongly enough: having a human-readable change log is essential to quickly bringing new developers up to speed with a project. Therefore, whenever you work on the pattern library you need to update CHANGELOG.md
to reflect those changes.
It's best to document changes as you go; that way updates to CHANGELOG.md
get committed alongside the changes to the code. This can lead to merge conflicts, however, so you may wish to track change log entries in a local file within your patterns while you develop then merge these into master later.
At a minimum, each time you add a Git tag and release a new version of the pattern library the change log should be updated to reflect that new version, the date it was released and the changes that have occurred since the last version.
See CHANGELOG.md.
The DPL uses a combination of Node, Grunt, Compass (Sass), Handlebars and various other tools to compile the source code in /src/
and build two collections of components:
/core/
- Production CSS, JavaScript, fonts and images./docs/
- Documentation about using the patterns in the library and other information for developers who use the core assets.
(Docs relies on core for its look-and-feel. In other words, the DPL documentation uses the DPL to present itself.)
In the repository, we have the following additional documentation aimed at assisting those who contribute and develop the pattern library:
- SETUP.md – How to set up your development environment.
- FILES.md – Overview of source folders and files.
- CONTRIBUTING.md – General guidelines for contributing to pattern library (this document).
After getting set up, you can use the following Grunt tasks to carry out the following actions:
$ grunt
This command will build the core assets and place them in core/
and then
build the documentation and place it in docs/
. Behind the scenes it runs the
following two individual commands:
$ grunt core
This command builds the core assets and places them in core/
.
$ grunt docs
This command builds the documentation and places it in docs/
and copies
what's currently in core/
into docs/assets/core/
for use by the
documentation and examples.
$ grunt watch
This command starts Grunt in a 'watch' mode. This monitors files in src/
and if something changes it will run the appropriate tasks to rebuild
core/
and docs/
. It also starts a live reload server so that any pages
open to local copies of the docs will reload automatically once core/
and docs/
have finished building.
This is really helpful when actively developing patterns.
Note: always run grunt
at least once before running grunt watch
since it only rebuilds the parts that have changed.
Individual patterns are stored within subfolders in /src/patterns/*
.
Each pattern comprises of the following files (where pattern
is the name of the pattern):
File / folder | Description |
---|---|
pattern.doc.hbs |
Documentation about the pattern, including options and source code. |
pattern.hbs |
HTML for the pattern, in Handlebars format. |
pattern-options.json |
Data for building the various pattern options. |
_pattern.scss |
Sass partial that contains the CSS to style the pattern. |
pattern.js |
JavaScript partial that adds interactivity to the pattern. |
There is a dummy pattern in the DPL which may be used as a template when creating a new pattern. You can find this in /src/patterns/dummy-pattern
.
First, decide the name of your new pattern. Then decide on a computer-friendly version for naming folders and files; it must only consist of lowercase letters and hyphens.
The name should be semantic, descriptive and obvious.
In the following example we will use these names:
Description | Value |
---|---|
Name of pattern | Widget |
Computer-friendly name | widget |
Using your preferred Git client, create a new branch using your new pattern name, e.g.
FEAT-widget-pattern
We tend to prefix the branch name with the type of change we are making, e.g. BREAK
, DOCS
, FEAT
, FIX
, etc. You can find a list of these in the commit messages style guide.
Create a new folder within \src\patterns\
with your computer-friendly pattern name. In this example it would be \src\patterns\widget
.
Now within your new folder, create the five basic files you need to create a pattern:
widget.doc.hbs
- Documentationwidget.hbs
- Pattern templatewidget-options.json
- Data detailing pattern options_widget.scss
- Sass that will be compiled to CSSwidget.js
- JavaScript
(This is where the dummy pattern can come in handy, simply copy the contents of \src\patterns\dummy-pattern
into your new pattern and rename the files using your new pattern name.)
The documentation file (in this example widget.doc.hbs
) is written in a combination of HTML and the logic-less JavaScript templating engine Handlebars, with a small YAML front piece at the top of the document. This title element is used both in the page <title>
and in the page heading.
The document looks something like this:
The options available block loops through the options[]
array in widget-options.json
to build a table of contents.
The second block ({{#widget-options.options}}
) loops through the options array again in widget-options.json
to output each of the options. This uses the widget.hbs
Handlebars partial ({{> widget}}
) as a template, passing in the data from the options array within the JSON file.
The second instance of the partial in that block outputs the same code but within a code block:
<pre><code class="pattern-source html">{{> widget}}</code></pre>
This block has two CSS classes:
- The mandatory
pattern-source
class instructs a JavaScript function in the DPL to encode all HTML elements, i.e. change<
to<
and>
to>
so that the code outputs on the page, rather than renders. - The optional
html
class instructs another JavaScript plugin to syntax highlight the code as HTML. (This uses the code pattern.)
When Grunt runs, an index.html
file is created within /docs/patterns/PATTERN_NAME/
, in this example, /docs/patterns/widget/
. It wraps your documentation file within the code found in /src/_layouts/pattern.hbs
.
The template file must be named after the computer-friendly version of the pattern name, in this example it would be widget.hbs
.
This file contains the pattern itself, written using a combination of HTML and Handlebars expressions. Using Handlebars means that you can populate dynamic portions of the HTML with Handlebars values; in other words, you can use the same template with multiple options using if... then statements.
The assemble-handlebars Grunt task builds HTML code using the data from the *-options.json
file.
For more information see the following for documentation:
- The options file must have the same filename as the template file, followed by
-options.json
. In this example, this would bewidget-options.json
.
This JSON file contains the following basic information:
{
"options" : [
{
"option-heading": "Default widget",
"option-description": "<p>Information about the option, written in HTML, with no line-breaks.</p>",
"option-anchor": "default-widget"
}
]
}
Other options are added as required.
- The first three entries are mandatory for each option, even if there is only one. These build the options available table of contents, and headings and descriptions for each of the options on the documentation page.
- Custom name/value pairs may be created as required.
Add the CSS you require for your pattern in this file.
- The filename must begin with an underscore (
_
) – without it the Sass processor will not consider it a partial. - The filename must have the same filename as the pattern template file but with a
.scss
suffix; in this example,_widget.scss
. - The file must begin and end with the following comments:
/*********************************/
/* BEGIN Pattern: widget */
/*********************************/
// Add your CSS/Sass code here.
/*********************************/
/* END Pattern: widget */
/*********************************/
This file will be compiled by Compass into CSS and added to /core/styles/screen.css
.
Add the JavaScript you require for your pattern in this file.
- You may use jQuery code as well as 'vanilla' JavaScript.
- The filename must have the same name as the pattern template file but with a
.js
suffix; in this examplewidget.js
. - The file must begin and end with the following comments:
/*********************************/
/* BEGIN Pattern: widget */
/*********************************/
// Add your JavaScript/jQuery code here.
/*********************************/
/* END Pattern: widget */
/*********************************/
When you run Grunt next time this file will be found automatically and included in /core/scripts/core.js
.
With the new files in place, you now need to tell the DPL where your new pattern is. You do this in two places:
Add your new Sass partial as an @import
to the file /src/styles/screen.scss
beneath the Patterns import
section. For example, in this example you would add _widget.scss
to:
@import 'tile/tile';
@import 'tile-grid/tile-grid';
@import 'widget/widget';
- You must not include the underscore or file suffix, just the pattern's directory name: the DPL will automatically add those.
- Make sure you add your new pattern to the list alphabetically; this simply makes the patterns easier to manage later.
Now add your new pattern to the correct category on the patterns page.
In the file /src/_meta/patterns_page.json
add an item at the appropriate place, like so:
{
"heading": "Content",
"subheading": "Patterns used to display content in various ways.",
"patterns": [
{ "name": "Accordion",
"img": "assets/docs/images/patterns/accordion.jpg",
"url": "patterns/accordion/index.html"
},
{
...
},
{ "name": "Widget",
"img": "assets/docs/images/patterns/widget.jpg",
"url": "patterns/widget/index.html"
}
]
}
If the pattern doesn't yet have a custom image use the generic pattern.jpg
, like this:
"img": "assets/docs/images/patterns/pattern.jpg",
After you've got the pattern created you should run grunt
. This will build the core/
folder and the docs/
folder.
Make sure you don't have any errors. If you open docs/patterns.html
in your browser you should be able to see your new pattern showing up in the listing.
You should also be able to visit the documentation page and see the basic examples displayed.
Now that we have a working stub of the pattern – perhaps without any working CSS or JavaScript or even maybe the correct HTML – we're ready to create a first commit.
Make sure that you've created a new branch for this feature and create a new commit containing the work to create the new pattern.
You should now be ready to continue working on your pattern.
Remember to commit small changes and often, using the code style guide for guidance on how to write your HTML, CSS and JavaScript code, and compose your commit messages.
Add example pages to the /src/examples/*
directory.
Similar to pattern documentation files, these should be written in a combination of HTML with Handlebars and a YAML front piece.
For example:
Pattern partials may be called directly, as Handlebars partials are global in scope.
You may call Handlebars data from the pattern options JSON files, or create local ones within the /src/patterns/_data/
directory. The format for this is: