Skip to content

Commit 85b4b7b

Browse files
committed
Add opengraph preview for audit post
Signed-off-by: Samuel Giddins <segiddins@segiddins.me>
1 parent 7c4ba27 commit 85b4b7b

File tree

7 files changed

+185
-0
lines changed

7 files changed

+185
-0
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ ruby file: ".ruby-version"
44
gem "base64", "~> 0.2.0"
55
gem "bigdecimal", "~> 3.1"
66
gem "csv", "~> 3.3"
7+
gem "grover", "~> 1.2"
78
gem "jekyll", "~> 4.0"
89
gem "puma", "~> 6.4"
910
gem "rack-jekyll", "~> 0.5.0", github: "adaoraul/rack-jekyll"

Gemfile.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ GEM
2626
google-protobuf (4.27.5)
2727
bigdecimal
2828
rake (>= 13)
29+
grover (1.2.1)
30+
nokogiri (~> 1)
2931
http_parser.rb (0.8.0)
3032
i18n (1.14.4)
3133
concurrent-ruby (~> 1.0)
34+
imgkit (1.6.3)
3235
jekyll (4.3.3)
3336
addressable (~> 2.4)
3437
colorator (~> 1.0)
@@ -58,12 +61,17 @@ GEM
5861
rb-fsevent (~> 0.10, >= 0.10.3)
5962
rb-inotify (~> 0.9, >= 0.9.10)
6063
mercenary (0.4.0)
64+
mini_portile2 (2.8.8)
6165
nio4r (2.7.3)
66+
nokogiri (1.17.1)
67+
mini_portile2 (~> 2.8.2)
68+
racc (~> 1.4)
6269
pathutil (0.16.2)
6370
forwardable-extended (~> 2.6)
6471
public_suffix (5.0.5)
6572
puma (6.4.3)
6673
nio4r (~> 2.0)
74+
racc (1.8.1)
6775
rack (3.0.10)
6876
rake (13.2.0)
6977
rb-fsevent (0.11.2)
@@ -84,6 +92,7 @@ GEM
8492
unicode-display_width (>= 1.1.1, < 3)
8593
unicode-display_width (2.5.0)
8694
webrick (1.8.2)
95+
wkhtmltoimage-binary (0.12.5)
8796

8897
PLATFORMS
8998
ruby
@@ -92,11 +101,14 @@ DEPENDENCIES
92101
base64 (~> 0.2.0)
93102
bigdecimal (~> 3.1)
94103
csv (~> 3.3)
104+
grover (~> 1.2)
105+
imgkit (~> 1.6)
95106
jekyll (~> 4.0)
96107
puma (~> 6.4)
97108
rack-jekyll (~> 0.5.0)!
98109
rake (~> 13.0)
99110
sass (~> 3.7)
111+
wkhtmltoimage-binary (~> 0.12.5)
100112

101113
RUBY VERSION
102114
ruby 3.3.0p0

_layouts/default.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,18 @@
2121
<script type="text/javascript" src="/javascripts/mobile-nav.js"></script>
2222
<script type="text/javascript" src="/javascripts/application.js"></script>
2323
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" name="viewport">
24+
<meta property="og:site_name" content="RubyGems Blog">
25+
<meta property="twitter:domain" content="blog.rubygems.org">
2426
{% if page.og_image %}
2527
<meta property="og:image" content="{{ page.og_image }}">
28+
{% elsif page.auto_preview %}
29+
<meta property="og:image" content="{{ site.url | absolute_url }}/images/previews/{{ page.slug }}.png">
30+
{% endif %}
31+
{% if page.layout == "post" %}
32+
<meta property="og:title" content="{{ page.title }}">
33+
<meta property="og:type" content="article">
34+
<meta property="og:url" content="{{ page.url | absolute_url }}">
35+
<meta property="og:description" content="{{ page.excerpt | strip_html }}">
2636
{% endif %}
2737
<!--[if IE 8]>
2838
<script src="/assets/html5shiv.js"></script>

_plugins/preview_image.rb

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# frozen_string_literal: true
2+
require 'fileutils'
3+
require 'grover'
4+
5+
Grover.configure do |config|
6+
config.options = {
7+
viewport: {
8+
width: 1200,
9+
height: 630,
10+
deviceScaleFactor: 2
11+
},
12+
prefer_css_page_size: true,
13+
emulate_media: 'screen',
14+
bypass_csp: true,
15+
wait_until: 'domcontentloaded',
16+
full_page: true,
17+
margin: {
18+
top: 0,
19+
bottom: 0,
20+
left: 0,
21+
right: 0
22+
},
23+
captureBeyondViewport: false,
24+
}
25+
end
26+
27+
module Previews
28+
class Generator < Jekyll::Generator
29+
safe true
30+
31+
def generate(site)
32+
# Loop through all the posts
33+
site.posts.docs.each do |post|
34+
next unless post.data['auto_preview']
35+
slug = post.data['slug']
36+
tmp_img = "/tmp/#{slug}.png"
37+
src_img = "./images/previews/#{slug}.png"
38+
39+
# Skip if there is already an existing image.
40+
# To regenerate a preview image, simply delete the image in the destination folder
41+
next if File.file?(src_img)
42+
puts "\n Creating preview: #{slug}.png"
43+
44+
# HTML for generating a @2x image of 1200x630 image at 100 quality
45+
# Setting the charset is helpful when you have accents in your posts title
46+
html = <<~HTML
47+
<!DOCTYPE HTML>
48+
<html>
49+
<head>
50+
<meta charset='utf-8' />
51+
<link href="https://fonts.googleapis.com/css2?family=Titillium+Web:wght@400;700&display=swap" rel="stylesheet">
52+
<style>
53+
#{File.read('./stylesheets/preview.css')}
54+
</style>
55+
</head>
56+
<body>
57+
<div class='top'>
58+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200" class="logo">
59+
<g fill="#e9573f">
60+
<path d="M68.8 69.9l-.1-.1L46.5 92l53.9 53.8 22.2-22.1L154.3 92l-22.2-22.2v-.1H68.7"/>
61+
<path d="M100.2 10.6l-78.5 45v90l78.5 45 78.5-45v-90l-78.5-45zM163.7 137l-63.5 36.6L36.7 137V64l63.5-36.6L163.7 64v73z"/>
62+
</g>
63+
</svg>
64+
<h2>#{post.data['title']}</h2>
65+
</div>
66+
<div class='excerpt'>
67+
#{post.data['excerpt']}
68+
</div>
69+
</body>
70+
</html>
71+
HTML
72+
73+
Grover.new(html,
74+
format: 'png',
75+
width: 1200,
76+
height: 630,
77+
zoom: 2,
78+
margin: {
79+
top: 0,
80+
bottom: 0,
81+
left: 0,
82+
right: 0
83+
},
84+
full_page: false,
85+
capture_beyond_viewport: false
86+
).to_png.then do |png|
87+
File.write(src_img, png)
88+
end
89+
90+
# Optimize to reduce the size to about a third
91+
system("pngquant", src_img, "-o", src_img, "-f", exception: true)
92+
end
93+
end
94+
end
95+
end

_posts/2024-12-11-security-audit.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: RubyGems.org Completes First Security Audit With Trail of Bits
33
layout: post
44
author: Rhiannon Payne
55
author_email: rhiannon@rubycentral.org
6+
auto_preview: true
67
---
78

89
At Ruby Central, ensuring the security of RubyGems.org—the central hub for Ruby packages—is one of our top priorities. With over 184 billion downloads, RubyGems.org is crucial to the Ruby ecosystem, supporting developers, businesses, and open source projects worldwide.

images/previews/security-audit.png

40.5 KB
Loading

stylesheets/preview.css

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
html {
2+
width: 1200px;
3+
height: 630px;
4+
}
5+
6+
p {
7+
margin: 0;
8+
}
9+
10+
body {
11+
background-color: rgb(251, 251, 251);
12+
font-family: "Titillium Web", sans-serif;
13+
font-weight: 100;
14+
font-size: 46px;
15+
color: #141c22;
16+
text-align: center;
17+
padding: 64px;
18+
margin: 0;
19+
20+
display: flex;
21+
flex-direction: column;
22+
justify-content: space-around;
23+
box-sizing: border-box;
24+
width: 100%;
25+
height: 100%;
26+
}
27+
28+
h2 {
29+
font-weight: 700;
30+
font-size: 4rem;
31+
align-self: center;
32+
flex-shrink: 1;
33+
text-align: end;
34+
line-height: 1.25;
35+
}
36+
37+
.excerpt {
38+
line-height: 1.25;
39+
flex: 1;
40+
text-align: initial;
41+
font-size: 2rem;
42+
vertical-align: middle;
43+
44+
display: flex;
45+
flex-direction: column;
46+
justify-content: center;
47+
}
48+
49+
.logo {
50+
display: inline-block;
51+
color: #e9573f;
52+
flex: 1 0 300px;
53+
aspect-ratio: 1/1;
54+
height: auto;
55+
}
56+
57+
.top {
58+
display: flex;
59+
flex-direction: row;
60+
align-items: center;
61+
justify-content: space-between;
62+
flex-shrink: 1;
63+
text-wrap: balance;
64+
width: 100%;
65+
gap: 1rem;
66+
}

0 commit comments

Comments
 (0)