UNPKG

19.4 kBMarkdownView Raw
1<h1 align="center">
2 data-visuals-create
3</h1>
4<p align="center">
5 <a href="https://www.npmjs.org/package/@data-visuals/create"><img src="https://img.shields.io/npm/v/@data-visuals/create.svg?style=flat" alt="npm"></a>
6 <a href="https://david-dm.org/texastribune/data-visuals-create"><img src="https://david-dm.org/texastribune/data-visuals-create/status.svg" alt="dependencies"></a>
7 <a href="https://david-dm.org/texastribune/data-visuals-create/?type=dev"><img src="https://david-dm.org/texastribune/data-visuals-create/dev-status.svg" alt="devDependencies"></a>
8</p>
9
10A tool for generating the scaffolding needed to create a graphic or feature the Data Visuals way.
11
12## Key features
13
14- 📐 **HTML templating with a familiar, easy Jinja2-esque format** via a modified instance of a [Nunjucks](https://github.com/mozilla/nunjucks) environment that comes with all the functionality of [`journalize`](https://github.com/rdmurphy/journalize) by default.
15- 🎨 **Supports SCSS syntax** for styles compiled with the super fast reference implementation of Sass via [`dart-sass`](https://github.com/sass/dart-sass). All CSS is passed through [`autoprefixer`](https://github.com/postcss/autoprefixer) and minified with [`clean-css`](https://github.com/jakubpawlowicz/clean-css) in production.
16- 📦 A **configured instance of Webpack ready to go** and optimized for a [two-path modern/legacy bundle approach](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/). Ship lean ES2015+ code to modern browsers, and a functional polyfilled/transpiled bundle to the rest!
17- 📑 Full-support for **[ArchieML](http://archieml.org/) formatted Google Docs and key/value or table formatted Google Sheets**. Use data you've collaborated on with reporters and editors directly in your templates.
18- 🎊 And so, so, so much more!
19
20## Getting started
21
22```sh
23npx @data-visuals/create feature my-great-project
24cd feature-my-great-project-YYYY-MM # the four digit year and two digit month
25npm start
26```
27
28> While you can install `@data-visuals/create` globally and use the `data-visuals-create` command, we recommend using the `npx` method instead to ensure you are always using the latest version.
29
30## Table of contents
31
32<!-- START doctoc generated TOC please keep comment here to allow auto update -->
33<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
34
35
36- [Installation](#installation)
37- [Usage](#usage)
38- [Development and testing](#development-and-testing)
39- [Folder structure](#folder-structure)
40 - [config/](#config)
41 - [data/](#data)
42 - [workspace/](#workspace)
43 - [project.config.js](#projectconfigjs)
44 - [app/](#app)
45 - [app/index.html, app/static.html](#appindexhtml-appstatichtml)
46 - [app/templates/](#apptemplates)
47 - [app/scripts/](#appscripts)
48 - [app/styles/](#appstyles)
49 - [app/assets/](#appassets)
50 - [Other directories you may see](#other-directories-you-may-see)
51 - [.tmp/](#tmp)
52 - [dist/](#dist)
53- [How to work with Google Doc and Google Sheet files](#how-to-work-with-google-doc-and-google-sheet-files)
54 - [Google Docs](#google-docs)
55 - [Google Sheets](#google-sheets)
56- [Supported browsers](#supported-browsers)
57- [How do JavaScript packs work?](#how-do-javascript-packs-work)
58 - [Creating a new entrypoint](#creating-a-new-entrypoint)
59 - [Connecting an entrypoint to an HTML file](#connecting-an-entrypoint-to-an-html-file)
60- [Available commands](#available-commands)
61 - [`npm start` or `npm run serve`](#npm-start-or-npm-run-serve)
62 - [`npm run deploy`](#npm-run-deploy)
63 - [`npm run data:fetch`](#npm-run-datafetch)
64 - [`npm run assets:push`](#npm-run-assetspush)
65 - [`npm run assets:pull`](#npm-run-assetspull)
66 - [`npm run workspace:push`](#npm-run-workspacepush)
67 - [`npm run workspace:pull`](#npm-run-workspacepull)
68- [Environment variables and authentication](#environment-variables-and-authentication)
69 - [AWS](#aws)
70 - [Google](#google)
71 - [CLIENT_SECRETS_FILE](#client_secrets_file)
72 - [GOOGLE_TOKEN_FILE](#google_token_file)
73- [License](#license)
74
75<!-- END doctoc generated TOC please keep comment here to allow auto update -->
76
77## Installation
78
79While we recommend using the `npx` method, you can also install the tool globally. If you do, replace all instances of `npx @data-visuals/create` you see with `data-visuals-create`.
80
81```sh
82npm install -g @data-visuals/create
83```
84
85## Usage
86
87```sh
88npx @data-visuals/create <project-type> <slug>
89```
90
91Currently there are two project types available — `graphic` and `feature`.
92
93```sh
94npx @data-visuals/create graphic school-funding
95```
96
97This will create a directory for you, copy in the files, install the dependencies, and do your first `git commit`.
98
99The directory name will be formatted like this:
100
101```
102<project-type>-<slug>-<year>-<month>
103
104Using the example command above, it would be the following:
105graphic-school-funding-2018-01
106```
107
108This is to ensure consistent naming of our directories!
109
110## Development and testing
111
112If you make changes locally to `@data-visuals/create` and want to test them, you can run `data-visuals-create/bin/data-visuals-create <project-type> <slug>` to generate a graphic or feature and see if your changes were included. Run the command one level above this repo, or you'll create a graphic or feature within `data-visuals-create`.
113
114## Folder structure
115
116After creation, your project directory should look something like this:
117
118```
119your-project/
120 README.md
121 node_modules/
122 config/
123 data/
124 workspace/
125 package.json
126 project.config.js
127 app/
128 index.html
129 templates/
130 styles/
131 scripts/
132 assets/
133```
134
135Here are the highlights of what each file/directory represents:
136
137#### config/
138
139This is the directory of all the configuration and tasks that power the kit. You probably do not need to ever go in here! (And eventually this will be abstracted away.)
140
141#### data/
142
143Where data downloaded and processed with `npm run data:fetch` ends up. You are also free to manually (or via your own scripts!) put data files here - they will get pulled in too! Be aware that the only compatible data files that belong here are ones that [`quaff`](https://github.com/rdmurphy/quaff) knows how to consume, otherwise it will ignore them.
144
145#### workspace/
146
147The `workspace` directory is for storing all of your analysis, production and raw data files. It's important to use this directory for these files (instead of `app/assets/` or `data/`) so we can keep them out of GitHub and away from other parts of the kit. You interact with it using the `npm run workspace:push` and `npm run workspace:pull` commands.
148
149#### project.config.js
150
151Where all the configuration for a project belongs. This is where you can change the S3 deploy parameters, manage the Google Drive documents that sync with this project, set up a bespoke API or add custom filters to Nunjucks.
152
153#### app/
154
155Where you'll spend most of your time! Here are where all the assets that go into building your project live.
156
157#### app/index.html, app/static.html
158
159The starter HTML pages provided by the kit. `index.html` is for scripted graphics that require additional JavaScript, and `static.html` is for graphics that do not, like Illustrator embeds. Feel free to rename them!
160
161If your project is only a single page (or graphic), you can pick one of them where you do all your HTML work. No special configuration is required to create new HTML files - just creating a new `.html` file in in the `app` directory (but _not_ within `app/scripts/` or `/app/templates/` - HTML files have special meanings in those directories) is enough to tell the kit about new pages it should compile.
162
163When embedding graphics other than `index.html`, remember to add the name of the template to the end of the embed link. The default link points to `index`.
164
165#### app/templates/
166
167Where all the Nunjucks templates (including the `base.html` template that `app/index.html` inherits from), includes and macros live.
168
169#### app/scripts/
170
171Where all of our JavaScript files live. Within this folder there are a number of helpful utilities and scripts we've created across tons of projects. JavaScript imports work as you'd expect, but the `app/scripts/packs/` directory is special - learn more about it in the [How do JavaScript packs work?](#how-do-javascript-packs-work) section.
172
173#### app/styles/
174
175All the SCSS files that are used to compile the CSS files live here. This includes all of our house styles and variables (`app/styles/_variables.scss`). `app/styles/main.scss` is the primary entrypoint - any changes you make will either need to be in this file or be imported into it.
176
177#### app/assets/
178
179Where all other assets should live. This includes images, font files, any JSON or CSV files you want to directly interact with in your JavaScript - these files are post-processed and deployed along with the other production files. Be aware, **anything in this directory will technically be public on deploy**. Use `workspace/` or `data/` instead for things that shouldn't be public.
180
181### Other directories you may see
182
183#### .tmp/
184
185This is a temporary folder where files compiled during development will be placed. You can safely ignore it.
186
187#### dist/
188
189This is the compiled project and the result of running `npm run build`.
190
191## How to work with Google Doc and Google Sheet files
192
193`@data-visuals/create` projects support downloading ArchieML-formatted Google Docs and correctly-formatted Google Sheets directly from Google Drive for use within your templates. All files you want to use in your projects should be listed in `project.config.js` under the `files` key. You are not limited to one of each, either! (Our current record is **seven** Google Docs and **two** Google Sheets in a single project.)
194
195```js
196{ // ...
197 /**
198 * Any Google Doc and Google Sheet files to be synced with this project.
199 */
200 files: [
201 {
202 fileId: '<the-document-id-from-the-url>',
203 type: 'doc',
204 name: 'text',
205 },
206 {
207 fileId: '<the-sheet-id-from-the-url>',
208 type: 'sheet',
209 name: 'data',
210 },
211 // ...
212}
213```
214
215Each object representing a file needs three things:
216
217**fileId**
218
219The `fileId` key represents the ID of a Google Doc or Google Sheet. This is most easily found in the URL of a document when you have it open in your browser.
220
221**type**
222
223The `type` key is used to denote whether this is a Google Doc (`doc`) or a Google Sheet (`sheet`). This controls how it gets processed.
224
225**name**
226
227The `name` key controls what filename it will receive once it's put in the `data/` directory. So if the `name` is `hello`, it'll be saved to `data/hello.json`.
228
229### Google Docs
230
231ArchieML Google Docs work as documented on the [ArchieML](http://archieml.org/) site. This includes the automatic conversion of links to `<a>` tags!
232
233Our kit can display variables pulled in from Google Docs in the template. This is helpful when we want to show data in our text that is in the `data/` folder. Nunjucks finds the variable syntax (anything in curly braces) in our Google Doc text and displays the corresponding value.
234
235By default, Nunjucks has access to every file in our `data/` folder as an object. For example, if there are two files in the `data/` folder named `data.json` and `text.json` respectively, it will be structured as:
236
237```json
238{
239 "text": {
240 "title": "Phasellus venenatis dapibus ante, vel sodales sem blandit sed.",
241 },
242 "data": {
243 "keyvalue_sheet": {
244 "key1": "value1",
245 }
246 }
247}
248```
249
250You can then reference values in this data object as a variable, i.e. `{{ data.keyvalue_sheet.key1 }}` in the Google Doc.
251
252You can also pass in your own data object for Nunjucks to reference to the `prose`, `raw` and `text` macros. This will override any values in the default data object.
253
254### Google Sheets
255
256Google Sheets processed by `@data-visuals/create` may potentially require some additional configuration. Each sheet (or tab) in a Google Sheet is converted separately by the kit, and keyed-off in the output object by the _name of the sheet_.
257
258By default it treats every sheet in a Google Sheet as being formatted as a `table`. In other words, every _row_ is considered an item, and the _header row_ determines the key of each value in a _column_.
259
260The Google Sheets processor also supports a `key-value` format as popularized by [`copytext`](https://github.com/nprapps/copytext) ([and its Node.js counterpart](https://github.com/rdmurphy/node-copytext)). This treats everything in the _first column_ as the key, and everything in the _second column_ as the value matched to its key. Every other column is _ignored_.
261
262To activate the `key-value` format, add `:kv` to the end of a sheet's filename. (For consistency you can also use `:table` to tell the processor to treat a sheet as a `table`, but it is not required due to it being the default.)
263
264If there are any sheets you want to exclude from being processed, you can do it via two ways: hide them using the native _hide_ mechanism in Google Sheets, or add `:skip` to the end of the sheet name.
265
266## Supported browsers
267
268`@data-visuals/create` projects use a two-prong JavaScript bundling method to ship a lean, modern bundle for evergreen browsers and and a polyfilled, larger bundle for legacy browsers. It uses the methods promoted in Philip Walton's [Deploying ES2015+ Code in Production Today](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) blog post and determines browser support based on whether a browser understands ES Module syntax. If a browser does, it gets the **modern** bundle. If it doesn't, it gets the **legacy** bundle.
269
270In practice this means you mostly do not have to worry about it - as long as you're using the [JavaScript packs correctly](#how-do-javascript-packs-work) everything should just work. In terms of actual browsers, while we do still currently do a courtesy check of how things look in _Internet Explorer 11_, it's not considered a dealbreaker if a complicated feature or graphic does not work there and would require extensive work to ensure compatibility.
271
272For CSS we currently pass the following to [`autoprefixer`](https://github.com/postcss/autoprefixer).
273
274```json
275"browserslist": ["> 0.5%", "last 2 versions", "Firefox ESR", "not dead"]
276```
277
278## How do JavaScript packs work?
279
280Projects created with `@data-visuals/create` borrow a Webpack approach from [`rails/webpacker`](https://github.com/rails/webpacker) to manage JavaScript entrypoints without configuration. To get the right scripts into the right pages, you have to do two things.
281
282### Creating a new entrypoint
283
284By default every project will come with an entrypoint file located at `app/scripts/packs/main.js`, but you're not required to only use that if it makes sense to have different sets of scripts for different pages. **Any** JavaScript file that exists within `app/scripts/packs/` is considered a Webpack entrypoint.
285
286```sh
287touch app/scripts/packs/maps.js
288# Now the build task will create a new entrypoint called `maps`! Don't forget to add your code.
289```
290
291### Connecting an entrypoint to an HTML file
292
293Because there's a lot more going on behind the scenes than just adding a `<script>` tag, you have to set a special variable in a template in order to get the right entrypoint into the right HTML file.
294
295Set `jsPackName` anywhere in the HTML file to the name of your entrypoint (__without__ the extension) to route the right JavaScript files to it.
296
297```html
298{% set jsPackName = 'map' %}
299{# This is now using the new entrypoint we created above #}
300```
301
302Pack entrypoints can be used multiple times across multiple pages, so if your code allows for it feel free to add an entrypoint to multiple pages. (You can also add `jsPackName` to the base `app/templates/base.html` file and have it inserted in every page that inherits from it).
303
304## Available commands
305
306All project templates share the same build commands.
307
308#### `npm start` or `npm run serve`
309
310The main command for development. This will build your HTML pages, prepare your SCSS files and compile your JavaScript. A local server is set up so you can view the project in your browser.
311
312#### `npm run deploy`
313
314The main command for deployment. It will always run `npm run build` first to ensure the compiled version is up-to-date. Use this when you want to put your project online. This will use the `bucket` and `folder` values in the `project.config.js` file to determine where it should be deployed on S3. Make sure those are set the appropriate values!
315
316#### `npm run data:fetch`
317
318This command uses the array of files listed under the `files` key in `project.config.js` to download data to the project. This data will be processed and made available in the `data` folder in the root of the project.
319
320You can also set `dataDir` in `project.config.js` to change the location of that directory if necessary.
321
322#### `npm run assets:push`
323
324This pushes all the raw files found in the `app/assets` directory to S3 to a `raw_assets` directory. This makes it possible for collaborators on the project to sync up with your assets when they run `npm run assets:pull`. This prevents potentially large assets like photos and audio clips from ending up in GitHub. This also runs automatically when `npm run deploy` is used.
325
326#### `npm run assets:pull`
327
328Pulls any raw assets that have been pushed to S3 back down to the project's `app/assets` directory. Good for ensuring you have the same files as anyone else who is working on the project.
329
330#### `npm run workspace:push`
331
332The `workspace` directory is for storing all of your analysis, production and raw data files. It's important to use this directory for these files (instead of `assets` or `data`) so we can keep them out of GitHub. This command will push the contents of the `workspace` directory to S3.
333
334#### `npm run workspace:pull`
335
336Pulls any `workspace` files that have been pushed to S3 back down to the project's local `workspace` directory. This is helpful for ensuring you're in sync with another developer.
337
338## Environment variables and authentication
339
340Any projects created with `data-visuals-create` assume you're working within a Texas Tribune environment, but it is possible to point AWS (used for deploying the project and assets to S3) and Google's API (used for interfacing with Google Drive) at your own credentials.
341
342### AWS
343
344Projects created with `data-visuals-create` support two of the built-in ways that `aws-sdk` can authenticate. If you are already set up with the [AWS shared credentials file](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html) (and those credentials are allowed to interact with your S3 buckets), you're good to go. `aws-sdk` will also recognize the [AWS credential environmental variables](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-environment.html).
345
346### Google
347
348The interface with Google Drive within `data-visuals-create` projects currently only supports using Oauth2 credentials to speak to the Google APIs. This requires a set of OAuth2 credentials that will be used to generate and save an access token to your computer. `data-visuals-create` projects have hardcoded locations for the credential file and token file, but you may override those with environmental variables.
349
350#### CLIENT_SECRETS_FILE
351
352**default**: `~/.tt_kit_google_client_secrets.json`
353
354#### GOOGLE_TOKEN_FILE
355
356**default**: `~/.google_drive_fetch_token`
357
358## License
359
360MIT