Module: JekyllAssetPostProcessor

Defined in:
lib/processors/scss.rb,
lib/hash.rb,
lib/cache.rb,
lib/config.rb,
lib/process.rb,
lib/processor.rb,
lib/liquid/process_asset_tag.rb

Overview

See lib/processor.rb for full documentation.

Defined Under Namespace

Classes: ProcessAssetTag, Processor, SassProcessor

Constant Summary collapse

DEFAULTS =
{
    'staging_path' => '_staging',
    'destination_path' => 'assets'
}

Class Method Summary collapse

Class Method Details

.cacheObject

Return the cache and create it if not present.



3
4
5
# File 'lib/cache.rb', line 3

def self.cache
    @cache ||= {}
end

.cache_hash(file_path) ⇒ Object

Generate a hash to be used in the internal cache to avoid processing a file more than once per build.



4
5
6
7
# File 'lib/hash.rb', line 4

def self.cache_hash(file_path)
    mtime = File.mtime(File.join(file_path))
    Digest::MD5.hexdigest(file_path + mtime.to_s)
end

.clear_cacheObject

Clear the cache.



8
9
10
# File 'lib/cache.rb', line 8

def self.clear_cache
    @cache = {}
end

.config_destination_path(jekyll_config) ⇒ Object



12
13
14
15
# File 'lib/config.rb', line 12

def self.config_destination_path(jekyll_config)
    config = jekyll_config['asset-post-processor'] || [{}]
    config[0]['destination_path'] || DEFAULTS['destination_path']
end

.config_staging_path(jekyll_config) ⇒ Object



7
8
9
10
# File 'lib/config.rb', line 7

def self.config_staging_path(jekyll_config)
    config = jekyll_config['asset-post-processor'] || [{}]
    return config[0]['staging_path'] || DEFAULTS['staging_path']
end

.file_hash(file_path, content) ⇒ Object

Generate a hash to be used in the final file name. Generated from the final rendered file contents.



11
12
13
# File 'lib/hash.rb', line 11

def self.file_hash(file_path, content)
    Digest::MD5.hexdigest(content)
end

.new_jekyll_asset(site, staging_path, output_path, filename) ⇒ Object

Register a new asset with Jekyll from the staging directory in order to be moved into the final build directory.



9
10
11
# File 'lib/process.rb', line 9

def self.new_jekyll_asset(site, staging_path, output_path, filename)
    site.static_files << Jekyll::StaticFile.new(site, staging_path, output_path, filename)
end

.process(context, file_path) ⇒ Object

Process a single asset file.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/process.rb', line 22

def self.process(context, file_path)
    site = context.registers[:site]
    jekyll_config = site.config

    generated_cache_hash = cache_hash(file_path)
    return cache[generated_cache_hash] if cache.key?(generated_cache_hash)

    source = site.source
    path = File.join(source, file_path)
    basename = File.basename(path)
    filename = File.basename(path, '.*')
    extension = File.extname(basename)

    # generate the destination path, by default insert into assets directory

    staging_path = config_staging_path(jekyll_config)
    destination_path = config_destination_path(jekyll_config)

    split_path = file_path.split('/')
    if split_path.length > 2
        destination_path += '/' + split_path[1..-2].join('/')
    end
    
    generated_file_hash = nil
    new_extension = extension
    rendered = nil

    rendered = nil
    rendered_binary = nil
    if processors.key?(extension)
        processor = processors[extension].new(filename, extension, file_path)
        new_extension = processor.new_extension

        new_contents = nil
        File.open(path, 'r') do |file|
            new_contents = processor.process(file.read, context)
        end
        if new_contents.nil?
            File.open(path, 'rb') do |file|
                new_binary_contents = processor.process_binary(file.read, context)
                if new_binary_contents.nil?
                    raise "Processor for #{extension} doesn't override process or process_binary"
                else
                    rendered_binary = new_binary_contents
                    generated_file_hash = file_hash(file_path, rendered_binary)
                end
            end
        else
            rendered = new_contents
            generated_file_hash = file_hash(file_path, rendered)
        end
    else
        File.open(path, 'rb') do |file|
            generated_file_hash = file_hash(file_path, file.read)
        end
    end


    generated_filename = "#{filename}-#{generated_file_hash}#{new_extension}"
    staging_destination = File.join(source, staging_path, destination_path)

    FileUtils.mkpath(staging_destination) unless File.directory?(staging_destination)
    generated_staging_path = File.join(staging_destination, generated_filename)
    if !File.file?(generated_staging_path)
        if !rendered.nil?
            File.open(generated_staging_path, 'w') do |file|
                file.write(rendered)
            end
        elsif !rendered_binary.nil?
            File.open(generated_staging_path, 'wb') do |file|
                file.write(rendered_binary)
            end
        else
            FileUtils.cp(path, File.join(staging_destination, generated_filename))
        end
    end
    
    new_jekyll_asset(site, staging_path, destination_path, generated_filename)

    generated_asset_site_path = '/' + File.join(destination_path, generated_filename)
    cache[cache_hash(file_path)] = generated_asset_site_path
    return generated_asset_site_path

end

.processorsObject



13
14
15
# File 'lib/process.rb', line 13

def self.processors
    @processors ||= {}
end

.register_processor(extension, processor) ⇒ Object



17
18
19
# File 'lib/process.rb', line 17

def self.register_processor(extension, processor)
    processors[extension] = processor
end

.remove_staged_assets(jekyll_config) ⇒ Object



2
3
4
5
# File 'lib/process.rb', line 2

def self.remove_staged_assets(jekyll_config)
    staging_path = File.join(config_staging_path(jekyll_config))
    FileUtils.rm_rf(staging_path)
end