jekyll-responsive_image 0.9.1 → 0.10.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
  SHA1:
3
- metadata.gz: dc0a20c9cc1f1bfd10aef481ca55672377b9379f
4
- data.tar.gz: 60044f0efde1042917c727817d597e11e38ca40a
3
+ metadata.gz: ed00bfad560bc67b74bd57aeae4cf8245a3584ec
4
+ data.tar.gz: 4f9315a2ac66b01e024b1c650783e864ff712b65
5
5
  SHA512:
6
- metadata.gz: 2c21adf98bc2bd32e379bb7721f7ff2ce9149f2a351dd00f99ead6f52b935ae82a30ce1d62fb76abbef567c5d0ad701e36ffc31617bef6b609ce316ae6c23d1d
7
- data.tar.gz: fb4cd91b2570b517e2e05662e1117adce75616b973a48faf6147e3f4ecc802be260e81e7e74a49b4be166025160c826cf3a4a6f7d1ea3dbe29519dd4419a5bc4
6
+ metadata.gz: 1951e99caf0c73b6716810dfa26043085f9b3aa522f3a393c5963ab85cd613bb5657ebb23c3af0a056a951200536e6af4a5c0b9c3a561d83f26d27a488da663f
7
+ data.tar.gz: 39505e832aad11402d47a1f4d617a6dca827e19104652a359f846f838b55f2c1b0891776ac663054e449383ddaa7977f966e5ddfd89f5824c178a3354ce98185
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  coverage
2
2
  Gemfile.lock
3
+ jekyll-responsive_image-*.gem
data/README.md CHANGED
@@ -27,15 +27,35 @@ An example configuration is below.
27
27
 
28
28
  ```yaml
29
29
  responsive_image:
30
- template: '_includes/responsive-image.html' # Path to the template to render. Required.
30
+ # [Required]
31
+ # Path to the image template.
32
+ template: _includes/responsive-image.html
31
33
 
32
- # An array of resize configurations. When this array is empty (or not specified),
33
- # no resizing will take place.
34
+ # [Optional, Default: 85]
35
+ # Quality to use when resizing images.
36
+ default_quality: 90
37
+
38
+ # [Optional, Default: []]
39
+ # An array of resize configuration objects. Each object must contain at least
40
+ # a `width` value.
34
41
  sizes:
35
- - width: 480 # How wide the resized image will be. Required
42
+ - width: 480 # [Required] How wide the resized image will be.
43
+ quality: 80 # [Optional] Overrides default_quality for this size.
36
44
  - width: 800
37
- quality: 90 # Override JPEG quality (default is 85). Optional.
38
45
  - width: 1400
46
+ quality: 90
47
+
48
+ # [Optional, Default: assets/resized/%{filename}-%{width}x%{height}.%{extension}]
49
+ # The template used when generating filenames for resized images.
50
+ #
51
+ # Parameters available are:
52
+ # %{basename} Basename of the file (assets/some-file.jpg => some-file.jpg)
53
+ # %{filename} Basename without the extension (assets/some-file.jpg => some-file)
54
+ # %{extension} Extension of the file (assets/some-file.jpg => jpg)
55
+ # %{width} Width of the resized image
56
+ # %{height} Height of the resized image
57
+ #
58
+ output_path_format: assets/resized/%{width}/%{basename}
39
59
  ```
40
60
 
41
61
  ## Usage
@@ -60,35 +80,60 @@ Any extra attributes will be passed straight to the template as variables.
60
80
 
61
81
  ### Template
62
82
 
63
- You will need to create a template in order to use the `responsive_image` tag. A sample template is below.
83
+ You will need to create a template in order to use the `responsive_image` tag. Below are some sample templates to get you started.
84
+
85
+ #### Basic image tag with `srcset`
64
86
 
65
87
  ```html
66
88
  <img src="/{{ path }}"
67
- alt="{{ alt }}"
68
- title="{{ title }}"
69
-
70
- {% if resized %}
71
- srcset="{% for i in resized %}
72
- /{{ i.path }} {{ i.width }}w{% if forloop.last == false %},{% endif %}
73
- {% endfor %}"
74
- {% endif %}
75
- >
89
+ srcset="
90
+ {% for i in resized %}/{{ i.path }} {{ i.width }}w,{% endfor %}
91
+ /{{ original.path }} {{ original.width }}w
92
+ ">
76
93
  ```
77
94
 
78
- #### Template Variables
95
+ #### Responsive images using [Imager.js](https://github.com/BBC-News/Imager.js/)
79
96
 
80
- The following variables are available in the template:
97
+ > This template assumes an `output_path_format` of `assets/resized/%{width}/%{basename}`
81
98
 
82
- | Variable | Type | Description |
83
- |-----------|--------|------------------------------------------------------------------------------------------------------|
84
- | `path` | String | The path of the unmodified image. This is always the same as the `path` attribute passed to the tag. |
85
- | `resized` | Array | An array of all the resized images. Each image contains the properties listed below. |
86
- | `*` | String | Any other attributes will be passed to the template verbatim as strings. |
99
+ ```html
100
+ {% assign smallest = resized | sort: 'width' | first %}
101
+
102
+ <div class="responsive-image">
103
+ <img class="responsive-image__placeholder" src="/{{ smallest.path }}">
104
+ <div class="responsive-image__delayed" data-src="/assets/resized/{width}/{{ original.basename }}"></div>
105
+ </div>
106
+
107
+ <script>
108
+ new Imager('.responsive-image__delayed', {
109
+ availableWidths: [{{ resized | map: 'width' | join: ', ' }}]
110
+ onImagesReplaced: function() {
111
+ $('.responsive-image__placeholder').hide();
112
+ }
113
+ });
114
+ </script>
115
+ ```
116
+
117
+ ### Template Variables
87
118
 
88
- Each element in the `resized` array contains the following properties:
119
+ The following variables are available in the template:
89
120
 
90
- | Variable | Type | Description |
91
- |----------|----------|----------------------------------|
92
- | `path` | String | The path of the resized image. |
93
- | `width` | Integer | The width of the resized image. |
94
- | `height` | Integer | The height of the resized image. |
121
+ | Variable | Type | Description |
122
+ |----------- |--------|------------------------------------------------------------------------------------------------------|
123
+ | `path` | String | The path of the unmodified image. This is always the same as the `path` attribute passed to the tag. |
124
+ | `resized` | Array | An array of all the resized images. Each image is an **Image Object**. |
125
+ | `original` | Object | An **Image Object** containing information about the original image. |
126
+ | `*` | String | Any other attributes will be passed to the template verbatim as strings. |
127
+
128
+ #### Image Objects
129
+
130
+ Image objects (like `original` and each object in `resized`) contain the following properties:
131
+
132
+ | Variable | Type | Description |
133
+ |-------------|---------|-------------------------------------------------------------------------|
134
+ | `path` | String | The path to the image. |
135
+ | `width` | Integer | The width of the image. |
136
+ | `height` | Integer | The height of the image. |
137
+ | `basename` | String | Basename of the file (`assets/some-file.jpg` => `some-file.jpg`). |
138
+ | `filename` | String | Basename without the extension (`assets/some-file.jpg` => `some-file`). |
139
+ | `extension` | String | Extension of the file (`assets/some-file.jpg` => `jpg`). |
@@ -1 +1 @@
1
- {{ resized | map: 'width' }}
1
+ [{{ resized | map: 'width' | join: ', ' }}]
@@ -1,5 +1,4 @@
1
- <img alt="{{ alt }}" src="/{{ path }}" title="{{ title }}"{% if resized %} srcset="
2
- {% for i in resized %}
3
- /{{ i.path }} {{ i.width }}w{% if forloop.last == false %},{% endif %}
4
- {% endfor %}
5
- "{% endif %}>
1
+ <img alt="{{ alt }}" src="/{{ path }}" title="{{ title }}" srcset="
2
+ {% for i in resized %}/{{ i.path }} {{ i.width }}w,{% endfor %}
3
+ /{{ original.path }} {{ original.width }}w
4
+ ">
@@ -55,6 +55,7 @@ Feature: Jekyll responsive-image tag
55
55
  Then I should see "<img alt=\"\" src=\"/assets/test.png\"" in "_site/index.html"
56
56
  And I should see "/assets/resized/test-100x50.png 100w" in "_site/index.html"
57
57
  And I should see "/assets/resized/test-200x100.png 200w" in "_site/index.html"
58
+ And I should see "/assets/test.png 300w" in "_site/index.html"
58
59
  And the file "assets/resized/test-100x50.png" should exist
59
60
  And the file "assets/resized/test-200x100.png" should exist
60
61
 
@@ -65,10 +66,27 @@ Feature: Jekyll responsive-image tag
65
66
  sizes:
66
67
  - width: 100
67
68
  - width: 200
69
+ - width: 300
68
70
  """
69
71
  And I have a file "index.html" with:
70
72
  """
71
73
  {% responsive_image path: assets/test.png template: _includes/custom-template.html %}
72
74
  """
73
75
  When I run Jekyll
74
- Then I should see "100200" in "_site/index.html"
76
+ Then I should see "[100, 200, 300]" in "_site/index.html"
77
+
78
+ Scenario: Overriding the generated filenames
79
+ Given I have a responsive_image configuration with:
80
+ """
81
+ template: _includes/responsive-image.html
82
+ output_path_format: assets/%{basename}-resized/%{width}/%{filename}-%{height}.%{extension}
83
+ sizes:
84
+ - width: 100
85
+ """
86
+ And I have a file "index.html" with:
87
+ """
88
+ {% responsive_image path: assets/test.png %}
89
+ """
90
+ When I run Jekyll
91
+ Then I should see "/assets/test.png-resized/100/test-50.png 100w" in "_site/index.html"
92
+ And the file "assets/test.png-resized/100/test-50.png" should exist
@@ -0,0 +1,13 @@
1
+ module Jekyll
2
+ class ResponsiveImage
3
+ @defaults = {
4
+ 'default_quality' => 85,
5
+ 'output_path_format' => 'assets/resized/%{filename}-%{width}x%{height}.%{extension}',
6
+ 'sizes' => [],
7
+ }.freeze
8
+
9
+ class << self
10
+ attr_reader :defaults
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,91 @@
1
+ module Jekyll
2
+ class ResponsiveImage
3
+ class Tag < Liquid::Tag
4
+ def initialize(tag_name, markup, tokens)
5
+ super
6
+
7
+ @attributes = {}
8
+
9
+ markup.scan(::Liquid::TagAttributes) do |key, value|
10
+ # Strip quotes from around attribute values
11
+ @attributes[key] = value.gsub(/^['"]|['"]$/, '')
12
+ end
13
+ end
14
+
15
+ def resize_image(img, config)
16
+ resized = []
17
+
18
+ config['sizes'].each do |size|
19
+ width = size['width']
20
+ ratio = width.to_f / img.columns.to_f
21
+ height = (img.rows.to_f * ratio).round
22
+
23
+ next unless needs_resizing?(img, width)
24
+
25
+ filepath = format_output_path(config['output_path_format'], img.filename, width, height)
26
+ resized.push(image_hash(filepath, width, height))
27
+
28
+ # Don't resize images more than once
29
+ next if File.exists?(filepath)
30
+
31
+ ensure_output_dir_exists!(File.dirname(filepath))
32
+
33
+ Jekyll.logger.info "Generating #{filepath}"
34
+
35
+ i = img.scale(ratio)
36
+ i.write(filepath) do |f|
37
+ f.quality = size['quality'] || config['default_quality']
38
+ end
39
+
40
+ i.destroy!
41
+ end
42
+
43
+ resized
44
+ end
45
+
46
+ def format_output_path(format, path, width, height)
47
+ params = Utils.symbolize_keys(image_hash(path, width, height))
48
+ format % params
49
+ end
50
+
51
+ def needs_resizing?(img, width)
52
+ img.columns > width
53
+ end
54
+
55
+ def ensure_output_dir_exists!(dir)
56
+ unless Dir.exists?(dir)
57
+ Jekyll.logger.info "Creating output directory #{dir}"
58
+ FileUtils.mkdir_p(dir)
59
+ end
60
+ end
61
+
62
+ # Build a hash containing image information
63
+ def image_hash(path, width, height)
64
+ {
65
+ 'path' => path,
66
+ 'basename' => File.basename(path),
67
+ 'filename' => File.basename(path, '.*'),
68
+ 'extension' => File.extname(path).delete('.'),
69
+ 'width' => width,
70
+ 'height' => height,
71
+ }
72
+ end
73
+
74
+ def render(context)
75
+ config = ResponsiveImage.defaults.dup
76
+ config.merge!(context.registers[:site].config['responsive_image'])
77
+
78
+ img = Magick::Image::read(@attributes['path']).first
79
+ @attributes['original'] = image_hash(@attributes['path'], img.columns, img.rows)
80
+ @attributes['resized'] = resize_image(img, config)
81
+
82
+ image_template = @attributes['template'] || config['template']
83
+
84
+ partial = File.read(image_template)
85
+ template = Liquid::Template.parse(partial)
86
+
87
+ template.render!(@attributes)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,13 @@
1
+ module Jekyll
2
+ class ResponsiveImage
3
+ class Utils
4
+ def self.symbolize_keys(hash)
5
+ result = {}
6
+ hash.each_key do |key|
7
+ result[key.to_sym] = hash[key]
8
+ end
9
+ result
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  class ResponsiveImage
3
- VERSION = '0.9.1'.freeze
3
+ VERSION = '0.10.0'.freeze
4
4
  end
5
5
  end
@@ -1,101 +1,11 @@
1
+ require 'fileutils'
2
+
1
3
  require 'jekyll'
2
4
  require 'rmagick'
3
5
 
4
- module Jekyll
5
- class ResponsiveImage
6
- class Tag < Liquid::Tag
7
- DEFAULT_QUALITY = 85
8
-
9
- def initialize(tag_name, markup, tokens)
10
- super
11
-
12
- @attributes = {}
13
- @markup = markup
14
-
15
- @markup.scan(::Liquid::TagAttributes) do |key, value|
16
- # Strip quotes from around attribute values
17
- @attributes[key] = value.gsub(/^['"]|['"]$/, '')
18
- end
19
- end
20
-
21
- def resize_image(path, config)
22
- sizes = config['sizes']
23
-
24
- return if sizes.empty?
25
-
26
- output_dir = config['output_dir']
27
- ensure_output_dir_exists!(output_dir)
28
-
29
- resized = []
30
- img = Magick::Image::read(path).first
31
-
32
- sizes.each do |size|
33
- width = size['width']
34
- ratio = width.to_f / img.columns.to_f
35
- height = (img.rows.to_f * ratio).round
36
-
37
- filename = resized_filename(path, width, height)
38
- newpath = "#{output_dir}/#{filename}"
39
-
40
- next unless needs_resizing?(img, width)
41
-
42
- resized.push({
43
- 'width' => width,
44
- 'height' => height,
45
- 'path' => newpath,
46
- })
47
-
48
- # Don't resize images more than once
49
- next if File.exists?(newpath)
50
-
51
- Jekyll.logger.info "Generating #{newpath}"
52
-
53
- i = img.scale(ratio)
54
- i.write(newpath) do |f|
55
- f.quality = size['quality'] || DEFAULT_QUALITY
56
- end
57
-
58
- i.destroy!
59
- end
60
-
61
- resized
62
- end
63
-
64
- # Insert resize information into a file path
65
- #
66
- # resized_filename(/foo/bar/file.name.jpg, 500, 300)
67
- # => /foo/bar/file.name-500x300.jpg
68
- #
69
- def resized_filename(path, width, height)
70
- File.basename(path).sub(/\.([^.]+)$/, "-#{width}x#{height}.\\1")
71
- end
72
-
73
- def needs_resizing?(img, width)
74
- img.columns > width
75
- end
76
-
77
- def ensure_output_dir_exists!(dir)
78
- unless Dir.exists?(dir)
79
- Jekyll.logger.info "Creating output directory #{dir}"
80
- Dir.mkdir(dir)
81
- end
82
- end
83
-
84
- def render(context)
85
- config = context.registers[:site].config['responsive_image']
86
- config['output_dir'] ||= 'assets/resized'
87
- config['sizes'] ||= []
88
-
89
- @attributes['template'] ||= config['template']
90
- @attributes['resized'] = resize_image(@attributes['path'], config)
91
-
92
- partial = File.read(@attributes['template'])
93
- template = Liquid::Template.parse(partial)
94
-
95
- template.render!(@attributes)
96
- end
97
- end
98
- end
99
- end
6
+ require 'jekyll/responsive_image/version'
7
+ require 'jekyll/responsive_image/defaults'
8
+ require 'jekyll/responsive_image/utils'
9
+ require 'jekyll/responsive_image/tag'
100
10
 
101
11
  Liquid::Template.register_tag('responsive_image', Jekyll::ResponsiveImage::Tag)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-responsive_image
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Wynn
@@ -64,6 +64,9 @@ files:
64
64
  - index.html
65
65
  - jekyll-responsive_image.gemspec
66
66
  - lib/jekyll/responsive_image.rb
67
+ - lib/jekyll/responsive_image/defaults.rb
68
+ - lib/jekyll/responsive_image/tag.rb
69
+ - lib/jekyll/responsive_image/utils.rb
67
70
  - lib/jekyll/responsive_image/version.rb
68
71
  - test-index.html
69
72
  homepage: https://github.com/wildlyinaccurate/jekyll-responsive-image