@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-visuals/create",
3
- "version": "7.1.0",
3
+ "version": "7.2.0",
4
4
  "description": "Create graphics and features the Data Visuals way.",
5
5
  "scripts": {
6
6
  "build:docs": "doctoc README.md --github",
@@ -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 graphicPath = path.join(folder, parentDir);
142
- const graphicURL = ensureSlash(`https://${bucket}/${folder}/${parentDir}`);
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 text from page
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
- // ignore graphics with no title
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(`${label} was skipped because no graphic was title set.`);
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
- const links = await page.$$eval('a', links =>
178
- links.map(link => {
179
- return {
180
- url: link.getAttribute('href'),
181
- text: link.textContent,
182
- isCTA:
183
- link.classList.contains('button') ||
184
- link.classList.contains('.c-button'),
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
- // take screenshots of page
190
- const { small, large } = await createPreviews({
191
- page,
192
- outputPath,
193
- });
197
+ // take screenshots of page
198
+ const { small, large } = await createPreviews({
199
+ page,
200
+ outputPath,
201
+ });
194
202
 
195
- // check if appleNewsIgnore is specified
196
- let showInAppleNews = true;
197
- if (parserOptions) {
198
- const { appleNewsIgnore } = parserOptions;
199
- showInAppleNews =
200
- !appleNewsIgnore.includes(parentDir) && !appleNewsIgnore.includes(label);
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
- // all graphic data
204
- return {
205
- title,
206
- altText,
207
- bucket,
208
- graphicPath,
209
- graphicURL,
210
- caption,
211
- createMonth,
212
- createYear,
213
- credits,
214
- folder,
215
- id,
216
- lastBuildTime,
217
- label,
218
- links,
219
- note,
220
- previews: {
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.graphicsIgnore,
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 graphic data
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} graphic(s)`, 'green');
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 (projectType === 'graphic') {
33
+ if (metadataType === 'graphic') {
34
34
  sheetName = 'Embedded';
35
35
  }
36
- if (projectType === 'feature') {
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.graphicURL,
133
- metadata.graphicPath,
134
- metadata.title,
135
- metadata.caption,
136
- metadata.altText,
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 content %}
16
- <div class="container">
17
- <header class="article-header text-center">
18
- <h1 class="article-title">{{ context.headline | widont or 'The only member-supported, digital-first, nonpartisan media organization' | widont }}</h1>
19
- <p class="article-byline">
20
- <span class="article-author">By {%- for author in context.authors or ['Super Cool Corgi', 'Friends'] -%}
21
- {% if not loop.last %}{{ authorComma() }}{% elif not loop.first %} and{% endif %} {{ author }}
22
- {%- endfor -%}
23
- </span>
24
- {% if context.update_date %}
25
- <span class="article-pub-update-date">
26
- <time datetime="{{ context.pub_date }}">Published: {{ apFormatDate(context.pub_date) }}</time>
27
- <time datetime="{{ context.update_date }}">Updated: {{ apFormatDate(context.update_date) | widont}} </time>
28
- </span>
29
- {% else %}
30
- <span class="article-pub-date">
31
- <time datetime="{{ context.pub_date }}">{{ apFormatDate(context.pub_date) }}</time>
32
- </span>
33
- {% endif %}
34
- </p>
35
- </header>
36
-
37
- {% include 'includes/shares.html' %}
38
- </div>
39
-
40
- <div class="container">
41
- <div class="intro-prose">
42
- {{ prose(context.prose, context, featureData) }}
43
- <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>
44
-
45
- <h2 class="article-subheader copy">{{ 'A cool subhead here' | widont }}</h2>
46
-
47
- <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>
48
-
49
- <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>
50
- </div>
51
- </div>
52
-
53
- {# use 'none' as the value if the ad shoud not have a gray background #}
54
- {# do not put ads inside a container div #}
55
- {{ ad('gray') }}
56
-
57
- {# create another container for more prose if the text needs to be split by an ad #}
58
- <div class="container">
59
- <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>
60
-
61
- <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>
62
- </div>
63
-
64
- {{ ad('gray', 'footer') }}
65
-
66
- <div class="related-content" id="related-content-container"></div>
67
-
68
- <div id="ribbon-container"></div>
69
- {% endblock content %}
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.guten_tag or "subject-politics" }}'
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">{headline}</h4>
26
- <p class="story-byline t-byline t-links t-uppercase t-lsp-m t-size-xs has-text-gray-dark">{apdate(new Date(pub_date))}</p>
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 #}
@@ -9,7 +9,7 @@
9
9
  {% endmacro %}
10
10
 
11
11
  {% macro list(value) %}
12
- <ul>
12
+ <ul class="copy">
13
13
  {% for item in value %}
14
14
  <li>{{ item }}</li>
15
15
  {% endfor %}
@@ -34,7 +34,8 @@ module.exports = {
34
34
  projectName: '<<name>>',
35
35
  /**
36
36
  * The destination S3 bucket for a deploy.
37
- * YOU CAN CHANGE THIS.
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
- {% if graphicCredit %}
26
- <meta name="tt-graphic-credit" content="{{ graphicCredit }}" />
27
- {% endif %}
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
- * YOU CAN CHANGE THIS.
37
+ * `capybara-test` is the test bucket.
38
+ * YOU CAN CHANGE THIS. Change to `graphics.texastribune.org` when publishing.
38
39
  */
39
- bucket: 'graphics.texastribune.org',
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
- graphicsIgnore: [],
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 %}