ICJ Project Template
A Node-based template system with a Gulp workflow set up for Github Pages publishing.
Features:
- Bootstrap 4.1.
- Sass with autoprefixer.
- Nunjucks templates with
journalize
filters. Data can be made available to templates through theproject.config.json
file or files in thenjk/_data
folder. - Browsersync server.
- Image compression for jpeg, png and webp formats.
- Publishing to
docs/
for Github Pages.
Setup
If you are in my ICJ class, this is already done, but others will need to make sure you have gulp installed globally: npm install -g gulp-cli
.
- Create a project folder to hold all your code.
- Open VS Code into that folder and open the Terminal.
- Run
degit utdata/icj-project-template
. - Create your Github repo and connect them.
Understanding this project
Most of the files you edit for this project are in the src
directory. The Gulp production process will generate the publishable files into the docs
folder, which you shouldn't touch.
├── src
| ├── img
| ├── js
| ├── njk
| | ├── index.njk (Each .njk file becomes an html page)
| | ├── detail-page.njk
| | ├── _data (For data)
| | ├── _layouts (For templates)
| | └── _partials (For reusable code)
| └── scss (For Sass files)
Each .njk
file inside src/njk
is published as an html file in docs/
All the other folders inside src/njk
support those pages through Nunjucks templates.
Nunjucks templates
Nunjucks allows you to break your HTML into reuseable templates so you don't have to repeat code for each page on your site.
Templates work off several basic concepts:
- Template inheritance using extends.
- blocks which serve as variables or replaceable code.
- include which pulls in code from other files.
With these tools, you can build a site framework once as a Layout, and then extend or "use" that layout and all it's code, but swap out predefined blocks specific to your new page.
Layouts
Layouts and partials are parts of files used and extended elsewhere.
- The layout
src/njk/_layouts/base.njk
is an example base template for a site. The idea is to build the framework of the site only once, even though you have many pages. - The layout
src/njk/_layouts/detail.njk
is an example of a layout that extends the base layout, but then allows the user to insert different content through the content block. - Anything in
src/njk/_partials/
are snippets of code used by other layouts through a Nunjucks tag called include.
The Nunjucks community has adopted .njk
as the file extension for templates. Because these files are in folder names that start with _
and not at the src/njk/
level, they do NOT become actual webpages on your site.
Pages
All pages are kept in the root of the src/njk/
folder. Each .njk
file created here becomes an HTML page in docs/
, and therefore a page on your website.
- The page
src/njk/index.njk
is the main website page that extendssrc/njk/_layouts/base.njk
. You are coding only the main content of the page, and inheriting all the nav and other framework from the layout. - The page
src/njk/detail-page.njk
extends thesrc/njk/_layouts/detail.njk
layout, which is already extendingbase.njk
. It allows you to have a different structure for your content, yet still reuse navigation and such from the base layout.
Using data in Nunjucks templates
Nunjucks has special tags to apply logic, like looping through data within templates.
Most data should be saved as key-value pairs in a javascript array in the src/njk/_data/data.json
. An example might be this:
"books": [
{
"title": "The Clown",
"author": "Heinrich Böll"
},
{
"title": "The Shipping News",
"author": "Annie Proulx"
}
]
}
- You can access this data in a loop as
data.books.title
. There is an example in theindex.njk
file. - You can add new
*.json
files intosrc/njk/_data/
and they will be added to the Nunjucks context asfilename.arrayname.property
. - You can also set global variables in
project.config.json
as key-value pairs or arrays.
IMPORTANT: If you add/change/delete data in JSON files, you must re-run the
gulp dev
command to make it available to Nunjucks.
Have a spreadsheet of data that you need to convert to JSON? Try csvjson.com.
Filtering data for detail pages
It is possible to select a single node or "row" from an array in data.filename.json
by its position to use in a detail page using the Nunjucks set tag. The position order starts at zero, so using the books example above, you could access "The Shipping News" author (and similar properties) like this:
{% set book = data.books[1] %}
<h1>{{ book.title }}</h1> # gets "The Shipping News" in data above
Using this method, you can create a single detail layout that can be extended to multiple detail pages, each using a single "row" from the JSON array. There is an example in src/njk/detail-page.html
.
Sass/scss
The src/scss/
folder holds all the SCSS files. It is configured for Bootstrap and the CSS gets compiled into the docs
folder for publication.
There is also and example of a Sass partial with the src/scss/_nav.scss
file, which is imported into src/scss/main.scss
.
Deployment
This project is designed to bundle the finished website into the docs
folder, which can then be published anywhere you have a server.
By default, the docs/
folder is committed to Github because we are using Github Pages for free hosting of our site.
Review Github Pages for specific directions on deployment.
Technical bits on how this project is structured
Gulp
Gulp is task runner and is configured in gulpfile.js
. Individual tasks live in the tasks
folder.
- The default
gulp
task runs thestyles
,lint
,scripts
,images
andnunjucks
tasks to create the production files. - Running
gulp dev
runs the default tasks above plusserve
for the BrowserSync server. - To run any specific gulp task:
gulp <name of task>
, e.g.gulp clean
.
Tasks
clean.js
: Deletes the contents of thedocs
directory usingdel
.clear.js
: Clears out the gulp cache. Useful to reprocess images of the same name stuck in cache. Rungulp clear
then re-rungulp
.images.js
: Optimize images usinggulp-imagemin
andimagemin-mozjpeg
packages.lint.js
: Checks syntax of your (optionally ES6) javascript in/src/js/
usinggulp-eslint
-- it's a good idea to have an eslint package installed in your text editor of choice, as well.nunjucks.js
: Builds out html pages using [gulp-nunjucks-render
].(https://github.com/carlosl/gulp-nunjucks-render) (see notes below).scripts.js
: Babel/concat/uglify javascript in/src/js/
usinggulp-babel
,gulp-concat
andgulp-uglify
.serve.js
: Spins up a BrowserSync server atlocalhost:3000
. Bundled with watch tasks for css/js/template changes.styles.js
: Processes Sass files from/src/scss/
into minified css usinggulp-sass
,gulp-sourcemaps
,gulp-autoprefixer
andgulp-cssnano
.
More on Nunjucks
You can add custom filters and global variables in the manageEnv
function inside tasks/nunjucks.js
.
A collection of functions useful for making prose reader friendly is already included with journalize
.
Future development
- I'd like to add a Nunjucks Markdown package of some sort to allow adding/editing of basic text in Markdown, perhaps with front-matter. Would prefer to hook up through Google Docs. See Issue 17.
- I'd like to loop through data to create detail pages.