├── .travis.yml ├── CODE_OF_CONDUCT.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── bin ├── linux-x64-cwebp ├── linux-x86-cwebp ├── osx-cwebp ├── win-x64-cwebp.exe └── win-x86-cwebp.exe ├── jekyll-webp.gemspec └── lib ├── jekyll-webp.rb └── jekyll-webp ├── defaults.rb ├── version.rb ├── webpExec.rb └── webpGenerator.rb /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | cache: bundler 3 | sudo: false 4 | rvm: 5 | - 2.2 6 | before_script: bundle update 7 | notifications: 8 | email: 9 | on_success: never 10 | on_failure: never -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [jekyll@sverrirs.com](mailto:jekyll@sverrirs.com). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in jekyll-webp.gemspec 4 | gemspec 5 | 6 | if ENV["JEKYLL_VERSION"] 7 | gem "jekyll", "~> #{ENV["JEKYLL_VERSION"]}" 8 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Sverrir Sigmundarson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Gem Version](https://img.shields.io/gem/v/jekyll-webp.svg)](https://rubygems.org/gems/jekyll-webp) 2 | [![Gem](https://img.shields.io/gem/dt/jekyll-webp.svg)](https://rubygems.org/gems/jekyll-webp) 3 | [![Join the chat at https://gitter.im/jekyll-webp/Lobby](https://badges.gitter.im/jekyll-webp/Lobby.svg)](https://gitter.im/jekyll-webp/Lobby) 4 | [![Dependency Status](https://gemnasium.com/badges/github.com/sverrirs/jekyll-webp.svg)](https://gemnasium.com/github.com/sverrirs/jekyll-webp) 5 | [![Code Climate](https://codeclimate.com/github/sverrirs/jekyll-webp/badges/gpa.svg)](https://codeclimate.com/github/sverrirs/jekyll-webp) 6 | [![security](https://hakiri.io/github/sverrirs/jekyll-webp/master.svg)](https://hakiri.io/github/sverrirs/jekyll-webp/master) 7 | 8 | # WebP Generator for Jekyll 9 | WebP Image Generator for Jekyll Sites can automatically generate WebP images for all images on your static site and serve them when possible. View on [rubygems.org](https://rubygems.org/gems/jekyll-webp). 10 | 11 | > Read more about this tool on my blog at blog.sverrirs.com 12 | 13 | ## Installation 14 | 15 | ``` 16 | gem install jekyll-webp 17 | ``` 18 | 19 | The release includes all necessary files to run, including the WebP redistributable executable files. 20 | 21 | > Currently the release includes the v0.6.1 version of the WebP utilities for Windows, Linux and Mac OS X 10.9 (Mountain Lion). Other versions and releases can be downloaded directly from the Google page. 22 | 23 | Add the gem to your `Gemfile` and to Jekyll's `_config.yml` then run `jekyll serve` again and you should see the generator run during site generation. 24 | 25 | ## Configuration 26 | The plugin can be configured in the site's `_config.yml` file by including the `webp` configuration element 27 | 28 | ``` yml 29 | ############################################################ 30 | # Site configuration for the WebP Generator Plugin 31 | # The values here represent the defaults if nothing is set 32 | webp: 33 | enabled: true 34 | 35 | # The quality of the webp conversion 0 to 100 (where 100 is least lossy) 36 | quality: 75 37 | 38 | # List of directories containing images to optimize, nested directories will only be checked if `nested` is true 39 | # By default the generator will search for a folder called `/img` under the site root and process all jpg, png and tiff image files found there. 40 | img_dir: ["/img"] 41 | 42 | # Whether to search in nested directories or not 43 | nested: false 44 | 45 | # add ".gif" to the format list to generate webp for animated gifs as well 46 | formats: [".jpeg", ".jpg", ".png", ".tiff"] 47 | 48 | # File extensions for animated gif files 49 | gifs: [".gif"] 50 | 51 | # Set to true to always regenerate existing webp files 52 | regenerate: false 53 | 54 | # Local path to the WebP utilities to use (relative or absolute) 55 | # Omit or leave as nil to use the utilities shipped with the gem, override only to use your local install 56 | # Eg : "/usr/local/bin/cwebp" 57 | webp_path: nil 58 | 59 | # List of files or directories to exclude 60 | # e.g. custom or hand generated webp conversion files 61 | exclude: [] 62 | 63 | # append '.webp' to filename after original extension rather than replacing it. 64 | # Default transforms `image.png` to `image.webp`, while changing to true transforms `image.png` to `image.png.webp` 65 | append_ext: false 66 | ############################################################ 67 | ``` 68 | 69 | ## Simplest use: HTML 70 | In case you don't have control over your webserver then using the `` element and specifying all image formats available is the best option. This way the browser will decide which format to use based on its own capabilities. 71 | 72 | ``` html 73 | 74 | 75 | 76 | 77 | ``` 78 | 79 | ## Advanced use: Webserver Configuration 80 | If you can, then configuring your webserver to serve your new _.webp_ files to clients that support the format is probably the least problematic approach. This way you don't need to make any changes to your HTML files as your webserver will automatically serve WebP images when the client supports them. 81 | 82 | Below is an example for a .htaccess configuration section in an Apache web-server. It will redirect users to webp images whenever possible. 83 | 84 | ``` 85 | #################### 86 | # Attempt to redirect images to WebP if one exists 87 | # and the client supports the file format 88 | #################### 89 | # check if browser accepts webp 90 | RewriteCond %{HTTP_ACCEPT} image/webp 91 | 92 | # check if file is jpg or png 93 | RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png)$ 94 | 95 | # check if corresponding webp file exists image.png -> image.webp 96 | RewriteCond %1\.webp -f 97 | 98 | # serve up webp instead 99 | RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1] 100 | 101 | AddType image/webp .webp 102 | ``` 103 | 104 | > Depending on other configurations in your `.htaccess` file you might have to update your `ExpiresByType`, `ExpiresDefault` and `Header set Cache-Control` directives to include the webp format as well. 105 | 106 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rake/testtask' 3 | 4 | Rake::TestTask.new do |t| 5 | t.libs.push 'lib' 6 | t.libs.push 'specs' 7 | t.verbose = true 8 | t.pattern = "spec/*_spec.rb" 9 | t.test_files = FileList['spec/*_spec.rb'] 10 | end 11 | 12 | desc "Run tests" 13 | task :default => [:test] -------------------------------------------------------------------------------- /bin/linux-x64-cwebp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sverrirs/jekyll-webp/162996d3def96558a07fda9c58679d08afafef1f/bin/linux-x64-cwebp -------------------------------------------------------------------------------- /bin/linux-x86-cwebp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sverrirs/jekyll-webp/162996d3def96558a07fda9c58679d08afafef1f/bin/linux-x86-cwebp -------------------------------------------------------------------------------- /bin/osx-cwebp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sverrirs/jekyll-webp/162996d3def96558a07fda9c58679d08afafef1f/bin/osx-cwebp -------------------------------------------------------------------------------- /bin/win-x64-cwebp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sverrirs/jekyll-webp/162996d3def96558a07fda9c58679d08afafef1f/bin/win-x64-cwebp.exe -------------------------------------------------------------------------------- /bin/win-x86-cwebp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sverrirs/jekyll-webp/162996d3def96558a07fda9c58679d08afafef1f/bin/win-x86-cwebp.exe -------------------------------------------------------------------------------- /jekyll-webp.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | require_relative 'lib/jekyll-webp/version' 3 | 4 | Gem::Specification.new do |spec| 5 | spec.name = "jekyll-webp" 6 | spec.version = Jekyll::Webp::VERSION 7 | spec.platform = Gem::Platform::RUBY 8 | spec.date = DateTime.now.strftime('%Y-%m-%d') 9 | spec.authors = ["Sverrir Sigmundarson"] 10 | spec.email = ["jekyll@sverrirs.com"] 11 | spec.homepage = "https://github.com/sverrirs/jekyll-webp" 12 | spec.license = "MIT" 13 | 14 | spec.summary = %q{WebP image generator for Jekyll 3 websites} 15 | spec.description = %q{WebP Image Generator for Jekyll 3 Sites that automatically generate WebP images for all images on your static site and serves them when possible. Includes the v0.6.1 version of the WebP utilities for Windows, Linux and Mac OS X 10.9 (Mountain Lion)} 16 | 17 | spec.files = Dir['CODE_OF_CONDUCT.md', 'README.md', 'LICENSE', 'Rakefile', '*.gemspec', 'Gemfile', 'lib/**/*', 'spec/**/*', 'bin/**/*'] 18 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 19 | spec.test_files = spec.files.grep(%r{^spec/}) 20 | spec.require_paths = ["lib"] 21 | 22 | spec.add_development_dependency "jekyll", "~> 3.0" 23 | spec.add_development_dependency "bundler", "~> 1.5" 24 | spec.add_development_dependency "rake", "~> 1.5" 25 | spec.add_development_dependency "minitest", '~> 5.4', '>= 5.4.3' 26 | end -------------------------------------------------------------------------------- /lib/jekyll-webp.rb: -------------------------------------------------------------------------------- 1 | require "jekyll-webp/version" 2 | require "jekyll-webp/defaults" 3 | require "jekyll-webp/webpExec" 4 | require "jekyll-webp/webpGenerator" 5 | 6 | module Jekyll 7 | module Webp 8 | end # module Webp 9 | end # module Jekyll -------------------------------------------------------------------------------- /lib/jekyll-webp/defaults.rb: -------------------------------------------------------------------------------- 1 | module Jekyll 2 | module Webp 3 | 4 | # The default configuration for the Webp generator 5 | # The values here represent the defaults if nothing is set 6 | DEFAULT = { 7 | 'enabled' => false, 8 | 9 | # The quality of the webp conversion 0 to 100 (where 100 is least lossy) 10 | 'quality' => 75, 11 | 12 | # Other flags to pass to the webp binary. For a list of valid parameters check here: 13 | # https://developers.google.com/speed/webp/docs/cwebp#options 14 | 'flags' => "-m 4 -pass 4 -af", 15 | 16 | # List of directories containing images to optimize, Nested directories only be checked if `nested` is true 17 | 'img_dir' => ["/img"], 18 | 19 | # Whether to search in nested directories or not 20 | 'nested' => false, 21 | 22 | # add ".gif" to the format list to generate webp for animated gifs as well 23 | 'formats' => [".jpeg", ".jpg", ".png", ".tiff"], 24 | 25 | # append .webp to existing extension instead of replacing it 26 | # (Enables more efficient nginx rules. 27 | # See http://www.lazutkin.com/blog/2014/02/23/serve-files-with-nginx-conditionally/) 28 | 'append_ext' => false, 29 | 30 | # File extensions for animated gif files 31 | 'gifs' => [".gif"], 32 | 33 | # Set to true to always regenerate existing webp files 34 | 'regenerate'=> false, 35 | 36 | # Local path to the WebP utilities to use (relative or absolute) 37 | # Leave as nil to use the cmd line utilities shipped with the gem, override to use your local install 38 | 'webp_path' => nil, 39 | 40 | # List of files or directories to exclude 41 | # e.g. custom or hand generated webp conversion files 42 | 'exclude' => [], 43 | 44 | # List of files or directories to explicitly include 45 | # e.g. single files outside of the main image directories 46 | 'include' => [] 47 | } 48 | 49 | end # module Webp 50 | end # module Jekyll 51 | -------------------------------------------------------------------------------- /lib/jekyll-webp/version.rb: -------------------------------------------------------------------------------- 1 | module Jekyll 2 | module Webp 3 | VERSION = "1.0.0" 4 | # When modifying remember to issue a new tag command in git before committing, then push the new tag 5 | # git tag -a v1.0.0 -m "Gem v1.0.0" 6 | # git push origin --tags 7 | end #module Webp 8 | end #module Jekyll 9 | -------------------------------------------------------------------------------- /lib/jekyll-webp/webpExec.rb: -------------------------------------------------------------------------------- 1 | require 'open3' 2 | 3 | module Jekyll 4 | module Webp 5 | 6 | class WebpExec 7 | 8 | # 9 | # Runs the WebP executable for the given input parameters 10 | # the function detects the OS platform and architecture automatically 11 | # 12 | def self.run(quality, flags, input_file, output_file, webp_bin_fullpath) 13 | 14 | if webp_bin_fullpath 15 | full_path = webp_bin_fullpath 16 | else 17 | # What is the path to the execs inside the gem? perhaps just bin/? 18 | bin_path = "bin/" 19 | 20 | # What is the OS and architecture specific executable name? 21 | exe_name = WebpExec.exe_name 22 | 23 | # We need to locate the Gems bin path as we're currently running inside the 24 | # jekyll site working directory 25 | # http://stackoverflow.com/a/10083594/779521 26 | gem_spec = Gem::Specification.find_by_name("jekyll-webp") 27 | gem_root = gem_spec.gem_dir 28 | 29 | # Construct the full path to the executable 30 | full_path = File.join(gem_root, bin_path, exe_name) 31 | end 32 | 33 | # Construct the full program call 34 | cmd = "\"#{full_path}\" -quiet -mt -q #{quality.to_s} #{flags} \"#{input_file}\" -o \"#{output_file}\"" 35 | 36 | # Execute the command 37 | exit_code = 0 38 | error = "" 39 | output = "" 40 | Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr| 41 | stdin.close # we don't pass any input to the process 42 | output = stdout.gets 43 | error = stderr.gets 44 | exit_code = wait_thr.value 45 | end 46 | 47 | if exit_code != 0 48 | Jekyll.logger.error("WebP:","Conversion for image #{input_file} failed, no webp version could be created for this image") 49 | Jekyll.logger.debug("WebP:","cwebp returned #{exit_code} with error #{error}") 50 | end 51 | 52 | # Return any captured return value 53 | return [output, error] 54 | end #function run 55 | 56 | # 57 | # Returns the correct executable name depending on the OS platform and OS architecture 58 | # 59 | def self.exe_name 60 | if OS.mac? 61 | return "osx-cwebp" 62 | elsif OS.windows? 63 | if OS.x32? 64 | return "win-x86-cwebp.exe" 65 | else 66 | return "win-x64-cwebp.exe" 67 | end 68 | elsif OS.unix? || OS.linux? 69 | if OS.x32? 70 | return "linux-x86-cwebp" 71 | else 72 | return "linux-x64-cwebp" 73 | end 74 | else 75 | raise ArgumentError.new("OS platform could not be identified (gem can only be run on linux,osx or windows)") 76 | end 77 | end #function exe_name 78 | 79 | end #class WebpExec 80 | 81 | end #module Webp 82 | 83 | module OS 84 | def OS.windows? 85 | (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil 86 | end 87 | 88 | def OS.mac? 89 | (/darwin/ =~ RUBY_PLATFORM) != nil 90 | end 91 | 92 | def OS.unix? 93 | !OS.windows? 94 | end 95 | 96 | def OS.linux? 97 | OS.unix? and not OS.mac? 98 | end 99 | 100 | def OS.x32? 101 | return 1.size != 8 102 | end 103 | 104 | def OS.x64? 105 | return 1.size == 8 106 | end 107 | end #module OS 108 | end #module Jekyll 109 | -------------------------------------------------------------------------------- /lib/jekyll-webp/webpGenerator.rb: -------------------------------------------------------------------------------- 1 | require 'jekyll/document' 2 | require 'fileutils' 3 | 4 | module Jekyll 5 | module Webp 6 | 7 | # 8 | # A static file to hold the generated webp image after generation 9 | # so that Jekyll will copy it into the site output directory 10 | class WebpFile < StaticFile 11 | def write(dest) 12 | true # Recover from strange exception when starting server without --auto 13 | end 14 | end #class WebpFile 15 | 16 | class WebpGenerator < Generator 17 | # This generator is safe from arbitrary code execution. 18 | safe true 19 | 20 | # This generator should be passive with regard to its execution 21 | priority :lowest 22 | 23 | # Generate paginated pages if necessary (Default entry point) 24 | # site - The Site. 25 | # 26 | # Returns nothing. 27 | def generate(site) 28 | 29 | # Retrieve and merge the configuration from the site yml file 30 | @config = DEFAULT.merge(site.config['webp'] || {}) 31 | 32 | # If disabled then simply quit 33 | if !@config['enabled'] 34 | Jekyll.logger.info "WebP:","Disabled in site.config." 35 | return 36 | end 37 | 38 | Jekyll.logger.debug "WebP:","Starting" 39 | 40 | # If the site destination directory has not yet been created then create it now. Otherwise, we cannot write our file there. 41 | Dir::mkdir(site.dest) if !File.directory? site.dest 42 | 43 | # If nesting is enabled, get all the nested directories too 44 | if @config['nested'] 45 | newdir = [] 46 | for imgdir in @config['img_dir'] 47 | # Get every directory below (and including) imgdir, recursively 48 | newdir.concat(Dir.glob(imgdir + "/**/")) 49 | end 50 | @config['img_dir'] = newdir 51 | end 52 | 53 | # Counting the number of files generated 54 | file_count = 0 55 | 56 | # Iterate through every image in each of the image folders and create a webp image 57 | # if one has not been created already for that image. 58 | for imgdir in @config['img_dir'] 59 | imgdir_source = File.join(site.source, imgdir) 60 | imgdir_destination = File.join(site.dest, imgdir) 61 | FileUtils::mkdir_p(imgdir_destination) 62 | Jekyll.logger.info "WebP:","Processing #{imgdir_source}" 63 | 64 | # handle only jpg, jpeg, png and gif 65 | for imgfile in Dir[imgdir_source + "**/*.*"] 66 | imgfile_relative_path = File.dirname(imgfile.sub(imgdir_source, "")) 67 | 68 | # Skip empty stuff 69 | file_ext = File.extname(imgfile).downcase 70 | 71 | # If the file is not one of the supported formats, exit early 72 | next if !@config['formats'].include? file_ext 73 | 74 | # TODO: Do an exclude check 75 | 76 | # Create the output file path 77 | outfile_filename = if @config['append_ext'] 78 | File.basename(imgfile) + '.webp' 79 | else 80 | file_noext = File.basename(imgfile, file_ext) 81 | file_noext + ".webp" 82 | end 83 | FileUtils::mkdir_p(imgdir_destination + imgfile_relative_path) 84 | outfile_fullpath_webp = File.join(imgdir_destination + imgfile_relative_path, outfile_filename) 85 | 86 | # Check if the file already has a webp alternative? 87 | # If we're force rebuilding all webp files then ignore the check 88 | # also check the modified time on the files to ensure that the webp file 89 | # is newer than the source file, if not then regenerate 90 | if @config['regenerate'] || !File.file?(outfile_fullpath_webp) || 91 | File.mtime(outfile_fullpath_webp) <= File.mtime(imgfile) 92 | Jekyll.logger.info "WebP:", "Change to source image file #{imgfile} detected, regenerating WebP" 93 | 94 | # Generate the file 95 | WebpExec.run(@config['quality'], @config['flags'], imgfile, outfile_fullpath_webp, @config['webp_path']) 96 | file_count += 1 97 | end 98 | if File.file?(outfile_fullpath_webp) 99 | # Keep the webp file from being cleaned by Jekyll 100 | site.static_files << WebpFile.new(site, 101 | site.dest, 102 | File.join(imgdir, imgfile_relative_path), 103 | outfile_filename) 104 | end 105 | end # dir.foreach 106 | end # img_dir 107 | 108 | Jekyll.logger.info "WebP:","Generator Complete: #{file_count} file(s) generated" 109 | 110 | end #function generate 111 | 112 | end #class WebPGenerator 113 | 114 | end #module Webp 115 | end #module Jekyll 116 | --------------------------------------------------------------------------------