jekyll_dynamic_assets 1.2.0 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05cd13c82fadc3c86b4d801b9add765ebf4550be874835c5e72bb3a52af0b2b8
4
- data.tar.gz: 8481c677ec9ea09c2b13d56ff5fc1c251a7f982725094e4b92c16331578e264a
3
+ metadata.gz: 8f4102ebcc09a9c91ad535a06179560476217a410d75511df6fd78762b2227c5
4
+ data.tar.gz: 1255d4fc1b4de77e09c30d9d388fa7f0dd6f75c0ba65a1ef3c35ecc3314cbf75
5
5
  SHA512:
6
- metadata.gz: 3e4618cfd1c9a52f8e2628c41f9c5869cfaee9695f2b9d21137d0622688b71dd3d3511faab48bf584997be2ec8b0d81e983fc826a6b073cd1854470922410450
7
- data.tar.gz: 263130438147471d34412b6a15a6b14b8b645444589c2b68866314ba58b2e532e22554e413eae14599b2f6a84551b686575762cb93aa4009a057ee69691d5a25
6
+ metadata.gz: 5543ce35aeb57e5aa44624e89dbb2393863fd1b80e3d1d1ac1394dd6463cc428f6756b4f416d447c629797f92d00b4d37128feb2eec0ca2ced1aa3ebab69f8b3
7
+ data.tar.gz: 3586a4f15eaabc0acdfbffe6e8080069f809f6f64ad5c71e2f56a801b3a352d85b9db6d62f44fee3015c1351d6aad6b85d975a7909430e31a7303b855379774d
data/.rubocop.yml CHANGED
@@ -18,4 +18,7 @@ Lint/ScriptPermission:
18
18
  Enabled: false
19
19
 
20
20
  Layout/EndOfLine:
21
+ Enabled: false
22
+
23
+ Metrics/ClassLength:
21
24
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -27,4 +27,21 @@
27
27
 
28
28
  ## [1.2.0] - 2025-06-06
29
29
 
30
- - Added option to select formats
30
+ - Added option to select formats
31
+
32
+ ## [1.3.0] - 2025-06-07
33
+
34
+ - Added Sub directory options
35
+ - Added Default Sub directories for
36
+ - css >> styles
37
+ - js >> scripts
38
+ - mjs >> scripts
39
+ - ts >> scripts
40
+ - json >> data
41
+ - ico >> icons
42
+ - woff >> fonts
43
+ - woff2 >> fonts
44
+ - ttf >> fonts
45
+ - otf >> fonts
46
+ - Updated Selection logic, added inline definition
47
+ - Added Absolute URL
data/README.md CHANGED
@@ -1,14 +1,16 @@
1
1
  # JekyllDynamicAssets
2
2
 
3
- JekyllDynamicAssets is a Jekyll plugin that allows you to dynamically manage and inject CSS, JS, and other head assets into your site using presets, per-page configuration, and flexible formatting.
3
+ JekyllDynamicAssets is a powerful Jekyll plugin for dynamic, flexible, and DRY asset management. It lets you define, group, and inject CSS, JS, and other head assets using presets, per-page config, and custom formatting.
4
4
 
5
5
  ## Features
6
6
  - Define global (master) assets and per-page assets
7
7
  - Use asset presets for reusable asset groups
8
- - Pre-defined default formats for common assets, can be overwritten
9
- - Auto and Manual select formats
8
+ - Pre-defined and overrideable formats and sources for common assets
9
+ - Auto, Select, and Inline formats and sources
10
10
  - Liquid tag `{% assets %}` for easy asset injection in templates and includes
11
- - Error reporting for missing presets
11
+ - Error reporting for missing presets and formats
12
+ - Absolute/relative URL support
13
+ - Supports all head assets: CSS, JS, module JS, fonts, icons, JSON, etc.
12
14
 
13
15
  ## Installation
14
16
 
@@ -34,59 +36,96 @@ plugins:
34
36
 
35
37
  Finally, in your terminal run:
36
38
 
37
- ```bash
39
+ ```powershell
38
40
  bundle install
39
41
  ```
40
42
 
41
43
  ## Usage
42
44
 
43
- 1. **Configure your assets in `config.yml`:**
45
+ ### 1. Configure your assets in `config.yml`
44
46
 
45
47
  ```yaml
46
48
  assets:
47
- master: # Master assets
49
+ master:
48
50
  - main.css
49
51
  - main.js
50
- source: "/assets/" # Optional: base path for all assets, skips assets starting with http
51
-
52
- presets: # Create presets to include multiple assets
52
+
53
+ source:
54
+ base: /assets
55
+ github: https://github.com/assets/
56
+ css: /css
57
+ js: /js
58
+ absolute: true # Use absolute URLs (uses `url` and `baseurl` from config)
59
+
60
+ presets:
53
61
  blog: [blog.css, blog.js]
54
62
  project: [project.css, project.js, code-highlight.css, slideshow.js, myApp.js]
55
-
63
+
56
64
  formats:
57
- js: <script defer src='%s'></script> # Overwrite defaults
58
- xyz: <custom> %s </custom> # Define Custom formats
65
+ js: <script defer src='%s'></script>
66
+ xyz: <custom> %s </custom>
59
67
  screen-css: <link rel="stylesheet" href="%s" media="screen">
60
68
  ```
61
69
 
62
- 2. **Per-page or per-collection configuration:**
70
+ If all your assets are in the same folder, you can simply do:
71
+
72
+ ```yaml
73
+ assets:
74
+ source: /asset_folder
75
+ ```
76
+
77
+ **Path rules:** Always use a leading slash, never a trailing slash.
78
+
79
+ ### 2. Per-page or per-collection configuration
63
80
 
64
81
  In your page or post front matter:
65
82
 
66
83
  ```yaml
67
84
  assets:
68
- files:
69
- - manual.css # include singular files
70
- - onscreen.css::screen-css # Use :: to select a format, default format is determined by file extension
85
+ files: # See Asset Definition Syntax below
86
+ - manual.css
87
+ - onscreen.css::screen-css
88
+ - no_script.css:::<noscript><link rel="stylesheet" href="%s"></noscript>
89
+ - github<<master.css
90
+ - /css/new<<<new-main.css
71
91
  presets:
72
- - blog # Use a preset
92
+ - blog
93
+ - project
73
94
  ```
74
95
 
75
- 3. **Inject assets in your templates:**
96
+ ### 3. Inject assets in your templates
76
97
 
77
98
  Use the Liquid tag where you want the assets to appear (typically in your `<head>`):
78
99
 
79
100
  ```liquid
80
101
  <head>
81
102
  <!-- other tags like meta etc. -->
82
-
83
103
  {% assets %}
84
104
  </head>
85
105
  ```
86
106
 
87
107
  This will output the appropriate HTML tags for all configured assets. The tag should generally be used inside your `<head>` tag but can be used anywhere else.
88
108
 
89
- For assets which you haven't defined any format and there isn't any default for it either, the code will simply write the name of that asset.
109
+ ---
110
+
111
+ ### Asset Definition Syntax
112
+
113
+ You can use the following syntax anywhere (config or front matter):
114
+
115
+ ```
116
+ Source<<Asset::Format
117
+ ```
118
+
119
+ - `<<` uses `Source` as a variable from config; `<<<` uses `Source` as a literal.
120
+ - `::` uses `Format` as a variable from config; `:::` uses `Format` as a literal.
121
+ - If either is not defined, source/format is taken from config using the file extension.
122
+ - If the source is not external, it will be determined using `base + Source`.
123
+
124
+ **NOTE:**
125
+ - If JDA can't find a source, it will use the `base` without sub-directories.
126
+ - If JDA can't find the format, it will raise an error. A format is required for each asset.
127
+
128
+ ---
90
129
 
91
130
  ## Contributing
92
131
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllDynamicAssets
4
+ DEFAULT_SOURCES = {
5
+ "base" => "/assets",
6
+ "css" => "/styles",
7
+ "js" => "/scripts",
8
+ "mjs" => "/scripts",
9
+ "ts" => "/scripts",
10
+ "json" => "/data",
11
+ "ico" => "/icons",
12
+ "woff" => "/fonts",
13
+ "woff2" => "/fonts",
14
+ "ttf" => "/fonts",
15
+ "otf" => "/fonts"
16
+ }.freeze
17
+ end
@@ -7,49 +7,111 @@ module JekyllDynamicAssets
7
7
  @config = site.config["assets"] || {}
8
8
  @page = page
9
9
  @page_config = page["assets"] || {}
10
+ @path = @page["path"] || @page["relative_path"] || "unknown"
11
+
12
+ sub_configs(site:)
10
13
  end
11
14
 
15
+ # Get all link tags to assets for this page
12
16
  def assets
13
17
  all_assets = combined_assets
14
18
  asset_insertions = []
15
- all_assets.each do |asset|
16
- link_format = asset.include?("::") ? asset.split("::").last : asset.split(".").last
17
- asset_link = format_string(link_format) % asset.split("::").first
18
- asset_insertions << asset_link
19
+ all_assets.each do |dir, asset, format_string|
20
+ directory = dir.start_with?("http") ? dir : prepare_dir(dir)
21
+ asset_link = directory + asset
22
+ asset_insertions << format_string % asset_link
19
23
  end
20
24
  asset_insertions
21
25
  end
22
26
 
23
27
  private
24
28
 
25
- def format_string(link_format)
26
- formats ||= formats_merge(DEFAULT_FORMATS, @config["formats"])
27
- formats[link_format] || "%s"
29
+ def sub_configs(site:)
30
+ @link_formats ||= setting_merge(DEFAULT_FORMATS, @config["formats"]) # Format Config
31
+
32
+ # Standardize Source Config
33
+ srcs ||= setting_merge(DEFAULT_SOURCES, @config["source"])
34
+ @asset_sources = if srcs.is_a?(String)
35
+ {
36
+ "base" => srcs
37
+ }.freeze
38
+ else
39
+ srcs
40
+ end
41
+
42
+ # Get URL for absolute_url filter
43
+ return unless @config["absolute"] == true
44
+
45
+ @url = (site.config["url"] || "") + (site.config["baseurl"] || "")
46
+ end
47
+
48
+ def setting_merge(default, custom)
49
+ if custom.nil?
50
+ default
51
+ elsif custom.is_a?(String)
52
+ custom
53
+ else
54
+ custom.merge default do |_key, custom_setting, default_setting|
55
+ custom_setting unless default_setting.respond_to? :merge
56
+ end
57
+ end
58
+ end
59
+
60
+ def prepare_dir(dir)
61
+ # Format URL assuming standard inputs, all leading slashes and no trailing
62
+ directory = @config["absolute"] ? @url : ""
63
+ directory += @asset_sources["base"] unless @asset_sources["base"] == ""
64
+ directory += dir unless dir.empty? || dir == ""
65
+ directory += "/"
66
+ directory
28
67
  end
29
68
 
30
- def formats_merge(default, custom)
31
- custom.merge default do |_key, custom_setting, default_setting|
32
- custom_setting unless default_setting.respond_to? :merge
69
+ def get_sub_dir(string)
70
+ return string.split("<<<").first if string.include?("<<<")
71
+
72
+ hash = string.include?("<<") ? string.split("<<").first : string.split(".").last
73
+
74
+ @asset_sources.fetch(hash) do
75
+ warn "DynamicAssets: No source defined for #{hash.inspect} in #{@path} - using base source"
76
+ ""
77
+ end
78
+ end
79
+
80
+ def get_format(string)
81
+ return string.split(":::").last if string.include?(":::")
82
+
83
+ hash = string.include?("::") ? string.split("::").last : string.split(".").last
84
+
85
+ @link_formats.fetch(hash) do
86
+ raise KeyError, "DynamicAssets: No #{hash.inspect} format defined"
33
87
  end
34
88
  end
35
89
 
36
90
  def combined_assets
37
91
  # Container
92
+ raw_assets = []
38
93
  assets = []
39
94
 
40
95
  # Add assets
41
- assets.concat(Array(@config["master"]))
42
- assets.concat(Array(preset_files))
43
- assets.concat(Array(@page_config["files"]))
96
+ raw_assets.concat(Array(@config["master"]))
97
+ raw_assets.concat(Array(preset_files))
98
+ raw_assets.concat(Array(@page_config["files"]))
44
99
 
45
- append_base(assets.uniq)
100
+ raw_assets.uniq.each do |asset|
101
+ assets << asset_array(asset)
102
+ end
103
+ assets
46
104
  end
47
105
 
48
- def append_base(assets)
49
- base = @config["source"].to_s
50
- base += "/" unless base.end_with?("/") || base.empty?
106
+ def asset_array(asset)
107
+ buff = Array.new(3)
108
+ buff[2] = get_format(asset) # Store Format
109
+ asset = asset.split(/:{2,}/).first # Remove Format selector
110
+ buff[0] = get_sub_dir(asset) # Store Source
111
+ asset = asset.split(/<{2,}/).last # Remove Source selector
112
+ buff[1] = asset # Store Asset path
51
113
 
52
- assets.map { |asset| asset.start_with?("http") ? asset : base + asset }
114
+ buff
53
115
  end
54
116
 
55
117
  def preset_files
@@ -58,6 +120,7 @@ module JekyllDynamicAssets
58
120
  bad_presets = []
59
121
  selected_presets = Array(@page_config["presets"])
60
122
  preset_map = @config["presets"] || {}
123
+
61
124
  selected_presets.each do |preset|
62
125
  if preset_map.key?(preset)
63
126
  preset_assets.concat(Array(preset_map[preset]))
@@ -65,17 +128,18 @@ module JekyllDynamicAssets
65
128
  bad_presets << preset
66
129
  end
67
130
  end
68
- remaining?(bad_presets) # Raise error for undefined errors
131
+
132
+ remaining_presets?(bad_presets) # Raise error for undefined errors
69
133
  preset_assets
70
134
  end
71
135
 
72
- def remaining?(remaining_presets)
73
- # Display the undefined presets
136
+ def remaining_presets?(remaining_presets)
137
+ # return if no undefined presets
74
138
  return if remaining_presets.empty?
75
139
 
76
- location = @page["path"] || @page["relative_path"] || "unknown"
140
+ # Raise error for all undefined presets
77
141
  missing_list = remaining_presets.to_a.join(", ")
78
- raise "DynamicAssets: No preset(s) defined: #{missing_list} at: #{location}"
142
+ raise KeyError, "DynamicAssets: No preset(s) defined: #{missing_list}"
79
143
  end
80
144
  end
81
145
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllDynamicAssets
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.0"
5
5
  end
@@ -4,6 +4,7 @@ require_relative "jekyll_dynamic_assets/version"
4
4
  require_relative "jekyll_dynamic_assets/processor"
5
5
  require_relative "jekyll_dynamic_assets/assets_tag"
6
6
  require_relative "jekyll_dynamic_assets/defaults/formats"
7
+ require_relative "jekyll_dynamic_assets/defaults/sources"
7
8
 
8
9
  module JekyllDynamicAssets
9
10
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll_dynamic_assets
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - M. Umar Shahbaz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-06 00:00:00.000000000 Z
11
+ date: 2025-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -67,6 +67,7 @@ files:
67
67
  - lib/jekyll_dynamic_assets.rb
68
68
  - lib/jekyll_dynamic_assets/assets_tag.rb
69
69
  - lib/jekyll_dynamic_assets/defaults/formats.rb
70
+ - lib/jekyll_dynamic_assets/defaults/sources.rb
70
71
  - lib/jekyll_dynamic_assets/processor.rb
71
72
  - lib/jekyll_dynamic_assets/version.rb
72
73
  - sig/jekyll_dynamic_assets.rbs