datalog-theme 0.6.1 → 0.8.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.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +175 -0
  3. data/CITATION.cff +2 -2
  4. data/README.md +26 -19
  5. data/_data/cdn-integrity.yml +0 -30
  6. data/_includes/analytics/dashboard.html +3 -1
  7. data/_includes/components/api-function.html +20 -1
  8. data/_includes/components/author-bio.html +2 -2
  9. data/_includes/components/enhanced-code-block.html +1 -1
  10. data/_includes/components/hero.html +19 -1
  11. data/_includes/csp-meta.html +115 -11
  12. data/_includes/footer.html +19 -20
  13. data/_includes/head.html +61 -29
  14. data/_includes/header/navigation.html +12 -15
  15. data/_includes/header.html +29 -20
  16. data/_includes/layouts/default/article.html +5 -1
  17. data/_includes/meta/math-config.html +27 -1
  18. data/_includes/meta/schema.html +5 -2
  19. data/_includes/meta/scripts-loader.html +16 -31
  20. data/_includes/post/related-posts.html +4 -7
  21. data/_includes/scripts.html +1 -9
  22. data/_includes/search/index-data.json +131 -0
  23. data/_includes/search/page.html +136 -0
  24. data/_layouts/dataset.html +1 -0
  25. data/_layouts/default.html +16 -8
  26. data/_layouts/home.html +6 -0
  27. data/_layouts/notebook.html +1 -0
  28. data/_layouts/package.html +1 -0
  29. data/_layouts/portfolio.html +1 -0
  30. data/_layouts/post.html +20 -5
  31. data/_layouts/project.html +2 -1
  32. data/_plugins/analytics_dashboard.rb +9 -3
  33. data/_plugins/config_validator.rb +12 -7
  34. data/_plugins/csp_generator.rb +18 -28
  35. data/_plugins/datalog_bibliography.rb +9 -7
  36. data/_plugins/datalog_comments.rb +8 -5
  37. data/_plugins/datalog_slides.rb +9 -8
  38. data/_plugins/i18n.rb +7 -8
  39. data/_plugins/image_optimizer.rb +17 -6
  40. data/_plugins/math_preprocessor.rb +36 -3
  41. data/_plugins/notebook_converter.rb +23 -43
  42. data/_plugins/plugin_loader.rb +3 -1
  43. data/_plugins/publications_generator.rb +8 -2
  44. data/_plugins/rouge_highlight_filter.rb +42 -0
  45. data/_plugins/search_code_blocks.rb +30 -0
  46. data/_plugins/search_normalizer.rb +15 -53
  47. data/_plugins/search_pages.rb +72 -0
  48. data/_sass/_academic-dashboard.scss +262 -0
  49. data/_sass/_base.scss +19 -1
  50. data/_sass/_components.scss +77 -1144
  51. data/_sass/_features.scss +17 -0
  52. data/_sass/_font-fallbacks.scss +43 -0
  53. data/_sass/_header.scss +10 -0
  54. data/_sass/_layout.scss +18 -12
  55. data/_sass/_mathematical.scss +1 -1
  56. data/_sass/_notebooks.scss +322 -0
  57. data/_sass/_open-science-badges.scss +56 -0
  58. data/_sass/{_phase1-enhancements.scss → _post-components.scss} +46 -1
  59. data/_sass/_search-page.scss +530 -0
  60. data/_sass/_search.scss +47 -1
  61. data/_sass/_syntax-highlighting.scss +212 -97
  62. data/_sass/_theme.scss +42 -18
  63. data/_sass/_typography.scss +14 -0
  64. data/_sass/_variables.scss +7 -4
  65. data/assets/css/main.scss +14 -0
  66. data/assets/img/hero-detail-640.webp +0 -0
  67. data/assets/img/hero-detail.webp +0 -0
  68. data/assets/img/social-card.png +0 -0
  69. data/assets/js/dist/academic.js +1 -0
  70. data/assets/js/dist/analytics-dashboard.js +1 -0
  71. data/assets/js/dist/chunks/chunk-225H5YXE.js +1 -0
  72. data/assets/js/dist/core.js +1 -0
  73. data/assets/js/dist/loader.js +1 -0
  74. data/assets/js/dist/math.js +1 -0
  75. data/assets/js/dist/notebook.js +1 -0
  76. data/assets/js/dist/search.js +1 -0
  77. data/assets/js/dist/visualizations.js +11 -0
  78. data/assets/js/loader.js +3 -1
  79. data/datalog-theme.gemspec +43 -22
  80. data/lib/datalog/cli.rb +53 -15
  81. data/lib/datalog/plugin_system/dependency_resolver.rb +0 -2
  82. data/lib/datalog/theme/package.rb +57 -0
  83. data/lib/datalog/theme/repository_checkout.rb +90 -0
  84. data/lib/datalog/theme/version.rb +1 -1
  85. data/lib/datalog/warning_filter.rb +5 -11
  86. data/lib/datalog-theme.rb +21 -0
  87. metadata +75 -146
  88. data/_data/academic.yml +0 -217
  89. data/_data/config/author.yml +0 -121
  90. data/_data/config/features.yml +0 -262
  91. data/_data/config/site.yml +0 -42
  92. data/_data/config/theme.yml +0 -181
  93. data/_data/datasets.yml +0 -28
  94. data/_data/js_meta.json +0 -371
  95. data/_data/navigation.yml +0 -145
  96. data/_data/projects.yml +0 -41
  97. data/_data/publications.yml +0 -28
  98. data/_data/social.yml +0 -73
  99. data/_data/visualizations.yml +0 -51
  100. data/_includes/components/advanced-search.html +0 -682
  101. data/_includes/components/bookmark-system.html +0 -96
  102. data/_includes/components/comments.html +0 -244
  103. data/_includes/components/content-recommendations.html +0 -228
  104. data/_includes/components/email-preferences.html +0 -200
  105. data/_includes/components/enhanced-metadata.html +0 -228
  106. data/_includes/components/language-switcher.html +0 -396
  107. data/_includes/components/navigation-enhancements.html +0 -454
  108. data/_includes/components/newsletter-signup.html +0 -178
  109. data/_includes/components/popular-posts.html +0 -233
  110. data/_includes/components/reading-progress.html +0 -133
  111. data/_includes/components/reading-time.html +0 -121
  112. data/_includes/components/series-navigation.html +0 -124
  113. data/_includes/components/social-proof.html +0 -34
  114. data/_includes/components/user-preferences.html +0 -566
  115. data/_layouts/archive.html +0 -282
  116. data/_layouts/post-sidebar.html +0 -183
  117. data/_sass/_phase3-enhancements.scss +0 -874
  118. data/_sass/_phase4-enhancements.scss +0 -1214
  119. data/_sass/_phase5-enhancements.scss +0 -414
  120. data/assets/img/20220607123041_detail.001.png +0 -0
  121. data/assets/js/academic.js +0 -262
  122. data/assets/js/analytics-dashboard.js +0 -382
  123. data/assets/js/core/dark-mode.js +0 -79
  124. data/assets/js/core/github-cards.js +0 -123
  125. data/assets/js/core/language-filter.js +0 -69
  126. data/assets/js/core/navigation.js +0 -184
  127. data/assets/js/core/scroll-progress.js +0 -45
  128. data/assets/js/core/search-hotkeys.js +0 -62
  129. data/assets/js/core/skip-links.js +0 -62
  130. data/assets/js/main.js +0 -23
  131. data/assets/js/math.js +0 -818
  132. data/assets/js/notebook.js +0 -158
  133. data/assets/js/search/analytics.js +0 -91
  134. data/assets/js/search/app.js +0 -271
  135. data/assets/js/search/autocomplete.js +0 -120
  136. data/assets/js/search/engine.js +0 -260
  137. data/assets/js/search/filters.js +0 -38
  138. data/assets/js/search/render.js +0 -217
  139. data/assets/js/search/utils.js +0 -99
  140. data/assets/js/search.js +0 -354
  141. data/assets/js/visualizations.js +0 -816
  142. data/assets/publications/datalog-publications.bib +0 -8
  143. data/assets/publications/datalog-publications.ris +0 -9
  144. data/assets/publications/publications.bib +0 -30
  145. data/assets/templates/diogo-ribeiro-cv.md +0 -31
  146. data/assets/templates/diogo-ribeiro-cv.tex +0 -32
  147. data/lib/datalog/theme/theme.rb +0 -18
@@ -1,200 +0,0 @@
1
- {%- comment -%}
2
- Email Subscription Preferences - Granular email controls
3
- {%- endcomment -%}
4
-
5
- <div class="email-preferences" data-email-preferences>
6
- <h3>Email Preferences</h3>
7
-
8
- <form class="email-preferences__form" data-preferences-form>
9
- <div class="form-group">
10
- <label for="email-input">Email Address</label>
11
- <input type="email" id="email-input" name="email" required placeholder="your@email.com">
12
- </div>
13
-
14
- <fieldset class="form-group">
15
- <legend>Subscription Types</legend>
16
-
17
- <label class="checkbox-label">
18
- <input type="checkbox" name="weekly_digest" value="true" checked>
19
- <span>Weekly Digest</span>
20
- <small>Best posts from the week, every Monday</small>
21
- </label>
22
-
23
- <label class="checkbox-label">
24
- <input type="checkbox" name="new_posts" value="true">
25
- <span>New Posts</span>
26
- <small>Notification for each new post</small>
27
- </label>
28
-
29
- <label class="checkbox-label">
30
- <input type="checkbox" name="comments" value="true">
31
- <span>Comment Replies</span>
32
- <small>When someone replies to your comments</small>
33
- </label>
34
-
35
- <label class="checkbox-label">
36
- <input type="checkbox" name="newsletter" value="true" checked>
37
- <span>Newsletter</span>
38
- <small>Monthly newsletter with curated content</small>
39
- </label>
40
- </fieldset>
41
-
42
- <fieldset class="form-group">
43
- <legend>Content Preferences</legend>
44
-
45
- <label class="checkbox-label">
46
- <input type="checkbox" name="topic_ml" value="true">
47
- <span>Machine Learning</span>
48
- </label>
49
-
50
- <label class="checkbox-label">
51
- <input type="checkbox" name="topic_statistics" value="true">
52
- <span>Statistics</span>
53
- </label>
54
-
55
- <label class="checkbox-label">
56
- <input type="checkbox" name="topic_visualization" value="true">
57
- <span>Data Visualization</span>
58
- </label>
59
-
60
- <label class="checkbox-label">
61
- <input type="checkbox" name="topic_python" value="true">
62
- <span>Python</span>
63
- </label>
64
- </fieldset>
65
-
66
- <div class="form-group">
67
- <label for="difficulty-select">Difficulty Level</label>
68
- <select id="difficulty-select" name="difficulty">
69
- <option value="all">All Levels</option>
70
- <option value="beginner">Beginner</option>
71
- <option value="intermediate">Intermediate</option>
72
- <option value="advanced">Advanced</option>
73
- <option value="expert">Expert</option>
74
- </select>
75
- </div>
76
-
77
- <div class="form-actions">
78
- <button type="submit" class="button button--primary">Save Preferences</button>
79
- <button type="button" class="button button--secondary" data-unsubscribe>Unsubscribe</button>
80
- </div>
81
-
82
- <div class="form-message" data-message hidden></div>
83
- </form>
84
- </div>
85
-
86
- <script>
87
- (function() {
88
- 'use strict';
89
-
90
- const STORAGE_KEY = 'emailPreferences';
91
-
92
- class EmailPreferences {
93
- constructor() {
94
- this.init();
95
- }
96
-
97
- init() {
98
- const form = document.querySelector('[data-preferences-form]');
99
- if (!form) return;
100
-
101
- this.loadPreferences(form);
102
-
103
- form.addEventListener('submit', (e) => {
104
- e.preventDefault();
105
- this.savePreferences(form);
106
- });
107
-
108
- const unsubBtn = form.querySelector('[data-unsubscribe]');
109
- unsubBtn?.addEventListener('click', () => this.unsubscribe(form));
110
- }
111
-
112
- loadPreferences(form) {
113
- try {
114
- const saved = localStorage.getItem(STORAGE_KEY);
115
- if (!saved) return;
116
-
117
- const prefs = JSON.parse(saved);
118
-
119
- // Set email
120
- const emailInput = form.querySelector('[name="email"]');
121
- if (emailInput && prefs.email) {
122
- emailInput.value = prefs.email;
123
- }
124
-
125
- // Set checkboxes
126
- Object.keys(prefs).forEach(key => {
127
- const input = form.querySelector(`[name="${key}"]`);
128
- if (input && input.type === 'checkbox') {
129
- input.checked = prefs[key] === 'true' || prefs[key] === true;
130
- } else if (input && input.type !== 'email') {
131
- input.value = prefs[key];
132
- }
133
- });
134
- } catch (e) {
135
- console.error('Failed to load preferences:', e);
136
- }
137
- }
138
-
139
- savePreferences(form) {
140
- const formData = new FormData(form);
141
- const prefs = {};
142
-
143
- for (const [key, value] of formData.entries()) {
144
- prefs[key] = value;
145
- }
146
-
147
- // Save checkboxes that are unchecked
148
- form.querySelectorAll('input[type="checkbox"]').forEach(cb => {
149
- if (!cb.checked) {
150
- prefs[cb.name] = 'false';
151
- }
152
- });
153
-
154
- try {
155
- localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));
156
- this.showMessage(form, 'Preferences saved successfully!', 'success');
157
-
158
- // In production, send to backend
159
- // fetch('/api/email-preferences', {
160
- // method: 'POST',
161
- // headers: {'Content-Type': 'application/json'},
162
- // body: JSON.stringify(prefs)
163
- // });
164
- } catch (e) {
165
- this.showMessage(form, 'Failed to save preferences', 'error');
166
- }
167
- }
168
-
169
- unsubscribe(form) {
170
- if (confirm('Are you sure you want to unsubscribe from all emails?')) {
171
- try {
172
- localStorage.removeItem(STORAGE_KEY);
173
- form.reset();
174
- this.showMessage(form, 'You have been unsubscribed', 'success');
175
-
176
- // In production, send to backend
177
- // fetch('/api/unsubscribe', {method: 'POST'});
178
- } catch (e) {
179
- this.showMessage(form, 'Failed to unsubscribe', 'error');
180
- }
181
- }
182
- }
183
-
184
- showMessage(form, text, type) {
185
- const messageEl = form.querySelector('[data-message]');
186
- if (!messageEl) return;
187
-
188
- messageEl.textContent = text;
189
- messageEl.className = `form-message form-message--${type}`;
190
- messageEl.hidden = false;
191
-
192
- setTimeout(() => {
193
- messageEl.hidden = true;
194
- }, 5000);
195
- }
196
- }
197
-
198
- new EmailPreferences();
199
- })();
200
- </script>
@@ -1,228 +0,0 @@
1
- {%- comment -%}
2
- Enhanced Metadata Display Component
3
- Displays comprehensive post metadata including last updated, related tags, and more
4
-
5
- Parameters:
6
- - show_updated_date: Show last updated date (default: true)
7
- - show_tags_cloud: Show related tags cloud (default: true)
8
- - show_category_path: Show category breadcrumb (default: true)
9
- - show_reading_level: Show reading level indicator (default: true)
10
- - show_word_count: Show detailed word count (default: true)
11
- - layout: Display layout (inline, stacked, card) (default: inline)
12
- {%- endcomment -%}
13
-
14
- {%- assign show_updated_date = include.show_updated_date | default: true -%}
15
- {%- assign show_tags_cloud = include.show_tags_cloud | default: true -%}
16
- {%- assign show_category_path = include.show_category_path | default: true -%}
17
- {%- assign show_reading_level = include.show_reading_level | default: true -%}
18
- {%- assign show_word_count = include.show_word_count | default: true -%}
19
- {%- assign layout = include.layout | default: "inline" -%}
20
-
21
- {%- comment -%} Calculate metadata {%- endcomment -%}
22
- {%- assign word_count = page.content | strip_html | number_of_words -%}
23
- {%- assign reading_time = word_count | divided_by: 200 | ceil -%}
24
-
25
- {%- comment -%} Determine reading level {%- endcomment -%}
26
- {%- if word_count < 500 -%}
27
- {%- assign reading_level = "Quick Read" -%}
28
- {%- assign level_class = "quick" -%}
29
- {%- elsif word_count < 1500 -%}
30
- {%- assign reading_level = "Standard" -%}
31
- {%- assign level_class = "standard" -%}
32
- {%- elsif word_count < 3000 -%}
33
- {%- assign reading_level = "In-Depth" -%}
34
- {%- assign level_class = "in-depth" -%}
35
- {%- else -%}
36
- {%- assign reading_level = "Comprehensive" -%}
37
- {%- assign level_class = "comprehensive" -%}
38
- {%- endif -%}
39
-
40
- {%- comment -%} Check for last updated date {%- endcomment -%}
41
- {%- assign has_updated_date = false -%}
42
- {%- if page.last_modified_at or page.updated_date -%}
43
- {%- assign has_updated_date = true -%}
44
- {%- assign updated_date = page.last_modified_at | default: page.updated_date -%}
45
- {%- endif -%}
46
-
47
- <div class="enhanced-metadata enhanced-metadata--{{ layout }}"
48
- data-enhanced-metadata
49
- itemscope
50
- itemtype="https://schema.org/Article">
51
-
52
- <div class="enhanced-metadata__primary">
53
- {%- comment -%} Published date {%- endcomment -%}
54
- <div class="metadata-item metadata-item--date">
55
- <svg class="metadata-item__icon"
56
- xmlns="http://www.w3.org/2000/svg"
57
- width="16"
58
- height="16"
59
- viewBox="0 0 24 24"
60
- fill="none"
61
- stroke="currentColor"
62
- stroke-width="2"
63
- aria-hidden="true">
64
- <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
65
- <line x1="16" y1="2" x2="16" y2="6"></line>
66
- <line x1="8" y1="2" x2="8" y2="6"></line>
67
- <line x1="3" y1="10" x2="21" y2="10"></line>
68
- </svg>
69
- <span class="metadata-item__label">Published</span>
70
- <time class="metadata-item__value"
71
- datetime="{{ page.date | date_to_xmlschema }}"
72
- itemprop="datePublished">
73
- {{ page.date | date: "%B %d, %Y" }}
74
- </time>
75
- </div>
76
-
77
- {%- comment -%} Updated date {%- endcomment -%}
78
- {%- if show_updated_date and has_updated_date -%}
79
- <div class="metadata-item metadata-item--updated">
80
- <svg class="metadata-item__icon"
81
- xmlns="http://www.w3.org/2000/svg"
82
- width="16"
83
- height="16"
84
- viewBox="0 0 24 24"
85
- fill="none"
86
- stroke="currentColor"
87
- stroke-width="2"
88
- aria-hidden="true">
89
- <polyline points="1 4 1 10 7 10"></polyline>
90
- <polyline points="23 20 23 14 17 14"></polyline>
91
- <path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"></path>
92
- </svg>
93
- <span class="metadata-item__label">Updated</span>
94
- <time class="metadata-item__value"
95
- datetime="{{ updated_date | date_to_xmlschema }}"
96
- itemprop="dateModified">
97
- {{ updated_date | date: "%B %d, %Y" }}
98
- </time>
99
- </div>
100
- {%- endif -%}
101
-
102
- {%- comment -%} Author {%- endcomment -%}
103
- {%- if page.author -%}
104
- <div class="metadata-item metadata-item--author"
105
- itemprop="author"
106
- itemscope
107
- itemtype="https://schema.org/Person">
108
- <svg class="metadata-item__icon"
109
- xmlns="http://www.w3.org/2000/svg"
110
- width="16"
111
- height="16"
112
- viewBox="0 0 24 24"
113
- fill="none"
114
- stroke="currentColor"
115
- stroke-width="2"
116
- aria-hidden="true">
117
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
118
- <circle cx="12" cy="7" r="4"></circle>
119
- </svg>
120
- <span class="metadata-item__label">By</span>
121
- <span class="metadata-item__value" itemprop="name">{{ page.author }}</span>
122
- </div>
123
- {%- endif -%}
124
-
125
- {%- comment -%} Word count and reading time {%- endcomment -%}
126
- {%- if show_word_count -%}
127
- <div class="metadata-item metadata-item--words">
128
- <svg class="metadata-item__icon"
129
- xmlns="http://www.w3.org/2000/svg"
130
- width="16"
131
- height="16"
132
- viewBox="0 0 24 24"
133
- fill="none"
134
- stroke="currentColor"
135
- stroke-width="2"
136
- aria-hidden="true">
137
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
138
- <polyline points="14 2 14 8 20 8"></polyline>
139
- <line x1="16" y1="13" x2="8" y2="13"></line>
140
- <line x1="16" y1="17" x2="8" y2="17"></line>
141
- <polyline points="10 9 9 9 8 9"></polyline>
142
- </svg>
143
- <span class="metadata-item__value">
144
- {{ word_count | divided_by: 1000 }},{{ word_count | modulo: 1000 | divided_by: 100 }}{{ word_count | modulo: 100 | divided_by: 10 }}{{ word_count | modulo: 10 }} words
145
- </span>
146
- <span class="metadata-item__separator">·</span>
147
- <span class="metadata-item__value"
148
- itemprop="timeRequired"
149
- content="PT{{ reading_time }}M">
150
- {{ reading_time }} min read
151
- </span>
152
- </div>
153
- {%- endif -%}
154
-
155
- {%- comment -%} Reading level {%- endcomment -%}
156
- {%- if show_reading_level -%}
157
- <div class="metadata-item metadata-item--level">
158
- <span class="reading-level reading-level--{{ level_class }}">
159
- {{ reading_level }}
160
- </span>
161
- </div>
162
- {%- endif -%}
163
- </div>
164
-
165
- {%- comment -%} Category path {%- endcomment -%}
166
- {%- if show_category_path and page.categories.size > 0 -%}
167
- <div class="enhanced-metadata__categories">
168
- <svg class="enhanced-metadata__categories-icon"
169
- xmlns="http://www.w3.org/2000/svg"
170
- width="14"
171
- height="14"
172
- viewBox="0 0 24 24"
173
- fill="none"
174
- stroke="currentColor"
175
- stroke-width="2"
176
- aria-hidden="true">
177
- <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
178
- </svg>
179
- <nav class="category-path" aria-label="Categories">
180
- {%- for category in page.categories -%}
181
- {%- unless forloop.first -%}
182
- <span class="category-path__separator" aria-hidden="true">/</span>
183
- {%- endunless -%}
184
- <a href="{{ '/categories/' | append: category | slugify | append: '/' | relative_url }}"
185
- class="category-path__link">
186
- {{ category }}
187
- </a>
188
- {%- endfor -%}
189
- </nav>
190
- </div>
191
- {%- endif -%}
192
-
193
- {%- comment -%} Tags cloud {%- endcomment -%}
194
- {%- if show_tags_cloud and page.tags.size > 0 -%}
195
- <div class="enhanced-metadata__tags">
196
- <svg class="enhanced-metadata__tags-icon"
197
- xmlns="http://www.w3.org/2000/svg"
198
- width="14"
199
- height="14"
200
- viewBox="0 0 24 24"
201
- fill="none"
202
- stroke="currentColor"
203
- stroke-width="2"
204
- aria-hidden="true">
205
- <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path>
206
- <line x1="7" y1="7" x2="7.01" y2="7"></line>
207
- </svg>
208
- <div class="tags-cloud" aria-label="Related tags">
209
- {%- for tag in page.tags -%}
210
- <a href="{{ '/tags/' | append: tag | slugify | append: '/' | relative_url }}"
211
- class="tag-pill"
212
- rel="tag">
213
- {{ tag }}
214
- </a>
215
- {%- endfor -%}
216
- </div>
217
- </div>
218
- {%- endif -%}
219
-
220
- {%- comment -%} Additional structured data {%- endcomment -%}
221
- <meta itemprop="wordCount" content="{{ word_count }}">
222
- {%- if page.description -%}
223
- <meta itemprop="description" content="{{ page.description | strip_html | truncate: 160 }}">
224
- {%- endif -%}
225
- {%- if page.featured_image or page.image -%}
226
- <meta itemprop="image" content="{{ page.featured_image | default: page.image | absolute_url }}">
227
- {%- endif -%}
228
- </div>