jekyll-linkpreview 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 587ad3275fda0960afb88ac33ce812ef44c58350a3b8458c84af9373e053337a
4
- data.tar.gz: 0c2ddddee8609c2948ec6e2c3e82ca98064e4687d0117fe833ce78d01329224b
3
+ metadata.gz: d55e7758cdacbdcbd976a0669efd3f4210a77e02f3ac6fa5e1518d8d1ee863e7
4
+ data.tar.gz: 6ca1a338b6bdc68e3a769b5c6c071a91a1dbaa909fdf86f4e1a41707b2edf043
5
5
  SHA512:
6
- metadata.gz: 412a6fa311be2724bb3161a8fc41bdd15a576e926c586cbdbe4790d118e279238575618d1641ad435f56fe56f56e9dfbe105c137c83e72b09501c1112bc7a927
7
- data.tar.gz: 6f962a6f0ac52e9615b873922bc483b45b07ced265e365b742d383432af68eb8327535e54c6c127f5fc01331ea38e39aefff8ec695fe551e59e7e986cca1fce3
6
+ metadata.gz: 8390070dc663f7f5a07d5e13c8b6e804a6e6649f1de07bf1443f054048858a8ccad6a6eff970a706c87a71baf3e2a9efc57e750bb82d596defaadc310fbd2719
7
+ data.tar.gz: ae3b069df61e1b9d151a56d20054ab67b910a3965c76265f7f8f3626e0b7c8a88b91bf56db20cd7d0468a5b46d77c52c28bf51a5860dd2e756355354167f571c
data/.gitignore CHANGED
@@ -12,3 +12,5 @@
12
12
 
13
13
  # Appraisal
14
14
  *.gemfile.lock
15
+ Gemfile.lock
16
+ vendor/
data/Dockerfile CHANGED
@@ -1,4 +1,14 @@
1
1
  FROM ruby:2.6.5
2
2
 
3
- RUN apt-get -y update
4
- RUN gem install jekyll bundler
3
+ RUN apt update \
4
+ && apt install -y \
5
+ vim \
6
+ && rm -rf /var/lib/apt/lists/*
7
+ RUN gem install \
8
+ bundler \
9
+ jekyll
10
+ RUN mkdir /jekyll-linkpreview
11
+ ADD Gemfile /jekyll-linkpreview
12
+ ADD jekyll-linkpreview.gemspec /jekyll-linkpreview
13
+ ADD lib/jekyll-linkpreview/version.rb /jekyll-linkpreview/lib/jekyll-linkpreview/version.rb
14
+ RUN cd /jekyll-linkpreview && bundle install
data/README.md CHANGED
@@ -1,59 +1,29 @@
1
1
  # Jekyll::Linkpreview
2
2
 
3
- [![Build Status](https://travis-ci.org/ysk24ok/jekyll-linkpreview.svg?branch=master)](https://travis-ci.org/ysk24ok/jekyll-linkpreview)
3
+ [![Build Status](https://travis-ci.com/ysk24ok/jekyll-linkpreview.svg?branch=master)](https://travis-ci.com/ysk24ok/jekyll-linkpreview)
4
4
 
5
5
  Jekyll plugin to generate link preview by `{% linkpreview %}` tag. The plugin fetches [Open Graph protocol](http://ogp.me/) metadata of the designated page to generate preview. The og properties are saved as JSON for caching and it is used when rebuilding the site.
6
6
 
7
7
  You can pass url directly to the tag,
8
8
 
9
9
  ```
10
- {% linkpreview "https://github.com" %}
10
+ {% linkpreview "https://github.com/ysk24ok/jekyll-linkpreview" %}
11
11
  ```
12
12
 
13
13
  or, can pass a url variable.
14
14
 
15
15
  ```
16
- {% assign github_toppage = 'https://github.com' %}
17
- {% linkpreview github_toppage %}
16
+ {% assign jekyll_linkpreview_page = "https://github.com/ysk24ok/jekyll-linkpreview" %}
17
+ {% linkpreview jekyll_linkpreview_page %}
18
18
  ```
19
19
 
20
- The tag above generates following HTML when you run `jekyll build`.
21
-
22
- ```html
23
- <div class="jekyll-linkpreview-wrapper">
24
- <p><a href="https://github.com" target="_blank">https://github.com</a></p>
25
- <div class="jekyll-linkpreview-wrapper-inner">
26
- <div class="jekyll-linkpreview-content">
27
- <div class="jekyll-linkpreview-image">
28
- <a href="https://github.com" target="_blank">
29
- <img src="https://github.githubassets.com/images/modules/open_graph/github-logo.png" />
30
- </a>
31
- </div>
32
- <div class="jekyll-linkpreview-body">
33
- <h2 class="jekyll-linkpreview-title">
34
- <a href="https://github.com" target="_blank">Build software better, together</a>
35
- </h2>
36
- <div class="jekyll-linkpreview-description">GitHub is where people build software. More than 31 million people use GitHub to discover, fork, and contribute to over 100 million projects.</div>
37
- </div>
38
- </div>
39
- <div class="jekyll-linkpreview-footer">
40
- <a href="https://github.com" target="_blank">github.com</a>
41
- </div>
42
- </div>
43
- </div>
44
- ```
45
-
46
- By applying appropriate CSS, the link preview will be like this.
20
+ By applying [linkpreview.css](assets/css/linkpreview.css), the link preview will be like this.
47
21
 
48
- <img width="613" alt="スクリーンショット 2019-04-03 20 52 50" src="https://user-images.githubusercontent.com/3449164/55479970-35baf100-565a-11e9-8c5d-709213917f74.png">
22
+ <img width="613" alt="スクリーンショット 2020-10-26 19 10 26" src="https://user-images.githubusercontent.com/3449164/97160548-db472f80-17bf-11eb-9cc2-383a076fb14d.png">
49
23
 
50
- When the page does not have Open Graph protocol metadata, following simple HTML will be generated.
24
+ When the page does not have Open Graph protocol metadata, the preview will be like this.
51
25
 
52
- ```html
53
- <div class="jekyll-linkpreview-wrapper">
54
- <p><a href="https://example.com" target="_blank">https://example.com</a></p>
55
- </div>
56
- ```
26
+ <img width="613" alt="スクリーンショット 2020-10-26 19 10 35" src="https://user-images.githubusercontent.com/3449164/97160564-e00be380-17bf-11eb-8adb-55c2a07520f1.png">
57
27
 
58
28
  You can override the default templates, see [Custom templates](#user-content-custom-templates).
59
29
 
@@ -91,7 +61,11 @@ You can override the default templates used for generating previews, both in cas
91
61
 
92
62
  1. Place `linkpreview_nog.html` file inside `_includes/` folder of your Jekyll site (`_includes/linkpreview_nog.html`)
93
63
 
94
- 2. Use built-in **link_url** variable to render URL data, i.e. `{{ link_url }}`
64
+ 2. Use built-in variables to extract data which you would like to render. Available variables are:
65
+ * **link_url** i.e. `{{ link_url }}`
66
+ * **link_title** i.e. `{{ link_title }}`
67
+ * **link_description** i.e. `{{ link_description }}`
68
+ * **link_domain** i.e. `{{ link_domain }}`
95
69
 
96
70
  ## Development
97
71
 
@@ -99,6 +73,39 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
99
73
 
100
74
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
101
75
 
76
+ ### Test with Jekyll site
77
+
78
+ First, build a Docker image and run a container.
79
+
80
+ ```console
81
+ $ docker build --no-cache -t jekyll_linkpreview_dev .
82
+ $ docker run --rm -it -w /jekyll-linkpreview -p 4000:4000 jekyll_linkpreview_dev /bin/bash
83
+ ```
84
+
85
+ Create a new Jekyll site and move into the new directory.
86
+
87
+ ```console
88
+ # bundle exec jekyll new testsite && cd testsite
89
+ ```
90
+
91
+ Add this line to `:jekyll_plugins` group of Gemfile.
92
+
93
+ ```console
94
+ gem "jekyll-linkpreview", git: "https://github.com/YOUR_ACCOUNT/jekyll-linkpreview", branch: "YOUR_BRANCH"
95
+ ```
96
+
97
+ Install the dependecies to your new site.
98
+
99
+ ```console
100
+ # bundle install
101
+ ```
102
+
103
+ Add a tag such as `{% linkpreview "https://github.com/ysk24ok/jekyll-linkpreview" %}` to `index.markdown` , then start a Jekyll server.
104
+
105
+ ```console
106
+ # bundle exec jekyll serve --host 0.0.0.0
107
+ ```
108
+
102
109
  ## Contributing
103
110
 
104
111
  Bug reports and pull requests are welcome on GitHub at https://github.com/ysk24ok/jekyll-linkpreview.
@@ -30,6 +30,10 @@
30
30
  margin-right: 110px;
31
31
  }
32
32
 
33
+ .jekyll-linkpreview-body-nog {
34
+ margin-right: 10px;
35
+ }
36
+
33
37
  .jekyll-linkpreview-title {
34
38
  font-size: 17px;
35
39
  margin: 0 0 2px;
@@ -1,5 +1,6 @@
1
1
  require "digest"
2
2
  require "json"
3
+ require 'uri'
3
4
 
4
5
  require "metainspector"
5
6
  require "jekyll-linkpreview/version"
@@ -7,31 +8,64 @@ require "jekyll-linkpreview/version"
7
8
  module Jekyll
8
9
  module Linkpreview
9
10
  class OpenGraphProperties
10
- def get(url)
11
- og_properties = fetch(url)
12
- og_url = get_og_property(og_properties, 'og:url')
13
- domain = extract_domain(og_url)
14
- image_url = get_og_property(og_properties, 'og:image')
11
+ @@template_file = 'linkpreview.html'
12
+
13
+ def initialize(title, url, image, description, domain)
14
+ @title = title
15
+ @url = url
16
+ @image = image
17
+ @description = description
18
+ @domain = domain
19
+ end
20
+
21
+ def to_hash()
15
22
  {
16
- 'title' => get_og_property(og_properties, 'og:title'),
17
- 'url' => og_url,
18
- 'image' => convert_to_absolute_url(image_url, domain),
19
- 'description' => get_og_property(og_properties, 'og:description'),
20
- 'domain' => domain
23
+ 'title' => @title,
24
+ 'url' => @url,
25
+ 'image' => @image,
26
+ 'description' => @description,
27
+ 'domain' => @domain,
21
28
  }
22
29
  end
23
30
 
31
+ def to_hash_for_custom_template()
32
+ {
33
+ 'link_title' => @title,
34
+ 'link_url' => @url,
35
+ 'link_image' => @image,
36
+ 'link_description' => @description,
37
+ 'link_domain' => @domain
38
+ }
39
+ end
40
+
41
+ def template_file()
42
+ @@template_file
43
+ end
44
+ end
45
+
46
+ class OpenGraphPropertiesFactory
47
+ def from_page(page)
48
+ og_properties = page.meta_tags['property']
49
+ image_url = get_og_property(og_properties, 'og:image')
50
+ title = get_og_property(og_properties, 'og:title')
51
+ url = get_og_property(og_properties, 'og:url')
52
+ image = convert_to_absolute_url(image_url, page.root_url)
53
+ description = get_og_property(og_properties, 'og:description')
54
+ domain = page.host
55
+ OpenGraphProperties.new(title, url, image, description, domain)
56
+ end
57
+
58
+ def from_hash(hash)
59
+ OpenGraphProperties.new(
60
+ hash['title'], hash['url'], hash['image'], hash['description'], hash['domain'])
61
+ end
62
+
24
63
  private
25
64
  def get_og_property(properties, key)
26
65
  if !properties.key? key then
27
66
  return nil
28
67
  end
29
- properties[key][0]
30
- end
31
-
32
- private
33
- def fetch(url)
34
- MetaInspector.new(url).meta_tags['property']
68
+ properties[key].first
35
69
  end
36
70
 
37
71
  private
@@ -41,54 +75,89 @@ module Jekyll
41
75
  end
42
76
  # root relative url
43
77
  if url[0] == '/' then
44
- return "//#{domain}#{url}"
78
+ return URI.join(domain, url).to_s
45
79
  end
46
80
  url
47
81
  end
82
+ end
83
+
84
+ class NonOpenGraphProperties
85
+ @@template_file = 'linkpreview_nog.html'
86
+
87
+ def initialize(title, url, description, domain)
88
+ @title = title
89
+ @url = url
90
+ @description = description
91
+ @domain = domain
92
+ end
93
+
94
+ def to_hash()
95
+ {
96
+ 'title' => @title,
97
+ 'url' => @url,
98
+ 'description' => @description,
99
+ 'domain' => @domain,
100
+ }
101
+ end
102
+
103
+ def to_hash_for_custom_template()
104
+ {
105
+ 'link_title' => @title,
106
+ 'link_url' => @url,
107
+ 'link_description' => @description,
108
+ 'link_domain' => @domain
109
+ }
110
+ end
111
+
112
+ def template_file()
113
+ @@template_file
114
+ end
115
+ end
116
+
117
+ class NonOpenGraphPropertiesFactory
118
+ def from_page(page)
119
+ NonOpenGraphProperties.new(
120
+ page.title, page.url, get_description(page), page.host)
121
+ end
122
+
123
+ def from_hash(hash)
124
+ NonOpenGraphProperties.new(
125
+ hash['title'], hash['url'], hash['description'], hash['domain'])
126
+ end
48
127
 
49
128
  private
50
- def extract_domain(url)
51
- if url.nil? then
52
- return nil
53
- end
54
- m = url.match(%r{(http|https)://([^/]+).*})
55
- if m.nil? then
56
- return nil
129
+ def get_description(page)
130
+ if !page.parsed.xpath('//p[normalize-space()]').empty? then
131
+ return page.parsed.xpath('//p[normalize-space()]').map(&:text).first[0..180] + "..."
132
+ else
133
+ return "..."
57
134
  end
58
- m[-1]
59
135
  end
60
136
  end
61
137
 
62
138
  class LinkpreviewTag < Liquid::Tag
63
139
  @@cache_dir = '_cache'
140
+ @@template_dir = '_includes'
64
141
 
65
142
  def initialize(tag_name, markup, parse_context)
66
143
  super
67
144
  @markup = markup.strip()
68
- @og_properties = OpenGraphProperties.new
69
145
  end
70
146
 
71
147
  def render(context)
72
148
  url = get_url_from(context)
73
149
  properties = get_properties(url)
74
- title = properties['title']
75
- image = properties['image']
76
- description = properties['description']
77
- domain = properties['domain']
78
-
79
- if title.nil? || image.nil? || domain.nil? then
80
- render_linkpreview_nog(context, url)
81
- else
82
- render_linkpreview_og(context, url, title, image, description, domain)
83
- end
150
+ render_linkpreview properties
84
151
  end
85
152
 
86
153
  def get_properties(url)
87
154
  cache_filepath = "#{@@cache_dir}/%s.json" % Digest::MD5.hexdigest(url)
88
155
  if File.exist?(cache_filepath) then
89
- return load_cache_file(cache_filepath)
156
+ hash = load_cache_file(cache_filepath)
157
+ return create_properties_from_hash(hash)
90
158
  end
91
- properties = @og_properties.get(url)
159
+ page = fetch(url)
160
+ properties = create_properties_from_page(page)
92
161
  if Dir.exists?(@@cache_dir) then
93
162
  save_cache_file(cache_filepath, properties)
94
163
  else
@@ -103,6 +172,11 @@ module Jekyll
103
172
  context[@markup]
104
173
  end
105
174
 
175
+ private
176
+ def fetch(url)
177
+ MetaInspector.new(url)
178
+ end
179
+
106
180
  private
107
181
  def load_cache_file(filepath)
108
182
  JSON.parse(File.open(filepath).read)
@@ -110,27 +184,68 @@ module Jekyll
110
184
 
111
185
  protected
112
186
  def save_cache_file(filepath, properties)
113
- File.open(filepath, 'w') { |f| f.write JSON.generate(properties) }
187
+ File.open(filepath, 'w') { |f| f.write JSON.generate(properties.to_hash) }
114
188
  end
115
189
 
116
190
  private
117
- def render_linkpreview_og(context, url, title, image, description, domain)
118
- template_path = get_linkpreview_og_template()
191
+ def create_properties_from_page(page)
192
+ if page.meta_tags['property'].empty? then
193
+ factory = NonOpenGraphPropertiesFactory.new
194
+ else
195
+ factory = OpenGraphPropertiesFactory.new
196
+ end
197
+ factory.from_page(page)
198
+ end
199
+
200
+ private
201
+ def create_properties_from_hash(hash)
202
+ if hash['image'] then
203
+ factory = OpenGraphPropertiesFactory.new
204
+ else
205
+ factory = NonOpenGraphPropertiesFactory.new
206
+ end
207
+ factory.from_hash(hash)
208
+ end
209
+
210
+ private
211
+ def render_linkpreview(properties)
212
+ template_path = get_custom_template_path properties
119
213
  if File.exist?(template_path)
120
- template_file = File.read template_path
121
- site = context.registers[:site]
122
- template_file = (Liquid::Template.parse template_file).render site.site_payload.merge!({"link_url" => url, "link_title" => title, "link_image" => image, "link_description" => description, "link_domain" => domain})
214
+ hash = properties.to_hash_for_custom_template
215
+ gen_custom_template template_path, hash
123
216
  else
124
- html = <<-EOS
217
+ gen_default_template properties.to_hash
218
+ end
219
+ end
220
+
221
+ private
222
+ def get_custom_template_path(properties)
223
+ File.join Dir.pwd, @@template_dir, properties.template_file
224
+ end
225
+
226
+ private
227
+ def gen_default_template(hash)
228
+ title = hash['title']
229
+ url = hash['url']
230
+ description = hash['description']
231
+ domain = hash['domain']
232
+ image = hash['image']
233
+ image_html = ""
234
+ if image then
235
+ image_html = <<-EOS
236
+ <div class="jekyll-linkpreview-image">
237
+ <a href="#{url}" target="_blank">
238
+ <img src="#{image}" />
239
+ </a>
240
+ </div>
241
+ EOS
242
+ end
243
+ html = <<-EOS
125
244
  <div class="jekyll-linkpreview-wrapper">
126
245
  <p><a href="#{url}" target="_blank">#{url}</a></p>
127
246
  <div class="jekyll-linkpreview-wrapper-inner">
128
247
  <div class="jekyll-linkpreview-content">
129
- <div class="jekyll-linkpreview-image">
130
- <a href="#{url}" target="_blank">
131
- <img src="#{image}" />
132
- </a>
133
- </div>
248
+ #{image_html}
134
249
  <div class="jekyll-linkpreview-body">
135
250
  <h2 class="jekyll-linkpreview-title">
136
251
  <a href="#{url}" target="_blank">#{title}</a>
@@ -139,40 +254,18 @@ module Jekyll
139
254
  </div>
140
255
  </div>
141
256
  <div class="jekyll-linkpreview-footer">
142
- <a href="//#{domain}" target="_blank">#{domain}</a>
257
+ <a href="#{domain}" target="_blank">#{domain}</a>
143
258
  </div>
144
259
  </div>
145
260
  </div>
146
261
  EOS
147
- html
148
- end
149
- end
150
-
151
- private
152
- def render_linkpreview_nog(context, url)
153
- template_path = get_linkpreview_nog_template()
154
- if File.exist?(template_path)
155
- template_file = File.read template_path
156
- site = context.registers[:site]
157
- template_file = (Liquid::Template.parse template_file).render site.site_payload.merge!({"link_url" => url})
158
- else
159
- html = <<-EOS
160
- <div class="jekyll-linkpreview-wrapper">
161
- <p><a href="#{url}" target="_blank">#{url}</a></p>
162
- </div>
163
- EOS
164
- html
165
- end
166
- end
167
-
168
- private
169
- def get_linkpreview_og_template()
170
- File.join Dir.pwd, "_includes", "linkpreview.html"
262
+ html
171
263
  end
172
264
 
173
265
  private
174
- def get_linkpreview_nog_template()
175
- File.join Dir.pwd, "_includes", "linkpreview_nog.html"
266
+ def gen_custom_template(template_path, hash)
267
+ template = File.read template_path
268
+ Liquid::Template.parse(template).render!(hash)
176
269
  end
177
270
  end
178
271
  end
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  module Linkpreview
3
- VERSION = "0.3.2"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-linkpreview
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Nishioka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-30 00:00:00.000000000 Z
11
+ date: 2020-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll