Skip to content

Commit

Permalink
feat: rename and redirect collections (resolves #1664) (#1677)
Browse files Browse the repository at this point in the history
  • Loading branch information
greatislander committed Feb 6, 2024
1 parent e460cdb commit 6e43e11
Show file tree
Hide file tree
Showing 136 changed files with 317 additions and 310 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
node_modules
_site
.env

# Local Netlify folder
.netlify
81 changes: 31 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,16 @@ The source code for the We Count website.

The front end of the website is built with [Eleventy](https://11ty.dev/).

The website uses [Netlify CMS](https://netlifycms.org) to manage the following content:
The website uses [Decap CMS](https://decapcms.org) to manage the following content:

- [initiatives](src/collections/initiatives)
- [events](src/collections/events)
- [pages](src/collections/pages)
- [news](src/collections/news)
- [views](src/collections/views)

The website uses [Netlify Large Media](https://docs.netlify.com/large-media/overview/) for storing uploaded files with
Git LFS. Developers must install [Git LFS](https://git-lfs.github.com/) and
[consult the documentation for Netlify Large Media](https://docs.netlify.com/large-media/setup/) to ensure that they are
working properly with the Git repository locally.
- [initiatives](src/collections/initiatives)

The website also uses one backend API:

- [Airtable API](https://airtable.com/api) that serves user comments for initiatives.
- [Airtable API](https://airtable.com/api) that serves user comments for events.
- The production table: WeCount
- The development table: WeCount_DEV

Expand All @@ -32,9 +27,7 @@ The website also uses one backend API:
To contribute, please be sure to review our development processes as documented in the
[contributing](.github/CONTRIBUTING.md) guide.

To work on the project, you need to install [NodeJS and NPM](https://nodejs.org/en/download/) for your operating system,
as well as [Git LFS](https://git-lfs.github.com/) to ensure that you can work with uploaded files managed via
[Netlify Large Media](https://docs.netlify.com/large-media/overview/) while working with the Git repository locally.
To work on the project, you need to install [NodeJS and NPM](https://nodejs.org/en/download/) for your operating system.

Then, clone the project from GitHub. [Create a fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo)
with your GitHub account, then enter the following in your command line (make sure to replace `your-username` with your username):
Expand All @@ -49,39 +42,27 @@ From the root of the cloned project, enter the following in your command line to
npm ci
```

Add _Large Media_ support to the local development environment:

```bash
netlify lm:install
```

After running the following command, the output may instruct you to run further commands; run these as well. **Please note
that the command will be different on every environment.**

```bash
# this is an example, the path may be different depending on the environment
source /home/username/.config/netlify/helper/path.bash.inc
```

## Content Management System (CMS)

[Netlify CMS](https://netlifycms.org) is a client-side React application which manages files in a git repository,
[Decap CMS](https://decapcms.org) is a client-side React application which manages files in a git repository,
creating pull requests when new content is drafted and merging them when it is published. Access to this website's
CMS is managed via [Netlify Identity](https://docs.netlify.com/visitor-access/identity/). If you need access to the
CMS, a team administrator must invite you to create a Netlify Identity account.

### CMS Configuration

The CMS is configured via a [config.yml](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/e082fdd17c08d53fd6910f055132e3dd150fbb79/src/admin/config.yml)
file according to Netlify CMS' [specifications](https://www.netlifycms.org/docs/configuration-options/).
As an example, here is the configuration for the initiatives collection, stored in [`src/collections/initiatives`](src/collections/initiatives):
file according to Decap CMS' [specifications](https://www.decapcms.org/docs/configuration-options/).
As an example, here is the configuration for the events collection, stored in [`src/collections/events`](src/collections/events):

```yaml
- name: initiatives
label: Initiatives
label_singular: Initiative
folder: src/collections/initiatives
- name: events
label: Events
label_singular: Event
folder: src/collections/events
sortable_fields: [eventDate, title]
slug: "{{title}}"
preview_path: "events/{{slug}}"
create: true
fields:
- label: Event Title
Expand All @@ -90,14 +71,14 @@ As an example, here is the configuration for the initiatives collection, stored
- label: Event ID
name: id
widget: uuid
hint: The ID is used to associate comments with this initiative and cannot be edited.
hint: The ID is used to associate comments with this event and cannot be edited.
- label: Permanent Link
name: permalink
widget: string
required: false
hint: |-
If you do not specify a permanent link, one will be automatically generated from the event title.
Permalinks must have the format /initiatives/event-title/ (the trailing slash is required).
Permalinks must have the format /events/event-title/ (the trailing slash is required).
- label: Event Date
name: eventDate
widget: datetime
Expand All @@ -117,43 +98,43 @@ As an example, here is the configuration for the initiatives collection, stored
- label: Short Description
name: shortDescription
widget: markdown
hint: The short description is shown on the Initiatives page.
hint: The short description is shown on the Events page.
- label: Preview Image
name: previewImageUrl
widget: image
required: false
hint: The preview image is shown on the Initiatives page.
hint: The preview image is shown on the Events page.
- label: Preview Image Alt Text
name: previewImageAltText
widget: string
required: false
```
For information on individual widgets and their configuration, see Netlify CMS' [widget documentation](https://www.netlifycms.org/docs/widgets/).
For information on individual widgets and their configuration, see Decap CMS' [widget documentation](https://www.decapcms.org/docs/widgets/).
### Previews
Netlify CMS supports [preview templates](https://www.netlifycms.org/docs/customization/) for CMS content, which must be
a React component registered with the following code (the following examples are for initiatives):
Decap CMS supports [preview templates](https://www.decapcms.org/docs/customization/) for CMS content, which must be
a React component registered with the following code (the following examples are for events):
```javascript
CMS.registerPreviewTemplate("initiatives", Initiative);
CMS.registerPreviewTemplate("events", Event);
```

The `Initiative` React component is created in [src/admin/cms.js](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/e082fdd17c08d53fd6910f055132e3dd150fbb79/src/admin/cms.js)
The `Event` React component is created in [src/admin/cms.js](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/main/src/admin/cms.js)
based on a technique demonstrated in [Andy Bell's Hylia Eleventy starter kit](https://github.com/hankchizljaw/hylia):

1. The site's Nunjucks templates are [precompiled](https://mozilla.github.io/nunjucks/api.html#precompiling) and copied
to the admin directory of the built site (Eleventy handles this [here](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/e082fdd17c08d53fd6910f055132e3dd150fbb79/src/admin/admin.11ty.js)).
2. A generic [`Preview`](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/e082fdd17c08d53fd6910f055132e3dd150fbb79/src/admin/cms.js#L20-L24)
to the admin directory of the built site (Eleventy handles this [here](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/dev/src/admin/admin.11ty.js)).
2. A generic [`Preview`](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/277cb52c0e7880bf400ab6f827c4b705080c9f73/src/admin/cms.js#L25-L30)
React component accepts a data object and a Nunjucks template path, renders the Nunjucks template with the supplied
data using [Nunjucks Slim](https://mozilla.github.io/nunjucks/getting-started.html#when-in-the-browser), and outputs
the resulting HTML.
3. The specific [`Initiative`](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/e082fdd17c08d53fd6910f055132e3dd150fbb79/src/admin/cms.js#L35-L52)
React component passes the Preview component the entry object (from Netlify CMS), the Nunjucks template path (relative
3. The specific [`Event`](https://github.com/greatislander/wecount.inclusivedesign.ca/blob/277cb52c0e7880bf400ab6f827c4b705080c9f73/src/admin/cms.js#L120-L142)
React component passes the Preview component the entry object (from Decap CMS), the Nunjucks template path (relative
to `src/_includes`), and a function which maps the entry object's data to what's needed in the Nunjucks template expects.

This approach allows the templates which Eleventy uses to render the production site to be consumed by Netlify CMS and
This approach allows the templates which Eleventy uses to render the production site to be consumed by Decap CMS and
used to generate live previews as content editors are updating content in the CMS interface.

### Testing the CMS
Expand Down Expand Up @@ -268,9 +249,9 @@ npm run lint

We use the following lint configurations:

- TODO: [ESLint (JS)](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/main/.eslintrc.js)
- [Stylelint (CSS/SCSS)](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/main/stylelint.config.js)
- [MarkdownLint (Markdown)](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/main/.markdownlint.json)
- [ESLint (JS)](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/main/.eslintrc.js)
- [Stylelint (CSS/SCSS)](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/main/.stylelintrc.js)
- [MarkdownLint (Markdown)](https://github.com/inclusive-design/wecount.inclusivedesign.ca/blob/main/.markdownlint-cli2.cjs)

## How to Build

Expand Down
17 changes: 8 additions & 9 deletions eleventy.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ require("./src/assets/scripts/utils.js");

module.exports = function (eleventyConfig) {

eleventyConfig.addCollection("initiatives", collection => {
eleventyConfig.addCollection("events", collection => {
return [
...collection.getFilteredByGlob("src/collections/initiatives/*.md").sort((a, b) => b.data.eventDate - a.data.eventDate)
...collection.getFilteredByGlob("src/collections/events/*.md").sort((a, b) => b.data.eventDate - a.data.eventDate)
];
});

eleventyConfig.addCollection("news", collection => {
eleventyConfig.addCollection("initiatives", collection => {
return [
...collection.getFilteredByGlob("src/collections/news/*.md").sort((a, b) => b.data.date - a.data.date)
...collection.getFilteredByGlob("src/collections/initiatives/*.md").sort((a, b) => b.data.date - a.data.date)
];
});

eleventyConfig.addCollection("views", collection => {
eleventyConfig.addCollection("recount", collection => {
return [
...collection.getFilteredByGlob("src/collections/views/*.md").sort((a, b) => b.data.date - a.data.date)
...collection.getFilteredByGlob("src/collections/recount/*.md").sort((a, b) => b.data.date - a.data.date)
];
});

Expand All @@ -60,8 +60,8 @@ module.exports = function (eleventyConfig) {
];
});

eleventyConfig.addCollection("viewsTags", collection => {
return getUniqueTags(collection.getFilteredByGlob("src/collections/views/*.md"));
eleventyConfig.addCollection("initiativesTags", collection => {
return getUniqueTags(collection.getFilteredByGlob("src/collections/initiatives/*.md"));
});

eleventyConfig.addCollection("allTags", collection => {
Expand Down Expand Up @@ -138,7 +138,6 @@ module.exports = function (eleventyConfig) {

// Configure passthrough file copy.
eleventyConfig.addPassthroughCopy({"src/_redirects": "_redirects"});
eleventyConfig.addPassthroughCopy({"manifest.json": "manifest.json"});
eleventyConfig.addPassthroughCopy({"node_modules/infusion": "lib/infusion"});
eleventyConfig.addPassthroughCopy({"src/assets/fonts": "assets/fonts"});
eleventyConfig.addPassthroughCopy({"src/assets/images": "assets/images"});
Expand Down
2 changes: 1 addition & 1 deletion functions/comments.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Handle client requests for adding comments for initiatives. This script does:
* Handle client requests for adding comments for events. This script does:
* 1. Save the comment to Airtable;
* 2. Send an email to moderator that a new comment has been posted and waiting for a review/
*
Expand Down
4 changes: 2 additions & 2 deletions src/_includes/components/filter.njk
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

<div class="filter-body">
<ul class="filter-choices">
{% for tag in collections.viewsTags %}
{# Since there are 2 filters on the "Views" page (one for the static view and the other for the dynamic view),
{% for tag in collections.initiativesTags %}
{# Since there are 2 filters on the "Initiatives" page (one for the static view and the other for the dynamic view),
randomize the "id" of checkboxes to make sure every ID is unique on the page to avoid the html validation error. #}
{% set tagId = tag.slug | randomizeFilter %}
<li>
Expand Down
4 changes: 2 additions & 2 deletions src/_includes/components/grid-item.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<article class="news-item">
{% if item.data.category === 'views' %}
{% if item.data.category === 'initiatives' %}
<div class="preview-media-wrapper">
<figure class="content">
{% if item.data.picture %}
Expand All @@ -16,7 +16,7 @@
<h2 class="h3">
<a href="{{ item.url if item.url else item.data.link }}">{{ item.data.title | safe }}</a>
</h2>
{% if item.data.category === 'views' %}
{% if item.data.category === 'initiatives' %}
<div class="author">{{ item.data.author | safe }}</div>
{% endif %}
<div class="date">
Expand Down
58 changes: 58 additions & 0 deletions src/_includes/layouts/event.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{% if previewMode %}
{% extends 'layouts/preview.njk' %}
{% else %}
{% extends 'layouts/base.njk' %}
{% endif %}

{% set pageTitle = page.title %}

{% block content %}
<article class="event-page">
<h1>{{ title | safe }}</h1>
{% if coverImageUrl %}
<img class="event-cover-image" src="{{ coverImageUrl | safe }}" alt="{{ coverImageAltText }}">
{% endif %}

<div class="description">{{ content | safe }}</div>

<form id="comment-form">
<h3>Comments</h3>
<div class="form-field">
<span>*</span><p class="asterisk-def"> Indicates required field</p>
</div>

<div class="form-field">
<span>*</span><h4><label for="name">Name</label></h4><span class="required-name">Required</span>
<input id="name" type="text" name="name" placeholder="" aria-label="Enter your name">
</div>

<div class="form-field">
<span>*</span><h4><label for="comment">Post a comment or question</label></h4><span class="required-comment">Required</span>
<textarea id="comment" name="comment" placeholder="" aria-label="Enter your comment"></textarea>
<input type="hidden" name="initiativeId" id="initiativeId" value="{{ id }}">
<button id="post-comment" type="submit">Post a comment</button>
</div>
</form>

<div class="submit-success-message" role="status">
<span>Thank you for submitting your comment. It will be posted on the page once it is approved</span>
</div>

<div class="submit-failure-message" role="alert">
<span>There was an error submitting your comment. Please try again</span>
</div>

<div class="comments">
{% for comment in collections.comments %}
{% if comment.initiativeId === id %}
{% include 'components/comment.njk' %}
{% endif %}
{% endfor %}
</div>
</article>
{% endblock %}

{% block footerScripts %}
<script src="/assets/scripts/utils.js"></script>
<script src="/assets/scripts/event-comments.js"></script>
{% endblock %}
Loading

0 comments on commit 6e43e11

Please sign in to comment.