ultimate-jekyll-manager 1.2.0 → 1.2.2
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/CHANGELOG.md +15 -0
- package/CLAUDE.md +50 -23
- package/dist/defaults/CHANGELOG.md +15 -0
- package/dist/defaults/CLAUDE.md +17 -5
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/extension/index.html +0 -26
- package/dist/defaults/docs/README.md +17 -0
- package/dist/defaults/test/README.md +31 -0
- package/docs/ads.md +78 -0
- package/docs/analytics.md +90 -0
- package/docs/appearance.md +65 -0
- package/docs/assets.md +314 -0
- package/docs/audit.md +11 -0
- package/docs/css.md +73 -0
- package/docs/icons.md +125 -0
- package/docs/images.md +42 -0
- package/docs/javascript-libraries.md +457 -0
- package/docs/jekyll-plugin.md +69 -0
- package/docs/layouts-and-pages.md +31 -0
- package/docs/lazy-loading.md +58 -0
- package/docs/local-development.md +59 -0
- package/docs/page-loading.md +85 -0
- package/docs/project-structure.md +23 -0
- package/docs/seo.md +206 -0
- package/docs/xss-prevention.md +126 -0
- package/package.json +1 -1
- package/docs/_legacy-claude-md.md +0 -1832
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
14
14
|
- `Fixed` for any bug fixes.
|
|
15
15
|
- `Security` in case of vulnerabilities.
|
|
16
16
|
|
|
17
|
+
---
|
|
18
|
+
## [1.2.2] - 2026-05-18
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **`docs/<topic>.md` deep references** — 17 new files referenced by the v1.2.0 CLAUDE.md reorg that hadn't been committed yet: `ads.md`, `analytics.md`, `appearance.md`, `assets.md`, `audit.md`, `css.md`, `icons.md`, `images.md`, `javascript-libraries.md`, `jekyll-plugin.md`, `layouts-and-pages.md`, `lazy-loading.md`, `local-development.md`, `page-loading.md`, `project-structure.md`, `seo.md`, `xss-prevention.md`. Restores parity with the cross-links already shipped in [CLAUDE.md](CLAUDE.md).
|
|
23
|
+
- **`src/defaults/docs/README.md`, `src/defaults/test/README.md`, `src/defaults/CHANGELOG.md`** — consumer-project scaffolding files distributed via the `defaults` gulp task.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
## [1.2.1] - 2026-05-18
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Default `/extension` page** — removed the redundant downloads-section heading block ("Install" badge + "Available on every browser" headline + "Choose your browser below to get started" subheadline) that duplicated the role of the page hero. Browser-selector pills now sit directly under the hero. Affects `src/defaults/dist/_layouts/themes/classy/frontend/pages/extension/index.html` and drops the now-unused `downloads.superheadline` / `downloads.headline` / `downloads.headline_accent` / `downloads.subheadline` frontmatter keys.
|
|
31
|
+
|
|
17
32
|
---
|
|
18
33
|
## [1.2.0] - 2026-05-12
|
|
19
34
|
|
package/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Ultimate Jekyll Manager (UJM)
|
|
2
2
|
|
|
3
|
-
> **Note for contributors and Claude:** This file is the architectural overview — identity, top-level conventions, and a map to deep references. The **meat** (per-subsystem APIs, page customization recipes, theming, behavior tables, defaults lists) lives in `docs/<topic>.md`. When extending or adding content, write it in the matching `docs/*.md` file and cross-link from here — do NOT inline it. If a topic doesn't have a doc yet, create one. Goal: keep this file under
|
|
3
|
+
> **Note for contributors and Claude:** This file is the architectural overview — identity, top-level conventions, and a map to deep references. The **meat** (per-subsystem APIs, page customization recipes, theming, behavior tables, defaults lists) lives in `docs/<topic>.md`. When extending or adding content, write it in the matching `docs/*.md` file and cross-link from here — do NOT inline it. If a topic doesn't have a doc yet, create one. Goal: keep this file under 250 lines.
|
|
4
4
|
|
|
5
5
|
## Identity
|
|
6
6
|
|
|
@@ -20,6 +20,19 @@ The only things that ARE safe to run inside UJM itself:
|
|
|
20
20
|
- `npm run prepare` — copies `src/` → `dist/` via prepare-package
|
|
21
21
|
- `npm test` (aka `npx mgr test`) — runs UJM's own three-layer test suite
|
|
22
22
|
|
|
23
|
+
## Recommended skills
|
|
24
|
+
|
|
25
|
+
- **`UJM:patterns`** — SSOT for Ultimate Jekyll Manager architecture, gulp pipeline, frontend Manager, and theme conventions. Auto-loads on UJM-specific keywords (`_config.yml`, `theme.id`, `uj_icon`, `page.resolved`, `npx mgr setup`, etc.) and when touching files in `src/_layouts/`, `src/_includes/`, `src/pages/`, `src/assets/`, `config/ultimate-jekyll-manager.json`.
|
|
26
|
+
- **`js:patterns`** — JavaScript/Node.js conventions: file structure, JSDoc, defensive coding (`?.` usage), template literals, `package.json` conventions. Auto-loads when creating new `.js` files or touching JS module structure.
|
|
27
|
+
|
|
28
|
+
## 🚨 READ WEB-MANAGER TOO
|
|
29
|
+
|
|
30
|
+
**UJM ships `web-manager` as a runtime singleton on every page** — it powers auth, Firebase, reactive `data-wm-bind` directives, analytics, error tracking, and utilities (`escapeHTML`, etc.). Any task that touches auth flows, Firestore reads/writes, subscription resolution, push notifications, or DOM bindings means you are working with web-manager as much as with UJM.
|
|
31
|
+
|
|
32
|
+
**Required reading:**
|
|
33
|
+
- **`node_modules/web-manager/CLAUDE.md`** — top-level overview + index
|
|
34
|
+
- **`node_modules/web-manager/docs/`** — module deep references (Auth, Bindings, Firestore, Notifications, etc.)
|
|
35
|
+
|
|
23
36
|
## Quick Start
|
|
24
37
|
|
|
25
38
|
### For Consuming Projects
|
|
@@ -35,7 +48,7 @@ The only things that ARE safe to run inside UJM itself:
|
|
|
35
48
|
|
|
36
49
|
1. `npm install` — install UJM's own deps
|
|
37
50
|
2. `npm start` (≡ `npm run prepare:watch`) — copies `src/` → `dist/` on file change
|
|
38
|
-
3. Test in a consumer project: `
|
|
51
|
+
3. Test in a consumer project: from inside the consumer, run `npx mgr install local` (swaps UJM to the local repo via the `install` CLI). Reverse with `npx mgr install prod`.
|
|
39
52
|
4. `npm test` — runs UJM's own 60 test suites
|
|
40
53
|
|
|
41
54
|
## Architecture
|
|
@@ -166,30 +179,44 @@ Don't ship behavioral changes with stale docs. Validate first, then document —
|
|
|
166
179
|
|
|
167
180
|
## Documentation
|
|
168
181
|
|
|
169
|
-
Deep references live in `docs/`. Treat docs as a first-class deliverable.
|
|
182
|
+
Deep references live in `docs/`. Treat docs as a first-class deliverable. **Whenever you make a behavioral change, update both this overview AND the relevant `docs/*.md` deep reference.**
|
|
183
|
+
|
|
184
|
+
### Framework reference
|
|
170
185
|
|
|
171
186
|
- [docs/test-framework.md](docs/test-framework.md) — three-layer test harness reference (build / page / boot)
|
|
172
187
|
- [docs/test-boot-layer.md](docs/test-boot-layer.md) — boot layer deep-dive (_site/ discovery, HTTP server, fixture vs consumer)
|
|
173
188
|
- [docs/cross-context-helpers.md](docs/cross-context-helpers.md) — `isTesting`/`isDevelopment`/`isProduction`/`getVersion`
|
|
174
|
-
- [docs/
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
189
|
+
- [docs/jekyll-plugin.md](docs/jekyll-plugin.md) — UJ Powertools gem: filters, tags, page variables (`page.resolved`, `uj_icon`, `uj_hash`, `iftruthy`, etc.)
|
|
190
|
+
- [docs/audit.md](docs/audit.md) — workflow for fixing issues raised by `gulp/tasks/audit.js`
|
|
191
|
+
|
|
192
|
+
### Project & dev environment
|
|
193
|
+
|
|
194
|
+
- [docs/project-structure.md](docs/project-structure.md) — UJM repo layout and consuming-project layout
|
|
195
|
+
- [docs/local-development.md](docs/local-development.md) — browsersync URL, Firebase emulator connect, PurgeCSS safelist
|
|
196
|
+
- [docs/assets.md](docs/assets.md) — UJM vs consumer file layout, section config (nav/footer/account), frontmatter-driven page customization, webpack aliases, page module pattern
|
|
197
|
+
|
|
198
|
+
### Pages, layouts, content
|
|
199
|
+
|
|
200
|
+
- [docs/layouts-and-pages.md](docs/layouts-and-pages.md) — page types, layout chain, `asset_path` frontmatter
|
|
201
|
+
- [docs/images.md](docs/images.md) — `@post/` shortcut for blog post images, BEM admin/post image handling
|
|
202
|
+
- [docs/icons.md](docs/icons.md) — Font Awesome conventions, `{% uj_icon %}` vs prerendered icons in JS, size reference
|
|
203
|
+
- [docs/seo.md](docs/seo.md) — Alternatives collection (competitor comparison pages) + Schema/JSON-LD (`SoftwareApplication`, `FAQPage`)
|
|
204
|
+
|
|
205
|
+
### Frontend behavior
|
|
206
|
+
|
|
207
|
+
- [docs/css.md](docs/css.md) — section padding rule, theme-adaptive classes, cards in colored sections, `<html>` data attributes
|
|
208
|
+
- [docs/appearance.md](docs/appearance.md) — dark/light/system mode switching: JS API, HTML attributes
|
|
209
|
+
- [docs/page-loading.md](docs/page-loading.md) — page-loading protection, `.btn-action`, layered form-protection strategy
|
|
210
|
+
- [docs/lazy-loading.md](docs/lazy-loading.md) — `data-lazy="@type value"` syntax and supported types
|
|
211
|
+
- [docs/ads.md](docs/ads.md) — Vert units: AdSense include + Promo Server fallback, size presets
|
|
212
|
+
|
|
213
|
+
### JS libraries & security
|
|
214
|
+
|
|
215
|
+
- [docs/javascript-libraries.md](docs/javascript-libraries.md) — WebManager singleton + UJM libs at `src/assets/js/libs/` (prerendered icons, authorizedFetch, usage bindings, payment-config, FormManager)
|
|
216
|
+
- [docs/xss-prevention.md](docs/xss-prevention.md) — zero-trust DOM injection rules, `escapeHTML`, postMessage origin checks, redirect validation
|
|
217
|
+
|
|
218
|
+
### Analytics
|
|
219
|
+
|
|
220
|
+
- [docs/analytics.md](docs/analytics.md) — ITM tracking, gtag/fbq/ttq guidelines, TikTok-specific rules
|
|
194
221
|
|
|
195
222
|
`TODO.md` + `TODO-*.md` files at the repo root track pass-by-pass progress and decisions.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
+
|
|
7
|
+
## Changelog Categories
|
|
8
|
+
|
|
9
|
+
- `BREAKING` for breaking changes.
|
|
10
|
+
- `Added` for new features.
|
|
11
|
+
- `Changed` for changes in existing functionality.
|
|
12
|
+
- `Deprecated` for soon-to-be removed features.
|
|
13
|
+
- `Removed` for now removed features.
|
|
14
|
+
- `Fixed` for any bug fixes.
|
|
15
|
+
- `Security` in case of vulnerabilities.
|
package/dist/defaults/CLAUDE.md
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
# ========== Default Values ==========
|
|
2
2
|
# Ultimate Jekyll Manager (UJM) — consumer project
|
|
3
3
|
|
|
4
|
-
> **Auto-managed file.** Everything between `# ========== Default Values ==========` and `# ========== Custom Values ==========` is owned by `ultimate-jekyll-manager` and rewritten on every `npx mgr setup`. Put your own project-specific notes BELOW the `Custom Values` marker — that section is preserved verbatim across setups.
|
|
5
|
-
|
|
6
4
|
## Framework
|
|
7
5
|
|
|
8
6
|
This project consumes **Ultimate Jekyll Manager** (UJM) — a comprehensive framework for building modern Jekyll-powered static sites. UJM provides one-line bootstrap per context (build / frontend / service-worker), a multi-stage gulp pipeline (defaults / distribute / webpack / sass / imagemin / jekyll / audit / translation / minifyHtml / serve), default Jekyll layouts + themes, a frontend ES-module Manager with dynamic per-page module loading, a service worker with Firebase Messaging + cache management, and a built-in three-layer test framework.
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
## 🚨 READ THE FRAMEWORK DOCS FIRST
|
|
9
|
+
|
|
10
|
+
**Before doing ANY work on this codebase, Claude MUST read the framework documentation — that is where the architecture, conventions, APIs, and gotchas live. Skipping these will result in solutions that conflict with framework patterns.**
|
|
11
|
+
|
|
12
|
+
**Required reading:**
|
|
13
|
+
- **`node_modules/ultimate-jekyll-manager/CLAUDE.md`** — top-level overview + index
|
|
14
|
+
- **`node_modules/ultimate-jekyll-manager/docs/`** — subsystem deep references (read the relevant ones for the task at hand)
|
|
15
|
+
|
|
16
|
+
## 🚨 READ WEB-MANAGER TOO
|
|
17
|
+
|
|
18
|
+
**UJM ships `web-manager` as a runtime singleton on every page** — it powers auth, Firebase, reactive `data-wm-bind` directives, analytics, error tracking, and utilities (`escapeHTML`, etc.). Any task that touches auth flows, Firestore reads/writes, subscription resolution, push notifications, or DOM bindings means you are working with web-manager as much as with UJM.
|
|
19
|
+
|
|
20
|
+
**Required reading:**
|
|
21
|
+
- **`node_modules/web-manager/CLAUDE.md`** — top-level overview + index
|
|
22
|
+
- **`node_modules/web-manager/docs/`** — module deep references (Auth, Bindings, Firestore, Notifications, etc.)
|
|
13
23
|
|
|
14
24
|
## Quick start
|
|
15
25
|
|
|
@@ -67,6 +77,8 @@ At build time, `require('ultimate-jekyll-manager/build')` exposes:
|
|
|
67
77
|
- `Manager.logger(name)` — timestamped logger instance
|
|
68
78
|
- `Manager.require(path)` — escape hatch for UJM transitive deps (use sparingly)
|
|
69
79
|
|
|
80
|
+
<!-- Everything above this marker is owned by the framework and rewritten on every `npx mgr setup`. Add your project-specific notes below — they are preserved across setups. -->
|
|
81
|
+
|
|
70
82
|
# ========== Custom Values ==========
|
|
71
83
|
|
|
72
84
|
## Project-specific notes
|
|
@@ -11,12 +11,6 @@ hero:
|
|
|
11
11
|
|
|
12
12
|
# Downloads Section
|
|
13
13
|
downloads:
|
|
14
|
-
superheadline:
|
|
15
|
-
icon: "puzzle-piece"
|
|
16
|
-
text: "Install"
|
|
17
|
-
headline: "Available on every"
|
|
18
|
-
headline_accent: "browser"
|
|
19
|
-
subheadline: "Choose your browser below to get started"
|
|
20
14
|
loading:
|
|
21
15
|
headline: "Detecting Browser"
|
|
22
16
|
description: "Determining your browser..."
|
|
@@ -124,26 +118,6 @@ cta:
|
|
|
124
118
|
<!-- Downloads Section -->
|
|
125
119
|
<section class="pt-0">
|
|
126
120
|
<div class="container">
|
|
127
|
-
<div class="text-center mb-5" data-lazy="@class animation-slide-up">
|
|
128
|
-
{% iftruthy page.resolved.downloads.superheadline.text %}
|
|
129
|
-
<span class="badge bg-body-tertiary border-gradient-rainbow border-1 text-body p-2 mb-1 fw-semibold small">
|
|
130
|
-
{% iftruthy page.resolved.downloads.superheadline.icon %}
|
|
131
|
-
{% uj_icon page.resolved.downloads.superheadline.icon, "me-1" %}
|
|
132
|
-
{% endiftruthy %}
|
|
133
|
-
{{ page.resolved.downloads.superheadline.text }}
|
|
134
|
-
</span>
|
|
135
|
-
{% endiftruthy %}
|
|
136
|
-
<h2 class="h2 mb-2">
|
|
137
|
-
{{ page.resolved.downloads.headline }}
|
|
138
|
-
{% iftruthy page.resolved.downloads.headline_accent %}
|
|
139
|
-
<span class="text-accent">{{ page.resolved.downloads.headline_accent }}</span>
|
|
140
|
-
{% endiftruthy %}
|
|
141
|
-
</h2>
|
|
142
|
-
{% iftruthy page.resolved.downloads.subheadline %}
|
|
143
|
-
<p class="fs-5 text-muted">{{ page.resolved.downloads.subheadline }}</p>
|
|
144
|
-
{% endiftruthy %}
|
|
145
|
-
</div>
|
|
146
|
-
|
|
147
121
|
<!-- Browser Selector -->
|
|
148
122
|
<div class="row justify-content-center mb-5">
|
|
149
123
|
<div class="col-12">
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Project docs
|
|
2
|
+
|
|
3
|
+
Per-subsystem deep references live here. Keep `CLAUDE.md` short — it should read as a **table of contents** that points at files in this directory.
|
|
4
|
+
|
|
5
|
+
## Pattern
|
|
6
|
+
|
|
7
|
+
When you find yourself adding more than a paragraph to `CLAUDE.md`, create a new `docs/<topic>.md` instead and link to it from `CLAUDE.md`. Goal: the project's `CLAUDE.md` stays under ~250 lines.
|
|
8
|
+
|
|
9
|
+
Examples of good `docs/*.md` topics:
|
|
10
|
+
- Subsystem deep-dives (one per area of the codebase)
|
|
11
|
+
- Architectural decisions / "why we built it this way"
|
|
12
|
+
- Defaults tables, behavior matrices, edge cases
|
|
13
|
+
- Setup walkthroughs that don't belong in `README.md`
|
|
14
|
+
|
|
15
|
+
## See also
|
|
16
|
+
|
|
17
|
+
The framework's own docs follow this same pattern — browse `node_modules/ultimate-jekyll-manager/docs/` for the canonical examples.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Project tests
|
|
2
|
+
|
|
3
|
+
Drop your project test suites here. The framework auto-runs them alongside its own when you run `npx mgr test`.
|
|
4
|
+
|
|
5
|
+
## Layers
|
|
6
|
+
|
|
7
|
+
Match the framework's three layers — Ultimate Jekyll Manager's test runner discovers files by the directory they sit in:
|
|
8
|
+
|
|
9
|
+
| Directory | Runtime | Use for |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| `test/build/` | Plain Node | Build-time logic, config validation, pure utilities |
|
|
12
|
+
| `test/page/` | Browser page served from a local HTTP server | DOM, frontend Manager, page-specific scripts, `data-wm-bind` directives |
|
|
13
|
+
| `test/boot/` | Consumer's actual built `_site/` | End-to-end smoke tests (does the site boot, does the service worker register, do dynamic pages load) |
|
|
14
|
+
|
|
15
|
+
## Quick example
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
// test/build/my-feature.test.js
|
|
19
|
+
const assert = require('ultimate-jekyll-manager/test/assert');
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
'my feature does the thing': async () => {
|
|
23
|
+
const result = await doTheThing();
|
|
24
|
+
assert.equal(result, 'expected');
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## See also
|
|
30
|
+
|
|
31
|
+
`node_modules/ultimate-jekyll-manager/docs/test-framework.md` — full reference for the test framework (layers, assert API, fixtures, runner internals).
|
package/docs/ads.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Ad Units (Verts)
|
|
2
|
+
|
|
3
|
+
Ultimate Jekyll provides ad unit includes that display Google AdSense ads with automatic fallback to in-house ads served from promo-server when AdSense is blocked or unfilled.
|
|
4
|
+
|
|
5
|
+
## Include Files
|
|
6
|
+
|
|
7
|
+
| Include | Purpose |
|
|
8
|
+
|---------|---------|
|
|
9
|
+
| `modules/adunits/adsense.html` | AdSense ad with promo-server fallback |
|
|
10
|
+
| `modules/adunits/promo-server.html` | Direct promo-server ad (no AdSense) |
|
|
11
|
+
|
|
12
|
+
## AdSense Include
|
|
13
|
+
|
|
14
|
+
```liquid
|
|
15
|
+
{% include /modules/adunits/adsense.html type="in-article" %}
|
|
16
|
+
{% include /modules/adunits/adsense.html type="in-article" vert-size="rectangle" %}
|
|
17
|
+
{% include /modules/adunits/adsense.html type="display" vert-size="banner" %}
|
|
18
|
+
{% include /modules/adunits/adsense.html type="display" vert-size="300" %}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Parameters:**
|
|
22
|
+
|
|
23
|
+
| Parameter | Required | Default | Description |
|
|
24
|
+
|-----------|----------|---------|-------------|
|
|
25
|
+
| `type` | No | `display` | Ad type: `display`, `in-article`, `in-feed`, `multiplex` |
|
|
26
|
+
| `slot` | No | From site config | Override the ad slot ID |
|
|
27
|
+
| `vert-size` | No | (unconstrained) | Max height preset or pixel value (cannot use `size` — conflicts with Liquid's built-in `size` filter) |
|
|
28
|
+
| `style` | No | `""` | Custom inline CSS |
|
|
29
|
+
| `layout` | No | `image-above` | Layout for `in-feed` type: `image-above`, `image-side` |
|
|
30
|
+
|
|
31
|
+
## Promo Server Include
|
|
32
|
+
|
|
33
|
+
```liquid
|
|
34
|
+
{% include /modules/adunits/promo-server.html vert-id="/verts/units/test/google" %}
|
|
35
|
+
{% include /modules/adunits/promo-server.html vert-id="/verts/units/test/google" vert-size="banner" %}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Parameters:**
|
|
39
|
+
|
|
40
|
+
| Parameter | Required | Default | Description |
|
|
41
|
+
|-----------|----------|---------|-------------|
|
|
42
|
+
| `vert-id` | Yes | `""` | Path to the vert on promo-server |
|
|
43
|
+
| `vert-size` | No | (unconstrained) | Max height preset or pixel value |
|
|
44
|
+
| `style` | No | `""` | Custom inline CSS |
|
|
45
|
+
|
|
46
|
+
## Size Presets
|
|
47
|
+
|
|
48
|
+
The `vert-size` parameter accepts preset names or raw pixel values. Presets constrain the ad unit's max-height:
|
|
49
|
+
|
|
50
|
+
| Preset | Max Height | Typical Use |
|
|
51
|
+
|--------|-----------|-------------|
|
|
52
|
+
| `banner` | 150px | Horizontal banner ads |
|
|
53
|
+
| `leaderboard` | 90px | Wide horizontal ads (alias for banner) |
|
|
54
|
+
| `rectangle` | 250px | Medium rectangle, in-content ads |
|
|
55
|
+
| `large-rectangle` | 600px | Large rectangle, sidebar ads |
|
|
56
|
+
| `skyscraper` | 600px | Tall sidebar ads |
|
|
57
|
+
|
|
58
|
+
Raw pixel values are also accepted: `vert-size="300"` → 300px max-height.
|
|
59
|
+
|
|
60
|
+
When no `vert-size` is specified, the ad unit renders unconstrained.
|
|
61
|
+
|
|
62
|
+
## How It Works
|
|
63
|
+
|
|
64
|
+
1. The include renders a `data-lazy="@script ..."` div that lazy-loads `vert.bundle.js` when scrolled into view
|
|
65
|
+
2. `vert.js` creates a `<vert-unit>` custom element with `max-height` + `overflow: hidden` (if `vert-size` is set)
|
|
66
|
+
3. For AdSense types: loads the AdSense script, pushes the ad, and monitors fill status
|
|
67
|
+
4. If AdSense is blocked or unfilled, falls back to a promo-server iframe
|
|
68
|
+
5. The promo-server iframe content uses CSS container queries to adapt its layout to the available space
|
|
69
|
+
6. Ad units are hidden for non-basic plan users via `data-wm-bind="@hide auth.account.subscription.product.id !== basic"`
|
|
70
|
+
|
|
71
|
+
## File Locations
|
|
72
|
+
|
|
73
|
+
| Purpose | Path |
|
|
74
|
+
|---------|------|
|
|
75
|
+
| AdSense include | `src/defaults/dist/_includes/modules/adunits/adsense.html` |
|
|
76
|
+
| Promo Server include | `src/defaults/dist/_includes/modules/adunits/promo-server.html` |
|
|
77
|
+
| Vert JS module | `src/assets/js/modules/vert.js` |
|
|
78
|
+
| Vert CSS | `src/assets/css/core/_verts.scss` |
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Analytics & Tracking
|
|
2
|
+
|
|
3
|
+
Ultimate Jekyll uses three tracking platforms: Google Analytics (gtag), Facebook Pixel (fbq), and TikTok Pixel (ttq).
|
|
4
|
+
|
|
5
|
+
## ITM (Internal Tracking Medium)
|
|
6
|
+
|
|
7
|
+
Internal tracking system modeled after UTM for cross-property user journey tracking.
|
|
8
|
+
|
|
9
|
+
| Parameter | Purpose | Examples |
|
|
10
|
+
|-----------|---------|----------|
|
|
11
|
+
| `itm_source` | Platform/origin | `website`, `browser-extension`, `app`, `email` |
|
|
12
|
+
| `itm_medium` | Delivery mechanism | `modal`, `prompt`, `banner`, `tooltip` |
|
|
13
|
+
| `itm_campaign` | Specific campaign/feature | `exit-popup`, `premium-unlock`, `newsletter-signup` |
|
|
14
|
+
| `itm_content` | Specific context | Page path, feature ID, variant |
|
|
15
|
+
|
|
16
|
+
**Examples:**
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
# Website exit popup
|
|
20
|
+
?itm_source=website&itm_medium=modal&itm_campaign=exit-popup&itm_content=/pricing
|
|
21
|
+
|
|
22
|
+
# Extension premium unlock
|
|
23
|
+
?itm_source=browser-extension&itm_medium=prompt&itm_campaign=premium-unlock&itm_content=bulk-export
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Tracking Guidelines
|
|
27
|
+
|
|
28
|
+
**IMPORTANT Rules:**
|
|
29
|
+
- Track important user events with `gtag()`, `fbq()`, and `ttq()` functions
|
|
30
|
+
- NEVER add conditional checks for tracking functions (e.g., `if (typeof gtag !== 'undefined')`)
|
|
31
|
+
- Always assume tracking functions exist — they're globally available or stubbed
|
|
32
|
+
- Reference standard events documentation before implementing custom tracking
|
|
33
|
+
|
|
34
|
+
**Standard Events Documentation:**
|
|
35
|
+
- **Google Analytics GA4:** https://developers.google.com/analytics/devguides/collection/ga4/reference/events
|
|
36
|
+
- **Facebook Pixel:** https://www.facebook.com/business/help/402791146561655?id=1205376682832142
|
|
37
|
+
- **TikTok Pixel:** https://ads.tiktok.com/help/article/standard-events-parameters?redirected=2
|
|
38
|
+
|
|
39
|
+
## Platform-Specific Requirements
|
|
40
|
+
|
|
41
|
+
### TikTok Pixel Requirements
|
|
42
|
+
|
|
43
|
+
TikTok has strict validation requirements:
|
|
44
|
+
|
|
45
|
+
**Required Parameters:**
|
|
46
|
+
- `content_id` — MUST be included in all events
|
|
47
|
+
|
|
48
|
+
**Valid Content Types:**
|
|
49
|
+
- `"product"`
|
|
50
|
+
- `"product_group"`
|
|
51
|
+
- `"destination"`
|
|
52
|
+
- `"hotel"`
|
|
53
|
+
- `"flight"`
|
|
54
|
+
- `"vehicle"`
|
|
55
|
+
|
|
56
|
+
Any other content type will generate a validation error.
|
|
57
|
+
|
|
58
|
+
**Example:**
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
// ✅ CORRECT
|
|
62
|
+
ttq.track('ViewContent', {
|
|
63
|
+
content_id: 'product-123',
|
|
64
|
+
content_type: 'product'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// ❌ WRONG - Missing content_id
|
|
68
|
+
ttq.track('ViewContent', {
|
|
69
|
+
content_type: 'product'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// ❌ WRONG - Invalid content_type
|
|
73
|
+
ttq.track('ViewContent', {
|
|
74
|
+
content_id: 'product-123',
|
|
75
|
+
content_type: 'custom' // Not in approved list
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Tracking Implementation
|
|
80
|
+
|
|
81
|
+
**IMPORTANT:** Always track events to ALL THREE platforms in this order:
|
|
82
|
+
1. Google Analytics (gtag)
|
|
83
|
+
2. Facebook Pixel (fbq)
|
|
84
|
+
3. TikTok Pixel (ttq)
|
|
85
|
+
|
|
86
|
+
Track events directly without existence checks. All three tracking calls should be made together for every event.
|
|
87
|
+
|
|
88
|
+
**Development Mode:**
|
|
89
|
+
|
|
90
|
+
In development mode, all tracking calls are intercepted and logged to the console for debugging. See `src/assets/js/libs/dev.js` for implementation.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Appearance Switching System
|
|
2
|
+
|
|
3
|
+
Ultimate Jekyll supports dark/light/system theme switching with user preference persistence.
|
|
4
|
+
|
|
5
|
+
## Supported Modes
|
|
6
|
+
|
|
7
|
+
- `dark` — Force dark mode
|
|
8
|
+
- `light` — Force light mode
|
|
9
|
+
- `system` — Auto-detect from OS preference (`prefers-color-scheme`)
|
|
10
|
+
|
|
11
|
+
## JavaScript API
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
// Get/set preference
|
|
15
|
+
webManager.uj().appearance.get(); // Returns 'dark', 'light', 'system', or null
|
|
16
|
+
webManager.uj().appearance.set('dark'); // Save and apply preference
|
|
17
|
+
webManager.uj().appearance.getResolved(); // Returns actual theme: 'dark' or 'light'
|
|
18
|
+
|
|
19
|
+
// Utilities
|
|
20
|
+
webManager.uj().appearance.toggle(); // Toggle between dark/light
|
|
21
|
+
webManager.uj().appearance.cycle(); // Cycle: dark → light → system → dark
|
|
22
|
+
webManager.uj().appearance.clear(); // Clear saved preference
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## HTML Data Attributes
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<!-- Buttons to set appearance (auto-gets 'active' class) -->
|
|
29
|
+
<button data-appearance-set="light">Light</button>
|
|
30
|
+
<button data-appearance-set="dark">Dark</button>
|
|
31
|
+
<button data-appearance-set="system">System</button>
|
|
32
|
+
|
|
33
|
+
<!-- Display current mode as text -->
|
|
34
|
+
<span data-appearance-current></span>
|
|
35
|
+
|
|
36
|
+
<!-- Show/hide icons based on current mode -->
|
|
37
|
+
<span data-appearance-icon="light" hidden>☀️</span>
|
|
38
|
+
<span data-appearance-icon="dark" hidden>🌙</span>
|
|
39
|
+
<span data-appearance-icon="system" hidden>💻</span>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Dropdown Example
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<div class="dropdown">
|
|
46
|
+
<button class="btn dropdown-toggle" data-bs-toggle="dropdown">
|
|
47
|
+
<span data-appearance-icon="light" hidden>{% uj_icon "sun", "fa-md me-2" %}</span>
|
|
48
|
+
<span data-appearance-icon="dark" hidden>{% uj_icon "moon-stars", "fa-md me-2" %}</span>
|
|
49
|
+
<span data-appearance-icon="system" hidden>{% uj_icon "circle-half-stroke", "fa-md me-2" %}</span>
|
|
50
|
+
<span data-appearance-current></span>
|
|
51
|
+
</button>
|
|
52
|
+
<ul class="dropdown-menu">
|
|
53
|
+
<li><a class="dropdown-item" href="#" data-appearance-set="light">Light</a></li>
|
|
54
|
+
<li><a class="dropdown-item" href="#" data-appearance-set="dark">Dark</a></li>
|
|
55
|
+
<li><a class="dropdown-item" href="#" data-appearance-set="system">System</a></li>
|
|
56
|
+
</ul>
|
|
57
|
+
</div>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Implementation
|
|
61
|
+
|
|
62
|
+
- **Inline script:** `src/defaults/dist/_includes/core/body.html` — Runs immediately to prevent flash
|
|
63
|
+
- **Module:** `src/assets/js/core/appearance.js` — API and UI handling
|
|
64
|
+
- **Storage:** Saved under `_manager.appearance.preference` in localStorage
|
|
65
|
+
- **Test page:** `/test/libraries/appearance`
|