al_folio_core 1.0.12 → 1.0.14

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: 5387437a7b8347fc9e93b04cdeba7c8c1dfb465b93fcd38bf15b8f8bccba5e82
4
- data.tar.gz: 9788c8d4bfa98fffcaa773a498a90a05f184cb5a9f64b2efee7122b684777953
3
+ metadata.gz: f2f1858ae1303cd5ae1f61fde71d9222ca59d4df20d37cdce083789287f16eca
4
+ data.tar.gz: 7bc84f2d2effc1dd18130d089d55d782c3262dd6fb86ae53f7f2314f0d30ba8c
5
5
  SHA512:
6
- metadata.gz: fd3e8be0858390fa7b6737da0fbd9c2679525d949d8de240b8252219bff7fd0cc5f74b45a1f9e01cef300c3355d1bea3f047b93062f20310297780e5743f3133
7
- data.tar.gz: ca219b220b25f6ef0162c34eaed26cce81df78f6ab49c1cce68140a82c70f30224d1053544ca9a35997c3d0bd9ae1230a8ef829d8fac6761fca7d67ed467d6ab
6
+ metadata.gz: db52abe776a109c94b27ecce1f18b11f334f159dcc431470f2b036fd9a332824481d39f9b522c111e75eaba63c7f9cad50a91fa326bb3f9b1933deddb67e3c35
7
+ data.tar.gz: '008b6d4f07a0af5bee8315559fa4846b0ccef27128dc3329ebefb5d4e4b85ca0908845aaab4d82ff4fa0bdec2c63a6212d8e86ec1beb6e9862976c224b3aefd4'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.14 - 2026-08-02
4
+
5
+ - Added invocation hooks for three new plugin gems: `al_rtl`, `al_email_protect` and `al_marimo`. Each is a parse-safe wrapper under `_includes/plugins/` called from `head.liquid`, `scripts.liquid` or `default.liquid`, and every call sits inside a `site.plugins contains` guard — an unguarded custom tag is a parse error on any site that has not installed the gem, which fails the whole build rather than just the feature.
6
+ - `al_rtl` needs `dir` on the `<html>` element, which is what the browser's bidi algorithm, CSS logical properties and Tailwind's `rtl:` variant key off; a wrapper `div` would leave the navbar, footer and scrollbar placement laid out left-to-right. The attributes are captured into a variable rather than the tag being wrapped in `{% if %}`, because a conditional there stops Prettier seeing a static root element and it re-indents the entire document body. Sites without `al_rtl` get byte-identical output from the fallback branch.
7
+ - Added `.gitignore`. The repo had none, so `npm ci` (needed for the prettier lint) left `node_modules` addable and a routine `git add -A` swept ~208k lines of vendored JS into a commit.
8
+
9
+ ## 1.0.13 - 2026-07-29
10
+
11
+ - Added an `apple-touch-icon` link to `_includes/head.liquid`. Without it, "Add to Home Screen" on iOS falls back to a screenshot of the page instead of the site icon, because Safari only reads `rel="apple-touch-icon"` for that thumbnail — it never uses `rel="shortcut icon"`. The link is emitted only when a raster asset actually exists: a new optional `apple_touch_icon` config key (resolved under `/assets/img/` like `icon`, or used verbatim when it is a rooted path or an absolute URL), otherwise an `icon` that is itself a `.png`/`.jpg`/`.jpeg` file. The default emoji `icon` renders as an inline SVG data URI, which Safari ignores for touch icons, so in that case nothing is emitted rather than a link that would 404. Apple's recommended asset is a 180x180 PNG. Fixes alshedivat/al-folio#2774.
12
+ - Fixed the favicon `<link>` being emitted with an empty filename when no `icon` is configured. `site.icon != blank` is always true under plain Liquid — the `blank` literal compares by calling `blank?` on the other operand, and neither `nil` nor `String` defines it without ActiveSupport, so the comparison returns `nil` and `!=` inverts it to `true`. An unset `icon` therefore reached the image branch and produced `href="/assets/img/"`, a guaranteed 404 on every page. The check is now truthiness plus an explicit empty-string test.
13
+ - Rendered video publication previews as `<video>` instead of a broken `<img>` (`_layouts/bib.liquid`). `preview = {clip.mp4}` in a `.bib` entry was passed straight to the image path, so the publications list showed a broken-image placeholder. Previews ending in `.mp4`, `.webm`, `.ogg` or `.mov` are now handed to `_includes/video.liquid` with `controls=true`; local files still resolve under `/assets/img/publication_preview/` and remote URLs are passed through unchanged. The image branch is untouched, so nothing changes for existing previews. Fixes alshedivat/al-folio#3564.
14
+ - Made `_includes/video.liquid` recognize `.mov` files, and normalize the extension before matching it (lower-casing it and dropping any query string). A `CLIP.MP4` or a `clip.mp4?raw=1` URL previously fell through to the `<iframe>` branch and rendered as an empty frame. Local `.mov` files did the same.
15
+ - Constrained `video.preview` in `_sass/_publications.scss`. Unlike `<img>`, a `<video>` has no intrinsic responsive sizing and falls back to its 300x150 default, which overflowed the publication thumbnail column.
16
+
3
17
  ## 1.0.12 - 2026-07-27
4
18
 
5
19
  - Switched the default repository/user stat-card service from the unmaintained `github-readme-stats.vercel.app` to the actively maintained `github-stats-extended.vercel.app` fork (`_includes/repository/repo.liquid`, `_includes/repository/repo_user.liquid`). The public github-readme-stats instance has been unreliable for a long time, leaving repository cards blank; the fork is API-compatible, so every existing query parameter (`theme`, `locale`, `show_owner`, `description_lines_count`, `show_icons`) keeps working and the cards render identically. Requested upstream by a github-stats-extended maintainer in alshedivat/al-folio#3629.
@@ -77,14 +77,48 @@
77
77
  >
78
78
  {% endif %}
79
79
 
80
+ {% comment %}
81
+ Note: `x != blank` is unreliable here — Liquid's `blank` literal compares by calling
82
+ `blank?` on the other operand, and plain Ruby's NilClass/String have no `blank?`, so
83
+ the comparison yields nil and `!=` is therefore always true. An unset `site.icon`
84
+ used to fall through to the `elsif` below and emit `href="/assets/img/"`. Truthiness
85
+ plus an explicit empty-string check behaves correctly with or without ActiveSupport.
86
+ {% endcomment %}
80
87
  {% if site.icon.size <= 4 %}
81
88
  <link
82
89
  rel="shortcut icon"
83
90
  href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>{{ site.icon }}</text></svg>"
84
91
  >
85
- {% elsif site.icon != blank %}
92
+ {% elsif site.icon and site.icon != '' %}
86
93
  <link rel="shortcut icon" href="{{ site.icon | prepend: '/assets/img/' | relative_url | bust_file_cache}}">
87
94
  {% endif %}
95
+ {% comment %}
96
+ iOS home-screen bookmarks need `rel="apple-touch-icon"` pointing at a real raster
97
+ image; Safari ignores the inline SVG data URI used for the emoji favicon above and
98
+ falls back to a screenshot of the page. So the tag is emitted only when a usable
99
+ asset actually exists — an explicit `apple_touch_icon` (a 180x180 PNG is what Apple
100
+ recommends), or an `icon` that is already a raster image file. When `icon` is an
101
+ emoji, nothing is emitted rather than a link that would 404.
102
+ See alshedivat/al-folio#2774.
103
+ {% endcomment %}
104
+ {% if site.apple_touch_icon and site.apple_touch_icon != '' %}
105
+ {% assign apple_touch_icon = site.apple_touch_icon %}
106
+ {% elsif site.icon and site.icon.size > 4 %}
107
+ {% assign icon_extension = site.icon | split: '.' | last | split: '?' | first | downcase %}
108
+ {% if icon_extension == 'png' or icon_extension == 'jpg' or icon_extension == 'jpeg' %}
109
+ {% assign apple_touch_icon = site.icon %}
110
+ {% endif %}
111
+ {% endif %}
112
+ {% if apple_touch_icon %}
113
+ {% if apple_touch_icon contains '://' %}
114
+ {% assign apple_touch_icon_url = apple_touch_icon %}
115
+ {% elsif apple_touch_icon contains '/' %}
116
+ {% assign apple_touch_icon_url = apple_touch_icon | relative_url | bust_file_cache %}
117
+ {% else %}
118
+ {% assign apple_touch_icon_url = apple_touch_icon | prepend: '/assets/img/' | relative_url | bust_file_cache %}
119
+ {% endif %}
120
+ <link rel="apple-touch-icon" href="{{ apple_touch_icon_url }}">
121
+ {% endif %}
88
122
  <link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url | bust_css_cache }}">
89
123
  {% if page.layout == 'cv' and site.plugins contains 'al_folio_cv' and site.al_folio.features.cv.enabled != false %}
90
124
  <link rel="stylesheet" href="{{ '/assets/css/al-folio-cv.css' | relative_url | bust_file_cache }}">
@@ -157,3 +191,18 @@
157
191
  <!-- Cookie Consent -->
158
192
  {% include plugins/al_cookie_styles.liquid %}
159
193
  {% endif %}
194
+
195
+ {% if site.plugins contains 'al_rtl' %}
196
+ <!-- Right-to-left support -->
197
+ {% include plugins/al_rtl_styles.liquid %}
198
+ {% endif %}
199
+
200
+ {% if site.protect_email and site.plugins contains 'al_email_protect' %}
201
+ <!-- Email obfuscation -->
202
+ {% include plugins/al_email_protect_styles.liquid %}
203
+ {% endif %}
204
+
205
+ {% if page.marimo and site.plugins contains 'al_marimo' %}
206
+ <!-- Marimo notebooks -->
207
+ {% include plugins/al_marimo_styles.liquid %}
208
+ {% endif %}
@@ -0,0 +1,4 @@
1
+ {% comment %}
2
+ Parse-safe wrapper for al_email_protect custom tag.
3
+ {% endcomment %}
4
+ {% al_email_protect_scripts %}
@@ -0,0 +1,4 @@
1
+ {% comment %}
2
+ Parse-safe wrapper for al_email_protect custom tag.
3
+ {% endcomment %}
4
+ {% al_email_protect_styles %}
@@ -0,0 +1,4 @@
1
+ {% comment %}
2
+ Parse-safe wrapper for al_marimo custom tag.
3
+ {% endcomment %}
4
+ {% al_marimo_scripts %}
@@ -0,0 +1,4 @@
1
+ {% comment %}
2
+ Parse-safe wrapper for al_marimo custom tag.
3
+ {% endcomment %}
4
+ {% al_marimo_styles %}
@@ -0,0 +1,7 @@
1
+ {%- comment -%}
2
+ Parse-safe wrapper for al_rtl custom tag.
3
+
4
+ Whitespace-controlled: the output of this include lands *inside* the <html>
5
+ tag, so a stray newline would sit between the tag name and its attributes.
6
+ {%- endcomment -%}
7
+ {%- al_rtl_html_attrs -%}
@@ -0,0 +1,4 @@
1
+ {% comment %}
2
+ Parse-safe wrapper for al_rtl custom tag.
3
+ {% endcomment %}
4
+ {% al_rtl_styles %}
@@ -142,3 +142,13 @@
142
142
  {% include plugins/al_newsletter_scripts.liquid %}
143
143
  {% endif %}
144
144
  {% endif %}
145
+
146
+ {% if site.protect_email and site.plugins contains 'al_email_protect' %}
147
+ <!-- Email obfuscation -->
148
+ {% include plugins/al_email_protect_scripts.liquid %}
149
+ {% endif %}
150
+
151
+ {% if page.marimo and site.plugins contains 'al_marimo' %}
152
+ <!-- Marimo notebooks -->
153
+ {% include plugins/al_marimo_scripts.liquid %}
154
+ {% endif %}
@@ -1,7 +1,12 @@
1
- {% assign extension = include.path | split: '.' | last %}
1
+ {%- comment -%}
2
+ Normalize the extension before matching: strip any query string (`clip.mp4?raw=1`)
3
+ and lower-case it (`CLIP.MP4`), otherwise a perfectly good video file falls through
4
+ to the <iframe> branch below and renders as an empty frame.
5
+ {%- endcomment -%}
6
+ {% assign extension = include.path | split: '.' | last | split: '?' | first | downcase %}
2
7
 
3
8
  <figure>
4
- {% if extension == 'mp4' or extension == 'webm' or extension == 'ogg' %}
9
+ {% if extension == 'mp4' or extension == 'webm' or extension == 'ogg' or extension == 'mov' %}
5
10
  <video
6
11
  src="{% if include.cache_bust %}{{ include.path | relative_url | bust_file_cache }}{% else %}{{ include.path | relative_url }}{% endif %}"
7
12
  {% if include.class %}
data/_layouts/bib.liquid CHANGED
@@ -26,7 +26,23 @@
26
26
  {% endif %}
27
27
  {% endif %}
28
28
  {% if entry.preview %}
29
- {% if entry.preview contains '://' %}
29
+ {%- comment -%}
30
+ A preview may be a video file rather than an image. Rendering one through the
31
+ image path below produces a broken <img>, so hand it to video.liquid instead.
32
+ Keep this list in sync with the native-video branch of _includes/video.liquid:
33
+ an extension it does not recognize falls through to its <iframe> branch.
34
+ See alshedivat/al-folio#3564.
35
+ {%- endcomment -%}
36
+ {% assign preview_video_extensions = 'mp4,webm,ogg,mov' | split: ',' %}
37
+ {% assign preview_extension = entry.preview | split: '.' | last | split: '?' | first | downcase %}
38
+ {% if preview_video_extensions contains preview_extension %}
39
+ {% if entry.preview contains '://' %}
40
+ {% assign preview_video_path = entry.preview %}
41
+ {% else %}
42
+ {% assign preview_video_path = entry.preview | prepend: '/assets/img/publication_preview/' %}
43
+ {% endif %}
44
+ {% include video.liquid path=preview_video_path class="preview z-depth-1 rounded" controls=true %}
45
+ {% elsif entry.preview contains '://' %}
30
46
  <img class="preview z-depth-1 rounded" src="{{ entry.preview }}">
31
47
  {% else %}
32
48
  {% assign entry_path = entry.preview | prepend: '/assets/img/publication_preview/' %}
@@ -381,7 +397,7 @@
381
397
  <div class="bibtex hidden">
382
398
  {% highlight bibtex %}
383
399
  {{- entry.bibtex | hideCustomBibtex -}}
384
- {% endhighlight %}
400
+ {% endhighlight %}
385
401
  </div>
386
402
  {% endif %}
387
403
 
@@ -1,5 +1,22 @@
1
1
  <!doctype html>
2
- <html lang="{{ site.lang }}">
2
+ {%- comment -%}
3
+ al_rtl owns the language and direction attributes when it is installed, because
4
+ `dir` has to sit on <html> for the browser's bidi handling, CSS logical
5
+ properties and Tailwind's rtl: variant to apply to the whole document.
6
+
7
+ Captured into a variable rather than wrapping the <html> tag in a conditional:
8
+ a conditional there stops the tag being a single static element, and Prettier
9
+ then re-indents the entire document body. The guard keeps this parse-safe —
10
+ without the plugin the tag does not exist and Liquid fails on every page.
11
+ {%- endcomment -%}
12
+ {%- capture html_attributes -%}
13
+ {%- if site.plugins contains 'al_rtl' -%}
14
+ {%- include plugins/al_rtl_html_attrs.liquid -%}
15
+ {%- else -%}
16
+ lang="{{ site.lang }}"
17
+ {%- endif -%}
18
+ {%- endcapture -%}
19
+ <html {{ html_attributes }}>
3
20
  <!-- Head -->
4
21
  <head>
5
22
  {% if page.redirect %}
@@ -43,6 +43,14 @@
43
43
  display: inline-block;
44
44
  }
45
45
 
46
+ // Video previews have no intrinsic responsive sizing the way <img> does, so
47
+ // without this a <video class="preview"> falls back to its 300x150 default and
48
+ // overflows the thumbnail column.
49
+ video.preview {
50
+ max-width: 100%;
51
+ height: auto;
52
+ }
53
+
46
54
  .abbr {
47
55
  margin-bottom: 0.5rem;
48
56
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AlFolioCore
4
- VERSION = "1.0.12"
4
+ VERSION = "1.0.14"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: al_folio_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.12
4
+ version: 1.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - al-folio maintainers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-29 00:00:00.000000000 Z
11
+ date: 2026-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -117,15 +117,21 @@ files:
117
117
  - _includes/plugins/al_comments.liquid
118
118
  - _includes/plugins/al_cookie_scripts.liquid
119
119
  - _includes/plugins/al_cookie_styles.liquid
120
+ - _includes/plugins/al_email_protect_scripts.liquid
121
+ - _includes/plugins/al_email_protect_styles.liquid
120
122
  - _includes/plugins/al_icons_styles.liquid
121
123
  - _includes/plugins/al_img_tools_scripts.liquid
122
124
  - _includes/plugins/al_img_tools_styles.liquid
125
+ - _includes/plugins/al_marimo_scripts.liquid
126
+ - _includes/plugins/al_marimo_styles.liquid
123
127
  - _includes/plugins/al_math_scripts.liquid
124
128
  - _includes/plugins/al_math_styles.liquid
125
129
  - _includes/plugins/al_newsletter_form_center.liquid
126
130
  - _includes/plugins/al_newsletter_form_center_margin.liquid
127
131
  - _includes/plugins/al_newsletter_form_left.liquid
128
132
  - _includes/plugins/al_newsletter_scripts.liquid
133
+ - _includes/plugins/al_rtl_html_attrs.liquid
134
+ - _includes/plugins/al_rtl_styles.liquid
129
135
  - _includes/plugins/al_search_assets.liquid
130
136
  - _includes/projects.liquid
131
137
  - _includes/projects_horizontal.liquid