Implement responsive_image_block tag
This commit is contained in:
parent
c8d48350b1
commit
6f9f13e62f
19
README.md
19
README.md
|
@ -78,6 +78,25 @@ Any extra attributes will be passed straight to the template as variables.
|
|||
{% 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 important!
|
||||
|
||||
```
|
||||
{% 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.
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
Feature: Jekyll responsive_image_block tag
|
||||
As a Jekyll template developer
|
||||
I want to include Liquid variables when rendering my responsive images
|
||||
In order to dynamically generate my responsive images
|
||||
|
||||
Scenario: Simple image tag
|
||||
Given I have a responsive_image configuration with:
|
||||
"""
|
||||
template: _includes/responsive-image.html
|
||||
"""
|
||||
And I have a file "index.html" with:
|
||||
"""
|
||||
{% assign path = 'assets/test.png' %}
|
||||
{% assign alt = 'Lorem ipsum' %}
|
||||
|
||||
{% responsive_image_block %}
|
||||
path: {{ path }}
|
||||
title: Magic rainbow adventure!
|
||||
alt: {{ alt }}
|
||||
{% endresponsive_image_block %}
|
||||
"""
|
||||
When I run Jekyll
|
||||
Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/test.png\" title=\"Magic rainbow adventure!\"" in "_site/index.html"
|
||||
|
||||
Scenario: More complex logic in the block tag
|
||||
Given I have a responsive_image configuration with:
|
||||
"""
|
||||
template: _includes/responsive-image.html
|
||||
"""
|
||||
And I have a file "index.html" with:
|
||||
"""
|
||||
{% assign path = 'assets/test.png' %}
|
||||
{% assign alt = 'Lorem ipsum' %}
|
||||
|
||||
{% responsive_image_block %}
|
||||
path: {{ path }}
|
||||
|
||||
{% if another_alt %}
|
||||
alt: {{ another_alt }}
|
||||
{% else %}
|
||||
alt: {{ alt }}
|
||||
{% endif %}
|
||||
{% endresponsive_image_block %}
|
||||
"""
|
||||
When I run Jekyll
|
||||
Then I should see "<img alt=\"Lorem ipsum\" src=\"/assets/test.png\"" in "_site/index.html"
|
|
@ -1,4 +1,4 @@
|
|||
Feature: Jekyll responsive-image tag
|
||||
Feature: Jekyll responsive_image tag
|
||||
As a Jekyll template developer
|
||||
I want to include responsive images in my page
|
||||
In order to best cater for devices of all sizes
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require 'fileutils'
|
||||
require 'yaml'
|
||||
|
||||
require 'jekyll'
|
||||
require 'rmagick'
|
||||
|
@ -6,6 +7,9 @@ require 'rmagick'
|
|||
require 'jekyll/responsive_image/version'
|
||||
require 'jekyll/responsive_image/defaults'
|
||||
require 'jekyll/responsive_image/utils'
|
||||
require 'jekyll/responsive_image/resize_handler'
|
||||
require 'jekyll/responsive_image/tag'
|
||||
require 'jekyll/responsive_image/block'
|
||||
|
||||
Liquid::Template.register_tag('responsive_image', Jekyll::ResponsiveImage::Tag)
|
||||
Liquid::Template.register_tag('responsive_image_block', Jekyll::ResponsiveImage::Block)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
module Jekyll
|
||||
class ResponsiveImage
|
||||
class Block < Liquid::Block
|
||||
def render(context)
|
||||
config = ResponsiveImage.defaults.dup
|
||||
config.merge!(context.registers[:site].config['responsive_image'])
|
||||
|
||||
attributes = YAML.load(super)
|
||||
image_template = attributes['template'] || config['template']
|
||||
|
||||
resize_handler = ResizeHandler.new
|
||||
img = Magick::Image::read(attributes['path']).first
|
||||
attributes['original'] = Utils.image_hash(attributes['path'], img.columns, img.rows)
|
||||
attributes['resized'] = resize_handler.resize_image(img, config)
|
||||
|
||||
partial = File.read(image_template)
|
||||
template = Liquid::Template.parse(partial)
|
||||
|
||||
template.render!(attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,52 @@
|
|||
module Jekyll
|
||||
class ResponsiveImage
|
||||
class ResizeHandler
|
||||
def resize_image(img, config)
|
||||
resized = []
|
||||
|
||||
config['sizes'].each do |size|
|
||||
width = size['width']
|
||||
ratio = width.to_f / img.columns.to_f
|
||||
height = (img.rows.to_f * ratio).round
|
||||
|
||||
next unless needs_resizing?(img, width)
|
||||
|
||||
filepath = format_output_path(config['output_path_format'], img.filename, width, height)
|
||||
resized.push(Utils.image_hash(filepath, width, height))
|
||||
|
||||
# Don't resize images more than once
|
||||
next if File.exists?(filepath)
|
||||
|
||||
ensure_output_dir_exists!(File.dirname(filepath))
|
||||
|
||||
Jekyll.logger.info "Generating #{filepath}"
|
||||
|
||||
i = img.scale(ratio)
|
||||
i.write(filepath) do |f|
|
||||
f.quality = size['quality'] || config['default_quality']
|
||||
end
|
||||
|
||||
i.destroy!
|
||||
end
|
||||
|
||||
resized
|
||||
end
|
||||
|
||||
def format_output_path(format, path, width, height)
|
||||
params = Utils.symbolize_keys(Utils.image_hash(path, width, height))
|
||||
format % params
|
||||
end
|
||||
|
||||
def needs_resizing?(img, width)
|
||||
img.columns > width
|
||||
end
|
||||
|
||||
def ensure_output_dir_exists!(dir)
|
||||
unless Dir.exists?(dir)
|
||||
Jekyll.logger.info "Creating output directory #{dir}"
|
||||
FileUtils.mkdir_p(dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,72 +12,14 @@ module Jekyll
|
|||
end
|
||||
end
|
||||
|
||||
def resize_image(img, config)
|
||||
resized = []
|
||||
|
||||
config['sizes'].each do |size|
|
||||
width = size['width']
|
||||
ratio = width.to_f / img.columns.to_f
|
||||
height = (img.rows.to_f * ratio).round
|
||||
|
||||
next unless needs_resizing?(img, width)
|
||||
|
||||
filepath = format_output_path(config['output_path_format'], img.filename, width, height)
|
||||
resized.push(image_hash(filepath, width, height))
|
||||
|
||||
# Don't resize images more than once
|
||||
next if File.exists?(filepath)
|
||||
|
||||
ensure_output_dir_exists!(File.dirname(filepath))
|
||||
|
||||
Jekyll.logger.info "Generating #{filepath}"
|
||||
|
||||
i = img.scale(ratio)
|
||||
i.write(filepath) do |f|
|
||||
f.quality = size['quality'] || config['default_quality']
|
||||
end
|
||||
|
||||
i.destroy!
|
||||
end
|
||||
|
||||
resized
|
||||
end
|
||||
|
||||
def format_output_path(format, path, width, height)
|
||||
params = Utils.symbolize_keys(image_hash(path, width, height))
|
||||
format % params
|
||||
end
|
||||
|
||||
def needs_resizing?(img, width)
|
||||
img.columns > width
|
||||
end
|
||||
|
||||
def ensure_output_dir_exists!(dir)
|
||||
unless Dir.exists?(dir)
|
||||
Jekyll.logger.info "Creating output directory #{dir}"
|
||||
FileUtils.mkdir_p(dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Build a hash containing image information
|
||||
def image_hash(path, width, height)
|
||||
{
|
||||
'path' => path,
|
||||
'basename' => File.basename(path),
|
||||
'filename' => File.basename(path, '.*'),
|
||||
'extension' => File.extname(path).delete('.'),
|
||||
'width' => width,
|
||||
'height' => height,
|
||||
}
|
||||
end
|
||||
|
||||
def render(context)
|
||||
config = ResponsiveImage.defaults.dup
|
||||
config.merge!(context.registers[:site].config['responsive_image'])
|
||||
|
||||
resize_handler = ResizeHandler.new
|
||||
img = Magick::Image::read(@attributes['path']).first
|
||||
@attributes['original'] = image_hash(@attributes['path'], img.columns, img.rows)
|
||||
@attributes['resized'] = resize_image(img, config)
|
||||
@attributes['original'] = Utils.image_hash(@attributes['path'], img.columns, img.rows)
|
||||
@attributes['resized'] = resize_handler.resize_image(img, config)
|
||||
|
||||
image_template = @attributes['template'] || config['template']
|
||||
|
||||
|
|
|
@ -8,6 +8,18 @@ module Jekyll
|
|||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Build a hash containing image information
|
||||
def self.image_hash(path, width, height)
|
||||
{
|
||||
'path' => path,
|
||||
'basename' => File.basename(path),
|
||||
'filename' => File.basename(path, '.*'),
|
||||
'extension' => File.extname(path).delete('.'),
|
||||
'width' => width,
|
||||
'height' => height,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue