monoholic 1.3.0 → 1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 944d762c5b588ea620fe59093575adf3fe51488e84a04cbb31dd5b34619d9aed
4
- data.tar.gz: 1ba6737b6d4e3b1e6e207f4cebadb2b51ea7f8608ff89cb139e89d1de8c25561
3
+ metadata.gz: 0b2feef2d72bb935b6e4e6bdb2d5c39034616dadd12f3c6ca9158a43cafe24d8
4
+ data.tar.gz: 354b3cc49d0afcbcfe40e21f2e0da506310c34b3ee44a06392a397d8e90360a4
5
5
  SHA512:
6
- metadata.gz: 2051528bae7940745198bb450bf329d07f0e203230e05226735625a8da40d6b73bf726a58452f3d016fdefb4a052bd2d38e61655d07c828ec7d5c2adedef313a
7
- data.tar.gz: 650a541107d5966c16485b3c483654ab3c5f9fa3ca7897401d92f00b423d8eadd4722107b8c97844bbf389879af30966c58a9649d625dc4dc082d52c5a3c3237
6
+ metadata.gz: 3acf3815b503469a52aab55448404d6c2f3869fb636c11831c4d698d962510558b1d6f282f749fe51b8e923c9c29ed9e9ed56705f1ea6d28c5a940f5f3c57a21
7
+ data.tar.gz: 929ca0d46b670294db583b75f4e633bbe2eabc990cd916b360694159ac357a689bcf3409fffc9f7e06b6d5cbc930e65e1b50010cc4dc6d16642022169eb2091f
data/README.md CHANGED
@@ -40,10 +40,14 @@ $ bundle install
40
40
 
41
41
  ### Manual Installation (GitHub Pages)
42
42
 
43
- If you're running Jekyll without RubyGems or prefer to use GitHub Pages remote themes, update your `_config.yml`:
43
+ For GitHub's built-in Jekyll build, add the following to `_config.yml`:
44
44
 
45
45
  ```yaml
46
- remote_theme: stiermid/monoholic
46
+ title: "Your site"
47
+ description: "A short description of your site."
48
+ remote_theme: stiermid/monoholic@v1.4.0
49
+ url: "https://<user>.github.io"
50
+ baseurl: "/your-repo"
47
51
  plugins:
48
52
  - jekyll-remote-theme
49
53
  - jekyll-feed
@@ -51,16 +55,54 @@ plugins:
51
55
  - jekyll-sitemap
52
56
  ```
53
57
 
54
- `jekyll-remote-theme` fetches the theme on Pages; `jekyll-feed` and `jekyll-seo-tag` are required by the theme's `head.html` (`{% feed_meta %}`, `{% seo %}`), and `jekyll-sitemap` generates `sitemap.xml` referenced by the theme's `robots.txt`. For project sites, also set `baseurl` (e.g. `/your-repo`) and `url` (e.g. `https://<user>.github.io`). To pin a release: `remote_theme: stiermid/monoholic@v1.3.0`.
58
+ Replace the user and repository placeholders. Use `baseurl: ""` for a user
59
+ site or a custom domain served at its root. Pinning a release keeps theme
60
+ updates explicit; omit `@v1.4.0` only if you want the repository's default
61
+ branch instead.
55
62
 
56
- > **Pages note:** Native GitHub Pages builds run Jekyll 3.9. The `monoholic` RubyGem requires Jekyll 4.4, so on GitHub Pages use `remote_theme` only (not `theme:` + `gem "monoholic"`). SCSS intentionally uses `@import` for 3.9 compatibility.
63
+ `jekyll-remote-theme` loads the theme. Feed and SEO tags require
64
+ `jekyll-feed` and `jekyll-seo-tag`; `jekyll-sitemap` generates the sitemap
65
+ and a default `robots.txt` when the site does not supply one.
57
66
 
58
- | Install method | Jekyll | How |
59
- | -------------------------------------------------------- | ------------- | --------------------------- |
60
- | RubyGems (`theme: monoholic`) | 4.4 | local / CI / non-Pages host |
61
- | GitHub Pages (`remote_theme: stiermid/monoholic@v1.3.0`) | 3.9 via Pages | Pages only |
67
+ Create a homepage, such as `index.md`:
62
68
 
63
- Or, simply fork this repository, adapt the `_config.yml` according to your needs, and you're good to go!
69
+ ```markdown
70
+ ---
71
+ layout: home
72
+ ---
73
+
74
+ Welcome to my site.
75
+ ```
76
+
77
+ Also create `_data/menu.yml` in your site:
78
+
79
+ ```yaml
80
+ entries:
81
+ - title: all posts
82
+ post_list: true
83
+ ```
84
+
85
+ Native Jekyll 3.10 does not inherit a remote theme's `_data` directory, so
86
+ your site must supply its own menu. Add your posts under `_posts/` and
87
+ extend the menu using the options below.
88
+
89
+ > **Pages note:** Native Pages currently uses Jekyll 3.10.0 and Sass converter
90
+ > 1.5.2 with Ruby Sass. The `monoholic` gem requires Jekyll 4.4, so do not
91
+ > combine it with the native Pages bundle. Use `remote_theme` instead of
92
+ > `theme: monoholic` for that build. SCSS retains `@import` for this older
93
+ > Sass compiler.
94
+
95
+ | Method | Jekyll | Build |
96
+ | ------------ | ------ | ------------------- |
97
+ | RubyGem | 4.4 | Local / custom CI |
98
+ | Remote theme | 3.10 | Native GitHub Pages |
99
+
100
+ You can still deploy a Jekyll 4.4 gem-based site to Pages as static output
101
+ from a custom build workflow. The version restriction applies to GitHub's
102
+ built-in Jekyll build, not to static hosting.
103
+
104
+ For a full source checkout instead, fork this repository and adapt
105
+ `_config.yml` to your site.
64
106
 
65
107
  ## Usage
66
108
 
@@ -80,8 +122,35 @@ theme_config:
80
122
  date_format: "%Y-%m-%d" # Date format for post metadata
81
123
  monochrome_images: true # Apply grayscale filter to images (default: true)
82
124
  footer: true # Show/hide site footer (default: true)
125
+ skip_link_label: "Skip to content" # Keyboard skip-link text
126
+ site_sections_label: "Site sections" # Accessible name of the homepage navigation
83
127
  ```
84
128
 
129
+ ### Language and Interface Labels
130
+
131
+ The document's `<html lang>` uses the page's `lang` front matter, then the site's `lang` setting, then `en`. Use BCP 47 language tags such as `de`, `en-GB`, or `zh-Hant-TW`. Surrounding whitespace is trimmed; missing, empty, whitespace-only, or `false` values fall back to the next setting.
132
+
133
+ For example, configure a German site in `_config.yml`:
134
+
135
+ ```yaml
136
+ lang: de
137
+ theme_config:
138
+ skip_link_label: "Zum Inhalt"
139
+ site_sections_label: "Seitenbereiche"
140
+ back: "Zurück"
141
+ ```
142
+
143
+ Override the document language for an individual page or post in its front matter:
144
+
145
+ ```yaml
146
+ ---
147
+ layout: page
148
+ lang: fr-CA
149
+ ---
150
+ ```
151
+
152
+ Declaring `lang` helps browsers and assistive technology interpret your content; it does not translate the content or interface automatically. Interface labels above are site-wide and rendered as plain text, not HTML. Missing or blank labels retain their English defaults so the skip link and navigation keep accessible names. Existing scroll labels and hints can also be translated under [Responsive Content](#responsive-content).
153
+
85
154
  ### Fediverse Creator tag
86
155
 
87
156
  Monoholic supports `fediverse:creator` meta tag:
@@ -116,9 +185,12 @@ entries:
116
185
 
117
186
  - `title`: The section header.
118
187
  - `content`: Custom HTML or text for the menu section.
119
- - `content_file`: Path to an external markdown file (e.g., `about.md`) to load content from your root directory.
188
+ - `content_include`: Path relative to `_includes/` for a Markdown fragment with Liquid support (recommended for reusable content).
189
+ - `content_file`: Path to an existing Jekyll page (e.g., `about.md`) relative to your site root. Retained for compatibility; does not reliably evaluate Liquid.
120
190
  - `post_list`: Set to `true` to auto-generate a list of your Jekyll posts under this section.
121
191
 
192
+ Use one content source per entry. If several are supplied, precedence is `content_include`, then `content_file`, then `content`.
193
+
122
194
  #### Nested Menu Sections
123
195
 
124
196
  Menu entries can contain nested `entries` to create recursive sub-sections:
@@ -147,7 +219,29 @@ Each titled section is labelled by its heading. Heading IDs include the ancestor
147
219
 
148
220
  #### Using External Content Files
149
221
 
150
- You can reference external markdown files instead of inline content:
222
+ For reusable content containing Liquid, create a Markdown fragment in your site's `_includes/` directory, for example `_includes/fragments/about.md`:
223
+
224
+ ```liquid
225
+ Welcome to **{{ site.title }}**.
226
+
227
+ [Home]({{ '/' | relative_url }})
228
+ ```
229
+
230
+ Reference it using `content_include`:
231
+
232
+ ```yaml
233
+ entries:
234
+ - title: about
235
+ content_include: fragments/about.md
236
+ ```
237
+
238
+ Jekyll renders Liquid first, then Monoholic converts the resulting Markdown to HTML once. Standard Liquid variables, filters, tags, and nested includes work without a custom plugin, including in safe mode. `page` refers to the page displaying the menu, not the fragment. Use `relative_url` for links that must work on project sites such as `/blog`.
239
+
240
+ Fragments must **not** have YAML front matter. They do not generate standalone pages. Paths are relative to `_includes/`, even when the menu appears on a nested page; missing files and invalid paths fail the build with Jekyll's include error rather than silently omitting content. Only include trusted, author-controlled files.
241
+
242
+ ##### Existing `content_file` references
243
+
244
+ Existing page references remain supported:
151
245
 
152
246
  ```yaml
153
247
  entries:
@@ -155,7 +249,17 @@ entries:
155
249
  content_file: about.md
156
250
  ```
157
251
 
158
- This will load and render the content from `about.md` in your site's root directory.
252
+ The referenced file must be a Jekyll page with YAML front matter (an empty `---` block is sufficient) and must not be excluded from the build. Its Markdown content is embedded without its layout; the page can also generate its own standalone URL. Missing page references are silently omitted, preserving existing behavior.
253
+
254
+ `content_file` does not run a separate Liquid rendering pass. Results for Liquid expressions can depend on page rendering order, so use `content_include` whenever the content contains Liquid.
255
+
256
+ To migrate, move reusable content from `about.md` to `_includes/fragments/about.md`, remove its YAML front matter, and replace `content_file: about.md` with `content_include: fragments/about.md`. If you still need a standalone About page, keep `about.md` with its front matter and include the fragment in its body:
257
+
258
+ ```liquid
259
+ {% include fragments/about.md %}
260
+ ```
261
+
262
+ Use a Markdown page for this wrapper so Jekyll converts the included Markdown normally. Remove an old standalone page only if you no longer need its URL.
159
263
 
160
264
  ### Favicon
161
265
 
@@ -185,6 +289,10 @@ To override CSS custom properties (colors, spacing, fonts) without touching SCSS
185
289
 
186
290
  ### Responsive Content
187
291
 
292
+ Body text defaults to `1rem`, following the browser's default font size
293
+ instead of fixing it at 16 pixels. When overriding `--font-size-base`, use
294
+ a relative value such as `1rem` or `1.125rem` to preserve that preference.
295
+
188
296
  Long words, URLs, and inline code wrap when necessary. Plain and highlighted code blocks preserve indentation and source lines, scrolling horizontally inside the block instead of expanding the page.
189
297
 
190
298
  The small, dependency-free `assets/js/content-scroll.js` script progressively enhances tables with scroll containers while preserving native table semantics. Overflowing tables and code blocks receive a keyboard tab stop, an accessible name, and a visible scrolling hint. These are updated when the viewport, content dimensions, or fonts change; fitting content does not add automatic tab stops.
@@ -226,24 +334,87 @@ npx playwright install --with-deps chromium firefox webkit
226
334
  bundle exec ruby _tests/release_workflow_test.rb
227
335
  bundle exec ruby _tests/release_tag_test.rb
228
336
  bundle exec ruby _tests/home_layout_test.rb
337
+ bundle exec ruby _tests/localization_test.rb
338
+ JEKYLL_SAFE=1 bundle exec ruby _tests/localization_test.rb
229
339
  bundle exec ruby _tests/menu_layout_test.rb
230
340
  JEKYLL_SAFE=1 bundle exec ruby _tests/menu_layout_test.rb
341
+ bundle exec ruby _tests/menu_content_test.rb
342
+ JEKYLL_SAFE=1 bundle exec ruby _tests/menu_content_test.rb
231
343
  npm run test:browser
232
344
  ```
233
345
 
234
346
  Browser tests build and serve an isolated fixture site. They cover Chromium, Firefox, and WebKit at 320px, 375px, 768px, and 1280px, including long text, plain and highlighted code, Markdown and HTML tables, keyboard scrolling, resizing, and JavaScript-disabled layouts. External fonts are blocked so the tests do not depend on Google Fonts being available.
235
347
 
348
+ Text-sizing checks enlarge the root font to 200% at each viewport width,
349
+ with and without JavaScript. A Firefox-specific test also changes the
350
+ actual browser default-font preference to 32 pixels. These are focused
351
+ regression checks, not a complete WCAG conformance audit.
352
+
236
353
  Menu rendering checks cover branching recursion, deep nesting, untitled groups, repeated titles, unique IDs, escaped labels, and independent menu instances in normal and Jekyll safe mode. Browser tests also verify native heading and section semantics with JavaScript disabled.
237
354
 
355
+ Menu content checks build root and `/blog` sites in normal and safe mode. They cover Liquid-before-Markdown rendering, nested includes and host pages, recursive sections, literal Liquid examples, legacy content sources, and invalid include paths.
356
+
357
+ Localization checks cover language inheritance across all four layouts, page overrides, blank-value fallbacks, escaped attributes, translated labels, and unchanged skip-link destinations in normal and safe mode.
358
+
238
359
  To run one browser, use `npm run test:browser -- --project=chromium`. You can also set `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` to use a locally installed Chromium binary. Generated sites, screenshots, and traces are ignored by Git; CI retains failure diagnostics for seven days.
239
360
 
240
- ### Release Validation
361
+ ### Native GitHub Pages Checks
241
362
 
242
- Both pull requests and release-tag pushes run the build and test checks. Publishing depends on all checks succeeding and is restricted to pushed `v*` tags; pull requests never publish. The tag must be `v` followed by the exact gem version in `monoholic.gemspec`, including any RubyGems prerelease suffix. Update the version metadata and lockfiles together before tagging.
363
+ The Pages tests use a separate Gemfile and lockfile so the theme's Jekyll 4.4
364
+ dependency cannot affect the native Pages graph. CI runs them on Ruby 3.3.
365
+ Install and run them with:
243
366
 
244
- CI builds the gem once and installs it into a temporary gem home. A clean consumer site uses that installed package with the existing lockfile dependencies, without downloading gems or falling back to repository theme files. The checks build root and `/blog` sites and verify layouts, compiled CSS, scripts, favicons, feeds, and URLs. Negative tests reject broken packages and invalid versions.
367
+ ```sh
368
+ BUNDLE_GEMFILE=_tests/pages/Gemfile bundle install
369
+ BUNDLE_GEMFILE=_tests/pages/Gemfile bundle exec \
370
+ ruby _tests/pages/consumer_test.rb
371
+ ```
372
+
373
+ This bundle pins GitHub Pages 232, Jekyll 3.10.0, Sass converter 1.5.2, and
374
+ the other published Pages dependencies. The test invokes the real Pages
375
+ build command with its safe-mode configuration and default plugins. It
376
+ checks root and `/blog` sites, layouts, menu data, nested Liquid includes,
377
+ recursive headings, language settings, compiled CSS, scripts, favicons,
378
+ feeds, sitemap URLs, and rejection of a broken theme archive.
379
+
380
+ Only the theme-download HTTP response is supplied locally, using a ZIP of
381
+ the checkout. The real `jekyll-remote-theme` plugin downloads, extracts, and
382
+ loads it. No live GitHub requests or installed `monoholic` gem are used.
383
+ The generated lockfile retains Bundler's checksum format.
384
+
385
+ Review the [published dependency matrix](https://pages.github.com/versions/)
386
+ when updating this bundle. Update its Gemfile, lockfile, and expected versions
387
+ in `_tests/pages/consumer_test.rb` together.
388
+
389
+ ### Release Validation
245
390
 
246
- After validation, tag runs upload the gem and its SHA-256 manifest as a seven-day artifact. The publishing job downloads those same bytes, verifies the checksum and package name/version, and pushes the same gem to GitHub Packages and RubyGems—without checking out or rebuilding the source. Rerunning validation replaces the artifact only after checks succeed; if it has expired, rerun validation rather than just the publishing job.
391
+ Pull requests and release-tag pushes run gem checks on Ruby 3.3 and 3.4,
392
+ plus the separate native Pages check on Ruby 3.3. Publishing requires all
393
+ three jobs to succeed and is restricted to pushed `v*` tags; pull requests
394
+ never publish. The tag must be `v` followed by the exact gem version in
395
+ `monoholic.gemspec`, including any RubyGems prerelease suffix. Update the
396
+ version metadata and lockfiles together before tagging.
397
+
398
+ Each gem-validation job builds the gem once and installs it into a temporary
399
+ gem home. A clean consumer's Gemfile declares only `monoholic`; Bundler resolves
400
+ its runtime dependencies from installed gems without downloading gems or
401
+ falling back to repository theme files. The checks run
402
+ `bundle exec jekyll build` for root and `/blog` sites and verify layouts,
403
+ compiled CSS, scripts, favicons, feeds, and URLs. Negative tests reject broken
404
+ packages and invalid versions. ERB must be declared as a runtime dependency,
405
+ even on hosts that provide it as a default gem; this is checked on both Rubies.
406
+
407
+ Consumer builds use resolved Ruby and gem executable paths, with no Jekyll
408
+ wrapper available on `PATH`. This also covers vendored CI installations
409
+ without relying on globally installed gem executables.
410
+
411
+ After validation, the Ruby 3.3 gem job uploads its gem and SHA-256 manifest
412
+ as a seven-day artifact; the other jobs do not upload a competing release
413
+ artifact. Once both gem jobs and native Pages pass, publishing downloads
414
+ those same bytes, verifies the checksum and package name/version, and pushes
415
+ the same gem to GitHub Packages and RubyGems—without checking out or rebuilding
416
+ the source. Rerunning validation replaces the artifact only after checks
417
+ succeed; if it has expired, rerun validation rather than just publishing.
247
418
 
248
419
  Publishing keeps the existing authentication: `GITHUB_TOKEN` with package-write permission for GitHub Packages, and the repository's `RUBYGEMS_API_KEY` secret for RubyGems. Validation has read-only repository permissions; registry credentials are used only by publishing steps.
249
420
 
data/_includes/menu.html CHANGED
@@ -70,7 +70,12 @@
70
70
  </h2>
71
71
  {%- endif -%}
72
72
  {%- endif -%}
73
- {%- if item.content_file -%}
73
+ {%- if item.content_include -%}
74
+ {%- capture _menu_content -%}
75
+ {%- include {{ item.content_include }} -%}
76
+ {%- endcapture -%}
77
+ {{ _menu_content | markdownify }}
78
+ {%- elsif item.content_file -%}
74
79
  {%- assign _menu_page = site.pages
75
80
  | where: 'path', item.content_file
76
81
  | first
@@ -1,8 +1,16 @@
1
+ {%- assign _page_lang = page.lang | default: '' | strip -%}
2
+ {%- assign _site_lang = site.lang | default: '' | strip -%}
3
+ {%- assign _skip_link_label = site.theme_config.skip_link_label
4
+ | default: ''
5
+ | strip
6
+ -%}
1
7
  <!doctype html>
2
- <html lang="{{ page.lang | default: "en" }}">
8
+ <html lang="{{ _page_lang | default: _site_lang | default: 'en' | escape }}">
3
9
  {%- include head.html -%}
4
10
  <body class="{% if site.theme_config.monochrome_images != false %}images-monochrome{% endif %}">
5
- <a class="skip-link" href="#main">Skip to content</a>
11
+ <a class="skip-link" href="#main">
12
+ {{- _skip_link_label | default: 'Skip to content' | escape -}}
13
+ </a>
6
14
  <div class="wrapper">
7
15
  {%- unless page.layout == 'post' -%}
8
16
  {%- include header.html -%}
data/_layouts/home.html CHANGED
@@ -3,6 +3,10 @@ layout: default
3
3
  ---
4
4
  {{ content }}
5
5
 
6
- <nav aria-label="Site sections">
6
+ {%- assign _site_sections_label = site.theme_config.site_sections_label
7
+ | default: ''
8
+ | strip
9
+ -%}
10
+ <nav aria-label="{{ _site_sections_label | default: 'Site sections' | escape }}">
7
11
  {%- include menu.html collection=site.data.menu.entries level=2 -%}
8
12
  </nav>
@@ -7,7 +7,7 @@
7
7
 
8
8
  // Typography
9
9
  --font-family: "JetBrains Mono", monospace;
10
- --font-size-base: 16px;
10
+ --font-size-base: 1rem;
11
11
  --font-size-sm: 0.85rem;
12
12
  --font-size-section: 1.1rem;
13
13
  --font-size-site-title: 2rem;
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monoholic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Agil Mammadov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-15 00:00:00.000000000 Z
11
+ date: 2026-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: erb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '7.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '2.2'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '7.0'
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: jekyll
15
35
  requirement: !ruby/object:Gem::Requirement