@awesomeness-js/server 1.0.1 → 1.1.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 (130) hide show
  1. package/README.md +61 -0
  2. package/build/build.js +7 -0
  3. package/build/postBuild.js +7 -0
  4. package/example-.awesomeness/componentLocations.js +15 -0
  5. package/example-.awesomeness/config.js +5 -21
  6. package/example-site/example.awesomenessjs.com/api/readme.md +1 -0
  7. package/example-site/example.awesomenessjs.com/components/example/index.js +3 -0
  8. package/example-site/example.awesomenessjs.com/components/notCommonExample/_.css +1 -0
  9. package/example-site/example.awesomenessjs.com/components/notCommonExample/index.js +3 -0
  10. package/example-site/example.awesomenessjs.com/pages/_md/_info.js +15 -0
  11. package/example-site/example.awesomenessjs.com/pages/_md/css/example.css +4 -0
  12. package/example-site/example.awesomenessjs.com/pages/_md/drafts/example.md +32 -0
  13. package/example-site/example.awesomenessjs.com/pages/_md/getBlogData.js +117 -0
  14. package/example-site/example.awesomenessjs.com/pages/_md/getData.js +36 -0
  15. package/example-site/example.awesomenessjs.com/pages/_md/js/callToAction.js +43 -0
  16. package/example-site/example.awesomenessjs.com/pages/_md/js/init.js +88 -0
  17. package/example-site/example.awesomenessjs.com/pages/_md/meta.template.md +33 -0
  18. package/example-site/example.awesomenessjs.com/pages/_md/pages/mission.md +345 -0
  19. package/example-site/example.awesomenessjs.com/pages/_template/_info.js +9 -0
  20. package/example-site/example.awesomenessjs.com/pages/_template/css/_.css +4 -0
  21. package/example-site/example.awesomenessjs.com/pages/_template/getData.js +6 -0
  22. package/example-site/example.awesomenessjs.com/pages/_template/js/init.js +3 -0
  23. package/example-site/example.awesomenessjs.com/pages/blog/_info.js +14 -0
  24. package/example-site/example.awesomenessjs.com/pages/blog/css/topics.css +17 -0
  25. package/example-site/example.awesomenessjs.com/pages/blog/getData.js +22 -0
  26. package/example-site/example.awesomenessjs.com/pages/blog/js/colors.js +159 -0
  27. package/example-site/example.awesomenessjs.com/pages/blog/js/init.js +242 -0
  28. package/example-site/example.awesomenessjs.com/pages/blog/js/tag.js +111 -0
  29. package/example-site/example.awesomenessjs.com/pages/examples/_info.js +9 -0
  30. package/example-site/example.awesomenessjs.com/pages/examples/css/footer.css +6 -0
  31. package/example-site/example.awesomenessjs.com/pages/examples/css/intro.css +67 -0
  32. package/example-site/example.awesomenessjs.com/pages/examples/css/nav.css +221 -0
  33. package/example-site/example.awesomenessjs.com/pages/examples/getData.js +8 -0
  34. package/example-site/example.awesomenessjs.com/pages/examples/js/init.js +15 -0
  35. package/example-site/example.awesomenessjs.com/pages/examples/js/updateState.js +14 -0
  36. package/example-site/example.awesomenessjs.com/pages/start/_info.js +11 -0
  37. package/example-site/example.awesomenessjs.com/pages/start/css/footer.css +6 -0
  38. package/example-site/example.awesomenessjs.com/pages/start/css/intro.css +67 -0
  39. package/example-site/example.awesomenessjs.com/pages/start/css/nav.css +221 -0
  40. package/example-site/example.awesomenessjs.com/pages/start/getData.js +8 -0
  41. package/example-site/example.awesomenessjs.com/pages/start/js/init.js +30 -0
  42. package/example-site/example.awesomenessjs.com/pages/start/js/updateState.js +14 -0
  43. package/example-site/example.awesomenessjs.com/public/images/awesomeness.webp +0 -0
  44. package/example-site/example.awesomenessjs.com/public/manifest.webmanifest.json +8 -0
  45. package/example-site/example.awesomenessjs.com/specialRoutes.js +14 -0
  46. package/index.js +105 -22
  47. package/package.json +5 -2
  48. package/{server → src}/applicationMap.js +1 -1
  49. package/{server → src}/awesomenessNormalizeRequest.js +24 -3
  50. package/{server → src}/componentDependencies.js +11 -5
  51. package/{config.js → src/config.js} +6 -1
  52. package/{server → src}/fetchPage.js +6 -6
  53. package/src/getConfig.js +3 -0
  54. package/src/init.js +3 -0
  55. package/{server → src}/koa/attachAwesomenessRequest.js +5 -6
  56. package/{server → src}/koa/cors.js +2 -4
  57. package/{server → src}/koa/errorHandler.js +3 -3
  58. package/{server → src}/koa/finalFormat.js +2 -5
  59. package/{server → src}/koa/jsonBodyParser.js +3 -3
  60. package/src/koa/routeRequest.js +334 -0
  61. package/{server → src}/koa/serverUp.js +2 -4
  62. package/{server → src}/koa/staticFiles.js +10 -11
  63. package/{server → src}/koa/timeout.js +3 -3
  64. package/{server → src}/pageInfo.js +6 -6
  65. package/{server → src}/reRoute.js +3 -2
  66. package/{server → src}/resolveRealCasePath.js +1 -1
  67. package/{start.js → src/start.js} +14 -13
  68. package/{server → src}/validateRequest.js +1 -1
  69. package/{server → src}/ws/handlers.js +4 -2
  70. package/{server → src}/ws/index.js +2 -2
  71. package/ui/README.md +438 -0
  72. package/ui/awesomeness-ui.instructions.md +156 -0
  73. package/ui/build.js +119 -0
  74. package/ui/commonComponent.test.js +27 -0
  75. package/ui/components/blogPost/all.css +371 -0
  76. package/ui/components/blogPost/headerImage.js +153 -0
  77. package/ui/components/blogPost/index.js +45 -0
  78. package/ui/components/blogPost/marked.js +74 -0
  79. package/ui/components/blogPost/md.js +73 -0
  80. package/ui/components/blogPost/parseAwesomeness.jQuery.js +47 -0
  81. package/ui/components/blogPost/readme.md +8 -0
  82. package/ui/components/colors/README.md +65 -0
  83. package/ui/components/colors/dynamic.css +1884 -0
  84. package/ui/components/colors/dynamic.css.js +135 -0
  85. package/ui/components/colors/dynamic.css.php +79 -0
  86. package/ui/components/colors/example.js +133 -0
  87. package/ui/components/colors/index.js +65 -0
  88. package/ui/components/colors/map.js +13 -0
  89. package/ui/components/colors/random.js +17 -0
  90. package/ui/components/colors/tailwind-colors.css +247 -0
  91. package/ui/components/insertIntoList/insertIntoList.jquery.js +150 -0
  92. package/ui/components/tag/category.js +8 -0
  93. package/ui/components/tag/index.js +33 -0
  94. package/ui/components/tag/list.js +42 -0
  95. package/ui/components/tag/map.js +64 -0
  96. package/ui/components/tag/tagMap.css +60 -0
  97. package/ui/components/tag/tags.css +20 -0
  98. package/ui/core/css/_normalize.css +57 -0
  99. package/ui/core/css/dynamic/flex.js +36 -0
  100. package/ui/core/css/dynamic/grid.js +185 -0
  101. package/ui/core/css/dynamic/shortcuts.js +48 -0
  102. package/ui/core/css/dynamic/spacing.js +61 -0
  103. package/ui/core/css/dynamic/text.js +80 -0
  104. package/ui/core/css/dynamic/width.js +75 -0
  105. package/ui/core/css/dynamic.js +40 -0
  106. package/ui/core/js/app/api.js +143 -0
  107. package/ui/core/js/app/init.js +88 -0
  108. package/ui/core/js/app/initDarkMode.js +26 -0
  109. package/ui/core/js/app/initialScroll.js +28 -0
  110. package/ui/core/js/app/meta/update/components.js +65 -0
  111. package/ui/core/js/app/meta/update/pages.js +86 -0
  112. package/ui/core/js/app/metaUpdates.js +10 -0
  113. package/ui/core/js/app/page.js +319 -0
  114. package/ui/core/js/app/resize.js +52 -0
  115. package/ui/core/js/app/state/back.js +16 -0
  116. package/ui/core/js/app/state/create.js +50 -0
  117. package/ui/core/js/app/state/get.js +5 -0
  118. package/ui/core/js/app/state/init.js +25 -0
  119. package/ui/core/js/app.js +41 -0
  120. package/ui/core/js/jquery-3.7.1.min.js +2 -0
  121. package/ui/core/public/app.css +1 -0
  122. package/ui/core/public/app.js +975 -0
  123. package/ui/core/public/favicon.ico +0 -0
  124. package/ui/core/public/index.html +40 -0
  125. package/server/koa/routeRequest.js +0 -286
  126. /package/{server/errors.js → errors.js} +0 -0
  127. /package/{server → src}/brotliJsonResponse.js +0 -0
  128. /package/{server → src}/checkAccess.js +0 -0
  129. /package/{server → src}/getMD.js +0 -0
  130. /package/{server → src}/specialPaths.js +0 -0
@@ -0,0 +1,27 @@
1
+ import componentDependencies from '../src/componentDependencies.js';
2
+ import { expect, test } from 'vitest';
3
+
4
+ test('component test', () => {
5
+
6
+ const test = componentDependencies([ '_example' ],{
7
+ showDetails: true
8
+ });
9
+
10
+ expect(test._example.js).toBeDefined();
11
+ expect(test._example.js).toContain('ui._example');
12
+ expect(test._example.css).toBeDefined();
13
+ expect(test._example.js_details).toBeDefined();
14
+ expect(test._example.css_details).toBeDefined();
15
+
16
+ const test2 = componentDependencies([ 'notCommonExample' ],{
17
+ showDetails: false,
18
+ customLocation: `./sites/demo.awesomenessjs.com/components`,
19
+ });
20
+
21
+ expect(test2.notCommonExample.js).toBeDefined();
22
+ expect(test2.notCommonExample.js).toContain('ui.notCommonExample');
23
+ expect(test2.notCommonExample.css).toBeDefined();
24
+ expect(test2.notCommonExample.js_details).toBeUndefined();
25
+ expect(test2.notCommonExample.css_details).toBeUndefined();
26
+
27
+ });
@@ -0,0 +1,371 @@
1
+ .blogPost {
2
+ display: grid;
3
+ grid-template-columns: 1fr; /* single column */
4
+ justify-items: stretch; /* <— critical */
5
+ align-items: stretch; /* optional */
6
+ width: 100%;
7
+ margin-inline: auto; /* center the 800px box */
8
+ min-width: 0; /* avoid overflow issues */
9
+ }
10
+
11
+ .blogPost h2 {
12
+ text-transform: inherit;
13
+ font-size: 1.5em;
14
+ margin-top: 50px;
15
+ }
16
+
17
+ .blogPost .break {
18
+ width: 100%;
19
+ display: block;
20
+ }
21
+
22
+
23
+ .blogPost h3 {
24
+ font-weight: 300;
25
+ text-transform: inherit;
26
+ letter-spacing: 1.3px;
27
+ text-align: left;
28
+ color: #777;
29
+ margin-top: 0px;
30
+ font-size: 1.1em;
31
+ margin-bottom: 20px;
32
+ }
33
+
34
+ .blogPost p {
35
+ font-size: 1.2em;
36
+ line-height: 2em;
37
+ color: #404040;
38
+ }
39
+
40
+ .blogPost blockquote {
41
+ background-color: #e6e6e6;
42
+ margin: 0;
43
+ padding: 15px 25px;
44
+ color: #343434;
45
+ border-radius: 10px;
46
+ }
47
+
48
+
49
+ .blogPost blockquote p {
50
+ font-size: 1.1em;
51
+ line-height: 1.8 em;
52
+ margin: 5px;
53
+ }
54
+
55
+ .blogPost a {
56
+ color: #0a99ff;
57
+ text-decoration: none;
58
+ font-weight: 500;
59
+ cursor: pointer;
60
+ }
61
+
62
+ .blogPost a:hover {
63
+ text-decoration: underline;
64
+ }
65
+
66
+ .blogPost table {
67
+ width: 100%;
68
+ border-collapse: collapse;
69
+ margin: 25px 0;
70
+ font-size: 1em;
71
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
72
+ }
73
+
74
+ .blogPost tr {
75
+ margin-bottom: 15px;
76
+ }
77
+
78
+ .blogPost th {
79
+ text-align: left;
80
+ padding: 13px 15px;
81
+ background-color: #dedede;
82
+ color: #333;
83
+ font-weight: 600;
84
+ }
85
+
86
+ .blogPost th:first-child {
87
+ border-top-left-radius: 6px;
88
+ }
89
+
90
+ .blogPost th:last-child {
91
+ border-top-right-radius: 6px;
92
+ }
93
+
94
+ .blogPost td {
95
+ padding: 13px 15px;
96
+ border-bottom: 1px solid #e6e6e6;
97
+ color: #555;
98
+ font-weight: 400;
99
+ }
100
+
101
+ .blogPost ol,
102
+ .blogPost ul {
103
+ margin: 20px 0;
104
+ padding-left: 1.5em;
105
+ font-size: 1em;
106
+ color: #555;
107
+ line-height: 1.6;
108
+ }
109
+
110
+ /* Ordered list numbers */
111
+ .blogPost ol {
112
+ list-style-type: decimal;
113
+ }
114
+
115
+ /* Unordered list bullets */
116
+ .blogPost ul {
117
+ list-style-type: disc;
118
+ }
119
+
120
+ /* List items */
121
+ .blogPost li {
122
+ margin-bottom: 8px;
123
+ }
124
+
125
+ /* List items */
126
+ .blogPost ul li ul {
127
+ margin-top: 5px;
128
+ }
129
+
130
+ /* List items */
131
+ .blogPost ul li ul li {
132
+ margin-bottom: 8px;
133
+ list-style: circle;
134
+ font-size: 0.9em;
135
+ margin-top: 0px;
136
+ }
137
+
138
+ /* Nested lists get lighter style */
139
+ .blogPost ol ol,
140
+ .blogPost ul ul {
141
+ margin: 20px 0;
142
+ font-size: 1em;
143
+ color: #555;
144
+ line-height: 1.6;
145
+ font-size: 1.1em;
146
+ padding-left: 30px;
147
+ }
148
+
149
+ .blogPost ol li::marker {
150
+ font-weight: 600;
151
+ /* optional: make numbers bolder */
152
+ padding-right: 10px;
153
+ /* adds space after number */
154
+ }
155
+
156
+ .blogPost-header-image {
157
+ position: relative;
158
+ min-height: 500px;
159
+ display: flex;
160
+ justify-content: center;
161
+ align-items: center;
162
+ flex-direction: column;
163
+ text-align: center;
164
+ color: var(--white);
165
+ background-size: cover;
166
+ background-position: center;
167
+ overflow: hidden; /* ensures overlay stays contained */
168
+ padding-bottom: 5%;
169
+ margin-bottom: 25px;
170
+ min-height: 700px;
171
+ }
172
+
173
+ .app-size-p .blogPost-header-image { min-height: 400px; }
174
+
175
+ .app-size-d .blogPost-header-image { min-height: 800px; }
176
+ .app-size-xl .blogPost-header-image { min-height: 800px; }
177
+
178
+ .blogPost-header-image::before {
179
+ content: "";
180
+ position: absolute;
181
+ top: 0;
182
+ left: 0;
183
+ width: 100%;
184
+ height: 100%;
185
+ background: linear-gradient(
186
+ rgba(0, 0, 0, 0.0) 0%,
187
+ rgba(0, 0, 0, 0.4) 35%,
188
+ rgba(0, 0, 0, 0.4) 65%,
189
+ rgba(0, 0, 0, 0.0) 100%
190
+ );
191
+ z-index: 0;
192
+ }
193
+
194
+
195
+ .blogPost-header-image > * {
196
+ position: relative;
197
+ z-index: 1; /* keeps text above the dark overlay */
198
+ }
199
+
200
+ .blogPost-title{
201
+ font-weight: 700;
202
+ font-size: 3em;
203
+ margin-bottom: 10px;
204
+ padding: 0px 50px;
205
+ }
206
+
207
+ .blogPost-subTitle{
208
+ font-weight: 300;
209
+ font-size: 1.6em;
210
+ margin-bottom: 15px;
211
+ text-transform: none;
212
+ color: var(--white);
213
+ padding: 0px 50px;
214
+ }
215
+
216
+ .app-size-p .blogPost-subTitle{
217
+ font-size: 1.2em;
218
+ }
219
+
220
+
221
+ .blogPost-catDateTime {
222
+ display: flex;
223
+ align-items: center;
224
+ justify-content: flex-start;
225
+ gap: 10px;
226
+ font-size: 1.05em;
227
+ color: var(--stone-100);
228
+ margin-bottom: 20px;
229
+ letter-spacing: 1px;
230
+ }
231
+
232
+ .blogPost-catDateTime > * {
233
+ display: inline;
234
+ }
235
+
236
+ .blogPost-category {
237
+ cursor: pointer;
238
+ text-transform: capitalize;
239
+ }
240
+
241
+ .app-size-p .blogPost-catDateTime {
242
+ flex-direction: column;
243
+ margin-top: 45px;
244
+ }
245
+
246
+
247
+ .app-size-p .blogPost-catDateTime > * {
248
+ display: flex;
249
+ }
250
+
251
+ .blogPost-category:hover {
252
+ font-weight: 500;
253
+ }
254
+
255
+ .blogPost-catDateTime-separator {
256
+ width: 7px;
257
+ height: 7px;
258
+ border-radius: 50%;
259
+ background-color: var(--stone-100);
260
+ flex-shrink: 0;
261
+ margin: 0px 5px;
262
+ }
263
+
264
+ .app-size-p .blogPost-catDateTime-separator {
265
+ display: none;
266
+ }
267
+
268
+ .blogPost-author {
269
+ display: flex;
270
+ align-items: center; /* vertically centers image and text */
271
+ gap: 10px; /* replaces margin-right for cleaner spacing */
272
+ font-size: 1em;
273
+ color: var(--white);
274
+ font-weight: 300;
275
+ margin-top: 25px;
276
+ padding-bottom: 40px;
277
+ }
278
+
279
+ .app-size-p .blogPost-author {
280
+ flex-direction: column;
281
+ padding-bottom: 100px;
282
+ }
283
+
284
+ .app-size-p .blogPost-author-name {
285
+ display: block;
286
+ margin-bottom: 10px;
287
+ }
288
+
289
+ .blogPost-author-name {
290
+ font-weight: 500;
291
+ margin-right: 10px;
292
+ font-size: 1.1em;
293
+ letter-spacing: 0.03em;
294
+ }
295
+ .blogPost-author-image {
296
+ margin-right: 10px;
297
+ width: 40px;
298
+ height: 40px;
299
+ border-radius: 50%;
300
+ background-color: var(--white);
301
+ background-size: cover;
302
+ background-position: center;
303
+ flex-shrink: 0; /* keeps it from squishing */
304
+ }
305
+
306
+ .blogPost-next-reads h2,
307
+ .blogPost-next-reads h3 {
308
+ margin-bottom: 10px;
309
+ }
310
+
311
+ .blogPost-next-reads li {
312
+ border: solid 1px var(--stone-200);
313
+ border-radius: 5px;
314
+ cursor: pointer;
315
+ }
316
+
317
+ .blogPost-next-reads li:hover {
318
+ background-color: var(--blue-100);
319
+ border-color: var(--blue-300);
320
+ font-weight: 500;
321
+ }
322
+
323
+ .blogPost-next-reads li a {
324
+ font-weight: 400;
325
+ display: block;
326
+ padding: 10px;
327
+ }
328
+
329
+ .blogPost-next-reads li a:hover,
330
+ .blogPost-tags-list .blogPost-tag:hover a {
331
+ text-decoration: none;
332
+ }
333
+
334
+ .blogPost-next-reads ul {
335
+ list-style: none;
336
+ margin: 0px;
337
+ padding: 0px;
338
+ }
339
+
340
+
341
+ .blogPost-tags-list {
342
+ position: absolute;
343
+ bottom: 25px;
344
+ font-size: 0.8em;
345
+ display: flex;
346
+ align-items: center;
347
+ gap: 8px;
348
+ flex-wrap: wrap;
349
+ justify-content: center;
350
+ padding: 0px 20px;
351
+ }
352
+
353
+ .blogPost-tag {
354
+ border: solid 1px var(--stone-200);
355
+ cursor: pointer;
356
+ padding: 5px 10px;
357
+ white-space: nowrap;
358
+ transition: all 200ms;
359
+ }
360
+
361
+ .blogPost-tag:hover {
362
+ color: var(--black);
363
+ background-color: var(--white);
364
+ }
365
+
366
+ .blogPost img {
367
+ max-width: 100%;
368
+ min-width: 100%;
369
+ border-radius: 8px;
370
+ margin: 20px 0px;
371
+ }
@@ -0,0 +1,153 @@
1
+ // awesomeness import 'tag'
2
+
3
+ export default ({
4
+ mdContent,
5
+ metadata,
6
+ tagBase = '/tag'
7
+ }) => {
8
+
9
+ const $headerImage = $(`<div class="blogPost-header-image"></div>`)
10
+ .css({ 'background-image': `url(${metadata.image})` });
11
+
12
+
13
+ const $catDateTime = $(`<div class="blogPost-catDateTime"></div>`)
14
+ .appendTo($headerImage);
15
+
16
+
17
+ if(!metadata.category && metadata?.tags.length > 0){
18
+
19
+ metadata.category = metadata.tags[0];
20
+
21
+ }
22
+
23
+ if(metadata.category){
24
+
25
+ $(`<a href="${tagBase}/${metadata.category}"><div class="blogPost-category">${metadata.category}</div></a>`)
26
+ .appendTo($catDateTime);
27
+
28
+ // add •
29
+ $(`<div class="blogPost-catDateTime-separator"></div>`)
30
+ .appendTo($catDateTime);
31
+
32
+ }
33
+
34
+ if(metadata.published){
35
+
36
+ // make EST default
37
+
38
+ let tz = metadata.timezone || 'America/New_York';
39
+
40
+ const [ y, m, d ] = metadata.published.split('-').map(Number);
41
+
42
+ // Create date in local time (NOT UTC)
43
+ const date = new Date(y, m - 1, d);
44
+
45
+ const options = {
46
+ year: 'numeric',
47
+ month: app && app.size && app.size.view !== 'p' ? 'long' : 'short',
48
+ day: 'numeric',
49
+ timeZone: tz
50
+ };
51
+
52
+ const formattedDate = date.toLocaleDateString(undefined, options);
53
+
54
+ $(`<div class="blogPost-published">${formattedDate}</div>`)
55
+ .appendTo($catDateTime);
56
+
57
+
58
+ // add •
59
+ $(`<div class="blogPost-catDateTime-separator"></div>`)
60
+ .appendTo($catDateTime);
61
+
62
+ }
63
+
64
+ if(!metadata.readTime && mdContent){
65
+
66
+ const wordsPerMinute = 200;
67
+ const words = mdContent.trim().split(/\s+/).length;
68
+ const readTime = Math.ceil(words / wordsPerMinute);
69
+
70
+ metadata.readTime = readTime;
71
+
72
+ }
73
+
74
+ if(metadata.readTime){
75
+
76
+ $(`<div class="blogPost-readTime"><i class="ico-clock"></i> ${metadata.readTime} min read</div>`)
77
+ .appendTo($catDateTime);
78
+
79
+ } else {
80
+
81
+ console.warn('Read time could not be calculated for blog post:', {
82
+ metadata,
83
+ mdContent
84
+ });
85
+
86
+ }
87
+
88
+
89
+ const $title = $(`<h1 class="blogPost-title"><a target="_blank" href="${metadata.url}">${metadata.title}</a></h1>`)
90
+ .appendTo($headerImage);
91
+
92
+ if(metadata.subTitle){
93
+
94
+ $(`<h2 class="blogPost-subTitle">${metadata.subTitle}</h2>`)
95
+ .appendTo($headerImage);
96
+
97
+ }
98
+
99
+
100
+ if(metadata.author){
101
+
102
+ let image;
103
+
104
+ let authorName = metadata.author.url ? `<a class="blogPost-author-name" href="${metadata.author.url}" target="_blank" rel="noopener">${metadata.author.name}</a>` : metadata.author.name;
105
+
106
+ if(metadata.author.title){
107
+
108
+ authorName += `${metadata.author.title}`;
109
+
110
+ }
111
+
112
+
113
+ const $author = $(`<div class="blogPost-author"><span>${authorName}</span></div>`)
114
+ .appendTo($headerImage);
115
+
116
+ if(metadata.author.image){
117
+
118
+ image = $(`<div class="blogPost-author-image"></div>`)
119
+ .css({ 'background-image': `url(${metadata.author.image})` })
120
+ .prependTo($author);
121
+
122
+
123
+ }
124
+
125
+ }
126
+
127
+
128
+ if(metadata.tags){
129
+
130
+ const $tagsList = $(`<div class="blogPost-tags-list"></div>`)
131
+ .appendTo($headerImage);
132
+
133
+ metadata?.tags?.forEach((tag) => {
134
+
135
+ const link = ui.tag.category(tag);
136
+
137
+ const $tag = $(`<a href="${tagBase}/${link}"><div class="blogPost-tag ${metadata.tagColor ? metadata.tagColor : ''}">${tag}</div></a>`)
138
+ .appendTo($tagsList)
139
+ .on('click', (e) => {
140
+
141
+ e.stopPropagation();
142
+ e.preventDefault();
143
+ app.page(`${tagBase}/${link}`);
144
+
145
+ });
146
+
147
+ });
148
+
149
+ }
150
+
151
+ return $headerImage;
152
+
153
+ };
@@ -0,0 +1,45 @@
1
+ export default (post) => {
2
+
3
+ let $out = $('<div class="blogPost"></div>');
4
+
5
+ if(!post || !post.sections){
6
+
7
+ $out.html('hmmm.... something is wrong with this post');
8
+
9
+ return $out;
10
+
11
+ }
12
+
13
+ post.sections.forEach((section) => {
14
+
15
+ if(
16
+ typeof ui.blogPost[section.type] !== 'function'
17
+ && !typeof section.custom === 'function'
18
+ ){
19
+
20
+ console.log(`blogPost section type "${section.type}" not found (not custom either...)`, section);
21
+
22
+ return;
23
+
24
+ }
25
+
26
+ const $sectionContainer = $(`<div class="blogPost-section"></div>`)
27
+ .appendTo($out);
28
+
29
+ const $sectionContent = ui.blogPost[section.type](section.data);
30
+
31
+ if(!$sectionContent){
32
+
33
+ console.log(`blogPost section type "${section.type}" returned no content`, section);
34
+
35
+ return;
36
+
37
+ }
38
+
39
+ $sectionContent.appendTo($sectionContainer);
40
+
41
+ });
42
+
43
+ return $out;
44
+
45
+ };