ultimate-jekyll-manager 0.0.117 → 0.0.119

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 (44) hide show
  1. package/CLAUDE.md +616 -138
  2. package/README.md +108 -0
  3. package/TODO.md +1 -1
  4. package/dist/assets/js/core/auth.js +8 -11
  5. package/dist/assets/js/core/cookieconsent.js +24 -17
  6. package/dist/assets/js/core/exit-popup.js +15 -12
  7. package/dist/assets/js/core/social-sharing.js +8 -4
  8. package/dist/assets/js/libs/auth/pages.js +14 -13
  9. package/dist/assets/js/libs/dev.js +192 -129
  10. package/dist/assets/js/libs/prerendered-icons.js +27 -0
  11. package/dist/assets/js/pages/account/index.js +4 -3
  12. package/dist/assets/js/pages/account/sections/api-keys.js +2 -6
  13. package/dist/assets/js/pages/account/sections/connections.js +101 -59
  14. package/dist/assets/js/pages/account/sections/delete.js +83 -84
  15. package/dist/assets/js/pages/account/sections/referrals.js +29 -29
  16. package/dist/assets/js/pages/account/sections/security.js +51 -71
  17. package/dist/assets/js/pages/admin/notifications/new/index.js +17 -10
  18. package/dist/assets/js/pages/blog/index.js +7 -5
  19. package/dist/assets/js/pages/contact/index.js +6 -33
  20. package/dist/assets/js/pages/download/index.js +3 -2
  21. package/dist/assets/js/pages/payment/checkout/index.js +6 -6
  22. package/dist/assets/js/pages/payment/checkout/modules/processors-main.js +2 -2
  23. package/dist/assets/js/pages/payment/checkout/modules/session.js +4 -4
  24. package/dist/assets/js/pages/pricing/index.js +5 -2
  25. package/dist/assets/themes/classy/css/components/_cards.scss +2 -2
  26. package/dist/defaults/_.env +6 -0
  27. package/dist/defaults/_.gitignore +7 -1
  28. package/dist/defaults/dist/_includes/core/body.html +18 -3
  29. package/dist/defaults/dist/_includes/core/foot.html +1 -0
  30. package/dist/defaults/dist/_includes/themes/classy/frontend/sections/nav.html +51 -36
  31. package/dist/defaults/dist/_layouts/blueprint/admin/notifications/new.html +13 -2
  32. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/about.html +84 -42
  33. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/account/index.html +67 -35
  34. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/index.html +72 -58
  35. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/post.html +46 -29
  36. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html +36 -16
  37. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/download.html +111 -73
  38. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/index.html +111 -56
  39. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +127 -81
  40. package/dist/defaults/dist/pages/pricing.md +7 -0
  41. package/dist/defaults/dist/pages/test/libraries/lazy-loading.html +1 -1
  42. package/dist/gulp/tasks/defaults.js +210 -1
  43. package/firebase-debug.log +504 -0
  44. package/package.json +5 -5
package/CLAUDE.md CHANGED
@@ -1,41 +1,214 @@
1
- # Identity
2
- This is Ultimate Jekyll, it is a template project that other "consuming" projects can use to build a Jekyll site. It comes installed as an NPM module and is helpful for setting up, configuring, and maintaining a Jekyll site with best practices in mind.
1
+ # Ultimate Jekyll Manager
3
2
 
4
- It is not a stand-alone project, but rather a collection of components that can be used to build a Jekyll site quickly and efficiently.
5
- * You cannot use `npm start` or `npm run build` in this project.
3
+ ## Project Overview
6
4
 
7
- ## Structure
8
- Ultimate Jekll has the following structure:
9
- src/gulp/tasks = Gulp tasks that are used to build the Jekyll site.
10
- src/defaults/src = Default source files that can be used as a starting point for a Jekyll site and ARE meant to be edited by the user. They are copied to the consuming project's "src" directory.
11
- src/defaults/dist = Default distribution files that can be used as a starting point for a Jekyll site and NOT meant to be edited by the user. They are copied to the consuming project's "dist" directory.
5
+ Ultimate Jekyll Manager is a template framework that consuming projects install as an NPM module to build Jekyll sites quickly and efficiently. It provides best-practice configurations, default components, themes, and build tools.
12
6
 
13
- The "consuming" project has the following structure:
14
- "src" = Compiled to "dist" with npm
15
- "dist" = Compiled to "_site" with Jekyll.
7
+ **Important:** This is NOT a standalone project. You cannot run `npm start` or `npm run build` directly in this repository.
8
+
9
+ ## Project Structure
10
+
11
+ ### Directory Organization
12
+ - `src/gulp/tasks` - Gulp tasks for building Jekyll sites
13
+ - `src/defaults/src` - Default source files (editable by users, copied to consuming project's `src/`)
14
+ - `src/defaults/dist` - Default distribution files (not editable by users, copied to consuming project's `dist/`)
15
+ - `src/assets/css` - Stylesheets (global, pages, themes)
16
+ - `src/assets/js` - JavaScript modules (core, pages, libraries)
17
+ - `src/assets/themes` - Theme SCSS and JS files
18
+
19
+ ### Consuming Project Structure
20
+ - `src/` - Compiled to `dist/` via npm
21
+ - `dist/` - Compiled to `_site/` via Jekyll
16
22
 
17
23
  ## Local Development
18
- When working with a consuming project, the local development server URL can be found in the `.temp/_config_browsersync.yml` file in the consuming project's root directory. You should read this file to determine the correct local URL for browsing and testing the site.
19
24
 
20
- ## Other Ultimate Jekyll Components:
21
- src/assets/css/ultimate-jekyll-manager.scss = Main stylesheet used by Ultimate Jekyll to style the site
22
- src/assets/css/global = Global styles that are used by Ultimate Jekyll
23
- src/assets/css/pages = Page-specific styles that are used by Ultimate Jekyll
24
- * If you are making a page, put the styles in this directory like so: `src/assets/css/pages/[page-name]/index.scss`
25
+ The local development server URL is stored in `.temp/_config_browsersync.yml` in the consuming project's root directory. Read this file to determine the correct URL for browsing and testing.
26
+
27
+ ## Asset Organization
28
+
29
+ ### Ultimate Jekyll Manager Files (THIS project)
30
+
31
+ **CSS:**
32
+ - `src/assets/css/ultimate-jekyll-manager.scss` - Main UJ stylesheet (provides core styles)
33
+ - `src/assets/css/global/` - Global UJ styles
34
+ - `src/assets/css/pages/` - Page-specific styles provided by UJ
35
+ - Format: `src/assets/css/pages/[page-name]/index.scss`
36
+ - Example: `src/assets/css/pages/download/index.scss`
37
+
38
+ **JavaScript:**
39
+ - `src/assets/js/ultimate-jekyll-manager.js` - Main UJ JavaScript entry point (provides core functionality)
40
+ - `src/assets/js/core/` - Core UJ modules
41
+ - `src/assets/js/pages/` - Page-specific JavaScript provided by UJ
42
+ - Format: `src/assets/js/pages/[page-name]/index.js`
43
+ - Example: `src/assets/js/pages/download/index.js`
44
+ - `src/assets/js/libs/` - UJ library modules (prerendered-icons, form-manager, authorized-fetch, etc.)
45
+
46
+ **Default Pages & Layouts:**
47
+
48
+ UJ provides default page templates and layouts in `src/defaults/dist/` that are copied to consuming projects. These are NOT meant to be edited by users.
49
+
50
+ - Format: `src/defaults/dist/_layouts/themes/[theme-id]/frontend/pages/[page-name].html`
51
+ - Examples:
52
+ - `src/defaults/dist/_layouts/themes/classy/frontend/pages/download.html`
53
+ - `src/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html`
54
+ - `src/defaults/dist/_layouts/themes/classy/frontend/pages/payment/checkout.html`
55
+ - `src/defaults/dist/_layouts/themes/classy/frontend/pages/payment/confirmation.html`
56
+ - `src/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html`
57
+ - Core layouts:
58
+ - `src/defaults/dist/_layouts/core/root.html` - Root HTML wrapper
59
+ - `src/defaults/dist/_layouts/themes/[theme-id]/frontend/core/base.html` - Theme base layout
60
+
61
+ **Complete UJ Page Example:**
62
+ - **HTML:** `src/defaults/dist/_layouts/themes/classy/frontend/pages/download.html`
63
+ - **CSS:** `src/assets/css/pages/download/index.scss`
64
+ - **JS:** `src/assets/js/pages/download/index.js`
65
+
66
+ These files serve as blueprints and reference implementations. When building custom pages in consuming projects, reference these for patterns and best practices.
67
+
68
+ **IMPORTANT:** Consuming projects CAN create files with the same paths in their own `src/` directory to override UJ defaults, but this should ONLY be done when absolutely necessary. Prefer using `src/pages/` and `src/_layouts/` for custom pages instead of overriding UJ default files.
69
+
70
+ ### Section Configuration Files (JSON)
71
+
72
+ UJ provides JSON configuration files for common sections like navigation and footer. These JSON files are consumed by corresponding HTML templates during the build process.
73
+
74
+ **Configuration Files:**
75
+ - `src/defaults/src/_includes/frontend/sections/nav.json` - Navigation configuration
76
+ - `src/defaults/src/_includes/frontend/sections/footer.json` - Footer configuration
77
+
78
+ **How It Works:**
79
+ 1. JSON files contain structured data (links, labels, settings)
80
+ 2. HTML templates in `src/defaults/dist/_includes/themes/[theme-id]/frontend/sections/` read and render this data
81
+ 3. The build process converts `.json` → data loaded by `.html` templates
82
+
83
+ **Customizing Navigation/Footer:**
84
+
85
+ Consuming projects should create their own JSON files in `src/_includes/frontend/sections/`:
86
+ - `src/_includes/frontend/sections/nav.json`
87
+ - `src/_includes/frontend/sections/footer.json`
88
+
89
+ **Example: Footer Configuration**
90
+
91
+ ```json
92
+ {
93
+ logo: {
94
+ href: '/',
95
+ class: 'filter-adaptive',
96
+ text: '{{ site.brand.name }}',
97
+ description: '{{ site.meta.description }}',
98
+ },
99
+ links: [
100
+ {
101
+ label: 'Company',
102
+ href: null,
103
+ links: [
104
+ {
105
+ label: 'About Us',
106
+ href: '/about',
107
+ },
108
+ {
109
+ label: 'Pricing',
110
+ href: '/pricing',
111
+ },
112
+ ],
113
+ },
114
+ ],
115
+ socials: {
116
+ enabled: true,
117
+ },
118
+ copyright: {
119
+ enabled: true,
120
+ text: null,
121
+ },
122
+ }
123
+ ```
124
+
125
+ **Note:** These are JSON5 files (support comments, trailing commas, unquoted keys). The corresponding HTML templates automatically process these files during the build.
126
+
127
+ ### Customizing Default Pages via Frontmatter
128
+
129
+ **BEST PRACTICE:** UJ default pages are designed to be customized through frontmatter WITHOUT writing any HTML. Consuming projects can create a simple page that includes ONLY frontmatter to configure the default page's behavior.
130
+
131
+ **How It Works:**
132
+ 1. UJ default pages use `page.resolved` to access merged frontmatter (site → layout → page)
133
+ 2. **IMPORTANT:** Before customizing, READ the UJ default page in `src/defaults/dist/_layouts/` to understand available frontmatter options and how they're used
134
+ 3. Consuming projects create a page in `src/pages/` with custom frontmatter
135
+ 4. The page uses a UJ layout (e.g., `blueprint/pricing`)
136
+ 5. Frontmatter overrides default values without any HTML
137
+
138
+ **Example: Customizing the Pricing Page**
139
+
140
+ **Step 1:** Read the UJ default pricing page to see available frontmatter options:
141
+ - File: `src/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html`
142
+ - Look for frontmatter at the top and how `page.resolved.pricing` is used in the HTML
143
+
144
+ **Step 2:** In consuming project, create `src/pages/pricing.html`:
145
+
146
+ ```yaml
147
+ ---
148
+ ### ALL PAGES ###
149
+ layout: blueprint/pricing
150
+ permalink: /pricing
151
+
152
+ ### PAGE CONFIG ###
153
+ pricing:
154
+ price_per_unit:
155
+ enabled: true
156
+ feature_id: "credits"
157
+ label: "credit"
158
+ plans:
159
+ - id: "basic"
160
+ name: "Basic"
161
+ tagline: "best for getting started"
162
+ url: "/download"
163
+ pricing:
164
+ monthly: 0
165
+ annually: 0
166
+ features:
167
+ - id: "credits"
168
+ name: "Credits"
169
+ value: 1
170
+ icon: "sparkles"
171
+ ...
172
+ ---
173
+ ```
174
+
175
+ That's it! No HTML needed. The UJ pricing layout reads `page.resolved.pricing` and renders the plans accordingly.
176
+
177
+ **When to Use Frontmatter Customization:**
178
+ - ✅ Customizing UJ default pages (pricing, contact, download, etc.)
179
+ - ✅ Changing configuration without touching HTML
180
+ - ✅ Maintaining upgradability when UJ updates
25
181
 
26
- src/assets/css/main.scss
27
- * This file runs on EVERY page and should be edited to contain site-wide CSS styles.
182
+ **When to Create Custom Pages:**
183
+ - Building entirely new page types
184
+ - ❌ Needing custom HTML structure
185
+ - ❌ Pages with unique layouts not provided by UJ
28
186
 
187
+ ### Consuming Project Files
29
188
 
30
- src/assets/js/ultimate-jekyll-manager.js = Main JavaScript file used by Ultimate Jekyll to manage the site
31
- src/assets/js/pages = Page-specific JavaScript files that are used by Ultimate Jekyll
32
- * If you are making a page, put the JavaScript in this directory like so: `src/assets/js/pages/[page-name]/index.js`
33
- * The page-specific JS and CSS files are automatically included in the page based on the page's canonical path.
34
- * You need to use our standardized structure:
35
- * Notice how how the helpers are outside the main export function.
36
- ```js
189
+ **CSS:**
190
+ - `src/assets/css/main.scss` - Site-wide custom styles (runs on every page, edits by consuming project)
191
+ - `src/assets/css/pages/` - Page-specific custom styles
192
+ - Format: `src/assets/css/pages/[page-name]/index.scss`
193
+
194
+ **JavaScript:**
195
+ - `src/assets/js/main.js` - Site-wide custom JavaScript (runs on every page, edits by consuming project)
196
+ - `src/assets/js/pages/` - Page-specific custom JavaScript
197
+ - Format: `src/assets/js/pages/[page-name]/index.js`
198
+
199
+ **Pages & Layouts:**
200
+ - `src/pages/` - Individual page HTML/Markdown files
201
+ - `src/_layouts/` - Custom layouts for the consuming project
202
+
203
+ **Asset Loading:** Page-specific CSS/JS files are automatically included based on the page's canonical path. Override with `asset_path` frontmatter.
204
+
205
+ ### Page Module Structure
206
+
207
+ All page modules must follow this standardized pattern:
208
+
209
+ ```javascript
37
210
  /**
38
- * XXX Page JavaScript
211
+ * [Page Name] Page JavaScript
39
212
  */
40
213
 
41
214
  // Libraries
@@ -50,7 +223,7 @@ export default (Manager) => {
50
223
  // Initialize when DOM is ready
51
224
  await webManager.dom().ready();
52
225
 
53
- // We just need to pause videos when switching tabs for better UX
226
+ // Page initialization logic
54
227
  helper1();
55
228
 
56
229
  // Resolve after initialization
@@ -60,155 +233,460 @@ export default (Manager) => {
60
233
 
61
234
  // Helper functions
62
235
  function helper1() {
63
- // ...
236
+ // Helper implementation
64
237
  }
65
238
  ```
66
239
 
67
- /src/assets/js/main.js
68
- * This file runs on EVERY page and should be edited to contain site-wide JavaScript functionality.
240
+ **Key Points:**
241
+ - Helpers are defined outside the main export function
242
+ - Use `webManager` shortcuts for common operations
243
+ - Always wait for DOM ready before manipulating elements
244
+
245
+ ## Layouts and Pages
246
+
247
+ ### Page Types
248
+ - **One-off pages** (e.g., `/categories`, `/sitemap`) - Create as pages without custom layouts; use existing layouts
249
+ - **Repeating page types** (e.g., blog posts, category pages) - Create a dedicated layout (e.g., `_layouts/category.html`)
250
+
251
+ ### Layout Requirements
252
+ All layouts and pages must eventually require a theme entry point:
253
+ ```yaml
254
+ layout: themes/[ site.theme.id ]/frontend/core/base
255
+ ```
256
+
257
+ **Note:** The `[ site.theme.id ]` syntax is correct and allows dynamic theme selection.
258
+
259
+ ### Asset Path Configuration
260
+
261
+ For pages sharing the same assets, use the `asset_path` frontmatter variable:
262
+
263
+ ```yaml
264
+ ---
265
+ # Instead of deriving path from page.canonical.path
266
+ asset_path: categories/category
267
+ ---
268
+ ```
269
+
270
+ **Example:**
271
+ - One-off page: `pages/categories.html` → `src/assets/css/pages/categories/index.scss`
272
+ - Repeating layout: `_layouts/category.html` → `src/assets/css/pages/categories/category.scss` (set `asset_path: categories/category` in layout frontmatter)
273
+
274
+ ## UJ Powertools (Jekyll Plugin)
275
+
276
+ Ultimate Jekyll uses the `jekyll-uj-powertools` gem for custom Liquid functionality.
277
+
278
+ **Documentation:** `/Users/ian/Developer/Repositories/ITW-Creative-works/jekyll-uj-powertools/README.md`
279
+
280
+ ### Available Features
281
+ - **Filters:** `uj_strip_ads`, `uj_json_escape`, `uj_title_case`, `uj_content_format`
282
+ - **Tags:** `iftruthy`, `iffalsy`, `uj_icon`, `uj_logo`, `uj_image`, `uj_member`, `uj_post`, `uj_readtime`, `uj_social`, `uj_translation_url`, `uj_fake_comments`, `uj_language`
283
+ - **Global Variables:** `site.uj.cache_breaker`
284
+ - **Page Variables:** `page.random_id`, `page.extension`, `page.layout_data`, `page.resolved`
285
+
286
+ **Always check the README before assuming functionality.**
287
+
288
+ ### Key Liquid Functions
289
+
290
+ #### `uj_content_format`
291
+ Formats content by first liquifying it, then markdownifying it (if markdown file).
292
+
293
+ #### `iftruthy` / `iffalsy`
294
+ Custom tags that check JavaScript truthiness (not null, undefined, or empty string).
295
+
296
+ ```liquid
297
+ {% iftruthy variable %}
298
+ <!-- Content -->
299
+ {% endiftruthy %}
300
+ ```
301
+
302
+ **Limitations:**
303
+ - Does NOT support logical operators
304
+ - Does NOT support `else` statements
305
+ - CAN contain nested sub-statements
306
+
307
+ #### `page.resolved`
308
+ A deeply merged object containing all site, layout, and page variables. Precedence: page > layout > site. Enables a system of defaults with progressive overrides.
309
+
310
+ #### `uj_icon`
311
+ Inserts Font Awesome icons:
312
+
313
+ ```liquid
314
+ {% uj_icon icon-name, "fa-md" %}
315
+ {% uj_icon "rocket", "fa-3xl" %}
316
+ ```
317
+
318
+ **Parameters:**
319
+ 1. Icon name (string or variable, without "fa-" prefix)
320
+ 2. CSS classes (optional, defaults to "fa-3xl")
321
+
322
+ #### `asset_path` Override
323
+ Override default page-specific CSS/JS path derivation:
324
+
325
+ ```yaml
326
+ ---
327
+ asset_path: blog/post
328
+ ---
329
+ ```
330
+
331
+ Uses `/assets/css/pages/{{ asset_path }}.bundle.css` instead of deriving from `page.canonical.path`. Useful when multiple pages share assets (e.g., all blog posts).
332
+
333
+ ## Icon System
334
+
335
+ Ultimate Jekyll uses Font Awesome icons but does NOT include the Font Awesome JavaScript or CSS library. All icons must be rendered server-side using Jekyll's `{% uj_icon %}` tag.
336
+
337
+ ### When to Use `{% uj_icon %}` vs Prerendered Icons
338
+
339
+ **IMPORTANT:** Use the correct method based on WHERE the icon will be used:
340
+
341
+ #### Use `{% uj_icon %}` in HTML/Liquid Templates
342
+
343
+ When icons are part of the static HTML template, use `{% uj_icon %}` directly:
344
+
345
+ ```liquid
346
+ <!-- Alerts -->
347
+ <div class="alert alert-success">
348
+ {% uj_icon "circle-check", "fa-sm" %} Success message
349
+ </div>
350
+
351
+ <!-- Buttons -->
352
+ <button class="btn btn-primary">
353
+ {% uj_icon "paper-plane", "fa-md me-2" %}
354
+ Send
355
+ </button>
356
+
357
+ <!-- Labels -->
358
+ <label>
359
+ {% uj_icon "envelope", "fa-sm me-1 text-info" %}
360
+ Email
361
+ </label>
362
+ ```
363
+
364
+ **Use this when:**
365
+ - The icon is in a Jekyll template (.html file)
366
+ - The icon is static and known at build time
367
+ - The icon is part of the page structure
368
+
369
+ #### Use Prerendered Icons in JavaScript
370
+
371
+ When icons need to be dynamically inserted via JavaScript, pre-render them in frontmatter and access them via the library:
372
+
373
+ **1. Add icons to page frontmatter:**
374
+ ```yaml
375
+ ---
376
+ prerender_icons:
377
+ - name: "mobile"
378
+ class: "fa-sm me-1"
379
+ - name: "envelope"
380
+ class: "fa-sm me-1"
381
+ - name: "bell"
382
+ class: "fa-sm me-1"
383
+ ---
384
+ ```
385
+
386
+ **2. Import the library in JavaScript:**
387
+ ```javascript
388
+ import { getPrerenderedIcon } from '__main_assets__/js/libs/prerendered-icons.js';
389
+ ```
390
+
391
+ **3. Use in your code:**
392
+ ```javascript
393
+ const iconHTML = getPrerenderedIcon('mobile');
394
+ $badge.innerHTML = `${iconHTML}Push Notification`;
395
+ ```
396
+
397
+ **Use this when:**
398
+ - Icons are dynamically inserted via JavaScript
399
+ - Icons are part of dynamically generated content
400
+ - Icons are added to elements created with `document.createElement()`
401
+
402
+ ### What NOT to Do
403
+
404
+ **NEVER use manual icon HTML in JavaScript:**
405
+ ```javascript
406
+ // ❌ WRONG - Bootstrap Icons (we don't use Bootstrap Icons)
407
+ $el.innerHTML = '<i class="bi bi-check-circle"></i> Text';
408
+
409
+ // ❌ WRONG - Manual Font Awesome (we don't have FA JS/CSS)
410
+ $el.innerHTML = '<i class="fa-solid fa-check"></i> Text';
411
+
412
+ // ✅ CORRECT - Use prerendered icons
413
+ const iconHTML = getPrerenderedIcon('circle-check');
414
+ $el.innerHTML = `${iconHTML} Text`;
415
+ ```
69
416
 
70
- src/assets/themes = Theme scss and js files that are can be picked and used by the consuming project.
417
+ ### Benefits
418
+ - Icons are rendered server-side with proper Font Awesome classes
419
+ - No client-side icon generation overhead
420
+ - Consistent icon styling across the application
421
+ - No Font Awesome JavaScript/CSS library needed
71
422
 
72
- ## UJ Powertools
73
- Ultimate Jekyll uses the `jekyll-uj-powertools` gem which provides many custom Liquid filters, tags, and variables. You should review the full documentation to understand all available tools: `/Users/ian/Developer/Repositories/ITW-Creative-works/jekyll-uj-powertools/README.md`
423
+ ## CSS Guidelines
74
424
 
75
- Key features include:
76
- * **Filters**: `uj_strip_ads`, `uj_json_escape`, `uj_title_case`, `uj_content_format`
77
- * **Tags**: `iftruthy`, `iffalsy`, `uj_icon`, `uj_logo`, `uj_image`, `uj_member`, `uj_post`, `uj_readtime`, `uj_social`, `uj_translation_url`, `uj_fake_comments`, `uj_language`
78
- * **Global Variables**: `site.uj.cache_breaker`
79
- * **Page Variables**: `page.random_id`, `page.extension`, `page.layout_data`, `page.resolved`
425
+ ### Theme-Adaptive Classes
80
426
 
81
- ALWAYS check the README before assuming a filter or tag exists or how it works.
427
+ **DO NOT USE:** `bg-light`, `bg-dark`, `text-light`, `text-dark`
82
428
 
83
- ## SOME SPECIAL LIQUID FUNCTIONS:
84
- * uj_content_format = A custom liquid filter that formats the content like so: first, it LIQUIFIES the content, then, if it's a markdown file, it runs MARKDOWNIFY.
85
- * iftruthy = a custom liquid tag that checks if a variable is truthy in JavaScript terms, meaning it checks if the variable is not null, undefined, or an empty string. Use it like this: `{% iftruthy variable %}`. But it DOES NOT SUPPORT any logical operators and does not support `else` statements. But you CAN put sub-statements inside it.
86
- * iffalsy = same but opposite of iftruthy.
87
- * page.resolved = a custom page object property of all site, layout, and page variables deeply merged together, with page variables taking precedence over layout, and layout variables taking precedence over site variables. This allows a system of site defaults, layout overrides, and page-specific overrides.
429
+ Ultimate Jekyll supports both light and dark modes. Use adaptive classes instead:
88
430
 
89
- ### Specifics:
90
- * {% uj_icon icon-name, "fa-md" %} = Custom tag for inserting fontawesome icons. "icon-name" can be a string or a variable. If its a string, put it in quotes like "rocket" (dont include "fa-")
91
- * Set `asset_path: path/to/asset` for layouts or pages to override the default page-specific CSS/JS path. When set, it uses `/assets/css/pages/{{ asset_path }}.bundle.css` instead of deriving the path from `page.canonical.path`. Useful when multiple pages share the same assets like all blog posts using `asset_path: blog/post`.
431
+ **Backgrounds:**
432
+ - `bg-body` - Primary background
433
+ - `bg-body-secondary` - Secondary background
434
+ - `bg-body-tertiary` - Tertiary background
92
435
 
93
- ## Layouts and Pages in Consuming Projects
94
- When creating pages in the consuming project, follow these guidelines:
95
- * **One-off pages** (like `/categories`, `/sitemap`, etc.) should be created directly as pages (e.g., `pages/categories.html`) WITHOUT their own custom layout. These pages should use an existing layout.
96
- * **Repeating page types** (like individual category pages, individual blog posts, etc.) should have a dedicated layout that all instances use (e.g., `_layouts/category.html` used by all category pages).
97
- * **All layouts and pages** must eventually require one of the theme entry points, such as `layout: themes/[ site.theme.id ]/frontend/core/base`. This ensures consistent theming across the site.
98
- * YES, the "[[ site.theme.id ]]" syntax is correct here; it allows dynamic selection of the theme based on site configuration.
99
- * This approach keeps the codebase maintainable by reusing layouts for similar pages while avoiding unnecessary layout files for unique pages.
100
- * So you should put assets like CSS and JS for a one-off page like `categories.html` in `src/assets/css/pages/categories/index.scss` and `src/assets/js/pages/categories/index.js` respectively, and for repeating page types like an individual category that uses a LAYOUT, put them in `src/assets/css/pages/categories/category.scss` and `src/assets/js/pages/categories/category.js` (and you will of course set the `asset_path: categories/category` frontmatter variable on the layout so that the correct assets are loaded).
436
+ **Text:**
437
+ - `text-body` - Body text color
101
438
 
102
- ## CSS
103
- DO NOT USE `bg-light`, `bg-dark`, `text-light`, or `text-dark`. We support BOTH light and dark mode, so instead use `bg-body`, `bg-body-secondary`, `bg-body-tertiary`, `text-body` and for buttons you can use `btn-adaptive` or `btn-outline-adaptive`.
104
- These classes adapt to light and dark mode automatically.
439
+ **Buttons:**
440
+ - `btn-adaptive` - Adaptive button
441
+ - `btn-outline-adaptive` - Adaptive outline button
105
442
 
106
- ## Page Loading State & Button Protection
107
- Ultimate Jekyll implements a sophisticated system to prevent premature button clicks during page initialization. This prevents race conditions and ensures JavaScript is fully loaded before users can trigger actions.
443
+ These classes automatically adapt to the current theme mode.
108
444
 
109
- ### How It Works:
110
- 1. **Initial State**: The HTML element starts with `data-page-loading="true"` and `aria-busy="true"` attributes (set in `src/defaults/dist/_layouts/core/root.html`)
111
- 2. **Protection During Load**: While `data-page-loading` is present, certain elements are automatically disabled via CSS and JavaScript
112
- 3. **Ready State**: When JavaScript initialization completes, these attributes are removed by `src/assets/js/core/complete.js`
445
+ ## Page Loading Protection System
113
446
 
114
- ### What Gets Protected:
115
- When `data-page-loading` is active, the following elements are automatically protected from clicks:
447
+ Ultimate Jekyll prevents race conditions by disabling buttons during JavaScript initialization.
116
448
 
117
- - **All form buttons**: `<button>`, `<input type="submit">`, `<input type="button">`, `<input type="reset">`
118
- - **Elements with `.btn` class**: Standard Bootstrap buttons
119
- - **Elements with `.btn-action` class**: Custom action triggers (see below)
120
- - **Always disabled**: Any element with `disabled` attribute, `.disabled` class, or `:disabled` state
449
+ ### How It Works
450
+ 1. HTML element starts with `data-page-loading="true"` and `aria-busy="true"` (`src/defaults/dist/_layouts/core/root.html`)
451
+ 2. Protected elements are automatically disabled during this state
452
+ 3. Attributes are removed when JavaScript completes (`src/assets/js/core/complete.js`)
121
453
 
122
- ### The `.btn-action` Class:
123
- Use the `.btn-action` class to selectively protect non-standard elements that trigger important actions:
454
+ ### Protected Elements
455
+ - All form buttons (`<button>`, `<input type="submit">`, `<input type="button">`, `<input type="reset">`)
456
+ - Elements with `.btn` class (Bootstrap buttons)
457
+ - Elements with `.btn-action` class (custom action triggers)
458
+
459
+ ### The `.btn-action` Class
460
+
461
+ Selectively protect non-standard elements that trigger important actions:
124
462
 
125
463
  ```html
126
- <!-- These will be protected during page load -->
464
+ <!-- Protected during page load -->
127
465
  <a href="/api/delete" class="custom-link btn-action">Delete Item</a>
128
466
  <div class="card-action btn-action" onclick="processData()">Process</div>
129
- <span class="text-link btn-action" data-action="save">Save Changes</span>
130
467
 
131
- <!-- These will NOT be protected (regular navigation/UI) -->
468
+ <!-- NOT protected (regular navigation/UI) -->
132
469
  <a href="/about" class="btn btn-primary">About Us</a>
133
470
  <button data-bs-toggle="modal">Show Info</button>
134
- <button data-bs-toggle="collapse">Toggle Details</button>
135
471
  ```
136
472
 
137
- ### When to Use `.btn-action`:
138
- - **Use it for**: API calls, form submissions, data modifications, payment processing, destructive actions
139
- - **Don't use it for**: Navigation links, UI toggles, modals, accordions, tabs, harmless interactions
473
+ **Use `.btn-action` for:**
474
+ - API calls
475
+ - Form submissions
476
+ - Data modifications
477
+ - Payment processing
478
+ - Destructive actions
479
+
480
+ **Don't use for:**
481
+ - Navigation links
482
+ - UI toggles (modals, accordions, tabs)
483
+ - Harmless interactions
140
484
 
141
- ### Implementation Files:
142
- - **CSS Styles**: `src/assets/css/core/utilities.scss` - Applies `cursor: not-allowed` and disabled styling
143
- - **Click Prevention**: `src/defaults/dist/_includes/core/body.html` - Inline script that prevents clicks
144
- - **State Removal**: `src/assets/js/core/complete.js` - Removes `data-page-loading` when ready
485
+ ### Implementation
486
+ - **CSS:** `src/assets/css/core/utilities.scss` - Disabled styling
487
+ - **Click Prevention:** `src/defaults/dist/_includes/core/body.html` - Inline script
488
+ - **State Removal:** `src/assets/js/core/complete.js` - Removes loading state
145
489
 
146
- This system ensures a smooth, error-free user experience by preventing premature interactions while maintaining full flexibility for developers.
490
+ ## Lazy Loading System
147
491
 
148
- ## Lazy Loading
149
- Ultimate Jekyll uses a custom lazy loading system powered by web-manager. Elements can be lazy-loaded using the `data-lazy` attribute with the following format:
492
+ Ultimate Jekyll uses a custom lazy loading system powered by web-manager.
150
493
 
494
+ ### Syntax
151
495
  ```html
152
496
  data-lazy="@type value"
153
497
  ```
154
498
 
155
- ### Supported Types:
156
- * `@src` - Lazy load the `src` attribute (for images, iframes, videos, source elements)
157
- ```html
158
- <img data-lazy="@src /assets/images/hero.jpg" alt="Hero">
159
- <iframe data-lazy="@src https://example.com/embed"></iframe>
160
- ```
499
+ ### Supported Types
161
500
 
162
- * `@srcset` - Lazy load the `srcset` attribute (for responsive images)
163
- ```html
164
- <img data-lazy="@srcset /img/small.jpg 480w, /img/large.jpg 1024w">
165
- ```
501
+ #### `@src` - Lazy load src attribute
502
+ ```html
503
+ <img data-lazy="@src /assets/images/hero.jpg" alt="Hero">
504
+ <iframe data-lazy="@src https://example.com/embed"></iframe>
505
+ ```
166
506
 
167
- * `@bg` - Lazy load background images via `background-image` CSS
168
- ```html
169
- <div data-lazy="@bg /assets/images/background.jpg"></div>
170
- ```
507
+ #### `@srcset` - Lazy load srcset attribute
508
+ ```html
509
+ <img data-lazy="@srcset /img/small.jpg 480w, /img/large.jpg 1024w">
510
+ ```
171
511
 
172
- * `@class` - Lazy add CSS classes when element comes into view (useful for animations)
173
- ```html
174
- <div data-lazy="@class animation-fade-in">Content</div>
175
- ```
512
+ #### `@bg` - Lazy load background images
513
+ ```html
514
+ <div data-lazy="@bg /assets/images/background.jpg"></div>
515
+ ```
176
516
 
177
- * `@html` - Lazy inject HTML content
178
- ```html
179
- <div data-lazy="@html <p>Lazy loaded content</p>"></div>
180
- ```
517
+ #### `@class` - Lazy add CSS classes
518
+ ```html
519
+ <div data-lazy="@class animation-fade-in">Content</div>
520
+ ```
521
+
522
+ #### `@html` - Lazy inject HTML content
523
+ ```html
524
+ <div data-lazy="@html <p>Lazy loaded content</p>"></div>
525
+ ```
181
526
 
182
- * `@script` - Lazy load external scripts with JSON configuration
183
- ```html
184
- <div data-lazy='@script {"src": "https://example.com/widget.js", "attributes": {"async": true}}'></div>
185
- ```
527
+ #### `@script` - Lazy load external scripts
528
+ ```html
529
+ <div data-lazy='@script {"src": "https://example.com/widget.js", "attributes": {"async": true}}'></div>
530
+ ```
186
531
 
187
- ### Features:
188
- * Automatically adds cache busters to URLs using `buildTime`
189
- * Uses IntersectionObserver for performance (starts loading 50px before element enters viewport)
190
- * Adds CSS classes during loading states: `lazy-loading`, `lazy-loaded`, `lazy-error`
191
- * Handles video/audio sources intelligently by observing the parent element
192
- * Automatically re-scans DOM for dynamically added elements
532
+ ### Features
533
+ - Automatic cache busting via `buildTime`
534
+ - IntersectionObserver for performance (50px threshold)
535
+ - Loading state CSS classes: `lazy-loading`, `lazy-loaded`, `lazy-error`
536
+ - Intelligent handling of video/audio sources
537
+ - Automatic DOM re-scanning for dynamic elements
193
538
 
194
- See implementation: [src/assets/js/core/lazy-loading.js](src/assets/js/core/lazy-loading.js)
539
+ **Implementation:** `src/assets/js/core/lazy-loading.js`
195
540
 
196
- ## Libraries
197
- I have some library preferences that I want you to follow:
541
+ ## JavaScript Libraries
198
542
 
199
543
  ### WebManager
200
- We use a custom library called `web-manager` to manage various aspects of the site. Please make yourself familiar with it by reviewing it: `/Users/ian/Developer/Repositories/ITW-Creative-Works/web-manager/src`
201
- It offers various ultities like webManager.auth(), webManager.utilities(), webManager.sentry(), webManager.dom(). You should be using these utilities instead of writing your own code all the time.
202
- DO NOT JUST ASSUME THAT webManager has a function, though, you should CHECK THE SOURCE CODE to see what functions are available and how to use them or check the README: `/Users/ian/Developer/Repositories/ITW-Creative-Works/web-manager/README.md`
203
-
204
- ## FormManager
205
- We use a custom library called `form-manager` to manage forms on the site. Please make yourself familiar with it by reviewing it: `/Users/ian/Developer/Repositories/ITW-Creative-Works/ultimate-jekyll-manager/src/assets/js/libs/form-manager.js`
206
- * A good example of how to use it is the contact page
207
- * HTML: `/Users/ian/Developer/Repositories/ITW-Creative-Works/ultimate-jekyll-manager/src/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html`
208
- * JS: `/Users/ian/Developer/Repositories/ITW-Creative-Works/ultimate-jekyll-manager/src/assets/js/pages/contact/index.js`
209
-
210
- ## Audits
211
- I may ask you to help me fix problems identified by the AUDIT TASK (@src/gulp/tasks/audit.js)
212
- * In that case, please LOOK AT THE AUDIT FILES (Which I will provide the location to) and help me fix the issues ONE BY ONE.
213
- * Make a TODO list for each category in the audit, then read the ENTIRE AUDIT file and make a plan for what items in that category need to be fixed.
214
- * Remember, these are BIG AUDIT FILES, so you will have to tackle them in parts. DO NOT TRY TO FIX EVERYTHING AT ONCE.
544
+
545
+ Custom library for site management functionality.
546
+
547
+ **Documentation:** `/Users/ian/Developer/Repositories/ITW-Creative-Works/web-manager/README.md`
548
+
549
+ **Available Utilities:**
550
+ - `webManager.auth()` - Authentication management
551
+ - `webManager.utilities()` - Utility functions
552
+ - `webManager.sentry()` - Error tracking
553
+ - `webManager.dom()` - DOM manipulation
554
+
555
+ **Important:** Always check the source code or README before assuming a function exists. Do not guess at API methods.
556
+
557
+ ### Ultimate Jekyll Libraries
558
+
559
+ Ultimate Jekyll provides helper libraries in `src/assets/js/libs/` that can be imported as needed.
560
+
561
+ #### Prerendered Icons Library
562
+
563
+ Provides access to icons defined in page frontmatter and rendered server-side.
564
+
565
+ **Import:**
566
+ ```javascript
567
+ import { getPrerenderedIcon } from '__main_assets__/js/libs/prerendered-icons.js';
568
+ ```
569
+
570
+ **Usage:**
571
+ ```javascript
572
+ const iconHTML = getPrerenderedIcon('apple');
573
+ ```
574
+
575
+ **Reference:** `src/assets/js/libs/prerendered-icons.js`
576
+
577
+ #### Authorized Fetch Library
578
+
579
+ Simplifies authenticated API requests by automatically adding Firebase authentication tokens via Authorization Bearer header.
580
+
581
+ **Import:**
582
+ ```javascript
583
+ import authorizedFetch from '__main_assets__/js/libs/authorized-fetch.js';
584
+ ```
585
+
586
+ **Usage:**
587
+ ```javascript
588
+ const response = await authorizedFetch(url, options);
589
+ ```
590
+
591
+ **Key Benefits:**
592
+ - No need to manually call `webManager.auth().getIdToken()`
593
+ - Automatic token injection as Authorization Bearer header
594
+ - Centralized authentication handling
595
+
596
+ **Reference:** `src/assets/js/libs/authorized-fetch.js`
597
+
598
+ #### FormManager Library
599
+
600
+ Form handling library with built-in state management and validation.
601
+
602
+ **Import:**
603
+ ```javascript
604
+ import { FormManager } from '__main_assets__/js/libs/form-manager.js';
605
+ ```
606
+
607
+ **Usage:**
608
+ ```javascript
609
+ const formManager = new FormManager('#my-form', options);
610
+ ```
611
+
612
+ **Reference:** `src/assets/js/libs/form-manager.js`
613
+ **Example:** `src/assets/js/pages/contact/index.js`
614
+
615
+ ## Analytics & Tracking
616
+
617
+ Ultimate Jekyll uses three tracking platforms: Google Analytics (gtag), Facebook Pixel (fbq), and TikTok Pixel (ttq).
618
+
619
+ ### Tracking Guidelines
620
+
621
+ **IMPORTANT Rules:**
622
+ - Track important user events with `gtag()`, `fbq()`, and `ttq()` functions
623
+ - NEVER add conditional checks for tracking functions (e.g., `if (typeof gtag !== 'undefined')`)
624
+ - Always assume tracking functions exist - they're globally available or stubbed
625
+ - Reference standard events documentation before implementing custom tracking
626
+
627
+ **Standard Events Documentation:**
628
+ - **Google Analytics GA4:** https://developers.google.com/analytics/devguides/collection/ga4/reference/events
629
+ - **Facebook Pixel:** https://www.facebook.com/business/help/402791146561655?id=1205376682832142
630
+ - **TikTok Pixel:** https://ads.tiktok.com/help/article/standard-events-parameters?redirected=2
631
+
632
+ ### Platform-Specific Requirements
633
+
634
+ #### TikTok Pixel Requirements
635
+ TikTok has strict validation requirements:
636
+
637
+ **Required Parameters:**
638
+ - `content_id` - MUST be included in all events
639
+
640
+ **Valid Content Types:**
641
+ - `"product"`
642
+ - `"product_group"`
643
+ - `"destination"`
644
+ - `"hotel"`
645
+ - `"flight"`
646
+ - `"vehicle"`
647
+
648
+ Any other content type will generate a validation error.
649
+
650
+ **Example:**
651
+ ```javascript
652
+ // ✅ CORRECT
653
+ ttq.track('ViewContent', {
654
+ content_id: 'product-123',
655
+ content_type: 'product'
656
+ });
657
+
658
+ // ❌ WRONG - Missing content_id
659
+ ttq.track('ViewContent', {
660
+ content_type: 'product'
661
+ });
662
+
663
+ // ❌ WRONG - Invalid content_type
664
+ ttq.track('ViewContent', {
665
+ content_id: 'product-123',
666
+ content_type: 'custom' // Not in approved list
667
+ });
668
+ ```
669
+
670
+ ### Tracking Implementation
671
+
672
+ **IMPORTANT:** Always track events to ALL THREE platforms in this order:
673
+ 1. Google Analytics (gtag)
674
+ 2. Facebook Pixel (fbq)
675
+ 3. TikTok Pixel (ttq)
676
+
677
+ Track events directly without existence checks. All three tracking calls should be made together for every event.
678
+
679
+ **Development Mode:**
680
+ In development mode, all tracking calls are intercepted and logged to the console for debugging. See `src/assets/js/libs/dev.js` for implementation.
681
+
682
+ ## Audit Workflow
683
+
684
+ When fixing issues identified by the audit task (`src/gulp/tasks/audit.js`):
685
+
686
+ 1. Review the audit file location provided
687
+ 2. Create a TODO list for each audit category
688
+ 3. Read the ENTIRE audit file and plan fixes for each category
689
+ 4. Tackle issues incrementally - DO NOT attempt to fix everything at once
690
+ 5. Work through one category at a time
691
+
692
+ **Remember:** Audit files are large. Systematic, incremental fixes prevent errors and ensure thoroughness.