jekyll-assets 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +2 -0
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/LICENSE +22 -0
- data/README.md +120 -0
- data/Rakefile +9 -0
- data/jekyll-assets.gemspec +27 -0
- data/lib/jekyll-assets.rb +1 -0
- data/lib/jekyll/assets_plugin.rb +16 -0
- data/lib/jekyll/assets_plugin/asset_file.rb +45 -0
- data/lib/jekyll/assets_plugin/configuration.rb +98 -0
- data/lib/jekyll/assets_plugin/generator.rb +26 -0
- data/lib/jekyll/assets_plugin/logging.rb +10 -0
- data/lib/jekyll/assets_plugin/site_patch.rb +56 -0
- data/lib/jekyll/assets_plugin/tag.rb +104 -0
- data/lib/jekyll/assets_plugin/version.rb +5 -0
- data/spec/fixtures/.gitignore +1 -0
- data/spec/fixtures/_assets/app.css.erb +5 -0
- data/spec/fixtures/_assets/app.js +1 -0
- data/spec/fixtures/_assets/noise.png +0 -0
- data/spec/fixtures/_assets/vapor.css +1 -0
- data/spec/fixtures/_assets/vapor.js +1 -0
- data/spec/fixtures/_config.yml +2 -0
- data/spec/fixtures/_layouts/default.html +9 -0
- data/spec/fixtures/_posts/2012-10-19-hello-world.md +6 -0
- data/spec/fixtures/index.html +0 -0
- data/spec/lib/jekyll/assets_plugin/asset_file_spec.rb +12 -0
- data/spec/lib/jekyll/assets_plugin/configuration_spec.rb +84 -0
- data/spec/lib/jekyll/assets_plugin/generator_spec.rb +12 -0
- data/spec/lib/jekyll/assets_plugin/logging_spec.rb +17 -0
- data/spec/lib/jekyll/assets_plugin/site_patch_spec.rb +47 -0
- data/spec/lib/jekyll/assets_plugin/tag_spec.rb +81 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/fixtures_path.rb +12 -0
- metadata +203 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require ./lib/jekyll-assets --color --format documentation
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Aleksey V Zapparov (http://ixti.net/)
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# Jekyll::AssetsPlugin
|
2
|
+
|
3
|
+
Jekyll plugin, that adds Rails-alike assets pipelines.
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'jekyll-assets'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install jekyll-assets
|
19
|
+
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Add this line to your sites `_plugins/ext.rb`:
|
24
|
+
|
25
|
+
require 'jekyll-assets'
|
26
|
+
|
27
|
+
Put your assets under following paths:
|
28
|
+
|
29
|
+
- `_assets/javascripts`
|
30
|
+
- `_assets/stylesheets`
|
31
|
+
- `_assets/images`
|
32
|
+
|
33
|
+
Name your "main" asset files `app.js` and `app.css` and use liquid tags:
|
34
|
+
|
35
|
+
- `{% javascript app %}` to output `<script>` tag for `app.js`
|
36
|
+
- `{% stylesheet app %}` to output `<link>` tag for `app.css`
|
37
|
+
- `{% asset_path logo.jpg %}` to output URL for `logo.jpg`
|
38
|
+
|
39
|
+
In order to use these tags, assets must be "bundled". By default only `app.js`,
|
40
|
+
`app.css`, and all files with extensions `.jpg`, `.png` or `.gif` are bundled.
|
41
|
+
You can change this by tuning up you `_config.yml` (see below).
|
42
|
+
|
43
|
+
|
44
|
+
## Configuration
|
45
|
+
|
46
|
+
You can fine-tune configuration by editing your `_config.yml`:
|
47
|
+
|
48
|
+
assets:
|
49
|
+
#
|
50
|
+
# Pathname of the destination of generated (bundled) assets relative
|
51
|
+
# to the destination of the root.
|
52
|
+
#
|
53
|
+
dirname: assets
|
54
|
+
#
|
55
|
+
# Pathnames where to find assets relative to the root of the site.
|
56
|
+
#
|
57
|
+
sources:
|
58
|
+
- _assets/javascripts
|
59
|
+
- _assets/stylesheets
|
60
|
+
- _assets/images
|
61
|
+
#
|
62
|
+
# Array of filenames or filename patterns that needs to be generated for
|
63
|
+
# the generated site. You can use `*` and `**` wildcards in patterns:
|
64
|
+
#
|
65
|
+
# 'foobar.jpg' will match 'foobar.jpg' only
|
66
|
+
# '*.jpg' will match 'foo.jpg', but not 'foo/bar.jpg'
|
67
|
+
# '**.jpg' will match 'foo.jpg', 'foo/bar.jpg', etc.
|
68
|
+
#
|
69
|
+
bundles:
|
70
|
+
- 'app.css'
|
71
|
+
- 'app.js'
|
72
|
+
- '**.jpg'
|
73
|
+
- '**.png'
|
74
|
+
- '**.gif'
|
75
|
+
#
|
76
|
+
# Sets compressors for the specific types of file: `js`, or `css`.
|
77
|
+
# No compression by default.
|
78
|
+
#
|
79
|
+
# Possible variants:
|
80
|
+
#
|
81
|
+
# css => 'yui', 'sass', nil
|
82
|
+
# js => 'yui', 'unglifier', nil
|
83
|
+
#
|
84
|
+
compress:
|
85
|
+
js: ~
|
86
|
+
css: ~
|
87
|
+
|
88
|
+
|
89
|
+
## Contributing
|
90
|
+
|
91
|
+
1. Fork it
|
92
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
93
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
94
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
95
|
+
5. Create new Pull Request
|
96
|
+
|
97
|
+
|
98
|
+
## License
|
99
|
+
|
100
|
+
Copyright (C) 2012 Aleksey V Zapparov (http://ixti.net/)
|
101
|
+
|
102
|
+
The MIT License
|
103
|
+
|
104
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
105
|
+
this software and associated documentation files (the “Software”), to deal in
|
106
|
+
the Software without restriction, including without limitation the rights to
|
107
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
108
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
109
|
+
so, subject to the following conditions:
|
110
|
+
|
111
|
+
The above copyright notice and this permission notice shall be included in all
|
112
|
+
copies or substantial portions of the Software.
|
113
|
+
|
114
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
115
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
116
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
117
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
118
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
119
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
120
|
+
SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/jekyll/assets_plugin/version', __FILE__)
|
3
|
+
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "jekyll-assets"
|
7
|
+
gem.version = Jekyll::AssetsPlugin::VERSION
|
8
|
+
gem.homepage = "http://ixti.github.com/jekyll-assets"
|
9
|
+
gem.authors = %w{Aleksey V Zapparov}
|
10
|
+
gem.email = %w{ixti@member.fsf.org}
|
11
|
+
gem.summary = "jekyll-assets-#{Jekyll::AssetsPlugin::VERSION}"
|
12
|
+
gem.description = %q{Adds assets pipelines for Jekyll}
|
13
|
+
|
14
|
+
gem.add_dependency "jekyll"
|
15
|
+
gem.add_dependency "sprockets", "~> 2.8"
|
16
|
+
|
17
|
+
gem.add_development_dependency "rake"
|
18
|
+
gem.add_development_dependency "rspec"
|
19
|
+
gem.add_development_dependency "guard-rspec"
|
20
|
+
gem.add_development_dependency "rb-inotify"
|
21
|
+
|
22
|
+
gem.files = `git ls-files`.split($\)
|
23
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
24
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
25
|
+
|
26
|
+
gem.require_paths = ["lib"]
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'jekyll/assets_plugin'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'jekyll'
|
2
|
+
require 'liquid'
|
3
|
+
|
4
|
+
|
5
|
+
require 'jekyll/assets_plugin/generator'
|
6
|
+
require 'jekyll/assets_plugin/site_patch'
|
7
|
+
require 'jekyll/assets_plugin/tag'
|
8
|
+
require 'jekyll/assets_plugin/version'
|
9
|
+
|
10
|
+
|
11
|
+
Jekyll::Site.send :include, Jekyll::AssetsPlugin::SitePatch
|
12
|
+
|
13
|
+
|
14
|
+
Liquid::Template.register_tag('javascript', Jekyll::AssetsPlugin::Tag)
|
15
|
+
Liquid::Template.register_tag('stylesheet', Jekyll::AssetsPlugin::Tag)
|
16
|
+
Liquid::Template.register_tag('asset_path', Jekyll::AssetsPlugin::Tag)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
module AssetsPlugin
|
7
|
+
# Represents single asset that can be used as StaticFile for Site
|
8
|
+
#
|
9
|
+
class AssetFile
|
10
|
+
@@mtimes = Hash.new
|
11
|
+
|
12
|
+
attr_reader :asset
|
13
|
+
|
14
|
+
def initialize site, asset
|
15
|
+
@site, @asset = site, asset
|
16
|
+
end
|
17
|
+
|
18
|
+
def destination dest
|
19
|
+
File.join(dest, @site.assets_config.dirname, @asset.digest_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def path
|
23
|
+
@asset.pathname.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def mtime
|
27
|
+
@asset.mtime.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
def modified?
|
31
|
+
@@mtimes[path] != mtime
|
32
|
+
end
|
33
|
+
|
34
|
+
def write dest
|
35
|
+
dest_path = destination dest
|
36
|
+
|
37
|
+
return false if File.exist?(dest_path) and !modified?
|
38
|
+
@@mtimes[path] = mtime
|
39
|
+
|
40
|
+
@asset.write_to dest_path
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# stdlib
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
module AssetsPlugin
|
7
|
+
# Plugin configuration class.
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# ##### sources
|
11
|
+
#
|
12
|
+
# Pathnames where to find assets relative to the root of the site.
|
13
|
+
#
|
14
|
+
# Default: ['_assets/javascripts', '_assets/stylesheets', '_assets/images']
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# ##### bundles
|
18
|
+
#
|
19
|
+
# Array of filenames or filename patterns that needs to be generated for the
|
20
|
+
# generated site. You can use `*` and `**` wildcards in filename patterns:
|
21
|
+
#
|
22
|
+
# 'foobar.jpg' will match 'foobar.jpg' only
|
23
|
+
# '*.jpg' will match 'foo.jpg', but not 'foo/bar.jpg'
|
24
|
+
# '**.jpg' will match 'foo.jpg', 'foo/bar.jpg', etc.
|
25
|
+
#
|
26
|
+
# Default: ['app.css', 'app.js', '**.jpg', '**.png', '**.gif']
|
27
|
+
#
|
28
|
+
#
|
29
|
+
# ##### compress
|
30
|
+
#
|
31
|
+
# Sets compressors for the specific types of file: `js`, or `css`.
|
32
|
+
#
|
33
|
+
# Possible variants:
|
34
|
+
#
|
35
|
+
# css => 'yui', 'sass', nil
|
36
|
+
# js => 'yui', 'unglifier', nil
|
37
|
+
#
|
38
|
+
# Default: { 'css' => nil, 'js' => nil } (no compression at all)
|
39
|
+
#
|
40
|
+
#
|
41
|
+
# ##### dirname
|
42
|
+
#
|
43
|
+
# Pathname of the destination of generated (bundled) assets relative to the
|
44
|
+
# destination of the root.
|
45
|
+
#
|
46
|
+
# Default: 'assets'
|
47
|
+
#
|
48
|
+
class Configuration < OpenStruct
|
49
|
+
@@defaults = {
|
50
|
+
:dirname => 'assets',
|
51
|
+
:sources => %w{_assets/javascripts _assets/stylesheets _assets/images},
|
52
|
+
:bundles => %w{app.css app.js **.jpg **.png **.gif},
|
53
|
+
:compress => { :css => nil, :js => nil }
|
54
|
+
}
|
55
|
+
|
56
|
+
def initialize config = {}
|
57
|
+
super @@defaults.merge(config)
|
58
|
+
|
59
|
+
self.sources = [ self.sources ] if self.sources.is_a? String
|
60
|
+
self.bundles = [ self.bundles ] if self.bundles.is_a? String
|
61
|
+
|
62
|
+
self.compress = OpenStruct.new(self.compress)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns bundles array with pattern strings converted to RegExps
|
66
|
+
#
|
67
|
+
# 'foobar.jpg' => 'foobar.jpg'
|
68
|
+
# '*.png' => /[^\]+\.png/
|
69
|
+
# '**.gif' => /.+?\.gif/
|
70
|
+
#
|
71
|
+
def bundle_filenames
|
72
|
+
bundles.map do |pattern|
|
73
|
+
if pattern =~ /^\*/
|
74
|
+
pattern = pattern.dup
|
75
|
+
|
76
|
+
pattern.gsub!(/\./, '\\.')
|
77
|
+
pattern.sub!(/\*{2}/, '.+?')
|
78
|
+
pattern.sub!(/\*{1}/, '[^/]+')
|
79
|
+
|
80
|
+
pattern = /^#{pattern}$/
|
81
|
+
end
|
82
|
+
|
83
|
+
pattern
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def js_compressor
|
88
|
+
return compress.js.to_sym if compress.js
|
89
|
+
false
|
90
|
+
end
|
91
|
+
|
92
|
+
def css_compressor
|
93
|
+
return compress.css.to_sym if compress.css
|
94
|
+
false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# internal
|
2
|
+
require 'jekyll/assets_plugin/logging'
|
3
|
+
require 'jekyll/assets_plugin/asset_file'
|
4
|
+
|
5
|
+
|
6
|
+
module Jekyll
|
7
|
+
module AssetsPlugin
|
8
|
+
# Jekyll hook that bundles all files specified in `bundles` config
|
9
|
+
#
|
10
|
+
class Generator < ::Jekyll::Generator
|
11
|
+
include Logging
|
12
|
+
|
13
|
+
safe false
|
14
|
+
priority :low
|
15
|
+
|
16
|
+
def generate site
|
17
|
+
filenames = site.assets_config.bundle_filenames
|
18
|
+
site.assets.each_logical_path(filenames).each do |logical_path|
|
19
|
+
if asset = site.assets.find_asset(logical_path)
|
20
|
+
site.static_files << AssetFile.new(site, asset) if asset
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# 3rd-party
|
2
|
+
require 'sprockets'
|
3
|
+
|
4
|
+
|
5
|
+
# internal
|
6
|
+
require 'jekyll/assets_plugin/asset_file'
|
7
|
+
require 'jekyll/assets_plugin/configuration'
|
8
|
+
|
9
|
+
|
10
|
+
module Jekyll
|
11
|
+
module AssetsPlugin
|
12
|
+
# Patch that provides #assets and #assets_config to Site
|
13
|
+
#
|
14
|
+
module SitePatch
|
15
|
+
def assets_config
|
16
|
+
@assets_config ||= Configuration.new(self.config['assets'] || {})
|
17
|
+
end
|
18
|
+
|
19
|
+
def assets
|
20
|
+
unless @assets
|
21
|
+
@assets = Sprockets::Environment.new(self.source)
|
22
|
+
|
23
|
+
assets_config.sources.each(&@assets.method(:append_path))
|
24
|
+
|
25
|
+
if js_compressor = assets_config.js_compressor
|
26
|
+
@assets.js_compressor = js_compressor
|
27
|
+
end
|
28
|
+
|
29
|
+
if css_compressor = assets_config.css_compressor
|
30
|
+
@assets.css_compressor = css_compressor
|
31
|
+
end
|
32
|
+
|
33
|
+
@assets.context_class.class_eval <<-RUBY, __FILE__, __LINE__
|
34
|
+
def asset_path(path, options = {})
|
35
|
+
asset = environment.find_asset path, options
|
36
|
+
raise FileNotFound, "couldn't find file '\#{path}'" unless asset
|
37
|
+
"/#{assets_config.dirname}/\#{asset.digest_path}".squeeze "/"
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
end
|
41
|
+
|
42
|
+
@assets
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_bundled_asset? asset
|
46
|
+
if asset.is_a? String
|
47
|
+
asset = assets[asset]
|
48
|
+
end
|
49
|
+
|
50
|
+
!self.static_files.index do |file|
|
51
|
+
file.is_a? AssetFile and file.asset == asset
|
52
|
+
end.nil?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# 3rd-party
|
2
|
+
require 'liquid'
|
3
|
+
|
4
|
+
|
5
|
+
# stdlib
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
|
9
|
+
# internal
|
10
|
+
require 'jekyll/assets_plugin/logging'
|
11
|
+
|
12
|
+
|
13
|
+
module Jekyll
|
14
|
+
module AssetsPlugin
|
15
|
+
# Class that implements some useful liquid tags:
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# ##### stylesheet
|
19
|
+
#
|
20
|
+
# Renders `<link>` tag for a logical path:
|
21
|
+
#
|
22
|
+
# {% stylesheet foo.css %}
|
23
|
+
# # => '<link type="text/css" rel="stylesheet"
|
24
|
+
# href="/assets/foo-b39e528efc3afe2def4bbc39de17f2b82cd8bd0d.css">
|
25
|
+
#
|
26
|
+
# You may omit extension so the following will give same result as above:
|
27
|
+
#
|
28
|
+
# {% stylesheet foo %}
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# ##### javascript
|
32
|
+
#
|
33
|
+
# Renders `<script>` tag for a logical path:
|
34
|
+
#
|
35
|
+
# {% javascript foo.js %}
|
36
|
+
# # => '<script type="text/javascript"
|
37
|
+
# src="/assets/foo-b39e528efc3afe2def4bbc39de17f2b82cd8bd0d.js">
|
38
|
+
# </script>
|
39
|
+
#
|
40
|
+
# You may omit extension so the following will give same result as above:
|
41
|
+
#
|
42
|
+
# {% javascript foo %}
|
43
|
+
#
|
44
|
+
#
|
45
|
+
# ##### asset_path
|
46
|
+
#
|
47
|
+
# Renders asset path for an asset (useful for images):
|
48
|
+
#
|
49
|
+
# {% asset_path foo.jpg %}
|
50
|
+
# # => '/assets/foo-b39e528efc3afe2def4bbc39de17f2b82cd8bd0d.jpg"
|
51
|
+
#
|
52
|
+
#
|
53
|
+
class Tag < Liquid::Tag
|
54
|
+
include Logging
|
55
|
+
|
56
|
+
STYLESHEET = '<link rel="stylesheet" type="text/css" href="%s">'
|
57
|
+
JAVASCRIPT = '<script type="text/javascript" src="%s"></script>'
|
58
|
+
EXTENSIONS = { 'stylesheet' => '.css', 'javascript' => '.js' }
|
59
|
+
|
60
|
+
@@errors = Set.new
|
61
|
+
|
62
|
+
def initialize tag_name, logical_path, tokens
|
63
|
+
super
|
64
|
+
|
65
|
+
@logical_path = logical_path.strip
|
66
|
+
|
67
|
+
# append auto-guessed extension if needed
|
68
|
+
@logical_path << default_extension if File.extname(@logical_path).empty?
|
69
|
+
end
|
70
|
+
|
71
|
+
def default_extension
|
72
|
+
EXTENSIONS[@tag_name].to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
def asset_not_found
|
76
|
+
if @@errors.add? @logical_path
|
77
|
+
log :error, "File not found: #{@logical_path}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def asset_not_bundled
|
82
|
+
if @@errors.add? @logical_path
|
83
|
+
log :warn, "File was not bundled: #{@logical_path}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def render context
|
88
|
+
site = context.registers[:site]
|
89
|
+
asset = site.assets[@logical_path]
|
90
|
+
|
91
|
+
return asset_not_found unless asset
|
92
|
+
return asset_not_bundled unless site.has_bundled_asset? asset
|
93
|
+
|
94
|
+
url = "/#{site.assets_config.dirname}/#{asset.digest_path}".squeeze "/"
|
95
|
+
|
96
|
+
case @tag_name
|
97
|
+
when 'stylesheet' then STYLESHEET % [url]
|
98
|
+
when 'javascript' then JAVASCRIPT % [url]
|
99
|
+
else url
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
_site/
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require vapor
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
/* vapor css framework */
|
@@ -0,0 +1 @@
|
|
1
|
+
/* vapor js framework */
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Jekyll::AssetsPlugin
|
5
|
+
describe AssetFile do
|
6
|
+
context '#destination' do
|
7
|
+
let(:file) { AssetFile.new(@site, @site.assets['app.css']) }
|
8
|
+
subject { file.destination @dest.to_s }
|
9
|
+
it { should match %r{/app-[0-9a-f]{32}\.css$} }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Jekyll::AssetsPlugin
|
5
|
+
describe Configuration do
|
6
|
+
let(:defaults) do
|
7
|
+
{
|
8
|
+
:dirname => 'assets',
|
9
|
+
:sources => %w{_assets/javascripts _assets/stylesheets _assets/images},
|
10
|
+
:bundles => %w{app.css app.js **.jpg **.png **.gif}
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with defaults' do
|
15
|
+
let(:config){ Configuration.new }
|
16
|
+
|
17
|
+
context 'output assets dirname' do
|
18
|
+
subject { config.dirname }
|
19
|
+
it { should == defaults[:dirname] }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'sources list' do
|
23
|
+
subject { config.sources }
|
24
|
+
it { should =~ defaults[:sources] }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'bundles list' do
|
28
|
+
subject { config.bundles }
|
29
|
+
it { should =~ defaults[:bundles] }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'js compressor' do
|
33
|
+
subject { config.compress.js }
|
34
|
+
it { should be_nil }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'css compressor' do
|
38
|
+
subject { config.compress.css }
|
39
|
+
it { should be_nil }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should override specified options and leave defaults for missing' do
|
44
|
+
config = Configuration.new({
|
45
|
+
:sources => %w{abc},
|
46
|
+
:compress => { :css => 'sass' }
|
47
|
+
})
|
48
|
+
|
49
|
+
config.dirname.should == 'assets'
|
50
|
+
config.sources.should =~ %w{abc}
|
51
|
+
config.bundles.should =~ defaults[:bundles]
|
52
|
+
config.compress.js.should be_nil
|
53
|
+
config.compress.css.should == 'sass'
|
54
|
+
end
|
55
|
+
|
56
|
+
context '#js_compressor' do
|
57
|
+
context 'when js compressor is given as "uglify"' do
|
58
|
+
let(:config){ Configuration.new(:compress => {:js => 'uglify'}) }
|
59
|
+
subject { config.js_compressor }
|
60
|
+
it { should be :uglify }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'otherwise' do
|
64
|
+
let(:config){ Configuration.new }
|
65
|
+
subject { config.js_compressor }
|
66
|
+
it { should be_false }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context '#css_compressor' do
|
71
|
+
context 'when js compressor is given as "sass"' do
|
72
|
+
let(:config){ Configuration.new(:compress => {:css => 'sass'}) }
|
73
|
+
subject { config.css_compressor }
|
74
|
+
it { should be :sass }
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'otherwise' do
|
78
|
+
let(:config){ Configuration.new }
|
79
|
+
subject { config.css_compressor }
|
80
|
+
it { should be_false }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Jekyll::AssetsPlugin
|
5
|
+
describe Generator do
|
6
|
+
it 'should output bundled files only' do
|
7
|
+
files = []
|
8
|
+
@dest.join('assets').each_child(false, &files.method(:push))
|
9
|
+
files.map(&:to_s).should have(3).thing
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Jekyll::AssetsPlugin
|
5
|
+
describe Logging do
|
6
|
+
it 'puts strings with [AssetsPlugin] prefix' do
|
7
|
+
loggable = Class.new do
|
8
|
+
include Logging
|
9
|
+
# make sure #log is public
|
10
|
+
def log(*args) super; end
|
11
|
+
end.new
|
12
|
+
|
13
|
+
loggable.should_receive(:puts).with(match %r{^\[AssetsPlugin\]})
|
14
|
+
loggable.log :info, 'test'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Jekyll::AssetsPlugin
|
5
|
+
describe SitePatch do
|
6
|
+
let(:site) do
|
7
|
+
Class.new do
|
8
|
+
include SitePatch
|
9
|
+
|
10
|
+
def config
|
11
|
+
@config ||= {
|
12
|
+
'bundles' => 'foobar',
|
13
|
+
'assets' => { 'sources' => 'foobar' }
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def source
|
18
|
+
@soure ||= '.'
|
19
|
+
end
|
20
|
+
end.new
|
21
|
+
end
|
22
|
+
|
23
|
+
context '#assets' do
|
24
|
+
subject { site.assets }
|
25
|
+
it { should be_an_instance_of Sprockets::Environment }
|
26
|
+
end
|
27
|
+
|
28
|
+
context '#assets_config' do
|
29
|
+
subject { site.assets_config }
|
30
|
+
it { should be_an_instance_of Configuration }
|
31
|
+
|
32
|
+
it 'should been populated with `assets` section of config' do
|
33
|
+
site.assets_config.bundles.should_not =~ %w{foobar}
|
34
|
+
site.assets_config.sources.should =~ %w{foobar}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should be included into Jekyll::Site' do
|
39
|
+
Jekyll::Site.included_modules.should include SitePatch
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should respond to #has_bundled_asset?' do
|
43
|
+
@site.has_bundled_asset?(@site.assets['app.css']).should be_true
|
44
|
+
@site.has_bundled_asset?(@site.assets['normalize.css']).should be_false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Jekyll::AssetsPlugin
|
5
|
+
describe Tag do
|
6
|
+
let(:context) { { :registers => { :site => @site } } }
|
7
|
+
|
8
|
+
def render content
|
9
|
+
Liquid::Template.parse(content).render({}, context)
|
10
|
+
end
|
11
|
+
|
12
|
+
context '{% stylesheet <file> %}' do
|
13
|
+
let(:tag_re) do
|
14
|
+
%r{^#{Tag::STYLESHEET % ['/assets/app-[a-f0-9]{32}\.css']}$}
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when <file> is bundled' do
|
18
|
+
subject { render('{% stylesheet app.css %}') }
|
19
|
+
it { should match tag_re }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when <file> extension is omited' do
|
23
|
+
subject { render('{% stylesheet app %}') }
|
24
|
+
it { should match tag_re }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when <file> is not found' do
|
28
|
+
subject { render('{% stylesheet not-found.css %}') }
|
29
|
+
it { should be_empty }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when <file> is not bundled' do
|
33
|
+
subject { render('{% stylesheet vapor.css %}') }
|
34
|
+
it { should be_empty }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context '{% javasript <file> %}' do
|
39
|
+
let(:tag_re) do
|
40
|
+
%r{^#{Tag::JAVASCRIPT % ['/assets/app-[a-f0-9]{32}\.js']}$}
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when <file> is bundled' do
|
44
|
+
subject { render('{% javascript app.js %}') }
|
45
|
+
it { should match tag_re }
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when <file> extension omited' do
|
49
|
+
subject { render('{% javascript app %}') }
|
50
|
+
it { should match tag_re }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when <file> is not found' do
|
54
|
+
subject { render('{% javascript not-found.js %}') }
|
55
|
+
it { should be_empty }
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when <file> is not bundled' do
|
59
|
+
subject { render('{% javascript vapor.js %}') }
|
60
|
+
it { should be_empty }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context '{% asset_path <file.ext> %}' do
|
65
|
+
context 'when <file> is bundled' do
|
66
|
+
subject { render('{% asset_path app.css %}') }
|
67
|
+
it { should match(%r{^/assets/app-[a-f0-9]{32}\.css$}) }
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when <file> is not found' do
|
71
|
+
subject { render('{% asset_path not-found.js %}') }
|
72
|
+
it { should be_empty }
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when <file> is not bundled' do
|
76
|
+
subject { render('{% asset_path vapor.js %}') }
|
77
|
+
it { should be_empty }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
|
4
|
+
require 'jekyll'
|
5
|
+
require 'liquid'
|
6
|
+
require 'sprockets'
|
7
|
+
|
8
|
+
|
9
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
10
|
+
# in spec/support/ and its subdirectories.
|
11
|
+
Dir[File.expand_path('../support', __FILE__) + "/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.include Jekyll::AssetsPlugin::RSpecHelpers
|
16
|
+
|
17
|
+
config.before(:all) do
|
18
|
+
@dest = fixtures_path.join('_site')
|
19
|
+
@site = Jekyll::Site.new(Jekyll.configuration({
|
20
|
+
'source' => fixtures_path.to_s,
|
21
|
+
'destination' => @dest.to_s
|
22
|
+
}))
|
23
|
+
|
24
|
+
@dest.rmtree if @dest.exist?
|
25
|
+
@site.process
|
26
|
+
end
|
27
|
+
|
28
|
+
config.after(:all) do
|
29
|
+
@dest.rmtree if @dest.exist?
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-assets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Aleksey
|
9
|
+
- V
|
10
|
+
- Zapparov
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-10-22 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: jekyll
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ! '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '0'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: sprockets
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.8'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.8'
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rake
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: rspec
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
type: :development
|
73
|
+
prerelease: false
|
74
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: guard-rspec
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: rb-inotify
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
description: Adds assets pipelines for Jekyll
|
113
|
+
email:
|
114
|
+
- ixti@member.fsf.org
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- .gitignore
|
120
|
+
- .rspec
|
121
|
+
- .travis.yml
|
122
|
+
- Gemfile
|
123
|
+
- Guardfile
|
124
|
+
- LICENSE
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- jekyll-assets.gemspec
|
128
|
+
- lib/jekyll-assets.rb
|
129
|
+
- lib/jekyll/assets_plugin.rb
|
130
|
+
- lib/jekyll/assets_plugin/asset_file.rb
|
131
|
+
- lib/jekyll/assets_plugin/configuration.rb
|
132
|
+
- lib/jekyll/assets_plugin/generator.rb
|
133
|
+
- lib/jekyll/assets_plugin/logging.rb
|
134
|
+
- lib/jekyll/assets_plugin/site_patch.rb
|
135
|
+
- lib/jekyll/assets_plugin/tag.rb
|
136
|
+
- lib/jekyll/assets_plugin/version.rb
|
137
|
+
- spec/fixtures/.gitignore
|
138
|
+
- spec/fixtures/_assets/app.css.erb
|
139
|
+
- spec/fixtures/_assets/app.js
|
140
|
+
- spec/fixtures/_assets/noise.png
|
141
|
+
- spec/fixtures/_assets/vapor.css
|
142
|
+
- spec/fixtures/_assets/vapor.js
|
143
|
+
- spec/fixtures/_config.yml
|
144
|
+
- spec/fixtures/_layouts/default.html
|
145
|
+
- spec/fixtures/_posts/2012-10-19-hello-world.md
|
146
|
+
- spec/fixtures/index.html
|
147
|
+
- spec/lib/jekyll/assets_plugin/asset_file_spec.rb
|
148
|
+
- spec/lib/jekyll/assets_plugin/configuration_spec.rb
|
149
|
+
- spec/lib/jekyll/assets_plugin/generator_spec.rb
|
150
|
+
- spec/lib/jekyll/assets_plugin/logging_spec.rb
|
151
|
+
- spec/lib/jekyll/assets_plugin/site_patch_spec.rb
|
152
|
+
- spec/lib/jekyll/assets_plugin/tag_spec.rb
|
153
|
+
- spec/spec_helper.rb
|
154
|
+
- spec/support/fixtures_path.rb
|
155
|
+
homepage: http://ixti.github.com/jekyll-assets
|
156
|
+
licenses: []
|
157
|
+
post_install_message:
|
158
|
+
rdoc_options: []
|
159
|
+
require_paths:
|
160
|
+
- lib
|
161
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
162
|
+
none: false
|
163
|
+
requirements:
|
164
|
+
- - ! '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
segments:
|
168
|
+
- 0
|
169
|
+
hash: -929384781
|
170
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
|
+
none: false
|
172
|
+
requirements:
|
173
|
+
- - ! '>='
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
segments:
|
177
|
+
- 0
|
178
|
+
hash: -929384781
|
179
|
+
requirements: []
|
180
|
+
rubyforge_project:
|
181
|
+
rubygems_version: 1.8.23
|
182
|
+
signing_key:
|
183
|
+
specification_version: 3
|
184
|
+
summary: jekyll-assets-0.1.0
|
185
|
+
test_files:
|
186
|
+
- spec/fixtures/.gitignore
|
187
|
+
- spec/fixtures/_assets/app.css.erb
|
188
|
+
- spec/fixtures/_assets/app.js
|
189
|
+
- spec/fixtures/_assets/noise.png
|
190
|
+
- spec/fixtures/_assets/vapor.css
|
191
|
+
- spec/fixtures/_assets/vapor.js
|
192
|
+
- spec/fixtures/_config.yml
|
193
|
+
- spec/fixtures/_layouts/default.html
|
194
|
+
- spec/fixtures/_posts/2012-10-19-hello-world.md
|
195
|
+
- spec/fixtures/index.html
|
196
|
+
- spec/lib/jekyll/assets_plugin/asset_file_spec.rb
|
197
|
+
- spec/lib/jekyll/assets_plugin/configuration_spec.rb
|
198
|
+
- spec/lib/jekyll/assets_plugin/generator_spec.rb
|
199
|
+
- spec/lib/jekyll/assets_plugin/logging_spec.rb
|
200
|
+
- spec/lib/jekyll/assets_plugin/site_patch_spec.rb
|
201
|
+
- spec/lib/jekyll/assets_plugin/tag_spec.rb
|
202
|
+
- spec/spec_helper.rb
|
203
|
+
- spec/support/fixtures_path.rb
|