jekyll-asset-pipeline 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +29 -13
- data/lib/jekyll_asset_pipeline.rb +21 -9
- data/lib/jekyll_asset_pipeline/asset.rb +10 -0
- data/lib/jekyll_asset_pipeline/cache.rb +17 -0
- data/lib/jekyll_asset_pipeline/compressor.rb +3 -1
- data/lib/jekyll_asset_pipeline/converter.rb +7 -6
- data/lib/jekyll_asset_pipeline/extensions/jekyll/static_asset_file.rb +5 -0
- data/lib/jekyll_asset_pipeline/{asset_file.rb → extensions/jekyll/static_file_extensions.rb} +1 -1
- data/lib/jekyll_asset_pipeline/extensions/liquid/asset_tag.rb +6 -0
- data/lib/jekyll_asset_pipeline/extensions/liquid/asset_tags/css_asset_tag.rb +14 -0
- data/lib/jekyll_asset_pipeline/extensions/liquid/asset_tags/javascript_asset_tag.rb +14 -0
- data/lib/jekyll_asset_pipeline/extensions/liquid/liquid_block_extensions.rb +53 -0
- data/lib/jekyll_asset_pipeline/{extendable.rb → extensions/ruby/subclass_tracking.rb} +3 -3
- data/lib/jekyll_asset_pipeline/pipeline.rb +165 -0
- data/lib/jekyll_asset_pipeline/template.rb +3 -1
- data/lib/jekyll_asset_pipeline/templates/css_tag_template.rb +4 -4
- data/lib/jekyll_asset_pipeline/templates/javascript_tag_template.rb +4 -4
- data/lib/jekyll_asset_pipeline/version.rb +1 -1
- metadata +19 -15
- data/lib/jekyll_asset_pipeline/bundler.rb +0 -150
- data/lib/jekyll_asset_pipeline/css_asset_tag.rb +0 -19
- data/lib/jekyll_asset_pipeline/javascript_asset_tag.rb +0 -19
data/README.md
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
[Jekyll Asset Pipeline](http://www.matthodan.com/2012/11/22/jekyll-asset-pipeline.html) is a powerful asset pipeline that automatically collects, converts and compresses/minifies your site's JavaScript and CSS assets when you compile your Jekyll site.
|
4
4
|
|
5
|
-
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/matthodan/jekyll-asset-pipeline)
|
6
|
-
|
7
5
|
## Table of Contents
|
8
6
|
|
9
7
|
- [Features](#features)
|
@@ -72,8 +70,10 @@ Jekyll Asset Pipeline is extremely easy to add to your Jekyll project and has no
|
|
72
70
|
5. Run the `jekyll` command to compile your site. You should see an output that includes the following Jekyll Asset Pipeline status messages.
|
73
71
|
|
74
72
|
``` bash
|
75
|
-
Asset Pipeline:
|
76
|
-
Asset Pipeline:
|
73
|
+
Asset Pipeline: Processing 'css_asset_tag' manifest 'global'
|
74
|
+
Asset Pipeline: Saved 'global-md5hash.css' to '_site/assets'
|
75
|
+
Asset Pipeline: Processing 'javascript_asset_tag' manifest 'global'
|
76
|
+
Asset Pipeline: Saved 'global-md5hash.js' to '_site/assets'
|
77
77
|
```
|
78
78
|
|
79
79
|
> *If you do not see these messages, check that you have __not__ set Jekyll's "safe" option to "true" in your site's "_config.yml". If the "safe" option is set to "true", Jekyll will not run plugins.*
|
@@ -94,11 +94,11 @@ In the following example, we will add a preprocessor that converts CoffeeScript
|
|
94
94
|
module JekyllAssetPipeline
|
95
95
|
class CoffeeScriptConverter < JekyllAssetPipeline::Converter
|
96
96
|
require 'coffee-script'
|
97
|
-
|
97
|
+
|
98
98
|
def self.filetype
|
99
99
|
'.coffee'
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
def convert
|
103
103
|
return CoffeeScript.compile(@content)
|
104
104
|
end
|
@@ -139,9 +139,14 @@ module JekyllAssetPipeline
|
|
139
139
|
end
|
140
140
|
end
|
141
141
|
```
|
142
|
-
|
143
142
|
> *Don't forget to install the "sass" gem before you run the `jekyll` command since the above SASS converter requires the "sass" library as a dependency.*
|
144
143
|
|
144
|
+
### Successive Preprocessing
|
145
|
+
|
146
|
+
If you would like to run an asset through multiple preprocessors successively, you can do so by naming your assets with nested file extensions. Nest the extensions in the order (right to left) that the asset should be processed. For example, `.css.scss.erb` would first be processed by an "erb" preprocessor then by a "scss" preprocessor before being rendered. This convention is very similar to the convention used by the [Ruby on Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html#preprocessing).
|
147
|
+
|
148
|
+
> *Don't forget to define preprocessors for the extensions you use in your filenames, otherwise Jekyll Asset Pipeline will not process your asset.*
|
149
|
+
|
145
150
|
## Asset Compression
|
146
151
|
|
147
152
|
Asset compression allows us to decrease the size of our assets and increase the speed of our site. One of Jekyll Asset Pipeline's key strengths is that it works with __any__ compression library that has a ruby wrapper. Adding asset compression is straightforward, but requires a small amount of additional code.
|
@@ -245,28 +250,39 @@ That is it! Your asset pipeline used your template to generate an HTML "link" t
|
|
245
250
|
|
246
251
|
## Configuration
|
247
252
|
|
248
|
-
Jekyll Asset Pipeline provides the following
|
253
|
+
Jekyll Asset Pipeline provides the following configuration options that can be controlled by adding the following to the end of your project's "\_config.yml" file.
|
249
254
|
|
250
255
|
``` yaml
|
251
256
|
asset_pipeline:
|
257
|
+
bundle: true # Default = true
|
252
258
|
compress: true # Default = true
|
253
259
|
output_path: assets # Default = assets
|
260
|
+
gzip: false # Default = false
|
254
261
|
```
|
255
262
|
|
256
263
|
> *If you don't have a "\_config.yml" file, consider reading the [configuration section](https://github.com/mojombo/jekyll/wiki/Configuration) of the Jekyll documentation.*
|
257
|
-
|
258
|
-
> The "
|
264
|
+
>
|
265
|
+
> - The "bundle" setting controls whether Jekyll Asset Pipeline bundles the assets defined in each manifest. If "bundle" is set to false, each asset will be saved individually and individual html tags pointing to each unbundled asset will be produced when you compile your site. It is useful to set this to false while you are debugging your site.
|
266
|
+
> - The "compress" setting tells Jekyll Asset Pipeline whether or not to compress the bundled assets. It is useful to set this setting to "false" while you are debugging your site.
|
267
|
+
> - The "output\_path" setting defines where generated bundles should be saved within the "\_site" folder of your project.
|
268
|
+
> - The "gzip" setting controls whether Jekyll Asset Pipeline saves gzipped versions of your assets alongside un-gzipped versions.
|
259
269
|
|
260
270
|
## Contribute
|
261
271
|
|
262
272
|
You can contribute to the Jekyll Asset Pipeline by submitting a pull request [via GitHub](https://github.com/matthodan/jekyll-asset-pipeline). I have identified the following areas for improvement:
|
263
273
|
|
264
|
-
- __Tests, tests, tests.__ I'm embarrassed to say that I didn't write a single test while building Jekyll Asset Pipeline. This started as a hack for my blog and quickly grew into a library as I tweaked it to support my own needs.
|
265
|
-
- __Handle remote assets.__ Right now, Jekyll Asset Pipeline does not provide any way to include remote assets in bundles unless you save them locally before generating your site. Moshen's [Jekyll Asset Bundler](https://github.com/moshen/jekyll-asset_bundler) allows you to include remote assets, which I thought was pretty interesting. That said, I think it is generally better to keep remote assets separate so that they load asynchronously.
|
266
|
-
- __Successive preprocessing.__ Currently you can only preprocess a file once. It would be better if you could run an asset through multiple preprocessors before it gets compressed and bundled.
|
274
|
+
- __Tests, tests, tests.__ I'm embarrassed to say that I didn't write a single test while building Jekyll Asset Pipeline. This started as a hack for my blog and quickly grew into a library as I tweaked it to support my own needs. **This project is now fully tested.**
|
275
|
+
- __Handle remote assets.__ Right now, Jekyll Asset Pipeline does not provide any way to include remote assets in bundles unless you save them locally before generating your site. Moshen's [Jekyll Asset Bundler](https://github.com/moshen/jekyll-asset_bundler) allows you to include remote assets, which I thought was pretty interesting. That said, I think it is generally better to keep remote assets separate so that they load asynchronously. **After some thought, I've decided that this is not a priority. If you disagree, let me know.**
|
276
|
+
- __Successive preprocessing.__ Currently you can only preprocess a file once. It would be better if you could run an asset through multiple preprocessors before it gets compressed and bundled. **As of v0.1.0, Jekyll Asset Pipeline now supports successive preprocessing.**
|
267
277
|
|
268
278
|
Feel free to message me on [Twitter](http://twitter.com/matthodan) or [Facebook](http://facebook.com/matthodan).
|
269
279
|
|
280
|
+
## Code Status
|
281
|
+
|
282
|
+
- [![Build Status](https://secure.travis-ci.org/matthodan/jekyll-asset-pipeline.png)](https://travis-ci.org/matthodan/jekyll-asset-pipeline)
|
283
|
+
- [![Dependency Status](https://gemnasium.com/matthodan/jekyll-asset-pipeline.png)](https://gemnasium.com/matthodan/jekyll-asset-pipeline)
|
284
|
+
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/matthodan/jekyll-asset-pipeline)
|
285
|
+
|
270
286
|
## Credits
|
271
287
|
|
272
288
|
As I was building Jekyll Asset Pipeline, I came across a number of tools that I was able to draw inspiration and best practices from, but one stood out in particular... I have to give credit to [Moshen](https://github.com/moshen/) for creating the [Jekyll Asset Bundler](https://github.com/moshen/jekyll-asset_bundler).
|
@@ -3,31 +3,43 @@ require 'digest/md5'
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'time'
|
5
5
|
require 'yaml'
|
6
|
+
require 'zlib'
|
6
7
|
|
7
8
|
# Third-party dependencies
|
8
9
|
require 'jekyll'
|
9
10
|
require 'liquid'
|
10
11
|
|
11
12
|
# Jekyll extensions
|
13
|
+
require 'jekyll_asset_pipeline/extensions/jekyll/static_file_extensions'
|
14
|
+
require 'jekyll_asset_pipeline/extensions/jekyll/static_asset_file'
|
15
|
+
|
16
|
+
# Liquid extensions
|
17
|
+
require 'jekyll_asset_pipeline/extensions/liquid/liquid_block_extensions'
|
18
|
+
require 'jekyll_asset_pipeline/extensions/liquid/asset_tag'
|
19
|
+
require 'jekyll_asset_pipeline/extensions/liquid/asset_tags/css_asset_tag'
|
20
|
+
require 'jekyll_asset_pipeline/extensions/liquid/asset_tags/javascript_asset_tag'
|
21
|
+
|
22
|
+
# Ruby extensions
|
23
|
+
require 'jekyll_asset_pipeline/extensions/ruby/subclass_tracking'
|
24
|
+
|
25
|
+
# Jekyll Asset Pipeline
|
12
26
|
require 'jekyll_asset_pipeline/version'
|
13
|
-
require 'jekyll_asset_pipeline/
|
14
|
-
require 'jekyll_asset_pipeline/asset_file'
|
15
|
-
require 'jekyll_asset_pipeline/bundler'
|
16
|
-
require 'jekyll_asset_pipeline/compressor'
|
27
|
+
require 'jekyll_asset_pipeline/asset'
|
17
28
|
require 'jekyll_asset_pipeline/converter'
|
29
|
+
require 'jekyll_asset_pipeline/compressor'
|
18
30
|
require 'jekyll_asset_pipeline/template'
|
19
31
|
require 'jekyll_asset_pipeline/templates/javascript_tag_template'
|
20
32
|
require 'jekyll_asset_pipeline/templates/css_tag_template'
|
21
|
-
|
22
|
-
|
23
|
-
require 'jekyll_asset_pipeline/css_asset_tag'
|
24
|
-
require 'jekyll_asset_pipeline/javascript_asset_tag'
|
33
|
+
require 'jekyll_asset_pipeline/cache'
|
34
|
+
require 'jekyll_asset_pipeline/pipeline'
|
25
35
|
|
26
36
|
module JekyllAssetPipeline
|
27
37
|
# Default configuration settings for Jekyll Asset Bundler
|
28
38
|
# Strings used for keys to play nice when merging with _config.yml
|
29
39
|
DEFAULTS = {
|
30
40
|
'output_path' => 'assets', # Destination for bundle file (within the '_site' directory)
|
31
|
-
'
|
41
|
+
'bundle' => true, # true = Bundle assets, false = Leave assets unbundled
|
42
|
+
'compress' => true, # true = Minify assets, false = Leave assets unminified
|
43
|
+
'gzip' => false # true = Create gzip versions, false = Do not create gzip versions
|
32
44
|
}
|
33
45
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module JekyllAssetPipeline
|
2
|
-
class Converter
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@
|
2
|
+
class Converter
|
3
|
+
extend JekyllAssetPipeline::SubclassTracking
|
4
|
+
|
5
|
+
def initialize(asset)
|
6
|
+
@content = asset.content
|
7
|
+
@type = File.extname(asset.filename).downcase
|
7
8
|
begin
|
8
9
|
@converted = self.convert
|
9
10
|
rescue Exception => e
|
10
|
-
puts "Failed to convert asset '#{
|
11
|
+
puts "Failed to convert asset '#{asset.filename}'."
|
11
12
|
raise e
|
12
13
|
end
|
13
14
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module JekyllAssetPipeline
|
2
|
+
class CssAssetTag < JekyllAssetPipeline::AssetTag
|
3
|
+
def self.tag_name
|
4
|
+
'css_asset_tag'
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.output_type
|
8
|
+
'.css'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Register CssAssetTag tag with Liquid
|
13
|
+
::Liquid::Template.register_tag(JekyllAssetPipeline::CssAssetTag.tag_name, JekyllAssetPipeline::CssAssetTag)
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module JekyllAssetPipeline
|
2
|
+
class JavaScriptAssetTag < JekyllAssetPipeline::AssetTag
|
3
|
+
def self.tag_name
|
4
|
+
'javascript_asset_tag'
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.output_type
|
8
|
+
'.js'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Register JavaScriptAssetTag tag with Liquid
|
13
|
+
::Liquid::Template.register_tag(JekyllAssetPipeline::JavaScriptAssetTag.tag_name, JekyllAssetPipeline::JavaScriptAssetTag)
|
14
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module JekyllAssetPipeline
|
2
|
+
module LiquidBlockExtensions
|
3
|
+
module ClassMethods
|
4
|
+
def output_type
|
5
|
+
''
|
6
|
+
end
|
7
|
+
|
8
|
+
def tag_name
|
9
|
+
''
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def render(context)
|
14
|
+
# Get YAML manifest from Liquid block
|
15
|
+
manifest = @nodelist.first
|
16
|
+
prefix = @markup.lstrip.rstrip
|
17
|
+
|
18
|
+
# Get site instance from Jekyll
|
19
|
+
site = context.registers[:site]
|
20
|
+
|
21
|
+
# Initialize configuration hash
|
22
|
+
config = site.config['asset_pipeline'] || {}
|
23
|
+
|
24
|
+
# Generate hash based on asset last modified dates and config options
|
25
|
+
hash = JekyllAssetPipeline::Pipeline.hash(site.source, manifest, config)
|
26
|
+
|
27
|
+
# Fetch pipeline from cache if recently processed
|
28
|
+
if JekyllAssetPipeline::Cache.has_key?(hash)
|
29
|
+
pipeline = JekyllAssetPipeline::Cache.get(hash)
|
30
|
+
|
31
|
+
# Return HTML tags pointing to assets
|
32
|
+
return pipeline.html
|
33
|
+
else
|
34
|
+
# Create pipeline and process assets
|
35
|
+
puts "Asset Pipeline: Processing '#{self.class.tag_name}' manifest '#{prefix}'"
|
36
|
+
pipeline = JekyllAssetPipeline::Pipeline.new(manifest, prefix, site.source, site.dest, self.class.output_type, config)
|
37
|
+
pipeline.process
|
38
|
+
|
39
|
+
# Prevent Jekyll from cleaning up saved assets
|
40
|
+
pipeline.assets.each do |asset|
|
41
|
+
puts "Asset Pipeline: Saved '#{asset.filename}' to '_site/#{asset.output_path}'"
|
42
|
+
site.static_files << JekyllAssetPipeline::StaticAssetFile.new(site, site.dest, asset.output_path, asset.filename)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Cache pipeline
|
46
|
+
JekyllAssetPipeline::Cache.add(hash, pipeline)
|
47
|
+
|
48
|
+
# Return HTML tags pointing to assets
|
49
|
+
return pipeline.html
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module JekyllAssetPipeline
|
2
|
-
|
2
|
+
module SubclassTracking
|
3
3
|
# Record subclasses of this class (this method is automatically called by ruby)
|
4
|
-
def
|
4
|
+
def inherited(base)
|
5
5
|
subclasses << base
|
6
6
|
end
|
7
7
|
|
8
8
|
# Return an array of classes that are subclasses of this object
|
9
|
-
def
|
9
|
+
def subclasses
|
10
10
|
@subclasses ||= []
|
11
11
|
end
|
12
12
|
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module JekyllAssetPipeline
|
2
|
+
class Pipeline
|
3
|
+
# Initialize new pipeline
|
4
|
+
def initialize(manifest, prefix, source, destination, type, options = {})
|
5
|
+
@manifest = manifest
|
6
|
+
@prefix = prefix
|
7
|
+
@source = source
|
8
|
+
@destination = destination
|
9
|
+
@type = type
|
10
|
+
@options = JekyllAssetPipeline::DEFAULTS.merge(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :assets, :html
|
14
|
+
|
15
|
+
# Process the pipeline
|
16
|
+
def process
|
17
|
+
collect
|
18
|
+
convert
|
19
|
+
bundle if @options['bundle']
|
20
|
+
compress if @options['compress']
|
21
|
+
gzip if @options['gzip']
|
22
|
+
save
|
23
|
+
markup
|
24
|
+
end
|
25
|
+
|
26
|
+
# Generate hash based on manifest contents
|
27
|
+
def self.hash(source, manifest, options = {})
|
28
|
+
options = JekyllAssetPipeline::DEFAULTS.merge(options)
|
29
|
+
begin
|
30
|
+
Digest::MD5.hexdigest(YAML::load(manifest).map! do |path|
|
31
|
+
"#{path}#{File.mtime(File.join(source, path)).to_i}"
|
32
|
+
end.join.concat(options.to_s))
|
33
|
+
rescue Exception => e
|
34
|
+
puts "Asset Pipeline: Failed to generate hash from provided manifest."
|
35
|
+
raise e
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Collect assets based on manifest
|
42
|
+
def collect
|
43
|
+
begin
|
44
|
+
@assets = YAML::load(@manifest).map! do |path|
|
45
|
+
File.open(File.join(@source, path)) do |file|
|
46
|
+
JekyllAssetPipeline::Asset.new(file.read, File.basename(path))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rescue Exception => e
|
50
|
+
puts "Asset Pipeline: Failed to load assets from provided manifest."
|
51
|
+
raise e
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Convert assets based on the file extension if converter is defined
|
56
|
+
def convert
|
57
|
+
@assets.each do |asset|
|
58
|
+
# Convert asset multiple times if more than one converter is found
|
59
|
+
finished = false
|
60
|
+
while finished == false
|
61
|
+
# Find a converter to use
|
62
|
+
klass = JekyllAssetPipeline::Converter.subclasses.select do |c|
|
63
|
+
c.filetype == File.extname(asset.filename).downcase
|
64
|
+
end.last
|
65
|
+
|
66
|
+
# Convert asset if converter is found
|
67
|
+
unless klass.nil?
|
68
|
+
begin
|
69
|
+
# Convert asset content
|
70
|
+
converter = klass.new(asset)
|
71
|
+
|
72
|
+
# Replace asset content and filename
|
73
|
+
asset.content = converter.converted
|
74
|
+
asset.filename = File.basename(asset.filename, '.*')
|
75
|
+
|
76
|
+
# Add back the output extension if no extension left
|
77
|
+
asset.filename = "#{asset.filename}#{@type}" if File.extname(asset.filename) == ''
|
78
|
+
rescue Exception => e
|
79
|
+
puts "Asset Pipeline: Failed to convert '#{asset.filename}' with '#{klass.to_s}'."
|
80
|
+
raise e
|
81
|
+
end
|
82
|
+
else
|
83
|
+
finished = true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Bundle multiple assets into a single asset
|
90
|
+
def bundle
|
91
|
+
content = @assets.map do |a|
|
92
|
+
a.content
|
93
|
+
end.join("\n")
|
94
|
+
|
95
|
+
hash = JekyllAssetPipeline::Pipeline.hash(@source, @manifest, @options)
|
96
|
+
@assets = [JekyllAssetPipeline::Asset.new(content, "#{@prefix}-#{hash}#{@type}")]
|
97
|
+
end
|
98
|
+
|
99
|
+
# Compress assets if compressor is defined
|
100
|
+
def compress
|
101
|
+
@assets.each do |asset|
|
102
|
+
# Find a compressor to use
|
103
|
+
klass = JekyllAssetPipeline::Compressor.subclasses.select do |c|
|
104
|
+
c.filetype == @type
|
105
|
+
end.last
|
106
|
+
|
107
|
+
unless klass.nil?
|
108
|
+
begin
|
109
|
+
asset.content = klass.new(asset.content).compressed
|
110
|
+
rescue Exception => e
|
111
|
+
puts "Asset Pipeline: Failed to compress '#{asset.filename}' with '#{klass.to_s}'."
|
112
|
+
raise e
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Create Gzip versions of assets
|
119
|
+
def gzip
|
120
|
+
@assets.map! do |asset|
|
121
|
+
gzip_content = Zlib::Deflate.deflate(asset.content)
|
122
|
+
[asset, JekyllAssetPipeline::Asset.new(gzip_content, "#{asset.filename}.gz")]
|
123
|
+
end.flatten!
|
124
|
+
end
|
125
|
+
|
126
|
+
# Save assets to file
|
127
|
+
def save
|
128
|
+
output_path = @options['output_path']
|
129
|
+
|
130
|
+
@assets.each do |asset|
|
131
|
+
# Create directories if necessary
|
132
|
+
directory = File.join(@destination, output_path)
|
133
|
+
FileUtils::mkpath(directory) unless File.directory?(directory)
|
134
|
+
|
135
|
+
begin
|
136
|
+
# Save file to disk
|
137
|
+
File.open(File.join(directory, asset.filename), 'w') do |file|
|
138
|
+
file.write(asset.content)
|
139
|
+
end
|
140
|
+
rescue Exception => e
|
141
|
+
puts "Asset Pipeline: Failed to save '#{asset.filename}' to disk."
|
142
|
+
raise e
|
143
|
+
end
|
144
|
+
|
145
|
+
# Store output path of saved file
|
146
|
+
asset.output_path = output_path
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Generate html markup pointing to assets
|
151
|
+
def markup
|
152
|
+
path = @options['output_path']
|
153
|
+
|
154
|
+
@html = @assets.map do |asset|
|
155
|
+
klass = JekyllAssetPipeline::Template.subclasses.select do |t|
|
156
|
+
t.filetype == File.extname(asset.filename).downcase
|
157
|
+
end.sort! { |x, y| y.priority <=> x.priority }.last
|
158
|
+
|
159
|
+
html = klass.new(path, asset.filename).html unless klass.nil?
|
160
|
+
|
161
|
+
html
|
162
|
+
end.join
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -5,12 +5,12 @@ module JekyllAssetPipeline
|
|
5
5
|
'.css'
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def self.priority
|
9
|
+
-1
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def html
|
13
|
+
"<link href='/#{@path}/#{@filename}' rel='stylesheet' type='text/css' />\n"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -5,12 +5,12 @@ module JekyllAssetPipeline
|
|
5
5
|
'.js'
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def self.priority
|
9
|
+
-1
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def html
|
13
|
+
"<script src='/#{@path}/#{@filename}' type='text/javascript'></script>\n"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-asset-pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: jekyll
|
@@ -48,7 +48,7 @@ dependencies:
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ! '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '0.9'
|
54
54
|
type: :development
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0.9'
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ! '>='
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '4.3'
|
70
70
|
type: :development
|
@@ -72,25 +72,29 @@ dependencies:
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '4.3'
|
78
|
-
description:
|
79
|
-
|
80
|
-
|
81
|
-
preprocessing or compression library.
|
78
|
+
description: Adds asset preprocessing (CoffeeScript, Sass, Less, ERB, etc.), asset
|
79
|
+
compression/minification/gzip (Yahoo YUI Compressor, Google Closure Compiler, etc.)
|
80
|
+
to Jekyll.
|
82
81
|
email: matthew.c.hodan@gmail.com
|
83
82
|
executables: []
|
84
83
|
extensions: []
|
85
84
|
extra_rdoc_files: []
|
86
85
|
files:
|
87
|
-
- lib/jekyll_asset_pipeline/
|
88
|
-
- lib/jekyll_asset_pipeline/
|
86
|
+
- lib/jekyll_asset_pipeline/asset.rb
|
87
|
+
- lib/jekyll_asset_pipeline/cache.rb
|
89
88
|
- lib/jekyll_asset_pipeline/compressor.rb
|
90
89
|
- lib/jekyll_asset_pipeline/converter.rb
|
91
|
-
- lib/jekyll_asset_pipeline/
|
92
|
-
- lib/jekyll_asset_pipeline/
|
93
|
-
- lib/jekyll_asset_pipeline/
|
90
|
+
- lib/jekyll_asset_pipeline/extensions/jekyll/static_asset_file.rb
|
91
|
+
- lib/jekyll_asset_pipeline/extensions/jekyll/static_file_extensions.rb
|
92
|
+
- lib/jekyll_asset_pipeline/extensions/liquid/asset_tag.rb
|
93
|
+
- lib/jekyll_asset_pipeline/extensions/liquid/asset_tags/css_asset_tag.rb
|
94
|
+
- lib/jekyll_asset_pipeline/extensions/liquid/asset_tags/javascript_asset_tag.rb
|
95
|
+
- lib/jekyll_asset_pipeline/extensions/liquid/liquid_block_extensions.rb
|
96
|
+
- lib/jekyll_asset_pipeline/extensions/ruby/subclass_tracking.rb
|
97
|
+
- lib/jekyll_asset_pipeline/pipeline.rb
|
94
98
|
- lib/jekyll_asset_pipeline/template.rb
|
95
99
|
- lib/jekyll_asset_pipeline/templates/css_tag_template.rb
|
96
100
|
- lib/jekyll_asset_pipeline/templates/javascript_tag_template.rb
|
@@ -1,150 +0,0 @@
|
|
1
|
-
module JekyllAssetPipeline
|
2
|
-
class Bundler
|
3
|
-
def initialize(site, prefix, manifest, type)
|
4
|
-
@site = site
|
5
|
-
@prefix = prefix
|
6
|
-
@manifest = manifest
|
7
|
-
@type = type
|
8
|
-
|
9
|
-
# Initialize configuration hash
|
10
|
-
overrides = @site.config['asset_pipeline']
|
11
|
-
if overrides.is_a? Hash
|
12
|
-
@config = JekyllAssetPipeline::DEFAULTS.merge(overrides)
|
13
|
-
else
|
14
|
-
@config = JekyllAssetPipeline::DEFAULTS
|
15
|
-
end
|
16
|
-
|
17
|
-
self.process
|
18
|
-
end
|
19
|
-
|
20
|
-
# Bundle assets into new file or fetch previously bundled file from cache
|
21
|
-
def process
|
22
|
-
@@cache ||= {}
|
23
|
-
|
24
|
-
self.extract
|
25
|
-
self.collect
|
26
|
-
self.hashify
|
27
|
-
|
28
|
-
if @@cache.has_key?(@hash)
|
29
|
-
print "Asset Pipeline: Using cached bundle..."
|
30
|
-
@file = @@cache[@hash]
|
31
|
-
|
32
|
-
# Prevent Jekyll from cleaning up bundle file
|
33
|
-
@site.static_files << JekyllAssetPipeline::AssetFile.new(@site, @site.dest, @config['output_path'], filename)
|
34
|
-
puts " used '#{@prefix}-#{@hash[0, 6]}#{@type}'."
|
35
|
-
else
|
36
|
-
print "Asset Pipeline: Compiling bundle..."
|
37
|
-
|
38
|
-
# Create directories if necessary
|
39
|
-
path = "#{@site.dest}/#{@config['output_path']}"
|
40
|
-
FileUtils::mkpath(path) unless File.directory?(path)
|
41
|
-
|
42
|
-
# Create bundle file
|
43
|
-
self.convert
|
44
|
-
self.bundle
|
45
|
-
self.compress if @config['compress']
|
46
|
-
|
47
|
-
@file = File.new(File.join(@site.dest, @config['output_path'], filename), "w")
|
48
|
-
@file.write(@bundled)
|
49
|
-
@file.close
|
50
|
-
|
51
|
-
# Prevent Jekyll from cleaning up bundle file
|
52
|
-
@site.static_files << JekyllAssetPipeline::AssetFile.new(@site, @site.dest, @config['output_path'], filename)
|
53
|
-
|
54
|
-
# Save generated file to cache
|
55
|
-
@@cache[@hash] = @file
|
56
|
-
|
57
|
-
puts " compiled '#{@prefix}-#{@hash[0, 6]}#{@type}'."
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Extract asset paths from YAML manifest
|
62
|
-
def extract
|
63
|
-
begin
|
64
|
-
@assets = YAML::load(@manifest)
|
65
|
-
rescue Exception => e
|
66
|
-
puts "Asset Pipeline: Failed to read YAML manifest."
|
67
|
-
raise e
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Collect assets from various sources
|
72
|
-
def collect
|
73
|
-
@assets.map! do |path|
|
74
|
-
begin
|
75
|
-
file = File.open(File.join(@site.source, path))
|
76
|
-
rescue Exception => e
|
77
|
-
puts "Asset Pipeline: Failed to open asset file."
|
78
|
-
raise e
|
79
|
-
end
|
80
|
-
file
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# Generate a hash id based on asset file paths and last modified dates
|
85
|
-
def hashify
|
86
|
-
payload = @assets.map do |file|
|
87
|
-
"#{file.path}-#{@config['compress'].to_s}-#{file.mtime.to_i.to_s}"
|
88
|
-
end
|
89
|
-
@hash = Digest::MD5.hexdigest(payload.join)
|
90
|
-
end
|
91
|
-
|
92
|
-
# Search for a Converter to use to convert a file based on the file extension
|
93
|
-
def convert
|
94
|
-
@assets.map! do |file|
|
95
|
-
converter_klass = JekyllAssetPipeline::Converter.subclasses.select do |c|
|
96
|
-
c.filetype == File.extname(file).downcase
|
97
|
-
end.last
|
98
|
-
|
99
|
-
converted = nil
|
100
|
-
unless converter_klass.nil?
|
101
|
-
converter = converter_klass.new(file)
|
102
|
-
converted = converter.converted
|
103
|
-
else
|
104
|
-
converted = file.read
|
105
|
-
end
|
106
|
-
converted
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Bundle all of the separate asset files into one big file
|
111
|
-
def bundle
|
112
|
-
@bundled = @assets.join("\n")
|
113
|
-
end
|
114
|
-
|
115
|
-
# Search for a Compressor to use to compress a file based on the output type
|
116
|
-
def compress
|
117
|
-
compressor_klass = JekyllAssetPipeline::Compressor.subclasses.select do |c|
|
118
|
-
c.filetype == @type
|
119
|
-
end.last
|
120
|
-
|
121
|
-
unless compressor_klass.nil?
|
122
|
-
compressor = compressor_klass.new(@bundled)
|
123
|
-
@bundled = compressor.compressed
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Return filename of bundle
|
128
|
-
def filename
|
129
|
-
"#{@prefix}-#{@hash}#{@type}"
|
130
|
-
end
|
131
|
-
|
132
|
-
# Return an HTML tag that points to the bundle file
|
133
|
-
def html_tag
|
134
|
-
path = @config['output_path']
|
135
|
-
|
136
|
-
template_klass = JekyllAssetPipeline::Template.subclasses.select do |t|
|
137
|
-
t.filetype == @type
|
138
|
-
end.sort! { |a, b| b.priority <=> a.priority }.last
|
139
|
-
|
140
|
-
template = nil
|
141
|
-
unless template_klass.nil?
|
142
|
-
template = template_klass.new(path, filename)
|
143
|
-
@html_tag = template.html
|
144
|
-
else
|
145
|
-
# Return link to file if no template exists
|
146
|
-
return "<a href='/#{path}/#{filename}'>AssetPipeline: No template available for '#{filename}'</a>"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module JekyllAssetPipeline
|
2
|
-
class CssAssetTag < Liquid::Block
|
3
|
-
def render(context)
|
4
|
-
# Get YAML manifest from Liquid block
|
5
|
-
manifest = @nodelist.first
|
6
|
-
prefix = @markup.lstrip.rstrip
|
7
|
-
|
8
|
-
# Compile bundle based on manifest
|
9
|
-
site = context.registers[:site]
|
10
|
-
bundle = JekyllAssetPipeline::Bundler.new(site, prefix, manifest, '.css')
|
11
|
-
|
12
|
-
# Return HTML tag linked to bundle
|
13
|
-
return bundle.html_tag
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Register CssAssetTag tag with Liquid
|
18
|
-
Liquid::Template.register_tag('css_asset_tag', JekyllAssetPipeline::CssAssetTag)
|
19
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module JekyllAssetPipeline
|
2
|
-
class JavaScriptAssetTag < Liquid::Block
|
3
|
-
def render(context)
|
4
|
-
# Get YAML manifest from Liquid block
|
5
|
-
manifest = @nodelist.first
|
6
|
-
prefix = @markup.lstrip.rstrip
|
7
|
-
|
8
|
-
# Compile bundle based on manifest
|
9
|
-
site = context.registers[:site]
|
10
|
-
bundle = JekyllAssetPipeline::Bundler.new(site, prefix, manifest, '.js')
|
11
|
-
|
12
|
-
# Return HTML tag linked to bundle
|
13
|
-
return bundle.html_tag
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Register JavaScriptAssetTag tag with Liquid
|
18
|
-
Liquid::Template.register_tag('javascript_asset_tag', JekyllAssetPipeline::JavaScriptAssetTag)
|
19
|
-
end
|