Compare commits

...

35 Commits

Author SHA1 Message Date
Joseph Wynn
0b01bc0f05 0.18.0 2016-09-02 22:06:45 +01:00
Joseph Wynn
756eccc5c3 UTF-8 support (#31)
* Create failing test case

* Force image filename encoding to UTF-8. Fixes #30
2016-09-02 08:53:29 +01:00
Joseph Wynn
f8c699c6de Lock to earlier version of simplecov for older Ruby platforms (#32)
* Lock to earlier version of simplecov for older Ruby platforms

Necessary due to the loose json dependency detailed in colszowka/simplecov#511

* Stop running tests on Rubinius (I'm sorry, rbx users!)
2016-09-02 08:41:42 +01:00
Joseph Wynn
b0da1e1a4e Nope, it's definitely jekyll/responsive_image 2016-07-23 11:16:38 +01:00
Kevin Funk
fd201e770c update README.md to include brace expansion option (#27) 2016-07-08 09:03:26 +01:00
Nathan Arthur
301d9bf466 Add option alt support into srcset template (#24) 2016-06-08 09:50:23 +01:00
Joseph Wynn
2f7e4effcd 0.17.0 2016-06-05 22:33:13 +01:00
Joseph Wynn
a3a5511c68 Resize extra images (#23)
* Switch deprecated {File,Dir}#exists? for #exist?

* Implement extra_images configuration.

Closes #21.
2016-06-05 22:32:13 +01:00
Joseph Wynn
17cf3dac3b Trigger RenderCache#get by including an image twice (#22) 2016-06-05 22:30:45 +01:00
Joseph Wynn
68cf843bd7 Everything is nicer with square badges 2016-03-17 08:45:02 +00:00
Joseph Wynn
e8dc907fb7 0.16.0 2016-03-17 08:27:20 +00:00
Joseph Wynn
1853bc19cb Merge pull request #19 from padenot/patch-1
Destroy the original image when done with resizing
2016-03-17 08:26:34 +00:00
Paul Adenot
89114ab2be Destroy the original image when done with resizing
When re-sizing a bunch of 24 megapixels image (direct from a digital camera) into responsive images, not destroying the `img` member made my server OOM (it does not have a lot of RAM, it's a cheap VPS).

Additionally, when re-generating the site, although there was no need to re-generate the images, it looked like it was still loading them up, and the GC was not kicking in so it was OOM-ing (or close to OOM-ing) as well.

This fixes both issues.
2016-03-16 18:35:34 +01:00
Joseph Wynn
a0166e8cbe Merge pull request #16 from wildlyinaccurate/only-build-on-rubinius-2
Restrict Rubinius versions to 2.x
2016-02-26 12:30:40 +00:00
Joseph Wynn
7fc132a808 Restrict Rubinius versions to 2.x 2016-02-26 12:20:50 +00:00
Joseph Wynn
4000e0532f Improve installation instructions. Closes #14. 2016-02-25 09:03:51 +00:00
Joseph Wynn
f6b42d264f v0.15.0 2016-02-02 20:58:18 +00:00
Joseph Wynn
b117107385 Merge pull request #12 from wildlyinaccurate/experimental-result-caching
[Experimental] enable internal caching of responsive_image tag results
2016-02-02 20:52:31 +00:00
Joseph Wynn
c9b9c97faf [Experimental] enable internal caching of responsive_image_block tag results 2016-02-02 20:46:22 +00:00
Joseph Wynn
1565091d6e [Experimental] enable internal caching of responsive_image tag results 2016-02-02 20:33:24 +00:00
Joseph Wynn
f297cf4c6e v0.14.0 2016-01-12 08:17:20 +00:00
Joseph Wynn
3a60fcf266 Merge pull request #9 from wildlyinaccurate/dirname-in-image-hash
Add `dirname` to image hashes
2016-01-11 09:12:23 +00:00
Joseph Wynn
b0c38098c8 Modify dirname to be relative to base_path 2015-12-27 22:41:04 +00:00
Joseph Wynn
76f834ce09 Add dirname to image hashes. Closes #5. 2015-12-27 21:14:24 +00:00
Joseph Wynn
9e122233e5 Merge pull request #11 from wildlyinaccurate/output-jekyll-version-on-build
Output Jekyll version on build
2015-12-26 18:46:03 +00:00
Joseph Wynn
fd418bb7f6 Output Jekyll version on build 2015-12-26 18:40:15 +00:00
Joseph Wynn
350adaa8d7 Merge pull request #10 from wildlyinaccurate/update-dependencies
Restrain rmagick to 2.x
2015-12-26 18:39:48 +00:00
Joseph Wynn
7500a6aef2 Tweak README 2015-12-26 18:34:45 +00:00
Joseph Wynn
8c9a131317 Restrain rmagick to 2.x 2015-12-26 18:24:00 +00:00
Joseph Wynn
64954f8610 Merge pull request #8 from wildlyinaccurate/update-travis-build
Run on container infra; run against latest patch versions and jruby
2015-12-26 18:07:36 +00:00
Joseph Wynn
54237df9e0 Run on container infra; run against latest patch versions and jruby 2015-12-26 17:27:13 +00:00
Joseph Wynn
66a9ef9759 0.13.0 2015-11-05 09:24:24 +00:00
Joseph Wynn
29fa70fea4 Merge pull request #3 from wildlyinaccurate/inject-jekyll-payload-into-liquid-attributes
Inject the Jekyll Site payload into the Liquid render attributes
2015-11-05 09:24:02 +00:00
Joseph Wynn
0c4a8e82e4 Add global variable test for block tag 2015-11-05 09:18:53 +00:00
Joseph Wynn
173205ec66 Inject the Jekyll Site payload into the Liquid render attributes
This enables the use of `site` and `jekyll` variables.

Closes #1.
2015-11-05 09:03:44 +00:00
23 changed files with 299 additions and 80 deletions

View File

@ -1,9 +1,10 @@
sudo: false
language: ruby language: ruby
bundler_args: --without debug bundler_args: --without debug
before_script: bundle exec jekyll --version
script: bundle exec rake features_with_coveralls script: bundle exec rake features_with_coveralls
rvm: rvm:
- 2.2.0 - 2.2
- 2.1.0 - 2.1
- 2.0.0 - 2.0
- 1.9.3 - 1.9
- rbx-2

View File

@ -7,4 +7,8 @@ group :development do
gem 'test-unit', '~> 3.1' gem 'test-unit', '~> 3.1'
gem 'coveralls', :require => false gem 'coveralls', :require => false
platform :ruby_18, :ruby_19 do
gem 'simplecov', '>= 0.10', '< 0.12'
end
end end

View File

@ -2,24 +2,25 @@
Jekyll Responsive Images is 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/). Jekyll Responsive Images is 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://travis-ci.org/wildlyinaccurate/jekyll-responsive-image.svg?branch=master)](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://coveralls.io/repos/wildlyinaccurate/jekyll-responsive-images/badge.svg?branch=master&service=github)](https://coveralls.io/github/wildlyinaccurate/jekyll-responsive-images?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://gemnasium.com/wildlyinaccurate/jekyll-responsive-images.svg)](https://gemnasium.com/wildlyinaccurate/jekyll-responsive-images) [![Dependency Status](https://img.shields.io/gemnasium/wildlyinaccurate/jekyll-responsive-images.svg?style=flat-square)](https://gemnasium.com/wildlyinaccurate/jekyll-responsive-images)
## Installation ## Installation
You can either use the gem and update your `_config.yml`: First, install the gem:
``` ```
$ gem install jekyll-responsive_image $ gem install jekyll-responsive_image
``` ```
Then you can either add it to the `gems` section of your `_config.yml`:
```yaml ```yaml
# _config.yml gems: [jekyll/responsive_image]
gems: [jekyll-responsive_image]
``` ```
Or you can simply copy [`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.
## Configuration ## Configuration
@ -45,11 +46,17 @@ responsive_image:
- width: 1400 - width: 1400
quality: 90 quality: 90
# [Optional, Default: assets]
# The base directory where assets are stored. This is used to determine the
# `dirname` value in `output_path_format` below.
base_path: assets
# [Optional, Default: assets/resized/%{filename}-%{width}x%{height}.%{extension}] # [Optional, Default: assets/resized/%{filename}-%{width}x%{height}.%{extension}]
# The template used when generating filenames for resized images. Must be a # The template used when generating filenames for resized images. Must be a
# relative path. # relative path.
# #
# Parameters available are: # Parameters available are:
# %{dirname} Directory of the file relative to `base_path` (assets/sub/dir/some-file.jpg => sub/dir)
# %{basename} Basename of the file (assets/some-file.jpg => some-file.jpg) # %{basename} Basename of the file (assets/some-file.jpg => some-file.jpg)
# %{filename} Basename without the extension (assets/some-file.jpg => some-file) # %{filename} Basename without the extension (assets/some-file.jpg => some-file)
# %{extension} Extension of the file (assets/some-file.jpg => jpg) # %{extension} Extension of the file (assets/some-file.jpg => jpg)
@ -57,6 +64,14 @@ responsive_image:
# %{height} Height of the resized image # %{height} Height of the resized image
# #
output_path_format: assets/resized/%{width}/%{basename} output_path_format: assets/resized/%{width}/%{basename}
# By default, only images referenced by the responsive_image and responsive_image_block
# tags are resized. Here you can set a list of paths or path globs to resize other
# images. This is useful for resizing images which will be referenced from stylesheets.
extra_images:
- assets/foo/bar.png
- assets/bgs/*.png
- assets/avatars/*.{jpeg,jpg}
``` ```
## Usage ## Usage
@ -83,7 +98,7 @@ Any extra attributes will be passed straight to the template as variables.
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. 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 important! > **Important!** The attributes in the `responsive_image_block` tag are parsed as YAML, so whitespace and indentation are significant!
```twig ```twig
{% assign path = 'assets/test.png' %} {% assign path = 'assets/test.png' %}
@ -111,7 +126,7 @@ You will need to create a template in order to use the `responsive_image` tag. B
{% endfor %} {% endfor %}
{% endcapture %} {% endcapture %}
<img src="/{{ path }}" srcset="{{ srcset | strip_newlines }} /{{ original.path }} {{ original.width }}w"> <img src="/{{ path }}" alt="{{ alt }}" srcset="{{ srcset | strip_newlines }} /{{ original.path }} {{ original.width }}w">
``` ```
#### Responsive images with `<picture>` #### Responsive images with `<picture>`
@ -127,7 +142,7 @@ You will need to create a template in order to use the `responsive_image` tag. B
#### Responsive images using [Imager.js](https://github.com/BBC-News/Imager.js/) #### Responsive images using [Imager.js](https://github.com/BBC-News/Imager.js/)
> This template assumes an `output_path_format` of `assets/resized/%{width}/%{basename}` > **Note:** This template assumes an `output_path_format` of `assets/resized/%{width}/%{basename}`
```twig ```twig
{% assign smallest = resized | sort: 'width' | first %} {% assign smallest = resized | sort: 'width' | first %}
@ -162,11 +177,12 @@ The following variables are available in the template:
Image objects (like `original` and each object in `resized`) contain the following properties: Image objects (like `original` and each object in `resized`) contain the following properties:
| Variable | Type | Description | | Variable | Type | Description |
|-------------|---------|-------------------------------------------------------------------------| |-------------|---------|----------------------------------------------------------------------------------------------|
| `path` | String | The path to the image. | | `path` | String | The path to the image. |
| `width` | Integer | The width of the image. | | `width` | Integer | The width of the image. |
| `height` | Integer | The height of the image. | | `height` | Integer | The height of the image. |
| `basename` | String | Basename of the file (`assets/some-file.jpg` => `some-file.jpg`). | | `basename` | String | Basename of the file (`assets/some-file.jpg` => `some-file.jpg`). |
| `filename` | String | Basename without the extension (`assets/some-file.jpg` => `some-file`). | | `dirname` | String | Directory of the file relative to `base_path` (`assets/sub/dir/some-file.jpg` => `sub/dir`). |
| `extension` | String | Extension of the file (`assets/some-file.jpg` => `jpg`). | | `filename` | String | Basename without the extension (`assets/some-file.jpg` => `some-file`). |
| `extension` | String | Extension of the file (`assets/some-file.jpg` => `jpg`). |

View File

@ -0,0 +1,43 @@
Feature: Extra image generation
As a Jekyll user
I want to resize images that aren't used in posts or pages
In order to use them in my stylesheets
Scenario: Resizing a single image
Given I have a responsive_image configuration with:
"""
sizes:
- width: 100
extra_images:
- assets/everybody-loves-jalapeño-pineapple-cornbread.png
"""
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"
Scenario: Using glob patterns
Given I have a responsive_image configuration with:
"""
sizes:
- width: 100
extra_images:
- assets/*.png
"""
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"
Scenario: No extra images
Given I have a responsive_image configuration with:
"""
sizes:
- width: 100
"""
And I have a file "index.html" with "Hello, world!"
When I run Jekyll
Then the file "assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should not exist

View File

@ -0,0 +1 @@
<img src="{{ site.baseurl }}/{{ path }}">

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,36 @@
Feature: Responsive image generation
As a Jekyll user
I want to generate responsive images
In order to use them on my pages
Scenario: Resizing images
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/everybody-loves-jalapeño-pineapple-cornbread.png alt: Foobar %}"
When I run Jekyll
Then the image "assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should have the dimensions "100x50"
Scenario: Handling subdirectories
Given I have a responsive_image configuration with:
"""
template: _includes/responsive-image.html
output_path_format: assets/resized/%{dirname}/%{filename}-%{width}.%{extension}
sizes:
- width: 100
"""
And I have a file "index.html" with:
"""
{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png %}
{% responsive_image path: assets/subdir/test.png %}
{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png cache: true %}
"""
When I run Jekyll
Then the file "assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100.png" should exist
And the file "assets/resized/subdir/test-100.png" should exist

View File

@ -7,7 +7,7 @@ Feature: Jekyll responsive_image_block tag
Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html" Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html"
And I have a file "index.html" with: And I have a file "index.html" with:
""" """
{% assign path = 'assets/test.png' %} {% assign path = 'assets/everybody-loves-jalapeño-pineapple-cornbread.png' %}
{% assign alt = 'Lorem ipsum' %} {% assign alt = 'Lorem ipsum' %}
{% responsive_image_block %} {% responsive_image_block %}
@ -17,13 +17,29 @@ Feature: Jekyll responsive_image_block tag
{% endresponsive_image_block %} {% endresponsive_image_block %}
""" """
When I run Jekyll When I run Jekyll
Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/test.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: Global variables available in templates
Given I have a file "index.html" with:
"""
{% responsive_image_block %}
path: assets/everybody-loves-jalapeño-pineapple-cornbread.png
{% endresponsive_image_block %}
"""
And I have a configuration with:
"""
baseurl: https://wildlyinaccurate.com
responsive_image:
template: _includes/base-url.html
"""
When I run Jekyll
Then I should see "<img src=\"https://wildlyinaccurate.com/assets/everybody-loves-jalapeño-pineapple-cornbread.png\">" in "_site/index.html"
Scenario: More complex logic in the block tag Scenario: More complex logic in the block tag
Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html" Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html"
And I have a file "index.html" with: And I have a file "index.html" with:
""" """
{% assign path = 'assets/test.png' %} {% assign path = 'assets/everybody-loves-jalapeño-pineapple-cornbread.png' %}
{% assign alt = 'Lorem ipsum' %} {% assign alt = 'Lorem ipsum' %}
{% responsive_image_block %} {% responsive_image_block %}
@ -37,7 +53,7 @@ Feature: Jekyll responsive_image_block tag
{% endresponsive_image_block %} {% endresponsive_image_block %}
""" """
When I run Jekyll When I run Jekyll
Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/test.png\"" in "_site/index.html" Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\"" in "_site/index.html"
Scenario: Handling a nil path Scenario: Handling a nil path
Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html" Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html"

View File

@ -5,24 +5,35 @@ Feature: Jekyll responsive_image tag
Scenario: Simple image tag Scenario: Simple image tag
Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html" Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html"
And I have a file "index.html" with "{% responsive_image path: assets/test.png alt: Foobar %}" And I have a file "index.html" with "{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png alt: Foobar %}"
When I run Jekyll When I run Jekyll
Then I should see "<img alt=\"Foobar\" src=\"/assets/test.png\"" in "_site/index.html" Then I should see "<img alt=\"Foobar\" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\"" in "_site/index.html"
Scenario: Global variables available in templates
Given I have a file "index.html" with "{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png %}"
And I have a configuration with:
"""
baseurl: https://wildlyinaccurate.com
responsive_image:
template: _includes/base-url.html
"""
When I run Jekyll
Then I should see "<img src=\"https://wildlyinaccurate.com/assets/everybody-loves-jalapeño-pineapple-cornbread.png\">" in "_site/index.html"
Scenario: Adding custom attributes Scenario: Adding custom attributes
Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html" Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html"
And I have a file "index.html" with: And I have a file "index.html" with:
""" """
{% responsive_image path: assets/test.png alt: 'Foobar bazbar' title: "Lorem Ipsum" %} {% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png alt: 'Foobar bazbar' title: "Lorem Ipsum" %}
""" """
When I run Jekyll When I run Jekyll
Then I should see "<img alt=\"Foobar bazbar\" src=\"/assets/test.png\" title=\"Lorem Ipsum\"" in "_site/index.html" Then I should see "<img alt=\"Foobar bazbar\" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\" title=\"Lorem Ipsum\"" in "_site/index.html"
Scenario: UTF-8 attributes Scenario: UTF-8 attributes
Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html" Given I have a responsive_image configuration with "template" set to "_includes/responsive-image.html"
And I have a file "index.html" with "{% responsive_image path: assets/test.png alt: ' ' %}" And I have a file "index.html" with "{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png alt: ' ' %}"
When I run Jekyll When I run Jekyll
Then I should see "<img alt=\" \" src=\"/assets/test.png\"" in "_site/index.html" Then I should see "<img alt=\" \" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\"" in "_site/index.html"
Scenario: Image with multiple sizes Scenario: Image with multiple sizes
Given I have a responsive_image configuration with: Given I have a responsive_image configuration with:
@ -32,14 +43,14 @@ Feature: Jekyll responsive_image tag
- width: 100 - width: 100
- width: 200 - width: 200
""" """
And I have a file "index.html" with "{% responsive_image path: assets/test.png %}" And I have a file "index.html" with "{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png %}"
When I run Jekyll When I run Jekyll
Then I should see "<img alt=\"\" src=\"/assets/test.png\"" in "_site/index.html" Then I should see "<img alt=\"\" src=\"/assets/everybody-loves-jalapeño-pineapple-cornbread.png\"" in "_site/index.html"
And I should see "/assets/resized/test-100x50.png 100w" in "_site/index.html" And I should see "/assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png 100w" in "_site/index.html"
And I should see "/assets/resized/test-200x100.png 200w" in "_site/index.html" And I should see "/assets/resized/everybody-loves-jalapeño-pineapple-cornbread-200x100.png 200w" in "_site/index.html"
And I should see "/assets/test.png 300w" in "_site/index.html" And I should see "/assets/everybody-loves-jalapeño-pineapple-cornbread.png 300w" in "_site/index.html"
And the file "assets/resized/test-100x50.png" should exist And the file "assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should exist
And the file "assets/resized/test-200x100.png" should exist And the file "assets/resized/everybody-loves-jalapeño-pineapple-cornbread-200x100.png" should exist
Scenario: Overriding the template Scenario: Overriding the template
Given I have a responsive_image configuration with: Given I have a responsive_image configuration with:
@ -50,7 +61,7 @@ Feature: Jekyll responsive_image tag
- width: 200 - width: 200
- width: 300 - width: 300
""" """
And I have a file "index.html" with "{% responsive_image path: assets/test.png template: _includes/custom-template.html %}" And I have a file "index.html" with "{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png template: _includes/custom-template.html %}"
When I run Jekyll When I run Jekyll
Then I should see "[100, 200, 300]" in "_site/index.html" Then I should see "[100, 200, 300]" in "_site/index.html"
@ -58,11 +69,11 @@ Feature: Jekyll responsive_image tag
Given I have a responsive_image configuration with: Given I have a responsive_image configuration with:
""" """
template: _includes/responsive-image.html template: _includes/responsive-image.html
output_path_format: assets/%{basename}-resized/%{width}/%{filename}-%{height}.%{extension} output_path_format: assets/%{dirname}/%{basename}-resized/%{width}/%{filename}-%{height}.%{extension}
sizes: sizes:
- width: 100 - width: 100
""" """
And I have a file "index.html" with "{% responsive_image path: assets/test.png %}" And I have a file "index.html" with "{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png %}"
When I run Jekyll When I run Jekyll
Then I should see "/assets/test.png-resized/100/test-50.png 100w" in "_site/index.html" Then I should see "/assets/everybody-loves-jalapeño-pineapple-cornbread.png-resized/100/everybody-loves-jalapeño-pineapple-cornbread-50.png 100w" in "_site/index.html"
And the file "assets/test.png-resized/100/test-50.png" should exist And the file "assets/everybody-loves-jalapeño-pineapple-cornbread.png-resized/100/everybody-loves-jalapeño-pineapple-cornbread-50.png" should exist

View File

@ -8,6 +8,10 @@ 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
Given /^I have a configuration with:$/ do |config|
write_file('_config.yml', config)
end
Given /^I have a responsive_image configuration with:$/ do |config| Given /^I have a responsive_image configuration with:$/ do |config|
write_file('_config.yml', "responsive_image:\n#{config}") write_file('_config.yml', "responsive_image:\n#{config}")
end end
@ -29,7 +33,17 @@ Then /^I should see "(.+)" in "(.*)"$/ do |text, file|
end end
Then /^the file "(.+)" should exist$/ do |path| Then /^the file "(.+)" should exist$/ do |path|
assert File.exists?(path) assert File.exist?(path)
end
Then /^the file "(.+)" should not exist$/ do |path|
assert !File.exist?(path)
end
Then /^the image "(.+)" should have the dimensions "(\d+)x(\d+)"$/ do |path, width, height|
img = Magick::Image::read(path).first
assert_equal "#{width}x#{height}", "#{img.columns}x#{img.rows}"
img.destroy!
end end
def write_file(path, contents) def write_file(path, contents)

View File

@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
end end
spec.add_runtime_dependency 'jekyll', ['>= 2.0', "< #{max_jekyll_version}"] spec.add_runtime_dependency 'jekyll', ['>= 2.0', "< #{max_jekyll_version}"]
spec.add_runtime_dependency 'rmagick' spec.add_runtime_dependency 'rmagick', ['>= 2.0', '< 3.0']
end end

View File

@ -7,11 +7,13 @@ require 'rmagick'
require 'jekyll/responsive_image/version' require 'jekyll/responsive_image/version'
require 'jekyll/responsive_image/defaults' require 'jekyll/responsive_image/defaults'
require 'jekyll/responsive_image/utils' require 'jekyll/responsive_image/utils'
require 'jekyll/responsive_image/render_cache'
require 'jekyll/responsive_image/image_processor' require 'jekyll/responsive_image/image_processor'
require 'jekyll/responsive_image/resize_handler' require 'jekyll/responsive_image/resize_handler'
require 'jekyll/responsive_image/common' require 'jekyll/responsive_image/common'
require 'jekyll/responsive_image/tag' require 'jekyll/responsive_image/tag'
require 'jekyll/responsive_image/block' require 'jekyll/responsive_image/block'
require 'jekyll/responsive_image/extra_image_generator'
Liquid::Template.register_tag('responsive_image', Jekyll::ResponsiveImage::Tag) Liquid::Template.register_tag('responsive_image', Jekyll::ResponsiveImage::Tag)
Liquid::Template.register_tag('responsive_image_block', Jekyll::ResponsiveImage::Block) Liquid::Template.register_tag('responsive_image_block', Jekyll::ResponsiveImage::Block)

View File

@ -4,19 +4,30 @@ module Jekyll
include Jekyll::ResponsiveImage::Common include Jekyll::ResponsiveImage::Common
def render(context) def render(context)
config = make_config(context.registers[:site])
attributes = YAML.load(super) attributes = YAML.load(super)
image_template = attributes['template'] || config['template']
image = ImageProcessor.process(attributes['path'], config) cache_key = attributes.to_s
attributes['original'] = image[:original] result = attributes['cache'] ? RenderCache.get(cache_key) : nil
attributes['resized'] = image[:resized]
partial = File.read(image_template) if result.nil?
template = Liquid::Template.parse(partial) site = context.registers[:site]
config = make_config(site)
template.render!(attributes) image_template = attributes['template'] || config['template']
image = ImageProcessor.process(attributes['path'], config)
attributes['original'] = image[:original]
attributes['resized'] = image[:resized]
partial = File.read(image_template)
template = Liquid::Template.parse(partial)
result = template.render!(attributes.merge(site.site_payload))
RenderCache.set(cache_key, result)
end
result
end end
end end
end end

View File

@ -7,7 +7,9 @@ module Jekyll
config = ResponsiveImage.defaults.dup.merge(site.config['responsive_image']).merge(:site_dest => site.dest) config = ResponsiveImage.defaults.dup.merge(site.config['responsive_image']).merge(:site_dest => site.dest)
# Not very nice, but this is needed to create a clean path to add to keep_files # Not very nice, but this is needed to create a clean path to add to keep_files
output_dir = format_output_path(config['output_path_format'], '*', '*', '*') output_dir = format_output_path(config['output_path_format'], config['base_path'], '*', '*', '*')
output_dir = "#{File.dirname(output_dir)}/*"
site.config['keep_files'] << output_dir unless site.config['keep_files'].include?(output_dir) site.config['keep_files'] << output_dir unless site.config['keep_files'].include?(output_dir)
config config

View File

@ -2,8 +2,10 @@ module Jekyll
class ResponsiveImage class ResponsiveImage
@defaults = { @defaults = {
'default_quality' => 85, 'default_quality' => 85,
'base_path' => 'assets',
'output_path_format' => 'assets/resized/%{filename}-%{width}x%{height}.%{extension}', 'output_path_format' => 'assets/resized/%{filename}-%{width}x%{height}.%{extension}',
'sizes' => [], 'sizes' => [],
'extra_images' => []
}.freeze }.freeze
class << self class << self

View File

@ -0,0 +1,15 @@
module Jekyll
class ResponsiveImage
class ExtraImageGenerator < Jekyll::Generator
include Jekyll::ResponsiveImage::Common
def generate(site)
config = make_config(site)
config['extra_images'].each do |pathspec|
Dir.glob(pathspec) { |path| ImageProcessor.process(path, config) }
end
end
end
end
end

View File

@ -4,13 +4,13 @@ module Jekyll
include ResponsiveImage::Utils include ResponsiveImage::Utils
def process(image_path, config) def process(image_path, config)
raise SyntaxError.new("Invalid image path specified: #{image_path}") unless File.exists?(image_path.to_s) raise SyntaxError.new("Invalid image path specified: #{image_path}") unless File.exist?(image_path.to_s)
resize_handler = ResizeHandler.new resize_handler = ResizeHandler.new
img = Magick::Image::read(image_path).first img = Magick::Image::read(image_path).first
{ {
original: image_hash(image_path, img.columns, img.rows), original: image_hash(config['base_path'], image_path, img.columns, img.rows),
resized: resize_handler.resize_image(img, config), resized: resize_handler.resize_image(img, config),
} }
end end

View File

@ -0,0 +1,21 @@
module Jekyll
class ResponsiveImage
class RenderCache
attr_accessor :store
class << self
def store
@store ||= {}
end
def get(key)
store[key]
end
def set(key, val)
store[key] = val
end
end
end
end
end

View File

@ -13,11 +13,12 @@ module Jekyll
next unless needs_resizing?(img, width) next unless needs_resizing?(img, width)
filepath = format_output_path(config['output_path_format'], img.filename, width, height) image_path = img.filename.force_encoding(Encoding::UTF_8)
resized.push(image_hash(filepath, width, height)) filepath = format_output_path(config['output_path_format'], config['base_path'], image_path, width, height)
resized.push(image_hash(config['base_path'], filepath, width, height))
# Don't resize images more than once # Don't resize images more than once
next if File.exists?(filepath) next if File.exist?(filepath)
ensure_output_dir_exists!(File.dirname(filepath)) ensure_output_dir_exists!(File.dirname(filepath))
@ -36,6 +37,8 @@ module Jekyll
i.destroy! i.destroy!
end end
img.destroy!
resized resized
end end
@ -44,7 +47,7 @@ module Jekyll
end end
def ensure_output_dir_exists!(dir) def ensure_output_dir_exists!(dir)
unless Dir.exists?(dir) unless Dir.exist?(dir)
Jekyll.logger.info "Creating output directory #{dir}" Jekyll.logger.info "Creating output directory #{dir}"
FileUtils.mkdir_p(dir) FileUtils.mkdir_p(dir)
end end

View File

@ -15,18 +15,28 @@ module Jekyll
end end
def render(context) def render(context)
config = make_config(context.registers[:site]) cache_key = @attributes.to_s
result = @attributes['cache'] ? RenderCache.get(cache_key) : nil
image = ImageProcessor.process(@attributes['path'], config) if result.nil?
@attributes['original'] = image[:original] site = context.registers[:site]
@attributes['resized'] = image[:resized] config = make_config(site)
image_template = @attributes['template'] || config['template'] image = ImageProcessor.process(@attributes['path'], config)
@attributes['original'] = image[:original]
@attributes['resized'] = image[:resized]
partial = File.read(image_template) image_template = @attributes['template'] || config['template']
template = Liquid::Template.parse(partial)
template.render!(@attributes) partial = File.read(image_template)
template = Liquid::Template.parse(partial)
result = template.render!(@attributes.merge(site.site_payload))
RenderCache.set(cache_key, result)
end
result
end end
end end
end end

View File

@ -1,3 +1,5 @@
require 'pathname'
module Jekyll module Jekyll
class ResponsiveImage class ResponsiveImage
module Utils module Utils
@ -9,22 +11,31 @@ module Jekyll
result result
end end
def format_output_path(format, path, width, height) def format_output_path(format, base_path, image_path, width, height)
params = symbolize_keys(image_hash(path, width, height)) params = symbolize_keys(image_hash(base_path, image_path, width, height))
format % params
Pathname.new(format % params).cleanpath.to_s
end end
# Build a hash containing image information # Build a hash containing image information
def image_hash(path, width, height) def image_hash(base_path, image_path, width, height)
{ {
'path' => path, 'path' => image_path,
'basename' => File.basename(path), 'dirname' => relative_dirname(base_path, image_path),
'filename' => File.basename(path, '.*'), 'basename' => File.basename(image_path),
'extension' => File.extname(path).delete('.'), 'filename' => File.basename(image_path, '.*'),
'extension' => File.extname(image_path).delete('.'),
'width' => width, 'width' => width,
'height' => height, 'height' => height,
} }
end end
def relative_dirname(base_path, image_path)
path = Pathname.new(image_path).expand_path
base = Pathname.new(base_path).expand_path
path.relative_path_from(base).dirname.to_s.delete('.')
end
end end
end end
end end

View File

@ -1,5 +1,5 @@
module Jekyll module Jekyll
class ResponsiveImage class ResponsiveImage
VERSION = '0.12.0'.freeze VERSION = '0.18.0'.freeze
end end
end end