jekyll-github-card 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0037bdb90e0651931f5719d6ac712d4e00cd62b88c404a11125a3682ab520f46
4
+ data.tar.gz: daaf2b1760e8d90eabd0426a8a972254805c2a19969cb60da5e8933962d7071c
5
+ SHA512:
6
+ metadata.gz: ab458fb8109ae7b4b9c66b3cc809fdfc15aafafaecef3a5c57807c16e0d387305b15a8b896b13563e30979d11b6beaea9c75699a87a7629bb6d84c37fef8f814
7
+ data.tar.gz: 8c13daffa7a93ea45db4956000a11d0e3198accefbc4525c111e5be27b82ab06f643fb78975f69f89b716fe897dda4735f0fe9cb9964aa013153c08f5a823dd9
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rodolfo Olivieri
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,61 @@
1
+ # Jekyll GitHub Card
2
+
3
+ A beautiful Jekyll plugin to display GitHub repository cards with live data from the GitHub API.
4
+
5
+ ## Features
6
+
7
+ - 🎨 Beautiful, responsive GitHub repository cards
8
+ - 🌙 Dark mode support (works perfectly with Chirpy theme)
9
+ - 📊 Live data from GitHub API (stars, forks, language)
10
+ - âš¡ Easy to use with simple Liquid tag
11
+ - 🎯 No configuration needed
12
+
13
+ ## Installation
14
+
15
+ Add this line to your Jekyll site's `Gemfile`:
16
+
17
+ ```ruby
18
+ gem 'jekyll-github-card'
19
+ ```
20
+
21
+ And then add this to your `_config.yml`:
22
+
23
+ ```yaml
24
+ plugins:
25
+ - jekyll-github-card
26
+ ```
27
+
28
+ Finally, add these lines to your layout file (e.g., `_layouts/default.html` or `_layouts/post.html`):
29
+
30
+ ```html
31
+ <head>
32
+ <!-- ... other head content ... -->
33
+ <link rel="stylesheet" href="{{ '/assets/css/github-card.css' | relative_url }}">
34
+ <script src="{{ '/assets/js/github-card.js' | relative_url }}"></script>
35
+ </head>
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ In your markdown posts or pages:
41
+
42
+ ```liquid
43
+ {% github facebook/react %}
44
+
45
+ {% github torvalds/linux %}
46
+ ```
47
+
48
+ ## Compatibility
49
+
50
+ - Jekyll 3.7+
51
+ - Ruby 2.6+
52
+ - Works with Chirpy theme and most Jekyll themes
53
+ - Supports both light and dark modes
54
+
55
+ ## GitHub API Rate Limiting
56
+
57
+ The plugin uses the public GitHub API which allows 60 requests per hour without authentication. For higher limits, you can add a personal access token in your JavaScript if needed.
58
+
59
+ ## License
60
+
61
+ MIT License - see LICENSE file for details
@@ -0,0 +1,123 @@
1
+ /* Base styles (defaults to dark mode for Chirpy) */
2
+ .github-card {
3
+ background: #0d1117;
4
+ border: 1px solid #30363d;
5
+ border-radius: 6px;
6
+ padding: 16px;
7
+ max-width: 400px;
8
+ transition: box-shadow 0.2s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
9
+ text-decoration: none;
10
+ display: block;
11
+ color: #e6edf3;
12
+ margin: 20px 0;
13
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
14
+ }
15
+
16
+ .github-card:hover {
17
+ box-shadow: 0 3px 12px rgba(0, 0, 0, 0.4);
18
+ border-color: #484f58;
19
+ }
20
+
21
+ .github-card.loading {
22
+ min-height: 120px;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ color: #8b949e;
27
+ }
28
+
29
+ .github-card .card-header {
30
+ display: flex;
31
+ align-items: center;
32
+ gap: 8px;
33
+ margin-bottom: 8px;
34
+ }
35
+
36
+ .github-card .github-icon {
37
+ width: 20px;
38
+ height: 20px;
39
+ fill: #8b949e;
40
+ flex-shrink: 0;
41
+ transition: fill 0.2s ease;
42
+ }
43
+
44
+ .github-card .repo-name {
45
+ font-size: 14px;
46
+ font-weight: 600;
47
+ color: #58a6ff;
48
+ margin: 0;
49
+ transition: color 0.2s ease;
50
+ }
51
+
52
+ .github-card .description {
53
+ font-size: 12px;
54
+ color: #8b949e;
55
+ margin: 8px 0 12px 0;
56
+ line-height: 1.5;
57
+ transition: color 0.2s ease;
58
+ }
59
+
60
+ .github-card .card-footer {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 16px;
64
+ font-size: 12px;
65
+ color: #8b949e;
66
+ flex-wrap: wrap;
67
+ transition: color 0.2s ease;
68
+ }
69
+
70
+ .github-card .stat {
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 4px;
74
+ }
75
+
76
+ .github-card .language-dot {
77
+ width: 12px;
78
+ height: 12px;
79
+ border-radius: 50%;
80
+ display: inline-block;
81
+ }
82
+
83
+ .github-card .error-message {
84
+ color: #f85149;
85
+ font-size: 12px;
86
+ transition: color 0.2s ease;
87
+ }
88
+
89
+ /* Light mode override for Chirpy theme */
90
+ html[data-mode="light"] .github-card {
91
+ background: #ffffff;
92
+ border-color: #d0d7de;
93
+ color: #1f2328;
94
+ }
95
+
96
+ html[data-mode="light"] .github-card:hover {
97
+ box-shadow: 0 3px 12px rgba(0, 0, 0, 0.1);
98
+ border-color: #c0c7ce;
99
+ }
100
+
101
+ html[data-mode="light"] .github-card .github-icon {
102
+ fill: #656d76;
103
+ }
104
+
105
+ html[data-mode="light"] .github-card .repo-name {
106
+ color: #0969da;
107
+ }
108
+
109
+ html[data-mode="light"] .github-card .description {
110
+ color: #656d76;
111
+ }
112
+
113
+ html[data-mode="light"] .github-card .card-footer {
114
+ color: #656d76;
115
+ }
116
+
117
+ html[data-mode="light"] .github-card.loading {
118
+ color: #656d76;
119
+ }
120
+
121
+ html[data-mode="light"] .github-card .error-message {
122
+ color: #cf222e;
123
+ }
@@ -0,0 +1,104 @@
1
+ window.createGitHubCard = async function(elementId, repo) {
2
+ const element = document.getElementById(elementId);
3
+
4
+ if (!element) {
5
+ console.error('GitHub Card: Element with id "' + elementId + '" not found');
6
+ return;
7
+ }
8
+
9
+ element.className = 'github-card loading';
10
+ element.innerHTML = 'Loading repository...';
11
+
12
+ try {
13
+ const response = await fetch('https://api.github.com/repos/' + repo);
14
+
15
+ if (!response.ok) {
16
+ throw new Error('Repository not found');
17
+ }
18
+
19
+ const data = await response.json();
20
+
21
+ function formatCount(count) {
22
+ if (count >= 1000) {
23
+ return (count / 1000).toFixed(1) + 'k';
24
+ }
25
+ return count.toString();
26
+ }
27
+
28
+ const languageColors = {
29
+ 'JavaScript': '#f1e05a',
30
+ 'TypeScript': '#3178c6',
31
+ 'Python': '#3572A5',
32
+ 'Java': '#b07219',
33
+ 'Ruby': '#701516',
34
+ 'Go': '#00ADD8',
35
+ 'Rust': '#dea584',
36
+ 'C++': '#f34b7d',
37
+ 'C': '#555555',
38
+ 'PHP': '#4F5D95',
39
+ 'Swift': '#F05138',
40
+ 'Kotlin': '#A97BFF',
41
+ 'HTML': '#e34c26',
42
+ 'CSS': '#563d7c',
43
+ 'Shell': '#89e051',
44
+ 'Dart': '#00B4AB',
45
+ 'Scala': '#c22d40'
46
+ };
47
+
48
+ const languageColor = languageColors[data.language] || '#858585';
49
+
50
+ function escapeHtml(text) {
51
+ const div = document.createElement('div');
52
+ div.textContent = text;
53
+ return div.innerHTML;
54
+ }
55
+
56
+ element.className = 'github-card';
57
+ element.innerHTML =
58
+ '<div class="card-header">' +
59
+ '<svg class="github-icon" viewBox="0 0 16 16">' +
60
+ '<path d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>' +
61
+ '</svg>' +
62
+ '<h3 class="repo-name">' + escapeHtml(data.full_name) + '</h3>' +
63
+ '</div>' +
64
+ '<p class="description">' +
65
+ escapeHtml(data.description || 'No description provided') +
66
+ '</p>' +
67
+ '<div class="card-footer">' +
68
+ '<span class="stat">' +
69
+ '<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">' +
70
+ '<path d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z"></path>' +
71
+ '</svg>' +
72
+ formatCount(data.stargazers_count) +
73
+ '</span>' +
74
+ '<span class="stat">' +
75
+ '<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">' +
76
+ '<path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75v-.878a2.25 2.25 0 111.5 0v.878a2.25 2.25 0 01-2.25 2.25h-1.5v2.128a2.251 2.251 0 11-1.5 0V8.5h-1.5A2.25 2.25 0 013 6.25v-.878a2.25 2.25 0 111.5 0zM5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm6.75.75a.75.75 0 100-1.5.75.75 0 000 1.5zm-3 8.75a.75.75 0 11-1.5 0 .75.75 0 011.5 0z"></path>' +
77
+ '</svg>' +
78
+ formatCount(data.forks_count) +
79
+ '</span>' +
80
+ (data.language ?
81
+ '<span class="stat">' +
82
+ '<span class="language-dot" style="background-color: ' + languageColor + ';"></span>' +
83
+ escapeHtml(data.language) +
84
+ '</span>'
85
+ : '') +
86
+ '</div>';
87
+
88
+ element.style.cursor = 'pointer';
89
+ element.onclick = function() {
90
+ window.open(data.html_url, '_blank');
91
+ };
92
+
93
+ } catch (error) {
94
+ element.className = 'github-card';
95
+ element.innerHTML = '<p class="error-message">Failed to load repository: ' + escapeHtml(repo) + '</p>';
96
+ console.error('GitHub Card Error:', error);
97
+ }
98
+
99
+ function escapeHtml(text) {
100
+ const div = document.createElement('div');
101
+ div.textContent = text;
102
+ return div.innerHTML;
103
+ }
104
+ };
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "jekyll-github-card/version"
4
+
5
+ module Jekyll
6
+ module GitHubCard
7
+ class Error < StandardError; end
8
+
9
+ # Tag for {% github owner/repo %}
10
+ class GitHubCardTag < Liquid::Tag
11
+ def initialize(tag_name, text, tokens)
12
+ super
13
+ @repo = text.strip
14
+ end
15
+
16
+ def render(context)
17
+ # Generate a unique ID from the repo name
18
+ id = @repo.gsub('/', '-').gsub(/[^a-zA-Z0-9\-]/, '')
19
+
20
+ <<~HTML
21
+ <div id="github-card-#{id}" class="github-card loading">Loading repository...</div>
22
+ <script>
23
+ (function() {
24
+ function initCard() {
25
+ if (typeof createGitHubCard === 'function') {
26
+ createGitHubCard('github-card-#{id}', '#{@repo}');
27
+ } else {
28
+ setTimeout(initCard, 100);
29
+ }
30
+ }
31
+
32
+ if (document.readyState === 'loading') {
33
+ document.addEventListener('DOMContentLoaded', initCard);
34
+ } else {
35
+ initCard();
36
+ }
37
+ })();
38
+ </script>
39
+ HTML
40
+ end
41
+ end
42
+
43
+ # Generator to copy assets to site
44
+ class AssetsGenerator < Jekyll::Generator
45
+ safe true
46
+ priority :low
47
+
48
+ def generate(site)
49
+ # Get the gem's asset directory
50
+ gem_dir = File.expand_path("../../", __dir__)
51
+ assets_dir = File.join(gem_dir, "assets")
52
+
53
+ return unless File.directory?(assets_dir)
54
+
55
+ # Copy CSS
56
+ css_source = File.join(assets_dir, "css", "github-card.css")
57
+ css_dest = File.join(site.source, "assets", "css", "github-card.css")
58
+
59
+ if File.exist?(css_source)
60
+ FileUtils.mkdir_p(File.dirname(css_dest))
61
+ FileUtils.cp(css_source, css_dest)
62
+ site.static_files << Jekyll::StaticFile.new(
63
+ site,
64
+ site.source,
65
+ "assets/css",
66
+ "github-card.css"
67
+ )
68
+ end
69
+
70
+ # Copy JS
71
+ js_source = File.join(assets_dir, "js", "github-card.js")
72
+ js_dest = File.join(site.source, "assets", "js", "github-card.js")
73
+
74
+ if File.exist?(js_source)
75
+ FileUtils.mkdir_p(File.dirname(js_dest))
76
+ FileUtils.cp(js_source, js_dest)
77
+ site.static_files << Jekyll::StaticFile.new(
78
+ site,
79
+ site.source,
80
+ "assets/js",
81
+ "github-card.js"
82
+ )
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ Liquid::Template.register_tag('github', Jekyll::GitHubCard::GitHubCardTag)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module GitHubCard
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-github-card
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rodolfo Olivieri
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 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: '3.7'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '5.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '3.7'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '5.0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: bundler
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '2.0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - "~>"
44
+ - !ruby/object:Gem::Version
45
+ version: '2.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '13.0'
53
+ type: :development
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '13.0'
60
+ description: Add beautiful, responsive GitHub repository cards to your Jekyll blog
61
+ with live data from the GitHub API. Supports dark mode and works seamlessly with
62
+ Jekyll themes like Chirpy.
63
+ email:
64
+ - rodolfo.olivieri3@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - LICENSE
70
+ - README.md
71
+ - assets/css/github-card.css
72
+ - assets/js/github-card.js
73
+ - lib/jekyll-github-card/jekyll-github-card.rb
74
+ - lib/jekyll-github-card/version.rb
75
+ homepage: https://github.com/r0x0d/jekyll-github-card
76
+ licenses:
77
+ - MIT
78
+ metadata:
79
+ homepage_uri: https://github.com/r0x0d/jekyll-github-card
80
+ source_code_uri: https://github.com/r0x0d/jekyll-github-card
81
+ changelog_uri: https://github.com/r0x0d/jekyll-github-card/blob/main/CHANGELOG.md
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 2.6.0
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubygems_version: 3.6.9
97
+ specification_version: 4
98
+ summary: A Jekyll plugin to display beautiful GitHub repository cards
99
+ test_files: []