jekyll-timeline 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +17 -0
- data/CONTRIBUTING.md +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +124 -0
- data/lib/jekyll/timeline_tag.rb +100 -0
- data/lib/jekyll-timeline.rb +4 -0
- metadata +67 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 6ba528cce1ef2c9f28ba15637bb84e820e0daa26cef50676d47ed500d732cf01
|
|
4
|
+
data.tar.gz: 314be5deed55191ada292275d17b0a0ef3e3af3416d3c1613c517c493235134d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c427bda6e18cfbd29b8c30f9553ac6f249030f6fc2ad83993d7c4762a3deda4763c4ab120c2eecaad009fc6c8d22f13e6fe6c12451aab0bbd11c90de86b386d8
|
|
7
|
+
data.tar.gz: 2c8593e301ba653a05f14530ea3d6b6ea1a5359fb7de9caa2bf989210b3aaf587624b4925b598888e505e2b8b11b6f57b6848f000eabcc8437762dc9b190b704
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-08-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release
|
|
12
|
+
- `{% timeline %}` / `{% endtimeline %}` outer block tag
|
|
13
|
+
- `{% event %}` / `{% endevent %}` inner block tag with `date`, `title`, `icon`, `color` attributes
|
|
14
|
+
- `order="asc"` (default) and `order="desc"` sort support
|
|
15
|
+
- Icon support: Font Awesome classes, emoji, plain text, or empty dot fallback
|
|
16
|
+
- `timeline.default_icon_prefix` config option (default: `fa-solid`)
|
|
17
|
+
- Pure HTML+CSS output — no JavaScript, no external dependencies
|
data/CONTRIBUTING.md
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jason Chance
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# jekyll-timeline
|
|
2
|
+
|
|
3
|
+
A Jekyll plugin providing `{% timeline %}` and `{% timeline_event %}` block tags that render a vertical timeline component. Pure HTML+CSS output — no JavaScript, no external dependencies.
|
|
4
|
+
|
|
5
|
+
[](https://rubygems.org/gems/jekyll-timeline)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add to your `Gemfile`:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem "jekyll-timeline"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Add to `_config.yml`:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
plugins:
|
|
19
|
+
- jekyll-timeline
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Run `bundle install`.
|
|
23
|
+
|
|
24
|
+
Copy `_timeline.scss` from the gem into your site's SCSS directory and import it:
|
|
25
|
+
|
|
26
|
+
```scss
|
|
27
|
+
@import "timeline";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
Wrap events in a `{% timeline %}` block. Each `{% timeline_event %}` block is one entry.
|
|
33
|
+
|
|
34
|
+
```liquid
|
|
35
|
+
{% timeline %}
|
|
36
|
+
|
|
37
|
+
{% timeline_event date="January 2024" title="Project launched" icon="fa-rocket" %}
|
|
38
|
+
We shipped the first public release after six months of development.
|
|
39
|
+
{% endtimeline_event %}
|
|
40
|
+
|
|
41
|
+
{% timeline_event date="March 2024" title="1,000 users" icon="fa-users" color="#2ecc71" %}
|
|
42
|
+
Crossed 1,000 active users. Added team management features.
|
|
43
|
+
{% endtimeline_event %}
|
|
44
|
+
|
|
45
|
+
{% timeline_event date="June 2024" title="v2.0 released" icon="fa-bolt" %}
|
|
46
|
+
Complete rewrite with improved performance and a new API.
|
|
47
|
+
{% endtimeline_event %}
|
|
48
|
+
|
|
49
|
+
{% endtimeline %}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Reverse order
|
|
53
|
+
|
|
54
|
+
```liquid
|
|
55
|
+
{% timeline order="desc" %}
|
|
56
|
+
...
|
|
57
|
+
{% endtimeline %}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Event attributes
|
|
61
|
+
|
|
62
|
+
| Attribute | Required | Description |
|
|
63
|
+
|-----------|----------|-------------|
|
|
64
|
+
| `date` | No | Display date string (any format — it's not parsed) |
|
|
65
|
+
| `title` | No | Event headline |
|
|
66
|
+
| `icon` | No | Icon class(es), emoji, or plain text. Omit for dot fallback. |
|
|
67
|
+
| `color` | No | CSS color value for this event's icon background |
|
|
68
|
+
|
|
69
|
+
### Icon formats
|
|
70
|
+
|
|
71
|
+
**Font Awesome classes** — pass one or two CSS classes:
|
|
72
|
+
|
|
73
|
+
```liquid
|
|
74
|
+
{% timeline_event icon="fa-rocket" %} <!-- uses default_icon_prefix -->
|
|
75
|
+
{% timeline_event icon="fa-solid fa-rocket" %} <!-- explicit style -->
|
|
76
|
+
{% timeline_event icon="fa-brands fa-github" %}
|
|
77
|
+
{% timeline_event icon="fa-duotone fa-star" %} <!-- FA Pro -->
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Emoji:**
|
|
81
|
+
|
|
82
|
+
```liquid
|
|
83
|
+
{% timeline_event icon="🚀" %}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**No icon** — omit the attribute entirely for a neutral dot:
|
|
87
|
+
|
|
88
|
+
```liquid
|
|
89
|
+
{% timeline_event date="2024" title="Something happened" %}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Configuration
|
|
93
|
+
|
|
94
|
+
All options are optional:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
timeline:
|
|
98
|
+
default_icon_prefix: "fa-solid" # prepended when icon has no spaces (default: fa-solid)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Styling
|
|
102
|
+
|
|
103
|
+
Copy `_timeline.scss` into your site and customize via CSS custom properties:
|
|
104
|
+
|
|
105
|
+
```css
|
|
106
|
+
:root {
|
|
107
|
+
--timeline-line-color: #dee2e6; /* vertical line color */
|
|
108
|
+
--timeline-icon-bg: #6c757d; /* default icon circle background */
|
|
109
|
+
--timeline-icon-color: #fff; /* icon/emoji color */
|
|
110
|
+
--timeline-date-color: #6c757d; /* date label color */
|
|
111
|
+
--timeline-title-color: inherit; /* event title color */
|
|
112
|
+
--timeline-body-color: inherit; /* body text color */
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Per-event color override via the `color=` attribute sets `--timeline-event-color` inline on that event, overriding `--timeline-icon-bg` for that circle only.
|
|
117
|
+
|
|
118
|
+
## GitHub Pages compatibility
|
|
119
|
+
|
|
120
|
+
Compatible with GitHub Pages when built via a custom GitHub Actions workflow. Not compatible with the default GitHub Pages safe-mode build.
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require "jekyll"
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
TIMELINE_ATTR_RE = /(\w+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+))/
|
|
5
|
+
|
|
6
|
+
def self.parse_attrs(markup)
|
|
7
|
+
attrs = {}
|
|
8
|
+
markup.scan(TIMELINE_ATTR_RE) do |key, dq, sq, bare|
|
|
9
|
+
attrs[key] = dq || sq || bare || ""
|
|
10
|
+
end
|
|
11
|
+
attrs
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Inner block tag — registered so Liquid knows about it.
|
|
15
|
+
# When rendered standalone (excerpt, search.json), outputs nothing silently.
|
|
16
|
+
# When rendered inside {% timeline %}, its output is collected by the outer tag.
|
|
17
|
+
class TimelineEventTag < Liquid::Block
|
|
18
|
+
def initialize(tag_name, markup, tokens)
|
|
19
|
+
super
|
|
20
|
+
@attributes = Jekyll.parse_attrs(markup)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def render(context)
|
|
24
|
+
site = context.registers[:site]
|
|
25
|
+
config = site.config["timeline"] || {}
|
|
26
|
+
default_prefix = config["default_icon_prefix"] || "fa-solid"
|
|
27
|
+
|
|
28
|
+
content = super.strip
|
|
29
|
+
|
|
30
|
+
rendered_content = begin
|
|
31
|
+
converter = site.find_converter_instance(Jekyll::Converters::Markdown)
|
|
32
|
+
converter.convert(content)
|
|
33
|
+
rescue StandardError
|
|
34
|
+
content
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
date = @attributes["date"] || ""
|
|
38
|
+
title = @attributes["title"] || ""
|
|
39
|
+
icon = @attributes["icon"]
|
|
40
|
+
color = @attributes["color"]
|
|
41
|
+
|
|
42
|
+
color_style = color ? %( style="--timeline-event-color: #{color};") : ""
|
|
43
|
+
|
|
44
|
+
icon_html = if icon.nil? || icon.strip.empty?
|
|
45
|
+
'<span class="timeline__icon timeline__icon--empty"></span>'
|
|
46
|
+
elsif !icon.match?(/[a-zA-Z]/) || (icon.length <= 4 && !icon.include?("-"))
|
|
47
|
+
%(<span class="timeline__icon timeline__icon--text">#{icon}</span>)
|
|
48
|
+
else
|
|
49
|
+
classes = icon.include?(" ") ? icon : "#{default_prefix} #{icon}"
|
|
50
|
+
%(<span class="timeline__icon"><i class="#{classes}" aria-hidden="true"></i></span>)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
html = <<~HTML
|
|
54
|
+
<div class="timeline__event"#{color_style}>
|
|
55
|
+
#{icon_html}
|
|
56
|
+
<div class="timeline__content">
|
|
57
|
+
<div class="timeline__date">#{date}</div>
|
|
58
|
+
<div class="timeline__title">#{title}</div>
|
|
59
|
+
<div class="timeline__body">#{rendered_content.strip}</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
HTML
|
|
63
|
+
|
|
64
|
+
# If inside a timeline, accumulate; otherwise silently drop
|
|
65
|
+
if context.registers[:timeline_events]
|
|
66
|
+
context.registers[:timeline_events] << html.strip
|
|
67
|
+
end
|
|
68
|
+
""
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Outer block tag
|
|
73
|
+
class TimelineTag < Liquid::Block
|
|
74
|
+
def initialize(tag_name, markup, tokens)
|
|
75
|
+
super
|
|
76
|
+
@attributes = Jekyll.parse_attrs(markup)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def render(context)
|
|
80
|
+
context.registers[:timeline_events] = []
|
|
81
|
+
super
|
|
82
|
+
|
|
83
|
+
events = context.registers[:timeline_events] || []
|
|
84
|
+
order = @attributes["order"] || "asc"
|
|
85
|
+
events = events.reverse if order == "desc"
|
|
86
|
+
|
|
87
|
+
# Clean up so nested timelines don't bleed
|
|
88
|
+
context.registers[:timeline_events] = nil
|
|
89
|
+
|
|
90
|
+
<<~HTML
|
|
91
|
+
<div class="timeline">
|
|
92
|
+
#{events.join("\n ")}
|
|
93
|
+
</div>
|
|
94
|
+
HTML
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
Liquid::Template.register_tag("timeline_event", Jekyll::TimelineEventTag)
|
|
100
|
+
Liquid::Template.register_tag("timeline", Jekyll::TimelineTag)
|
metadata
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jekyll-timeline
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jason Chance
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-08-22 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: jekyll
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '4.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '4.0'
|
|
26
|
+
description: A Jekyll plugin providing {% timeline %} and {% event %} block tags that
|
|
27
|
+
render a vertical timeline component. Pure HTML+CSS output — no JavaScript, no external
|
|
28
|
+
dependencies. Supports icon libraries (Font Awesome, emoji, or plain text) and per-event
|
|
29
|
+
color customization.
|
|
30
|
+
email:
|
|
31
|
+
- jchance@gmail.com
|
|
32
|
+
executables: []
|
|
33
|
+
extensions: []
|
|
34
|
+
extra_rdoc_files: []
|
|
35
|
+
files:
|
|
36
|
+
- CHANGELOG.md
|
|
37
|
+
- CONTRIBUTING.md
|
|
38
|
+
- LICENSE.txt
|
|
39
|
+
- README.md
|
|
40
|
+
- lib/jekyll-timeline.rb
|
|
41
|
+
- lib/jekyll/timeline_tag.rb
|
|
42
|
+
homepage: https://jasonchance.com/projects/jekyll-timeline/
|
|
43
|
+
licenses:
|
|
44
|
+
- MIT
|
|
45
|
+
metadata:
|
|
46
|
+
homepage_uri: https://jasonchance.com/projects/jekyll-timeline/
|
|
47
|
+
source_code_uri: https://github.com/jchance/jekyll-timeline
|
|
48
|
+
changelog_uri: https://github.com/jchance/jekyll-timeline/blob/main/CHANGELOG.md
|
|
49
|
+
bug_tracker_uri: https://github.com/jchance/jekyll-timeline/issues
|
|
50
|
+
rdoc_options: []
|
|
51
|
+
require_paths:
|
|
52
|
+
- lib
|
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '3.0'
|
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
requirements: []
|
|
64
|
+
rubygems_version: 3.6.2
|
|
65
|
+
specification_version: 4
|
|
66
|
+
summary: Jekyll Liquid tags for rendering a pure HTML/CSS vertical timeline
|
|
67
|
+
test_files: []
|