Compare commits

..

No commits in common. "master" and "v1.4.0" have entirely different histories.

23 changed files with 169 additions and 419 deletions

10
.github/stale.yml vendored
View File

@ -1,10 +0,0 @@
daysUntilStale: 18
daysUntilClose: 3
staleLabel: stale
exemptLabels:
- pinned
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
closeComment: false

View File

@ -5,8 +5,8 @@ bundler_args: --without debug
before_script: bundle exec jekyll --version before_script: bundle exec jekyll --version
script: bundle exec rake features_with_coveralls script: bundle exec rake features_with_coveralls
rvm: rvm:
- '2.6'
- '2.5'
- '2.4' - '2.4'
- '2.3' - '2.3'
- '2.2' - '2.2'
- '2.1'
- '2.0'

View File

@ -4,7 +4,7 @@ gemspec
group :development do group :development do
gem 'rake' gem 'rake'
gem 'cucumber', '~> 3.1' gem 'cucumber', '~> 2.4'
gem 'test-unit', '~> 3.2' gem 'test-unit', '~> 3.2'
gem 'simplecov', :require => false gem 'simplecov', :require => false

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2018 Joseph Wynn Copyright (c) 2014 Joseph Wynn
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

270
README.md
View File

@ -1,130 +1,31 @@
# jekyll-responsive-image # jekyll-responsive-image
A [Jekyll](http://jekyllrb.com/) plugin for automatically resizing images. Fully configurable and unopinionated, jekyll-responsive-image allows you to display responsive images however you like: using [`<img srcset>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#attr-srcset), [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture), or [Imager.js](https://github.com/BBC-News/Imager.js/). A [Jekyll](http://jekyllrb.com/) plugin and utility for automatically resizing images. Its intended use is for sites which want to display responsive images using something like [`srcset`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Specifications) or [Imager.js](https://github.com/BBC-News/Imager.js/).
[![Build Status](https://img.shields.io/travis/wildlyinaccurate/jekyll-responsive-image.svg?style=flat-square)](https://travis-ci.org/wildlyinaccurate/jekyll-responsive-image) [![Build Status](https://img.shields.io/travis/wildlyinaccurate/jekyll-responsive-image.svg?style=flat-square)](https://travis-ci.org/wildlyinaccurate/jekyll-responsive-image)
[![Coverage Status](https://img.shields.io/coveralls/wildlyinaccurate/jekyll-responsive-image.svg?style=flat-square)](https://coveralls.io/repos/github/wildlyinaccurate/jekyll-responsive-image/badge.svg?branch=master) [![Coverage Status](https://img.shields.io/coveralls/wildlyinaccurate/jekyll-responsive-image.svg?style=flat-square)](https://coveralls.io/repos/github/wildlyinaccurate/jekyll-responsive-image/badge.svg?branch=master)
[![Dependency Status](https://img.shields.io/gemnasium/wildlyinaccurate/jekyll-responsive-images.svg?style=flat-square)](https://gemnasium.com/wildlyinaccurate/jekyll-responsive-images)
## Installation ## Installation
This plugin can be installed in three steps: First, install the gem:
### 1. Install the gem
Either add `jekyll-responsive-image` to your Gemfile, or run the following command to install the gem:
``` ```
$ gem install jekyll-responsive-image $ gem install jekyll-responsive-image
``` ```
Then you can either add `jekyll-responsive-image` to the `plugins` section of your `_config.yml`: Then you can either add it to the `gems` section of your `_config.yml`:
```yaml ```yaml
plugins: gems:
- jekyll-responsive-image - jekyll-responsive-image
``` ```
Note: If you are using a Jekyll version less than 3.5.0, use the `gems` key instead of `plugins`.
Or you can copy the contents of [`responsive_image.rb`](lib/jekyll-responsive-image.rb) into your `_plugins` directory. Or you can copy the contents of [`responsive_image.rb`](lib/jekyll-responsive-image.rb) into your `_plugins` directory.
### 2. Create an image template file ## Configuration
You will need to create a template in order to use the `responsive_image` and `responsive_image_block` tags. Normally the template lives in your `_includes/` directory. Not sure where to start? [Take a look at the sample templates](sample-templates). An example configuration is below.
For more advanced templates, see the [**Templates**](#templates) section below.
### 3. Configure the plugin
You **must** have a `responsive_image` block in your `_config.yml` for this plugin to work. At a minimum, your `responsive_image` configuration should have a template path and a list of sizes.
```yaml
responsive_image:
template: _includes/responsive-image.html
sizes:
- width: 320
- width: 480
- width: 800
```
For a list of all the available configuration options, see the [**All configuration options**](#all-configuration-options) section below.
## Usage
Replace your images with the `responsive_image` tag, specifying the path to the image in the `path` attribute.
```twig
{% responsive_image path: assets/my-file.jpg %}
```
You can override the template on a per-image basis by specifying the `template` attribute.
```twig
{% responsive_image path: assets/my-file.jpg template: _includes/another-template.html %}
```
Any extra attributes will be passed straight to the template as variables.
```twig
{% responsive_image path: assets/image.jpg alt: "Lorem ipsum..." title: "Lorem ipsum..." %}
```
### Liquid variables as attributes
You can use Liquid variables as attributes with the `responsive_image_block` tag. This tag works in exactly the same way as the `responsive_image` tag, but is implemented as a block tag to allow for more complex logic.
> **Important!** The attributes in the `responsive_image_block` tag are parsed as YAML, so whitespace and indentation are significant!
```twig
{% assign path = 'assets/test.png' %}
{% assign alt = 'Lorem ipsum...' %}
{% responsive_image_block %}
path: {{ path }}
alt: {{ alt }}
{% if title %}
title: {{ title }}
{% endif %}
{% endresponsive_image_block %}
```
## Templates
It's easy to build your own custom templates to render images however you want using the template variables provided by jekyll-responsive-image.
### Template Variables
The following variables are available in the template:
| Variable | Type | Description |
|------------|---------------|------------------------------------------------------------------------------------------------------|
| `path` | String | The path of the unmodified image. This is always the same as the `path` attribute passed to the tag. |
| `resized` | Array<Object> | An array of all the resized images. Each image is an **Image Object**. |
| `original` | Object | An **Image Object** containing information about the original image. |
| `*` | String | Any other attributes will be passed to the template verbatim as strings (see below). |
Any other attributes that are given to the `responsive_image` or `responsive_image_block` tags will be available in the template. For example the following tag will provide an `{{ alt }}` variable to the template:
```twig
{% responsive_image path: assets/my-file.jpg alt: "A description of the image" %}
```
#### Image Objects
Image objects (like `original` and each object in `resized`) contain the following properties:
| Variable | Type | Description |
|-------------|---------|----------------------------------------------------------------------------------------------|
| `path` | String | The path to the image. |
| `width` | Integer | The width of the image. |
| `height` | Integer | The height of the image. |
| `basename` | String | Basename of the file (`assets/some-file.jpg` => `some-file.jpg`). |
| `dirname` | String | Directory of the file relative to `base_path` (`assets/sub/dir/some-file.jpg` => `sub/dir`). |
| `filename` | String | Basename without the extension (`assets/some-file.jpg` => `some-file`). |
| `extension` | String | Extension of the file (`assets/some-file.jpg` => `jpg`). |
## All configuration options
A full list of all of the available configuration options is below.
```yaml ```yaml
responsive_image: responsive_image:
@ -151,11 +52,6 @@ responsive_image:
# working with JPGs directly from digital cameras and smartphones # working with JPGs directly from digital cameras and smartphones
auto_rotate: false auto_rotate: false
# [Optional, Default: false]
# Strip EXIF and other JPEG profiles. Helps to minimize JPEG size and win friends
# at Google PageSpeed.
strip: false
# [Optional, Default: assets] # [Optional, Default: assets]
# The base directory where assets are stored. This is used to determine the # The base directory where assets are stored. This is used to determine the
# `dirname` value in `output_path_format` below. # `dirname` value in `output_path_format` below.
@ -194,24 +90,136 @@ responsive_image:
- assets/avatars/*.{jpeg,jpg} - assets/avatars/*.{jpeg,jpg}
``` ```
## Troubleshooting ## Usage
### Error: Can't install RMagick Replace your images with the `responsive_image` tag, specifying the path to the image in the `path` attribute.
`jekyll-responsive-image` uses `rmagick` which is currently incompatible with ImageMagick 7. If you get an error like: ```twig
{% responsive_image path: assets/my-file.jpg %}
```
Can't install RMagick 2.16.0. Can't find MagickWand.h
``` ```
Then you will need to install ImageMagick 6. If you are using Homebrew on Mac OS, this can be done with the following commands: You can override the template on a per-image basis by specifying the `template` attribute.
``` ```twig
$ brew uninstall imagemagick {% responsive_image path: assets/my-file.jpg template: _includes/another-template.html %}
$ brew install imagemagick@6 && brew link imagemagick@6 --force
``` ```
## Caching Any extra attributes will be passed straight to the template as variables.
```twig
{% responsive_image path: assets/image.jpg alt: "Lorem ipsum..." title: "Lorem ipsum..." %}
```
### Liquid variables as attributes
You can use Liquid variables as attributes with the `responsive_image_block` tag. This tag works in exactly the same way as the `responsive_image` tag, but is implemented as a block tag to allow for more complex logic.
> **Important!** The attributes in the `responsive_image_block` tag are parsed as YAML, so whitespace and indentation are significant!
```twig
{% assign path = 'assets/test.png' %}
{% assign alt = 'Lorem ipsum...' %}
{% responsive_image_block %}
path: {{ path }}
alt: {{ alt }}
{% if title %}
title: {{ title }}
{% endif %}
{% endresponsive_image_block %}
```
### Template
You will need to create a template in order to use the `responsive_image` tag. Below are some sample templates to get you started.
#### Responsive images with `srcset`
```twig
{% capture srcset %}
{% for i in resized %}
/{{ i.path }} {{ i.width }}w,
{% endfor %}
{% endcapture %}
<img src="/{{ path }}" alt="{{ alt }}" srcset="{{ srcset | strip_newlines }}">
```
#### Responsive image with `srcset` where the largest resized image is the default
> **Note:** This is useful if you don't want your originals to appear on your site. For example, if you're uploading full-res images directly from a device.
```twig
{% capture srcset %}
{% for i in resized %}
/{{ i.path }} {{ i.width }}w,
{% endfor %}
{% endcapture %}
{% assign largest = resized | sort: 'width' | last %}
<img src="/{{ largest.path }}" alt="{{ alt }}" srcset="{{ srcset | strip_newlines }}">
```
#### Responsive images with `<picture>`
```twig
<picture>
{% for i in resized %}
<source media="(min-width: {{ i.width }}px)" srcset="/{{ i.path }}">
{% endfor %}
<img src="/{{ path }}">
</picture>
```
#### Responsive images using [Imager.js](https://github.com/BBC-News/Imager.js/)
> **Note:** This template assumes an `output_path_format` of `assets/resized/%{width}/%{basename}`
```twig
{% assign smallest = resized | sort: 'width' | first %}
<div class="responsive-image">
<img class="responsive-image__placeholder" src="/{{ smallest.path }}">
<div class="responsive-image__delayed" data-src="/assets/resized/{width}/{{ original.basename }}"></div>
</div>
<script>
new Imager('.responsive-image__delayed', {
availableWidths: [{{ resized | map: 'width' | join: ', ' }}]
onImagesReplaced: function() {
$('.responsive-image__placeholder').hide();
}
});
</script>
```
### Template Variables
The following variables are available in the template:
| Variable | Type | Description |
|----------- |--------|------------------------------------------------------------------------------------------------------|
| `path` | String | The path of the unmodified image. This is always the same as the `path` attribute passed to the tag. |
| `resized` | Array | An array of all the resized images. Each image is an **Image Object**. |
| `original` | Object | An **Image Object** containing information about the original image. |
| `*` | String | Any other attributes will be passed to the template verbatim as strings. |
#### Image Objects
Image objects (like `original` and each object in `resized`) contain the following properties:
| Variable | Type | Description |
|-------------|---------|----------------------------------------------------------------------------------------------|
| `path` | String | The path to the image. |
| `width` | Integer | The width of the image. |
| `height` | Integer | The height of the image. |
| `basename` | String | Basename of the file (`assets/some-file.jpg` => `some-file.jpg`). |
| `dirname` | String | Directory of the file relative to `base_path` (`assets/sub/dir/some-file.jpg` => `sub/dir`). |
| `filename` | String | Basename without the extension (`assets/some-file.jpg` => `some-file`). |
| `extension` | String | Extension of the file (`assets/some-file.jpg` => `jpg`). |
### Caching
You may be able to speed up the build of large sites by enabling render caching. This is usually only effective when the same image is used many times, for example a header image that is rendered in every post. You may be able to speed up the build of large sites by enabling render caching. This is usually only effective when the same image is used many times, for example a header image that is rendered in every post.
@ -235,21 +243,3 @@ responsive_image:
sizes: sizes:
- ... - ...
``` ```
## Development
If you'd like to contribute to this repository, here's how you can set it up for development:
1. Fork this repository
2. Clone the fork to your local machine
3. Install [ImageMagick](http://www.imagemagick.org/) (if you haven't already)
4. Run `bundle install`
5. Run the tests like this: `cucumber`
If you'd like your Jekyll project to use your local fork directly, you can add the `:path` parameter to your gem command in the project's Gemfile:
```ruby
gem 'jekyll-responsive-image', :path => "/your/local/path/to/jekyll-responsive-image"
```
If you'd like your changes to be considered for the original repository, simply submit a pull request after you've made your changes. Please make sure all tests pass.

View File

@ -15,25 +15,6 @@ Feature: Extra image generation
And the file "_site/assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should exist And the file "_site/assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should exist
And the file "_site/assets/resized/progressive-100x50.jpeg" should exist And the file "_site/assets/resized/progressive-100x50.jpeg" should exist
Scenario: Specifying a recursive glob pattern
Given I have a responsive_image configuration with:
"""
sizes:
- width: 100
extra_images:
- assets/**/*
"""
And I have a file "index.html" with "Hello, world!"
When I run Jekyll
Then the image "assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should have the dimensions "100x50"
And the image "assets/resized/exif-rotation-100x50.jpeg" should have the dimensions "100x50"
And the image "assets/resized/progressive-100x50.jpeg" should have the dimensions "100x50"
And the image "assets/resized/test-100x50.png" should have the dimensions "100x50"
And the file "_site/assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should exist
And the file "_site/assets/resized/exif-rotation-100x50.jpeg" should exist
And the file "_site/assets/resized/progressive-100x50.jpeg" should exist
And the file "_site/assets/resized/test-100x50.png" should exist
Scenario: Honouring Jekyll 'source' configuration Scenario: Honouring Jekyll 'source' configuration
Given I have copied my site to "sub-dir/my-site-copy" Given I have copied my site to "sub-dir/my-site-copy"
And I have a configuration with: And I have a configuration with:

View File

@ -86,34 +86,3 @@ Feature: Responsive image generation
When I run Jekyll When I run Jekyll
Then the file "_site/assets/resized/exif-rotation-100x50.jpeg" should exist Then the file "_site/assets/resized/exif-rotation-100x50.jpeg" should exist
Then the file "_site/assets/resized/progressive-100x50.jpeg" should exist Then the file "_site/assets/resized/progressive-100x50.jpeg" should exist
Scenario: Images should not be stripped of EXIF info by default
Given I have a responsive_image configuration with:
"""
template: _includes/responsive-image.html
sizes:
- width: 100
"""
And I have a file "index.html" with:
"""
{% responsive_image path: assets/exif-rotation.jpeg %}
"""
When I run Jekyll
Then the file "_site/assets/resized/exif-rotation-100x50.jpeg" should exist
Then the image "_site/assets/resized/exif-rotation-100x50.jpeg" should have an EXIF orientation
Scenario: Images can be stripped of EXIF info
Given I have a responsive_image configuration with:
"""
template: _includes/responsive-image.html
sizes:
- width: 100
strip: true
"""
And I have a file "index.html" with:
"""
{% responsive_image path: assets/exif-rotation.jpeg %}
"""
When I run Jekyll
Then the file "_site/assets/resized/exif-rotation-100x50.jpeg" should exist
Then the image "_site/assets/resized/exif-rotation-100x50.jpeg" should have no EXIF orientation

View File

@ -1,12 +0,0 @@
Feature: General plugin usage
Scenario: No config at all
Given I have no configuration
When I run Jekyll
Then there should be no errors
Scenario: Config with empty responsive_image block
Given I have a responsive_image configuration with:
"""
"""
When I run Jekyll
Then there should be no errors

View File

@ -13,20 +13,6 @@ Feature: Jekyll responsive_image_block tag
When I run Jekyll When I run Jekyll
Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\" title=\"Magic rainbow adventure!\"" in "_site/index.html" Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\" title=\"Magic rainbow adventure!\"" in "_site/index.html"
Scenario: Tabs for indentation
Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html"
And I have a file "index.html" with:
"""
{% assign path = 'assets/everybody-loves-jalapeño-pineapple-cornbread.png' %}
{% responsive_image_block %}
path: {{ path }}
title: Magic rainbow adventure!
alt: Lorem ipsum
{% endresponsive_image_block %}
"""
When I run Jekyll
Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\" title=\"Magic rainbow adventure!\"" in "_site/index.html"
Scenario: Global variables available in templates Scenario: Global variables available in templates
Given I have a file "index.html" with: Given I have a file "index.html" with:
""" """
@ -70,4 +56,4 @@ Feature: Jekyll responsive_image_block tag
path: {{ path }} path: {{ path }}
{% endresponsive_image_block %} {% endresponsive_image_block %}
""" """
Then Jekyll should throw a "Magick::ImageMagickError" Then Jekyll should throw a "SyntaxError"

View File

@ -6,10 +6,6 @@ Then /^Jekyll should throw a "(.+)"$/ do |error_class|
assert_raise(Object.const_get(error_class)) { run_jekyll } assert_raise(Object.const_get(error_class)) { run_jekyll }
end end
Then /^there should be no errors$/ do
# Implicit pass
end
Given /^I have copied my site to "(.+)"$/ do |path| Given /^I have copied my site to "(.+)"$/ do |path|
new_site_dir = File.join(TEST_DIR, path) new_site_dir = File.join(TEST_DIR, path)
@ -20,10 +16,6 @@ Given /^I have copied my site to "(.+)"$/ do |path|
.each { |f| FileUtils.mv(f, new_site_dir) } .each { |f| FileUtils.mv(f, new_site_dir) }
end end
Given /^I have no configuration$/ do
write_file('_config.yml', '')
end
Given /^I have a configuration with:$/ do |config| Given /^I have a configuration with:$/ do |config|
write_file('_config.yml', config) write_file('_config.yml', config)
end end
@ -73,18 +65,6 @@ Then /^the image "(.+)" should be interlaced$/ do |path|
img.destroy! img.destroy!
end end
Then /^the image "(.+)" should have an EXIF orientation$/ do |path|
img = Magick::Image::read(path).first
assert_not_equal img.orientation.to_i, 0
img.destroy!
end
Then /^the image "(.+)" should have no EXIF orientation$/ do |path|
img = Magick::Image::read(path).first
assert_equal img.orientation.to_i, 0
img.destroy!
end
def write_file(path, contents) def write_file(path, contents)
File.open(path, 'w') do |f| File.open(path, 'w') do |f|
f.write(contents) f.write(contents)

View File

@ -1,3 +1 @@
{% assign largest = resized | sort: 'width' | last %}
<img alt="{{ alt }}" src="/{{ original.path }}" title="{{ title }}" srcset="{% for i in resized %}/{{ i.path }} {{ i.width }}w,{% endfor %}/{{ original.path }} {{ original.width }}w"> <img alt="{{ alt }}" src="/{{ original.path }}" title="{{ title }}" srcset="{% for i in resized %}/{{ i.path }} {{ i.width }}w,{% endfor %}/{{ original.path }} {{ original.width }}w">

View File

@ -22,6 +22,6 @@ Gem::Specification.new do |spec|
spec.executables = [] spec.executables = []
spec.require_paths = ['lib'] spec.require_paths = ['lib']
spec.add_runtime_dependency 'jekyll', ['>= 2.0', "< 5.0"] spec.add_runtime_dependency 'jekyll', ['>= 2.0', "< 4.0"]
spec.add_runtime_dependency 'rmagick', ['>= 2.0', '< 5.0'] spec.add_runtime_dependency 'rmagick', ['>= 2.0', '< 3.0']
end end

View File

@ -4,13 +4,7 @@ module Jekyll
include Jekyll::ResponsiveImage::Utils include Jekyll::ResponsiveImage::Utils
def render(context) def render(context)
content = super attributes = YAML.load(super)
if content.include?("\t")
content = content.lines.map {|line| line.gsub(/\G[\t ]/, " ")}.join("\n")
end
attributes = YAML.load(content)
Renderer.new(context.registers[:site], attributes).render_responsive_image Renderer.new(context.registers[:site], attributes).render_responsive_image
end end
end end

View File

@ -9,27 +9,15 @@ module Jekyll
'extra_images' => [], 'extra_images' => [],
'auto_rotate' => false, 'auto_rotate' => false,
'save_to_source' => true, 'save_to_source' => true,
'cache' => false, 'cache' => false
'strip' => false
} }
def initialize(site) def initialize(site)
@site = site @site = site
end end
def valid_config(config)
config.has_key?('responsive_image') && config['responsive_image'].is_a?(Hash)
end
def to_h def to_h
config = {} DEFAULTS.merge(@site.config['responsive_image'])
if valid_config(@site.config)
config = @site.config['responsive_image']
end
DEFAULTS.merge(config)
.merge(site_source: @site.source, site_dest: @site.dest) .merge(site_source: @site.source, site_dest: @site.dest)
end end
end end

View File

@ -2,7 +2,6 @@ module Jekyll
module ResponsiveImage module ResponsiveImage
class ExtraImageGenerator < Jekyll::Generator class ExtraImageGenerator < Jekyll::Generator
include Jekyll::ResponsiveImage::Utils include Jekyll::ResponsiveImage::Utils
include FileTest
def generate(site) def generate(site)
config = Config.new(site).to_h config = Config.new(site).to_h
@ -10,13 +9,11 @@ module Jekyll
config['extra_images'].each do |pathspec| config['extra_images'].each do |pathspec|
Dir.glob(site.in_source_dir(pathspec)) do |image_path| Dir.glob(site.in_source_dir(pathspec)) do |image_path|
if FileTest.file?(image_path) path = Pathname.new(image_path)
path = Pathname.new(image_path) relative_image_path = path.relative_path_from(site_source)
relative_image_path = path.relative_path_from(site_source)
result = ImageProcessor.process(relative_image_path, config) result = ImageProcessor.process(relative_image_path, config)
result[:resized].each { |image| keep_resized_image!(site, image) } result[:resized].each { |image| keep_resized_image!(site, image) }
end
end end
end end
end end

View File

@ -6,13 +6,14 @@ module Jekyll
def process(image_path, config) def process(image_path, config)
absolute_image_path = File.expand_path(image_path.to_s, config[:site_source]) absolute_image_path = File.expand_path(image_path.to_s, config[:site_source])
Jekyll.logger.warn "Invalid image path specified: #{image_path.inspect}" unless File.file?(absolute_image_path) raise SyntaxError.new("Invalid image path specified: #{image_path}") unless File.file?(absolute_image_path)
resize_handler = ResizeHandler.new(absolute_image_path, config) resize_handler = ResizeHandler.new
img = Magick::Image::read(absolute_image_path).first
{ {
original: image_hash(config, image_path, resize_handler.original_image.columns, resize_handler.original_image.rows), original: image_hash(config, image_path, img.columns, img.rows),
resized: resize_handler.resize_image, resized: resize_handler.resize_image(img, config),
} }
end end

View File

@ -25,11 +25,7 @@ module Jekyll
partial = File.read(image_template) partial = File.read(image_template)
template = Liquid::Template.parse(partial) template = Liquid::Template.parse(partial)
info = { result = template.render!(@attributes.merge(@site.site_payload))
registers: { site: @site }
}
result = template.render!(@attributes.merge(@site.site_payload), info)
RenderCache.set(cache_key, result) RenderCache.set(cache_key, result)
end end

View File

@ -3,39 +3,26 @@ module Jekyll
class ResizeHandler class ResizeHandler
include ResponsiveImage::Utils include ResponsiveImage::Utils
attr_reader :original_image def resize_image(img, config)
img.auto_orient! if config['auto_rotate']
def initialize(original_image_absolute_path, config)
@config = config
@original_image_absolute_path = original_image_absolute_path
if @config['auto_rotate']
load_full_image
@original_image.auto_orient!
else
load_image_properties_only
end
end
def resize_image
resized = [] resized = []
@config['sizes'].each do |size| config['sizes'].each do |size|
width = size['width'] width = size['width']
ratio = width.to_f / @original_image.columns.to_f ratio = width.to_f / img.columns.to_f
height = (@original_image.rows.to_f * ratio).round height = (img.rows.to_f * ratio).round
next unless needs_resizing?(width) next unless needs_resizing?(img, width)
image_path = @original_image.filename.force_encoding(Encoding::UTF_8) image_path = img.filename.force_encoding(Encoding::UTF_8)
filepath = format_output_path(@config['output_path_format'], @config, image_path, width, height) filepath = format_output_path(config['output_path_format'], config, image_path, width, height)
resized.push(image_hash(@config, filepath, width, height)) resized.push(image_hash(config, filepath, width, height))
site_source_filepath = File.expand_path(filepath, @config[:site_source]) site_source_filepath = File.expand_path(filepath, config[:site_source])
site_dest_filepath = File.expand_path(filepath, @config[:site_dest]) site_dest_filepath = File.expand_path(filepath, config[:site_dest])
if @config['save_to_source'] if config['save_to_source']
target_filepath = site_source_filepath target_filepath = site_source_filepath
else else
target_filepath = site_dest_filepath target_filepath = site_dest_filepath
@ -49,22 +36,13 @@ module Jekyll
Jekyll.logger.info "Generating #{target_filepath}" Jekyll.logger.info "Generating #{target_filepath}"
load_full_image unless @original_image_pixels_loaded i = img.scale(ratio)
if @config['strip']
@original_image.strip!
end
i = @original_image.scale(ratio)
quality = size['quality'] || @config['default_quality']
i.write(target_filepath) do |f| i.write(target_filepath) do |f|
f.interlace = i.interlace f.interlace = i.interlace
f.quality = quality f.quality = size['quality'] || config['default_quality']
end end
if @config['save_to_source'] if config['save_to_source']
# Ensure the generated file is copied to the _site directory # Ensure the generated file is copied to the _site directory
Jekyll.logger.info "Copying resized image to #{site_dest_filepath}" Jekyll.logger.info "Copying resized image to #{site_dest_filepath}"
FileUtils.copy_file(site_source_filepath, site_dest_filepath) FileUtils.copy_file(site_source_filepath, site_dest_filepath)
@ -73,7 +51,7 @@ module Jekyll
i.destroy! i.destroy!
end end
@original_image.destroy! img.destroy!
resized resized
end end
@ -84,18 +62,8 @@ module Jekyll
Pathname.new(format % params).cleanpath.to_s Pathname.new(format % params).cleanpath.to_s
end end
def needs_resizing?(width) def needs_resizing?(img, width)
@original_image.columns > width img.columns > width
end
def load_full_image
@original_image = Magick::Image::read(@original_image_absolute_path).first
@original_image_pixels_loaded = true
end
def load_image_properties_only
@original_image = Magick::Image::ping(@original_image_absolute_path).first
@original_image_pixels_loaded = false
end end
def ensure_output_dir_exists!(path) def ensure_output_dir_exists!(path)

View File

@ -1,5 +1,5 @@
module Jekyll module Jekyll
module ResponsiveImage module ResponsiveImage
VERSION = '1.6.0'.freeze VERSION = '1.4.0'.freeze
end end
end end

View File

@ -1,25 +0,0 @@
{% comment %}
Render your responsive images using Imager.js (https://github.com/BBC-News/Imager.js/), with the smallest resized image used as a fallback.
Usage:
{% responsive_image path: assets/image.jpg alt: "A description of the image" %}
(P.S. You can safely delete this comment block)
{% endcomment %}
{% assign smallest = resized | sort: 'width' | first %}
<div class="responsive-image">
<img class="responsive-image__placeholder" src="/{{ smallest.path }}">
<div class="responsive-image__delayed" data-src="/assets/resized/{width}/{{ original.basename }}"></div>
</div>
<script>
new Imager('.responsive-image__delayed', {
availableWidths: [{{ resized | map: 'width' | join: ', ' }}],
onImagesReplaced: function() {
$('.responsive-image__placeholder').hide()
}
})
</script>

View File

@ -1,16 +0,0 @@
{% comment %}
Render your responsive images using <picture>, with the original asset used as a fallback. Note: If your original assets are not web-friendly (e.g. they are very large), you can use a resized image as the fallback instead. See the srcset-resized-fallback.html template for how to do this.
Usage:
{% responsive_image path: assets/image.jpg alt: "A description of the image" %}
(P.S. You can safely delete this comment block)
{% endcomment %}
<picture>
{% for i in resized %}
<source media="(min-width: {{ i.width }}px)" srcset="/{{ i.path }}">
{% endfor %}
<img src="/{{ path }}">
</picture>

View File

@ -1,18 +0,0 @@
{% comment %}
Render your responsive images using <img srcset>, with the largest resized image used as a fallback.
Usage:
{% responsive_image path: assets/image.jpg alt: "A description of the image" %}
(P.S. You can safely delete this comment block)
{% endcomment %}
{% assign largest = resized | sort: 'width' | last %}
{% capture srcset %}
{% for i in resized %}
/{{ i.path }} {{ i.width }}w,
{% endfor %}
{% endcapture %}
<img src="/{{ largest.path }}" alt="{{ alt }}" srcset="{{ srcset | strip_newlines }} /{{ path }} {{ original.width }}w">

View File

@ -1,17 +0,0 @@
{% comment %}
Render your responsive images using <img srcset>, with the original asset used as a fallback. Note: If your original assets are not web-friendly (e.g. they are very large), you might prefer to use the srcset-resized-fallback.html template.
Usage:
{% responsive_image path: assets/image.jpg alt: "A description of the image" %}
(P.S. You can safely delete this comment block)
{% endcomment %}
{% capture srcset %}
{% for i in resized %}
/{{ i.path }} {{ i.width }}w,
{% endfor %}
{% endcapture %}
<img src="/{{ path }}" alt="{{ alt }}" srcset="{{ srcset | strip_newlines }} /{{ path }} {{ original.width }}w">