@data-visuals/create 7.1.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/__common__/config/tasks/graphics-meta.js +93 -65
- package/templates/__common__/utils/deployment/update-log-sheet.js +67 -32
- package/templates/feature/app/index.html +73 -64
- package/templates/feature/app/scripts/components/Story.js +6 -2
- package/templates/feature/app/templates/base-graphic.html +64 -0
- package/templates/feature/app/templates/base.html +2 -0
- package/templates/feature/app/templates/components/footer.html +3 -3
- package/templates/feature/app/templates/graphic.html +47 -0
- package/templates/feature/app/templates/index-old.html +76 -0
- package/templates/feature/app/templates/macros/processors-queso.html +2 -2
- package/templates/feature/app/templates/macros/processors.html +1 -1
- package/templates/feature/project.config.js +25 -1
- package/templates/graphic/app/index.html +0 -15
- package/templates/graphic/app/templates/base.html +3 -6
- package/templates/graphic/app/templates/graphic.html +3 -0
- package/templates/graphic/graphics-meta.md +1 -0
- package/templates/graphic/project.config.js +9 -4
- package/templates/feature/app/index-queso.html +0 -81
package/package.json
CHANGED
|
@@ -138,30 +138,32 @@ const parseGraphic = async (
|
|
|
138
138
|
: `${localURL}/${parentDir}/${name}.html`;
|
|
139
139
|
await page.goto(url, { waitUntil: 'load' });
|
|
140
140
|
const label = path.join(parentDir, `${name}.html`);
|
|
141
|
-
const
|
|
142
|
-
const
|
|
141
|
+
const projectPath = path.join(folder, parentDir);
|
|
142
|
+
const projectURL = ensureSlash(`https://${bucket}/${folder}/${parentDir}`);
|
|
143
143
|
|
|
144
|
-
// only consider HTML with data-graphic attribute present
|
|
144
|
+
// only consider HTML with data-graphic or data-feature attribute present
|
|
145
145
|
try {
|
|
146
|
-
await page.waitForSelector('[data-graphic]', {
|
|
146
|
+
await page.waitForSelector('[data-graphic], [data-feature]', {
|
|
147
147
|
timeout: 5000,
|
|
148
148
|
});
|
|
149
149
|
} catch (e) {
|
|
150
150
|
return false;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
// get
|
|
153
|
+
// get metadata
|
|
154
154
|
const title = await getText({ key: 'title', page });
|
|
155
|
-
const caption = await getText({ key: 'caption', page });
|
|
156
|
-
const altText = await getText({ key: 'alt-text', page });
|
|
157
|
-
const note = await getText({ key: 'note', page });
|
|
158
|
-
const source = await getText({ key: 'source', page });
|
|
159
155
|
const tags = await (await getText({ key: 'tags', page })).split(',');
|
|
160
156
|
let credits = await getText({ key: 'credit', page });
|
|
161
157
|
|
|
162
|
-
//
|
|
158
|
+
// determine type of metadata
|
|
159
|
+
// assume the type is graphic unless data-feature is present
|
|
160
|
+
const type = (await page.$('[data-feature]')) ? 'feature' : 'graphic';
|
|
161
|
+
|
|
162
|
+
// ignore projects with no title
|
|
163
163
|
if (title.length === 0) {
|
|
164
|
-
logMessage(
|
|
164
|
+
logMessage(
|
|
165
|
+
`${label} was skipped because no graphic or feature was title set.`
|
|
166
|
+
);
|
|
165
167
|
return false;
|
|
166
168
|
}
|
|
167
169
|
|
|
@@ -174,70 +176,96 @@ const parseGraphic = async (
|
|
|
174
176
|
}
|
|
175
177
|
|
|
176
178
|
// find all links
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
179
|
+
if (type == 'graphic') {
|
|
180
|
+
const caption = await getText({ key: 'caption', page });
|
|
181
|
+
const altText = await getText({ key: 'alt-text', page });
|
|
182
|
+
const note = await getText({ key: 'note', page });
|
|
183
|
+
const source = await getText({ key: 'source', page });
|
|
184
|
+
|
|
185
|
+
const links = await page.$$eval('a', links =>
|
|
186
|
+
links.map(link => {
|
|
187
|
+
return {
|
|
188
|
+
url: link.getAttribute('href'),
|
|
189
|
+
text: link.textContent,
|
|
190
|
+
isCTA:
|
|
191
|
+
link.classList.contains('button') ||
|
|
192
|
+
link.classList.contains('.c-button'),
|
|
193
|
+
};
|
|
194
|
+
})
|
|
195
|
+
);
|
|
188
196
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
197
|
+
// take screenshots of page
|
|
198
|
+
const { small, large } = await createPreviews({
|
|
199
|
+
page,
|
|
200
|
+
outputPath,
|
|
201
|
+
});
|
|
194
202
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
203
|
+
// check if appleNewsIgnore is specified
|
|
204
|
+
let showInAppleNews = true;
|
|
205
|
+
if (parserOptions) {
|
|
206
|
+
const { appleNewsIgnore } = parserOptions;
|
|
207
|
+
showInAppleNews =
|
|
208
|
+
!appleNewsIgnore.includes(parentDir) &&
|
|
209
|
+
!appleNewsIgnore.includes(label);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// all graphic data
|
|
213
|
+
return {
|
|
214
|
+
type,
|
|
215
|
+
title,
|
|
216
|
+
altText,
|
|
217
|
+
bucket,
|
|
218
|
+
projectPath,
|
|
219
|
+
projectURL,
|
|
220
|
+
caption,
|
|
221
|
+
createMonth,
|
|
222
|
+
createYear,
|
|
223
|
+
credits,
|
|
224
|
+
folder,
|
|
225
|
+
id,
|
|
226
|
+
lastBuildTime,
|
|
227
|
+
label,
|
|
228
|
+
links,
|
|
229
|
+
note,
|
|
230
|
+
previews: {
|
|
231
|
+
large: projectURL + large,
|
|
232
|
+
small: projectURL + small,
|
|
233
|
+
},
|
|
234
|
+
showInAppleNews,
|
|
235
|
+
source,
|
|
236
|
+
tags,
|
|
237
|
+
};
|
|
201
238
|
}
|
|
202
239
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
large: graphicURL + large,
|
|
222
|
-
small: graphicURL + small,
|
|
223
|
-
},
|
|
224
|
-
showInAppleNews,
|
|
225
|
-
source,
|
|
226
|
-
tags,
|
|
227
|
-
};
|
|
240
|
+
if (type == 'feature') {
|
|
241
|
+
// all feature data
|
|
242
|
+
return {
|
|
243
|
+
type,
|
|
244
|
+
title,
|
|
245
|
+
bucket,
|
|
246
|
+
projectPath,
|
|
247
|
+
projectURL,
|
|
248
|
+
createMonth,
|
|
249
|
+
createYear,
|
|
250
|
+
credits,
|
|
251
|
+
folder,
|
|
252
|
+
id,
|
|
253
|
+
lastBuildTime,
|
|
254
|
+
label,
|
|
255
|
+
tags,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
228
258
|
};
|
|
229
259
|
|
|
230
260
|
module.exports = async localURL => {
|
|
231
|
-
const {
|
|
232
|
-
parserOptions,
|
|
233
|
-
} = config;
|
|
261
|
+
const { parserOptions } = config;
|
|
234
262
|
|
|
235
263
|
// find all html pages in project
|
|
236
264
|
const pages = await glob('**/*.html', {
|
|
237
265
|
absolute: true,
|
|
238
266
|
cwd: './.tmp',
|
|
239
267
|
recursive: true,
|
|
240
|
-
ignore: parserOptions.
|
|
268
|
+
ignore: parserOptions.metadataIgnore,
|
|
241
269
|
});
|
|
242
270
|
|
|
243
271
|
// spin up headless browser using local chrome
|
|
@@ -277,7 +305,7 @@ module.exports = async localURL => {
|
|
|
277
305
|
// output path
|
|
278
306
|
const manifest = `${paths.appDist}/manifest.json`;
|
|
279
307
|
|
|
280
|
-
// output JSON of all
|
|
308
|
+
// output JSON of all metadata
|
|
281
309
|
try {
|
|
282
310
|
await fs.outputJson(manifest, filtered);
|
|
283
311
|
} catch (err) {
|
|
@@ -286,11 +314,11 @@ module.exports = async localURL => {
|
|
|
286
314
|
|
|
287
315
|
// print output info in terminal
|
|
288
316
|
if (filtered.length > 0) {
|
|
289
|
-
logMessage(`Generated metadata for ${filtered.length}
|
|
317
|
+
logMessage(`Generated metadata for ${filtered.length} item(s)`, 'green');
|
|
290
318
|
console.log(`✔ ${manifest}`);
|
|
291
319
|
} else {
|
|
292
320
|
logMessage(
|
|
293
|
-
`No metadata generated. Could not find the data-graphic attribute in any HTML files.`,
|
|
321
|
+
`No metadata generated. Could not find the data-graphic or data-feature attribute in any HTML files.`,
|
|
294
322
|
'red'
|
|
295
323
|
);
|
|
296
324
|
}
|
|
@@ -23,17 +23,17 @@ function getFileLink(files, type) {
|
|
|
23
23
|
async function writeToSheet(
|
|
24
24
|
sheets,
|
|
25
25
|
spreadsheetId,
|
|
26
|
-
projectType,
|
|
27
26
|
projectID,
|
|
28
27
|
projectURL,
|
|
28
|
+
metadataType,
|
|
29
29
|
metadataInput
|
|
30
30
|
) {
|
|
31
31
|
// get corresponding sheet
|
|
32
32
|
let sheetName;
|
|
33
|
-
if (
|
|
33
|
+
if (metadataType === 'graphic') {
|
|
34
34
|
sheetName = 'Embedded';
|
|
35
35
|
}
|
|
36
|
-
if (
|
|
36
|
+
if (metadataType === 'feature') {
|
|
37
37
|
sheetName = 'Feature';
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -96,6 +96,7 @@ let updateLogSheet = async (mainPath, config) => {
|
|
|
96
96
|
const spreadsheetId = '1hCP5zGx8dNxk59gI9wBSFY2juJVM8OFCDY45VnNb2nI';
|
|
97
97
|
|
|
98
98
|
// loop through metadata JSON
|
|
99
|
+
// if there is no metadata
|
|
99
100
|
if (manifestJSON.length == 0) {
|
|
100
101
|
let metadataInput = [
|
|
101
102
|
[
|
|
@@ -119,42 +120,76 @@ let updateLogSheet = async (mainPath, config) => {
|
|
|
119
120
|
await writeToSheet(
|
|
120
121
|
sheets,
|
|
121
122
|
spreadsheetId,
|
|
122
|
-
config.projectType,
|
|
123
123
|
config.id,
|
|
124
124
|
mainPath,
|
|
125
|
+
config.projectType,
|
|
125
126
|
metadataInput
|
|
126
127
|
);
|
|
127
128
|
} else {
|
|
128
129
|
for (const metadata of manifestJSON) {
|
|
129
|
-
let metadataInput
|
|
130
|
-
|
|
130
|
+
let metadataInput;
|
|
131
|
+
if (metadata.type == 'graphic') {
|
|
132
|
+
metadataInput = [
|
|
133
|
+
[
|
|
134
|
+
metadata.id,
|
|
135
|
+
metadata.projectURL,
|
|
136
|
+
metadata.projectPath,
|
|
137
|
+
metadata.title,
|
|
138
|
+
metadata.caption,
|
|
139
|
+
metadata.altText,
|
|
140
|
+
`${metadata.createYear}-${metadata.createMonth}`,
|
|
141
|
+
metadata.lastBuildTime,
|
|
142
|
+
metadata.note,
|
|
143
|
+
metadata.source,
|
|
144
|
+
metadata.credits.join(', '),
|
|
145
|
+
metadata.tags.join(', '),
|
|
146
|
+
getFileLink(config.files, 'sheet'),
|
|
147
|
+
getFileLink(config.files, 'doc'),
|
|
148
|
+
metadata.previews.large,
|
|
149
|
+
metadata.previews.small,
|
|
150
|
+
],
|
|
151
|
+
];
|
|
152
|
+
}
|
|
153
|
+
if (metadata.type == 'feature') {
|
|
154
|
+
metadataInput = [
|
|
155
|
+
[
|
|
156
|
+
metadata.id,
|
|
157
|
+
metadata.projectURL,
|
|
158
|
+
metadata.projectPath,
|
|
159
|
+
metadata.title,
|
|
160
|
+
'',
|
|
161
|
+
'',
|
|
162
|
+
`${metadata.createYear}-${metadata.createMonth}`,
|
|
163
|
+
metadata.lastBuildTime,
|
|
164
|
+
'',
|
|
165
|
+
'',
|
|
166
|
+
metadata.credits.join(', '),
|
|
167
|
+
metadata.tags.join(', '),
|
|
168
|
+
getFileLink(config.files, 'sheet'),
|
|
169
|
+
getFileLink(config.files, 'doc'),
|
|
170
|
+
'',
|
|
171
|
+
'',
|
|
172
|
+
],
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// find hostname
|
|
177
|
+
let urlObj = new URL(metadata.projectURL);
|
|
178
|
+
|
|
179
|
+
// do not write when capybara-test is the hostname
|
|
180
|
+
if (
|
|
181
|
+
urlObj.hostname == 'graphics.texastribune.org' ||
|
|
182
|
+
urlObj.hostname == 'apps.texastribune.org'
|
|
183
|
+
) {
|
|
184
|
+
await writeToSheet(
|
|
185
|
+
sheets,
|
|
186
|
+
spreadsheetId,
|
|
131
187
|
metadata.id,
|
|
132
|
-
metadata.
|
|
133
|
-
metadata.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
`${metadata.createYear}-${metadata.createMonth}`,
|
|
138
|
-
metadata.lastBuildTime,
|
|
139
|
-
metadata.note,
|
|
140
|
-
metadata.source,
|
|
141
|
-
metadata.credits.join(', '),
|
|
142
|
-
metadata.tags.join(', '),
|
|
143
|
-
getFileLink(config.files, 'sheet'),
|
|
144
|
-
getFileLink(config.files, 'doc'),
|
|
145
|
-
metadata.previews.large,
|
|
146
|
-
metadata.previews.small,
|
|
147
|
-
],
|
|
148
|
-
];
|
|
149
|
-
|
|
150
|
-
await writeToSheet(
|
|
151
|
-
sheets,
|
|
152
|
-
spreadsheetId,
|
|
153
|
-
config.projectType,
|
|
154
|
-
metadata.id,
|
|
155
|
-
metadata.graphicURL,
|
|
156
|
-
metadataInput
|
|
157
|
-
);
|
|
188
|
+
metadata.projectURL,
|
|
189
|
+
metadata.type,
|
|
190
|
+
metadataInput
|
|
191
|
+
);
|
|
192
|
+
}
|
|
158
193
|
}
|
|
159
194
|
}
|
|
160
195
|
}
|
|
@@ -1,77 +1,86 @@
|
|
|
1
1
|
{% extends 'base.html' %}
|
|
2
|
-
{% from 'macros/prose.html' import prose %}
|
|
3
|
-
{% from 'macros/processors.html' import ad %}
|
|
2
|
+
{% from 'macros/prose-queso.html' import prose %}
|
|
3
|
+
{% from 'macros/processors-queso.html' import ad %}
|
|
4
4
|
|
|
5
5
|
{% set jsPackName = 'main' %}
|
|
6
|
-
|
|
7
|
-
{# data.text --> data/text.json #}
|
|
8
6
|
{% set context = data.text %}
|
|
9
|
-
|
|
10
|
-
{# data.data --> data/data.json #}
|
|
11
|
-
{% set featureData = data.data %}
|
|
12
|
-
|
|
7
|
+
{% set graphicTags = context.guten_tags %}
|
|
13
8
|
{% set authorComma = joiner() %}
|
|
14
9
|
|
|
15
|
-
{% block
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
10
|
+
{% block google_fonts %}{# queso fonts found in CSS #}{% endblock google_fonts %}
|
|
11
|
+
{% block css_file %}
|
|
12
|
+
<link rel="stylesheet" href="{{ static('styles/min/main-queso.css') }}">
|
|
13
|
+
{% endblock css_file %}
|
|
14
|
+
|
|
15
|
+
{% block nav %}{% include 'components/navbar.html' %}{% endblock %}
|
|
16
|
+
|
|
17
|
+
{% block content_wrap %}
|
|
18
|
+
<main data-feature>
|
|
19
|
+
<article class="has-giant-btm-marg">
|
|
20
|
+
{% block content %}
|
|
21
|
+
<div class="has-page-padding has-giant-btm-marg">
|
|
22
|
+
<header class="t-align-center">
|
|
23
|
+
<h1 class="l-container l-container--m t-headline t-serif t-lh-s has-s-btm-marg" data-title>{{ context.headline | widont or 'The only member-supported, digital-first, nonpartisan media organization' | widont }}</h1>
|
|
24
|
+
<p class="t-byline t-links t-uppercase t-lsp-m t-size-xs has-text-gray-dark has-b-btm-marg">
|
|
25
|
+
<span class="t-byline__item">By <span data-credit>{%- for author in context.authors or ['Texas Tribune Staff'] -%}
|
|
26
|
+
{% if not loop.last %}{{ authorComma() }}{% elif not loop.first %} and{% endif %} <span class="l-display-ib">{{ author }}</span>
|
|
27
|
+
{%- endfor -%}</span>
|
|
28
|
+
</span>
|
|
29
|
+
|
|
30
|
+
{% if context.update_date %}
|
|
31
|
+
<span class="l-display-block">
|
|
32
|
+
<span class="t-byline__item">Published: <time datetime="{{ context.pub_date }}">{{ apFormatDate(context.pub_date) }}</time></span>
|
|
33
|
+
<span class="t-byline__item">Updated: <time datetime="{{ context.update_date }}">{{ apFormatDate(context.update_date) }}</time></span>
|
|
34
|
+
</span>
|
|
35
|
+
{% else %}
|
|
36
|
+
<span class="t-byline__item"><time datetime="{{ context.pub_date }}">{{ apFormatDate(context.pub_date) }}</time></span>
|
|
37
|
+
{% endif %}
|
|
38
|
+
</p>
|
|
39
|
+
</header>
|
|
40
|
+
|
|
41
|
+
{% include 'components/share.html' %}
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="t-serif t-links-underlined has-page-padding">
|
|
45
|
+
{{ prose(context.prose, context, data) }}
|
|
46
|
+
|
|
47
|
+
{# graphics are attached to this container #}
|
|
48
|
+
<div id="graphic"></div>
|
|
49
|
+
|
|
50
|
+
<p class="t-copy">Duis mattis orci a porta maximus. Pellentesque vel pellentesque augue, a condimentum nibh. Integer eget feugiat turpis, at vehicula metus. Vestibulum arcu dui, hendrerit sed purus sed, vulputate aliquam est. Duis quis metus sed odio commodo dapibus. Maecenas pulvinar elit sit amet lorem iaculis blandit. Aliquam vitae sollicitudin urna. Sed viverra tincidunt felis.</p>
|
|
51
|
+
|
|
52
|
+
<h2 class="t-copy t-copy--subheader">{{ 'A cool subhead here' | widont }}</h2>
|
|
53
|
+
|
|
54
|
+
<p class="t-copy">Curabitur vestibulum sagittis diam, vitae pulvinar lorem accumsan ut. Mauris enim massa, vestibulum sed sollicitudin dapibus, ultrices eget ligula. Aenean tempor mi urna, eu porta tortor vehicula quis. Morbi hendrerit, eros nec interdum tempus, sem purus fringilla leo, ut iaculis urna tortor id diam. Duis laoreet maximus sapien, sed scelerisque sapien volutpat vel. Sed est lacus, sollicitudin nec euismod eu, placerat eget turpis. Quisque ultricies urna et mollis bibendum. Quisque tempus, elit ut faucibus hendrerit, augue enim faucibus massa, eu scelerisque dui eros at dolor. Sed rutrum, ipsum id convallis facilisis, justo ex rhoncus ex, in ultrices nisi augue vitae erat. Donec consequat ipsum ac nunc aliquam, eu porttitor quam viverra. Praesent ultrices, diam eget placerat sodales, magna magna porttitor urna, nec mollis ipsum odio at magna. Nulla ac consectetur turpis. Cras non ligula elementum, aliquet arcu ut, interdum nulla.</p>
|
|
55
|
+
|
|
56
|
+
<p class="t-copy">Nam ornare ante eget erat egestas, eget pulvinar diam tincidunt. Nunc eget ligula ac mi facilisis tempus. Proin molestie nisl at urna pharetra commodo. Praesent tincidunt vestibulum purus, id dictum tortor aliquet ac. Pellentesque semper scelerisque justo ac luctus. Nullam malesuada urna a magna fringilla bibendum. Mauris quis hendrerit nisl, a lacinia lectus.</p>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
{# use 'none' as the value if the ad should not have a gray background #}
|
|
60
|
+
{# do not put ads inside a container div #}
|
|
61
|
+
{{ ad('gray') }}
|
|
62
|
+
|
|
63
|
+
{# create another container for more prose if the text needs to be split by an ad #}
|
|
64
|
+
<div class="t-serif t-links-underlined has-page-padding">
|
|
65
|
+
<p class="t-copy">Curabitur vestibulum sagittis diam, vitae pulvinar lorem accumsan ut. Mauris enim massa, vestibulum sed sollicitudin dapibus, ultrices eget ligula. Aenean tempor mi urna, eu porta tortor vehicula quis. Morbi hendrerit, eros nec interdum tempus, sem purus fringilla leo, ut iaculis urna tortor id diam. Duis laoreet maximus sapien, sed scelerisque sapien volutpat vel. Sed est lacus, sollicitudin nec euismod eu, placerat eget turpis. Quisque ultricies urna et mollis bibendum. Quisque tempus, elit ut faucibus hendrerit, augue enim faucibus massa, eu scelerisque dui eros at dolor. Sed rutrum, ipsum id convallis facilisis, justo ex rhoncus ex, in ultrices nisi augue vitae erat. Donec consequat ipsum ac nunc aliquam, eu porttitor quam viverra. Praesent ultrices, diam eget placerat sodales, magna magna porttitor urna, nec mollis ipsum odio at magna. Nulla ac consectetur turpis. Cras non ligula elementum, aliquet arcu ut, interdum nulla.</p>
|
|
66
|
+
|
|
67
|
+
<p class="t-copy">Nam ornare ante eget erat egestas, eget pulvinar diam tincidunt. Nunc eget ligula ac mi facilisis tempus. Proin molestie nisl at urna pharetra commodo. Praesent tincidunt vestibulum purus, id dictum tortor aliquet ac. Pellentesque semper scelerisque justo ac luctus. Nullam malesuada urna a magna fringilla bibendum. Mauris quis hendrerit nisl, a lacinia lectus.</p>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
{{ ad('gray', 'footer') }}
|
|
71
|
+
{% endblock content %}
|
|
72
|
+
</article>
|
|
73
|
+
</main>
|
|
74
|
+
<aside>
|
|
75
|
+
<div class="related-content l-container has-page-padding" id="related-content-container"></div>
|
|
76
|
+
<div id="ribbon-container"></div>
|
|
77
|
+
</aside>
|
|
78
|
+
{% endblock content_wrap %}
|
|
70
79
|
|
|
71
80
|
{% block inline_data %}
|
|
72
81
|
<script>
|
|
73
82
|
window.ttData = {
|
|
74
|
-
gutenTag: '{{ context.
|
|
83
|
+
gutenTag: '{{ context.related_tag or "subject-politics" }}'
|
|
75
84
|
};
|
|
76
85
|
</script>
|
|
77
86
|
{% endblock inline_data %}
|
|
@@ -22,8 +22,12 @@ const Story = ({ headline, url, pub_date, sitewide_image }) => {
|
|
|
22
22
|
</div>
|
|
23
23
|
<div class="story-text c-story-block__text">
|
|
24
24
|
<header class="story-header">
|
|
25
|
-
<h4 class="story-headline t-serif t-size-b t-lh-s has-xxxs-btm-marg">
|
|
26
|
-
|
|
25
|
+
<h4 class="story-headline t-serif t-size-b t-lh-s has-xxxs-btm-marg">
|
|
26
|
+
{headline}
|
|
27
|
+
</h4>
|
|
28
|
+
<p class="story-byline t-byline t-links t-uppercase t-lsp-m t-size-xs has-text-gray-dark">
|
|
29
|
+
{apdate(new Date(pub_date))}
|
|
30
|
+
</p>
|
|
27
31
|
</header>
|
|
28
32
|
</div>
|
|
29
33
|
</div>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
7
|
+
<title>The Texas Tribune</title>
|
|
8
|
+
<base target='_parent'>
|
|
9
|
+
|
|
10
|
+
{% if graphicTitle %}
|
|
11
|
+
<meta name="tt-graphic-title" content="{{ graphicTitle }}" />
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% if graphicAltText %}
|
|
14
|
+
<meta name="tt-graphic-alt-text" content="{{ graphicAltText }}" />
|
|
15
|
+
{% endif %}
|
|
16
|
+
{% if graphicCaption %}
|
|
17
|
+
<meta name="tt-graphic-caption" content="{{ graphicCaption }}" />
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% if graphicNote %}
|
|
20
|
+
<meta name="tt-graphic-note" content="{{ graphicNote }}" />
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% if graphicSource %}
|
|
23
|
+
<meta name="tt-graphic-source" content="{{ graphicSource }}" />
|
|
24
|
+
{% endif %}
|
|
25
|
+
|
|
26
|
+
<meta name="tt-graphic-credit" content="{{ graphicCredit or 'Texas Tribune Staff'}}" />
|
|
27
|
+
<meta name="tt-graphic-tags" content="{{ graphicTags or ['subject-politics'] }}" />
|
|
28
|
+
|
|
29
|
+
<link rel="dns-prefetch" href="https://www.google-analytics.com">
|
|
30
|
+
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
|
|
31
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
32
|
+
|
|
33
|
+
<!-- Start fonts -->
|
|
34
|
+
<script>
|
|
35
|
+
window.WebFontConfig = {
|
|
36
|
+
google: { families: ['Open Sans:300,400,700'] },
|
|
37
|
+
timeout: 10000,
|
|
38
|
+
};
|
|
39
|
+
</script>
|
|
40
|
+
<script async src="https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
|
|
41
|
+
<!-- End fonts -->
|
|
42
|
+
<link rel="stylesheet" href="{{ static('styles/main.css') }}">
|
|
43
|
+
|
|
44
|
+
{% if jsPackName %}
|
|
45
|
+
{% block head_scripts %}
|
|
46
|
+
{{ javascriptPack(jsPackName, { mjs: true }) }}
|
|
47
|
+
{% endblock head_scripts %}
|
|
48
|
+
{% endif %}
|
|
49
|
+
</head>
|
|
50
|
+
<body>
|
|
51
|
+
|
|
52
|
+
{% block content %}{% endblock content %}
|
|
53
|
+
|
|
54
|
+
{% block inline_data %}{% endblock inline_data %}
|
|
55
|
+
|
|
56
|
+
{% include 'includes/nomodule-shim.html' %}
|
|
57
|
+
|
|
58
|
+
{% if jsPackName %}
|
|
59
|
+
{% block scripts %}
|
|
60
|
+
{{ javascriptPack(jsPackName) }}
|
|
61
|
+
{% endblock scripts %}
|
|
62
|
+
{% endif %}
|
|
63
|
+
</body>
|
|
64
|
+
</html>
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
<title>{% if context.seo_headline %}{{ context.seo_headline + ' | ' }}{% elif context.headline %}{{ context.headline + ' | ' }}{% endif %}The Texas Tribune</title>
|
|
5
5
|
{% include 'includes/metas.html' %}
|
|
6
6
|
|
|
7
|
+
<meta name="tt-graphic-tags" content="{{ graphicTags or ['subject-politics'] }}" />
|
|
8
|
+
|
|
7
9
|
<link rel="dns-prefetch" href="https://www.google-analytics.com">
|
|
8
10
|
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
|
|
9
11
|
{% block google_fonts %}
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/about/">About Us</a></li>
|
|
8
8
|
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/contact/">Contact Us</a></li>
|
|
9
9
|
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/support-us/donors-and-members/">Who Funds Us?</a></li>
|
|
10
|
-
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/terms-of-service/">Terms of Service</a></li>
|
|
11
|
-
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/ethics/">Code of Ethics</a></li>
|
|
12
|
-
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/privacy/">Privacy Policy</a></li>
|
|
10
|
+
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/about/terms-of-service/">Terms of Service</a></li>
|
|
11
|
+
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/about/ethics/">Code of Ethics</a></li>
|
|
12
|
+
<li class="footer-nav-item"><a class="footer-link" href="http://www.texastribune.org/about/privacy-policy/">Privacy Policy</a></li>
|
|
13
13
|
<li class="footer-nav-item"><a class="footer-link footer-link-donate" href="https://support.texastribune.org/">Donate</a></li>
|
|
14
14
|
</ul>
|
|
15
15
|
</div>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{# Template for any scripted graphics, i.e. D3 charts #}
|
|
2
|
+
{% extends 'base-graphic.html' %}
|
|
3
|
+
{% from 'macros/prose.html' import prose %}
|
|
4
|
+
|
|
5
|
+
{# set pack that provides JS #}
|
|
6
|
+
{% set jsPackName = 'main' %}
|
|
7
|
+
|
|
8
|
+
{# data.text --> data/text.json #}
|
|
9
|
+
{% set context = data.text %}
|
|
10
|
+
|
|
11
|
+
{# data.data --> data/data.json #}
|
|
12
|
+
{% set graphicData = data.data %}
|
|
13
|
+
|
|
14
|
+
{# graphicAltText is used by the CMS for accessibility #}
|
|
15
|
+
{% set graphicAltText = context.alttext %}
|
|
16
|
+
|
|
17
|
+
{# graphics will be surfaced in the graphics plugin under these tags #}
|
|
18
|
+
{% set graphicTags = context.guten_tags %}
|
|
19
|
+
|
|
20
|
+
{% block content %}
|
|
21
|
+
{# data-graphic signifies that this can be embedded in the CMS #}
|
|
22
|
+
<div class="app" data-graphic>
|
|
23
|
+
{# data-title is used to grab the title in the CMS #}
|
|
24
|
+
<h1 class="graphic-title" data-title>{{ context.headline | widont }}</h1>
|
|
25
|
+
{# data-caption is used to grab the caption in the CMS #}
|
|
26
|
+
<span data-caption>{{ prose(context.graphic_prose, context, graphicData) }}</span>
|
|
27
|
+
|
|
28
|
+
{# container that JS is attached to #}
|
|
29
|
+
<div id="graphic" class="graphic"></div>
|
|
30
|
+
|
|
31
|
+
{# data-source, data-credit, and data-note are also used in the CMS #}
|
|
32
|
+
<ul class="graphic-footer">
|
|
33
|
+
{% if context.note %}<li data-note>Note: {{ context.note }}</li>{% endif %}
|
|
34
|
+
{% if context.source %}<li data-source>Source: {{ context.source }}</li>{% endif %}
|
|
35
|
+
{% if context.credit %}<li data-credit>Credit: {{ context.credit }}</li>{% endif %}
|
|
36
|
+
</ul>
|
|
37
|
+
</div>
|
|
38
|
+
{% endblock content %}
|
|
39
|
+
|
|
40
|
+
{# set data/data.json as a window variable #}
|
|
41
|
+
{% block inline_data %}
|
|
42
|
+
{% if data.data %}
|
|
43
|
+
<script>
|
|
44
|
+
window.DATA = {{ data.data|dump }};
|
|
45
|
+
</script>
|
|
46
|
+
{% endif %}
|
|
47
|
+
{% endblock inline_data %}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% from 'macros/prose.html' import prose %}
|
|
3
|
+
{% from 'macros/processors.html' import ad %}
|
|
4
|
+
|
|
5
|
+
{% set jsPackName = 'main' %}
|
|
6
|
+
{# data.text --> data/text.json #}
|
|
7
|
+
{% set context = data.text %}
|
|
8
|
+
{# data.data --> data/data.json #}
|
|
9
|
+
{% set featureData = data.data %}
|
|
10
|
+
{% set graphicTags = context.guten_tags %}
|
|
11
|
+
{% set authorComma = joiner() %}
|
|
12
|
+
|
|
13
|
+
{% block content %}
|
|
14
|
+
<div class="container" data-feature>
|
|
15
|
+
<header class="article-header text-center">
|
|
16
|
+
<h1 class="article-title" data-title>{{ context.headline | widont or 'The only member-supported, digital-first, nonpartisan media organization' | widont }}</h1>
|
|
17
|
+
<p class="article-byline">
|
|
18
|
+
<span class="article-author">By {%- for author in context.authors or ['Super Cool Corgi', 'Friends'] -%}
|
|
19
|
+
{% if not loop.last %}{{ authorComma() }}{% elif not loop.first %} and{% endif %} {{ author }}
|
|
20
|
+
{%- endfor -%}
|
|
21
|
+
</span>
|
|
22
|
+
{% if context.update_date %}
|
|
23
|
+
<span class="article-pub-update-date">
|
|
24
|
+
<time datetime="{{ context.pub_date }}">Published: {{ apFormatDate(context.pub_date) }}</time>
|
|
25
|
+
<time datetime="{{ context.update_date }}">Updated: {{ apFormatDate(context.update_date) | widont}} </time>
|
|
26
|
+
</span>
|
|
27
|
+
{% else %}
|
|
28
|
+
<span class="article-pub-date">
|
|
29
|
+
<time datetime="{{ context.pub_date }}">{{ apFormatDate(context.pub_date) }}</time>
|
|
30
|
+
</span>
|
|
31
|
+
{% endif %}
|
|
32
|
+
</p>
|
|
33
|
+
</header>
|
|
34
|
+
|
|
35
|
+
{% include 'includes/shares.html' %}
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="container">
|
|
39
|
+
<div class="intro-prose">
|
|
40
|
+
{{ prose(context.prose, context, featureData) }}
|
|
41
|
+
|
|
42
|
+
<p class="copy">Duis mattis orci a porta maximus. Pellentesque vel pellentesque augue, a condimentum nibh. Integer eget feugiat turpis, at vehicula metus. Vestibulum arcu dui, hendrerit sed purus sed, vulputate aliquam est. Duis quis metus sed odio commodo dapibus. Maecenas pulvinar elit sit amet lorem iaculis blandit. Aliquam vitae sollicitudin urna. Sed viverra tincidunt felis.</p>
|
|
43
|
+
|
|
44
|
+
<h2 class="article-subheader copy">{{ 'A cool subhead here' | widont }}</h2>
|
|
45
|
+
|
|
46
|
+
<p class="copy">Curabitur vestibulum sagittis diam, vitae pulvinar lorem accumsan ut. Mauris enim massa, vestibulum sed sollicitudin dapibus, ultrices eget ligula. Aenean tempor mi urna, eu porta tortor vehicula quis. Morbi hendrerit, eros nec interdum tempus, sem purus fringilla leo, ut iaculis urna tortor id diam. Duis laoreet maximus sapien, sed scelerisque sapien volutpat vel. Sed est lacus, sollicitudin nec euismod eu, placerat eget turpis. Quisque ultricies urna et mollis bibendum. Quisque tempus, elit ut faucibus hendrerit, augue enim faucibus massa, eu scelerisque dui eros at dolor. Sed rutrum, ipsum id convallis facilisis, justo ex rhoncus ex, in ultrices nisi augue vitae erat. Donec consequat ipsum ac nunc aliquam, eu porttitor quam viverra. Praesent ultrices, diam eget placerat sodales, magna magna porttitor urna, nec mollis ipsum odio at magna. Nulla ac consectetur turpis. Cras non ligula elementum, aliquet arcu ut, interdum nulla.</p>
|
|
47
|
+
|
|
48
|
+
<p class="copy">Nam ornare ante eget erat egestas, eget pulvinar diam tincidunt. Nunc eget ligula ac mi facilisis tempus. Proin molestie nisl at urna pharetra commodo. Praesent tincidunt vestibulum purus, id dictum tortor aliquet ac. Pellentesque semper scelerisque justo ac luctus. Nullam malesuada urna a magna fringilla bibendum. Mauris quis hendrerit nisl, a lacinia lectus.</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
{# use 'none' as the value if the ad shoud not have a gray background #}
|
|
53
|
+
{# do not put ads inside a container div #}
|
|
54
|
+
{{ ad('gray') }}
|
|
55
|
+
|
|
56
|
+
{# create another container for more prose if the text needs to be split by an ad #}
|
|
57
|
+
<div class="container">
|
|
58
|
+
<p class="copy">Curabitur vestibulum sagittis diam, vitae pulvinar lorem accumsan ut. Mauris enim massa, vestibulum sed sollicitudin dapibus, ultrices eget ligula. Aenean tempor mi urna, eu porta tortor vehicula quis. Morbi hendrerit, eros nec interdum tempus, sem purus fringilla leo, ut iaculis urna tortor id diam. Duis laoreet maximus sapien, sed scelerisque sapien volutpat vel. Sed est lacus, sollicitudin nec euismod eu, placerat eget turpis. Quisque ultricies urna et mollis bibendum. Quisque tempus, elit ut faucibus hendrerit, augue enim faucibus massa, eu scelerisque dui eros at dolor. Sed rutrum, ipsum id convallis facilisis, justo ex rhoncus ex, in ultrices nisi augue vitae erat. Donec consequat ipsum ac nunc aliquam, eu porttitor quam viverra. Praesent ultrices, diam eget placerat sodales, magna magna porttitor urna, nec mollis ipsum odio at magna. Nulla ac consectetur turpis. Cras non ligula elementum, aliquet arcu ut, interdum nulla.</p>
|
|
59
|
+
|
|
60
|
+
<p class="copy">Nam ornare ante eget erat egestas, eget pulvinar diam tincidunt. Nunc eget ligula ac mi facilisis tempus. Proin molestie nisl at urna pharetra commodo. Praesent tincidunt vestibulum purus, id dictum tortor aliquet ac. Pellentesque semper scelerisque justo ac luctus. Nullam malesuada urna a magna fringilla bibendum. Mauris quis hendrerit nisl, a lacinia lectus.</p>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
{{ ad('gray', 'footer') }}
|
|
64
|
+
|
|
65
|
+
<div class="related-content" id="related-content-container"></div>
|
|
66
|
+
|
|
67
|
+
<div id="ribbon-container"></div>
|
|
68
|
+
{% endblock content %}
|
|
69
|
+
|
|
70
|
+
{% block inline_data %}
|
|
71
|
+
<script>
|
|
72
|
+
window.ttData = {
|
|
73
|
+
gutenTag: '{{ context.related_tag or "subject-politics" }}'
|
|
74
|
+
};
|
|
75
|
+
</script>
|
|
76
|
+
{% endblock inline_data %}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{% endmacro %}
|
|
10
10
|
|
|
11
11
|
{% macro list(value) %}
|
|
12
|
-
<ul>
|
|
12
|
+
<ul class="t-copy c-list">
|
|
13
13
|
{% for item in value %}
|
|
14
14
|
<li>{{ item }}</li>
|
|
15
15
|
{% endfor %}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
{% endmacro %}
|
|
18
18
|
|
|
19
19
|
{% macro subhead(value) %}
|
|
20
|
-
<h2 class="t-subheader">{{ value | widont }}</h2>
|
|
20
|
+
<h2 class="t-copy t-copy--subheader">{{ value | widont }}</h2>
|
|
21
21
|
{% endmacro %}
|
|
22
22
|
|
|
23
23
|
{# set type to roof for roof ads, footer for footer ads #}
|
|
@@ -34,7 +34,8 @@ module.exports = {
|
|
|
34
34
|
projectName: '<<name>>',
|
|
35
35
|
/**
|
|
36
36
|
* The destination S3 bucket for a deploy.
|
|
37
|
-
*
|
|
37
|
+
* `capybara-test` is the test bucket.
|
|
38
|
+
* YOU CAN CHANGE THIS. Change to `apps.texastribune.org` when publishing.
|
|
38
39
|
*/
|
|
39
40
|
bucket: 'capybara-test.texastribune.org',
|
|
40
41
|
/**
|
|
@@ -106,4 +107,27 @@ module.exports = {
|
|
|
106
107
|
*
|
|
107
108
|
*/
|
|
108
109
|
customFilters: {},
|
|
110
|
+
/**
|
|
111
|
+
* Where custom settings for parsing graphics can be added.
|
|
112
|
+
*
|
|
113
|
+
* metadataIgnore
|
|
114
|
+
* Add paths here that you do not want parsed for metadata and shown
|
|
115
|
+
* in the graphics plugin in the CMS.
|
|
116
|
+
*
|
|
117
|
+
* appleNewsIgnore
|
|
118
|
+
* Some graphics are too dynamic to be accurately captured in a screenshot.
|
|
119
|
+
* Those graphics shouldn't be considered for platforms like Apple News.
|
|
120
|
+
*
|
|
121
|
+
* Paths for metadataIgnore and appleNewsIgnore are relative to the build folders.
|
|
122
|
+
* Example:
|
|
123
|
+
* appleNewsIgnore: [
|
|
124
|
+
* 'complex-graphic-folder/index.html',
|
|
125
|
+
* 'some-other-folder',
|
|
126
|
+
* ],
|
|
127
|
+
*
|
|
128
|
+
*/
|
|
129
|
+
parserOptions: {
|
|
130
|
+
metadataIgnore: [],
|
|
131
|
+
appleNewsIgnore: [],
|
|
132
|
+
},
|
|
109
133
|
};
|
|
@@ -2,21 +2,6 @@
|
|
|
2
2
|
{% extends 'base.html' %}
|
|
3
3
|
{% from 'macros/prose.html' import prose %}
|
|
4
4
|
|
|
5
|
-
{# set pack that provides JS #}
|
|
6
|
-
{% set jsPackName = 'main' %}
|
|
7
|
-
|
|
8
|
-
{# data.text --> data/text.json #}
|
|
9
|
-
{% set context = data.text %}
|
|
10
|
-
|
|
11
|
-
{# data.data --> data/data.json #}
|
|
12
|
-
{% set graphicData = data.data %}
|
|
13
|
-
|
|
14
|
-
{# graphicAltText is used by the CMS for accessibility #}
|
|
15
|
-
{% set graphicAltText = context.alttext %}
|
|
16
|
-
|
|
17
|
-
{# graphics will be surfaced in the graphics plugin under these tags #}
|
|
18
|
-
{% set graphicTags = context.guten_tags %}
|
|
19
|
-
|
|
20
5
|
{% block content %}
|
|
21
6
|
<div class="app">
|
|
22
7
|
<h1 class="article-subheader">Welcome to The Texas Tribune's data visuals graphics kit!</h1>
|
|
@@ -22,12 +22,9 @@
|
|
|
22
22
|
{% if graphicSource %}
|
|
23
23
|
<meta name="tt-graphic-source" content="{{ graphicSource }}" />
|
|
24
24
|
{% endif %}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
{% if graphicTags %}
|
|
29
|
-
<meta name="tt-graphic-tags" content="{{ graphicTags or 'subject-politics' }}" />
|
|
30
|
-
{% endif %}
|
|
25
|
+
|
|
26
|
+
<meta name="tt-graphic-credit" content="{{ graphicCredit or 'Texas Tribune Staff'}}" />
|
|
27
|
+
<meta name="tt-graphic-tags" content="{{ graphicTags or ['subject-politics'] }}" />
|
|
31
28
|
|
|
32
29
|
<link rel="dns-prefetch" href="https://www.google-analytics.com">
|
|
33
30
|
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
{# graphicAltText is used by the CMS for accessibility #}
|
|
15
15
|
{% set graphicAltText = context.alttext %}
|
|
16
16
|
|
|
17
|
+
{# graphics will be surfaced in the graphics plugin under these tags #}
|
|
18
|
+
{% set graphicTags = context.guten_tags %}
|
|
19
|
+
|
|
17
20
|
{% block content %}
|
|
18
21
|
{# data-graphic signifies that this can be embedded in the CMS #}
|
|
19
22
|
<div class="app" data-graphic>
|
|
@@ -72,6 +72,7 @@ Project config keys output in `manifest.json`
|
|
|
72
72
|
- `id`
|
|
73
73
|
- `tags`
|
|
74
74
|
- `parserOptions`
|
|
75
|
+
- `metadataIgnore` - This is an array of files or folders that should not be parsed for metadata and displayed in the CMS graphics plugin. For example, any graphics or features created for testing but are not publishable should be added here.
|
|
75
76
|
- `appleNewsIgnore` - This is an array of files or folders that should be flagged in the CMS as not compatible with Apple News. Use this for graphics that are too dynamic to be accurately captured in a screenshot.
|
|
76
77
|
|
|
77
78
|
### Sample `manifest.json` output
|
|
@@ -34,9 +34,10 @@ module.exports = {
|
|
|
34
34
|
projectName: '<<name>>',
|
|
35
35
|
/**
|
|
36
36
|
* The destination S3 bucket for a deploy.
|
|
37
|
-
*
|
|
37
|
+
* `capybara-test` is the test bucket.
|
|
38
|
+
* YOU CAN CHANGE THIS. Change to `graphics.texastribune.org` when publishing.
|
|
38
39
|
*/
|
|
39
|
-
bucket: '
|
|
40
|
+
bucket: 'capybara-test.texastribune.org',
|
|
40
41
|
/**
|
|
41
42
|
* The folder (or "Key" in S3 lingo) to deploy the project into.
|
|
42
43
|
* This is the slug in the project URL.
|
|
@@ -109,11 +110,15 @@ module.exports = {
|
|
|
109
110
|
/**
|
|
110
111
|
* Where custom settings for parsing graphics can be added.
|
|
111
112
|
*
|
|
113
|
+
* metadataIgnore
|
|
114
|
+
* Add paths here that you do not want parsed for metadata and shown
|
|
115
|
+
* in the graphics plugin in the CMS.
|
|
116
|
+
*
|
|
112
117
|
* appleNewsIgnore
|
|
113
118
|
* Some graphics are too dynamic to be accurately captured in a screenshot.
|
|
114
119
|
* Those graphics shouldn't be considered for platforms like Apple News.
|
|
115
|
-
* Paths are relative to the build folders.
|
|
116
120
|
*
|
|
121
|
+
* Paths for metadataIgnore and appleNewsIgnore are relative to the build folders.
|
|
117
122
|
* Example:
|
|
118
123
|
* appleNewsIgnore: [
|
|
119
124
|
* 'complex-graphic-folder/index.html',
|
|
@@ -122,7 +127,7 @@ module.exports = {
|
|
|
122
127
|
*
|
|
123
128
|
*/
|
|
124
129
|
parserOptions: {
|
|
125
|
-
|
|
130
|
+
metadataIgnore: [],
|
|
126
131
|
appleNewsIgnore: [],
|
|
127
132
|
},
|
|
128
133
|
};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
{% extends 'base.html' %}
|
|
2
|
-
{% from 'macros/prose-queso.html' import prose %}
|
|
3
|
-
{% from 'macros/processors-queso.html' import ad %}
|
|
4
|
-
|
|
5
|
-
{% set jsPackName = 'main' %}
|
|
6
|
-
{% set context = data.text %}
|
|
7
|
-
{% set authorComma = joiner() %}
|
|
8
|
-
|
|
9
|
-
{% block google_fonts %}{# queso fonts found in CSS #}{% endblock google_fonts %}
|
|
10
|
-
{% block css_file %}
|
|
11
|
-
<link rel="stylesheet" href="{{ static('styles/min/main-queso.css') }}">
|
|
12
|
-
{% endblock css_file %}
|
|
13
|
-
|
|
14
|
-
{% block nav %}{% include 'components/navbar.html' %}{% endblock %}
|
|
15
|
-
|
|
16
|
-
{% block content_wrap %}
|
|
17
|
-
<main>
|
|
18
|
-
<article class="has-giant-btm-marg">
|
|
19
|
-
{% block content %}
|
|
20
|
-
<div class="has-page-padding has-giant-btm-marg">
|
|
21
|
-
<header class="t-align-center">
|
|
22
|
-
<h1 class="l-container l-container--m t-headline t-serif t-lh-s has-s-btm-marg">{{ context.headline | widont or 'The only member-supported, digital-first, nonpartisan media organization' | widont }}</h1>
|
|
23
|
-
<p class="t-byline t-links t-uppercase t-lsp-m t-size-xs has-text-gray-dark has-b-btm-marg">
|
|
24
|
-
<span class="t-byline__item">By {%- for author in context.authors or ['Super Cool Corgi', 'Friends'] -%}
|
|
25
|
-
{% if not loop.last %}{{ authorComma() }}{% elif not loop.first %} and{% endif %} <span class="l-display-ib">{{ author }}</span>
|
|
26
|
-
{% endfor %}
|
|
27
|
-
</span>
|
|
28
|
-
|
|
29
|
-
{% if context.update_date %}
|
|
30
|
-
<span class="l-display-block">
|
|
31
|
-
<span class="t-byline__item">Published: <time datetime="{{ context.pub_date }}">{{ apFormatDate(context.pub_date) }}</time></span>
|
|
32
|
-
<span class="t-byline__item">Updated: <time datetime="{{ context.update_date }}">{{ apFormatDate(context.update_date) }}</time></span>
|
|
33
|
-
</span>
|
|
34
|
-
{% else %}
|
|
35
|
-
<span class="t-byline__item"><time datetime="{{ context.pub_date }}">{{ apFormatDate(context.pub_date) }}</time></span>
|
|
36
|
-
{% endif %}
|
|
37
|
-
</p>
|
|
38
|
-
</header>
|
|
39
|
-
|
|
40
|
-
{% include 'components/share.html' %}
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
<div class="t-serif t-links-underlined has-page-padding">
|
|
44
|
-
{{ prose(context.prose, context, data) }}
|
|
45
|
-
<p class="t-copy">Duis mattis orci a porta maximus. Pellentesque vel pellentesque augue, a condimentum nibh. Integer eget feugiat turpis, at vehicula metus. Vestibulum arcu dui, hendrerit sed purus sed, vulputate aliquam est. Duis quis metus sed odio commodo dapibus. Maecenas pulvinar elit sit amet lorem iaculis blandit. Aliquam vitae sollicitudin urna. Sed viverra tincidunt felis.</p>
|
|
46
|
-
|
|
47
|
-
<h2 class="t-copy t-copy--subheader">{{ 'A cool subhead here' | widont }}</h2>
|
|
48
|
-
|
|
49
|
-
<p class="t-copy">Curabitur vestibulum sagittis diam, vitae pulvinar lorem accumsan ut. Mauris enim massa, vestibulum sed sollicitudin dapibus, ultrices eget ligula. Aenean tempor mi urna, eu porta tortor vehicula quis. Morbi hendrerit, eros nec interdum tempus, sem purus fringilla leo, ut iaculis urna tortor id diam. Duis laoreet maximus sapien, sed scelerisque sapien volutpat vel. Sed est lacus, sollicitudin nec euismod eu, placerat eget turpis. Quisque ultricies urna et mollis bibendum. Quisque tempus, elit ut faucibus hendrerit, augue enim faucibus massa, eu scelerisque dui eros at dolor. Sed rutrum, ipsum id convallis facilisis, justo ex rhoncus ex, in ultrices nisi augue vitae erat. Donec consequat ipsum ac nunc aliquam, eu porttitor quam viverra. Praesent ultrices, diam eget placerat sodales, magna magna porttitor urna, nec mollis ipsum odio at magna. Nulla ac consectetur turpis. Cras non ligula elementum, aliquet arcu ut, interdum nulla.</p>
|
|
50
|
-
|
|
51
|
-
<p class="t-copy">Nam ornare ante eget erat egestas, eget pulvinar diam tincidunt. Nunc eget ligula ac mi facilisis tempus. Proin molestie nisl at urna pharetra commodo. Praesent tincidunt vestibulum purus, id dictum tortor aliquet ac. Pellentesque semper scelerisque justo ac luctus. Nullam malesuada urna a magna fringilla bibendum. Mauris quis hendrerit nisl, a lacinia lectus.</p>
|
|
52
|
-
</div>
|
|
53
|
-
|
|
54
|
-
{# use 'none' as the value if the ad shoud not have a gray background #}
|
|
55
|
-
{# do not put ads inside a container div #}
|
|
56
|
-
{{ ad('gray') }}
|
|
57
|
-
|
|
58
|
-
{# create another container for more prose if the text needs to be split by an ad #}
|
|
59
|
-
<div class="t-serif t-links-underlined has-page-padding">
|
|
60
|
-
<p class="t-copy">Curabitur vestibulum sagittis diam, vitae pulvinar lorem accumsan ut. Mauris enim massa, vestibulum sed sollicitudin dapibus, ultrices eget ligula. Aenean tempor mi urna, eu porta tortor vehicula quis. Morbi hendrerit, eros nec interdum tempus, sem purus fringilla leo, ut iaculis urna tortor id diam. Duis laoreet maximus sapien, sed scelerisque sapien volutpat vel. Sed est lacus, sollicitudin nec euismod eu, placerat eget turpis. Quisque ultricies urna et mollis bibendum. Quisque tempus, elit ut faucibus hendrerit, augue enim faucibus massa, eu scelerisque dui eros at dolor. Sed rutrum, ipsum id convallis facilisis, justo ex rhoncus ex, in ultrices nisi augue vitae erat. Donec consequat ipsum ac nunc aliquam, eu porttitor quam viverra. Praesent ultrices, diam eget placerat sodales, magna magna porttitor urna, nec mollis ipsum odio at magna. Nulla ac consectetur turpis. Cras non ligula elementum, aliquet arcu ut, interdum nulla.</p>
|
|
61
|
-
|
|
62
|
-
<p class="t-copy">Nam ornare ante eget erat egestas, eget pulvinar diam tincidunt. Nunc eget ligula ac mi facilisis tempus. Proin molestie nisl at urna pharetra commodo. Praesent tincidunt vestibulum purus, id dictum tortor aliquet ac. Pellentesque semper scelerisque justo ac luctus. Nullam malesuada urna a magna fringilla bibendum. Mauris quis hendrerit nisl, a lacinia lectus.</p>
|
|
63
|
-
</div>
|
|
64
|
-
|
|
65
|
-
{{ ad('gray', 'footer') }}
|
|
66
|
-
{% endblock content %}
|
|
67
|
-
</article>
|
|
68
|
-
</main>
|
|
69
|
-
<aside>
|
|
70
|
-
<div class="related-content l-container has-page-padding" id="related-content-container"></div>
|
|
71
|
-
<div id="ribbon-container"></div>
|
|
72
|
-
</aside>
|
|
73
|
-
{% endblock content_wrap %}
|
|
74
|
-
|
|
75
|
-
{% block inline_data %}
|
|
76
|
-
<script>
|
|
77
|
-
window.ttData = {
|
|
78
|
-
gutenTag: '{{ context.guten_tag or "subject-politics" }}'
|
|
79
|
-
};
|
|
80
|
-
</script>
|
|
81
|
-
{% endblock inline_data %}
|