yass 0.6.1 → 0.7.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: dbf192ae9cf4c4a5b3e25e2d9bf3dabdf3a1fececf59dad399d172011a6016f4
4
- data.tar.gz: 7b39f236d0b15b947be5a8553feefa12d8a65b7fdacfd75c7d98049089c3dbc1
3
+ metadata.gz: 649645d7b796ba02544a816464ff18efb5fdac5c3e914f16ce39ebde71337a37
4
+ data.tar.gz: e6e2268d8733f20efb0f03f7b29c2a5a58e8e0deac5a0a4d796db3ca2ae78971
5
5
  SHA512:
6
- metadata.gz: ad8980f7bcd8b5ff6a8620e21c083b21fb803296f7d19fe5e64ba0b9934f22c4d5f5df47d6e72297ca564fe990821d48795f824755da603f35ded65dd322b0ce
7
- data.tar.gz: 0d82bbf8fc40f76a1da01a634d5673364353d3db5db116283520b5cea266df1880d29a5b86be6347fe41d0e47efcc3d02f3268a5d2bc74779c08d515d7e740f7
6
+ metadata.gz: e0eae7b97dbf4cc49a7e37812f867d0734e249058f560e58067be91d69abd4c2ce3e3a4e37eb5203555bc2135fc958a7c30c80cac67e1cd6c0551e44548c0c10
7
+ data.tar.gz: df0d5bf462455417fed28d9725fee69bba326284e20e57532fb6a27a142363e8c91d4f670735f71d72a82a670dd2ec1a67d468829d043ef82304f336701b2690
data/README.md CHANGED
@@ -17,7 +17,7 @@ Creating blog/site/assets/highlight.min.js
17
17
  Creating blog/site/assets/highlightjs-atom-one-dark.min.css
18
18
  Creating blog/site/assets/main.css.liquid
19
19
  Creating blog/site/helpers/index.md.liquid
20
- Creating blog/site/index.splash.md.liquid
20
+ Creating blog/site/index.md.liquid
21
21
  Creating blog/site/layouts-templates/index.md.liquid
22
22
  Creating blog/templates/asset_tags.liquid
23
23
  Creating blog/templates/nav.liquid
@@ -4,6 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>{{ page.title }}</title>
7
+ <link rel="icon" href="{{ "favicon.png" | relative }}" sizes="32x32">
7
8
  {% render "asset_tags", files: files, page: page %}
8
9
  </head>
9
10
  <body>
@@ -4,6 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>{{ page.title }}</title>
7
+ <link rel="icon" href="{{ "favicon.png" | relative }}" sizes="32x32">
7
8
  {% render "asset_tags", files: files, page: page %}
8
9
  </head>
9
10
  <body>
Binary file
@@ -8,12 +8,15 @@ Your `.liquid` files have access to all the [standard Liquid tags and filters](h
8
8
 
9
9
  An object representing the current page. Properties:
10
10
 
11
- * `title` A titleized version of the filename (e.g. *My File* from *my-file.html*)
11
+ * `title` A titleized version of the filename (e.g. *My File* from *my-file.html*), or from YAML front matter
12
+ * `layout` Name of the page's layout (if any), e.g. *default.html*
12
13
  * `src_path` Path with the original filename (e.g. *foo/bar/zorp.md.liquid*)
13
14
  * `path` URL path relative to the relative root (e.g. *foo/bar/zorp.html*)
14
15
  * `dirname` Directory file is in (e.g. *foo/bar* from *foo/bar/zorp.html*)
15
16
  * `filename` Name of file (e.g. *zorp.html* from *foo/bar/zorp.html*)
16
17
  * `extname` File extension (e.g. *.html* from *foo/bar/zorp.html*)
18
+ * `filesize` Size of file in bytes
19
+ * Any other value defined in the file's YAML front matter
17
20
 
18
21
  {% highlight html %}
19
22
  <h1>{% echo "{{" %} page.title {% echo "}}" %}</h1>
@@ -1,6 +1,9 @@
1
+ ---
2
+ layout: splash
3
+ ---
1
4
  # What is Yass?
2
5
 
3
- Yass is an astonishingly un-opinionated static site generator. Your sites's structure is entirely up to you: organize static assets, `.html` files, `.md` ([Markdown](https://commonmark.org/)) files, and `.liquid` ([Liquid](https://shopify.github.io/liquid/)) templates however you want under `site/`. Liquid layouts and reusable templates are supported but optional.
6
+ Yass is an astonishingly un-opinionated static site generator. Your sites's structure is entirely up to you: organize static assets, `.html` files, `.md` ([Markdown](https://commonmark.org/)) files, and `.liquid` ([Liquid](https://shopify.github.io/liquid/)) templates however you want under `site/`. Liquid layouts, reusable templates, and YAML front matter are supported.
4
7
 
5
8
  The **one** opinion Yass holds is that **you** should decide everything. There's zero configuration and no conventions to learn!
6
9
 
@@ -17,7 +20,7 @@ Creating blog/site/assets/highlight.min.js
17
20
  Creating blog/site/assets/highlightjs-atom-one-dark.min.css
18
21
  Creating blog/site/assets/main.css.liquid
19
22
  Creating blog/site/helpers/index.md.liquid
20
- Creating blog/site/index.splash.md.liquid
23
+ Creating blog/site/index.md.liquid
21
24
  Creating blog/site/layouts-templates/index.md.liquid
22
25
  Creating blog/templates/asset_tags.liquid
23
26
  Creating blog/templates/nav.liquid
@@ -1,6 +1,19 @@
1
+ # Front Matter
2
+
3
+ Any file under `site/` may prepend YAML front matter to override the auto-generated title, set a layout, or set arbitrary attributes on the page for use in Liquid.
4
+
5
+ {% highlight yaml %}
6
+ ---
7
+ title: My Title
8
+ layout: foo
9
+ my_val: bar
10
+ ---
11
+ # File contents go here
12
+ {% endhighlight %}
13
+
1
14
  # Layouts
2
15
 
3
- Layouts live in `layouts/` and will be applied to files with matching names. The `content` variable contains the data to render in the layout.
16
+ Layouts are `.liquid` files in `layouts/`. The `content` variable contains the data to render.
4
17
 
5
18
  {% highlight html %}
6
19
  <!DOCTYPE html>
@@ -14,18 +27,20 @@ Layouts live in `layouts/` and will be applied to files with matching names. The
14
27
  </html>
15
28
  {% endhighlight %}
16
29
 
17
- If the above layout is named *page.html.liquid*, it will match any file named `*.page.html*`. Examples:
30
+ Layouts can be applied in the YAML front matter of any file under `site/`. If the following file is named `bar.html*` or `bar.md*`, it will look for a layout named `foo.html.liquid`:
18
31
 
19
- * `foo.page.html`
20
- * `foo.page.html.*`
21
- * `foo.page.md` (because *.md* converts to *.html*)
22
- * `foo.page.md.*`
23
-
24
- The name of the layout (e.g. `page`) is removed from the final filename, resulting in `foo.html`.
32
+ {% highlight yaml %}
33
+ ---
34
+ layout: foo
35
+ ---
36
+ My content
37
+ {% endhighlight %}
25
38
 
26
39
  ## Default layouts
27
40
 
28
- If you create a layout named `default.<ext>.liquid`, Yass will apply it to any `.<ext>` files without layouts. For example, a layout named `default.html.liquid` will match `foo.html` or `foo.not-a-layout.md.liquid`.
41
+ If you create a layout named `default.<ext>.liquid`, Yass will apply it to any `.<ext>` files without a layout. For example, a layout named `default.html.liquid` will match `foo.html` or `foo.md.liquid`.
42
+
43
+ A file may eschew the default layout by setting `layout: false` in the YAML front matter.
29
44
 
30
45
  # Templates
31
46
 
@@ -24,7 +24,7 @@ module Yass
24
24
 
25
25
  private
26
26
 
27
- def generate(source, outfile, content = source.path.read)
27
+ def generate(source, outfile, content = source.content)
28
28
  case outfile.extname
29
29
  when ".md"
30
30
  content = Kramdown::Document.new(content).to_html
@@ -1,23 +1,25 @@
1
1
  module Yass
2
2
  class LiquidTemplate
3
- def self.compile(config, name, src)
3
+ def self.compile(config, filename, src)
4
4
  template = Liquid::Template.parse(src, environment: config.liquid_env)
5
- new(name, template)
5
+ new(filename, template)
6
6
  end
7
7
 
8
- attr_reader :name
8
+ attr_reader :filename
9
9
 
10
- def initialize(name, template)
11
- @name = name
10
+ def initialize(filename, template)
11
+ @filename = filename
12
12
  @template = template
13
13
  end
14
14
 
15
+ def name = filename.sub(/\.liquid$/, "")
16
+
15
17
  def render(source)
16
18
  vars = { "page" => file_attrs(source), "files" => files_attrs(source.config.sources) }
17
19
  vars["content"] = yield if block_given?
18
20
  content = @template.render(vars, { strict_variables: true, strict_filters: true, registers: { source: source } })
19
21
  if @template.errors.any?
20
- source.config.stderr.puts "Errors found in #{name}:"
22
+ source.config.stderr.puts "Errors found in #{filename}:"
21
23
  source.config.stderr.puts @template.errors.map { |e| " #{e}" }.join("\n")
22
24
  end
23
25
  content
@@ -26,15 +28,16 @@ module Yass
26
28
  private
27
29
 
28
30
  def file_attrs(source)
29
- {
31
+ source.front_matter.merge({
30
32
  "title" => source.title,
33
+ "layout" => source.layout&.name,
31
34
  "path" => source.dest_path.to_s,
32
35
  "src_path" => source.src_path.to_s,
33
36
  "dirname" => source.dest_path.dirname.to_s,
34
37
  "filename" => source.dest_path.basename.to_s,
35
38
  "extname" => source.dest_path.basename.extname,
36
- "filesize" => File.stat(source.path).size,
37
- }
39
+ "filesize" => source.size,
40
+ })
38
41
  end
39
42
 
40
43
  def files_attrs(sources) = sources.map { |s| file_attrs s }
data/lib/yass/source.rb CHANGED
@@ -1,40 +1,64 @@
1
+ require 'yaml'
2
+
1
3
  module Yass
2
4
  class Source
3
5
  EXT_CONVERSIONS = {"md" => "html"}.freeze
4
- attr_reader :config, :path, :layout, :src_path, :dest_path, :outfile
6
+ YAML_HEADER = /\A---\s*\n/
7
+ FRONT_MATTER = /\A(?<matter>---\s*\n.*^---\s*\n?)(?<content>.+)?$/m
8
+
9
+ attr_reader :config, :front_matter, :path, :src_path, :dest_path, :outfile, :size
5
10
 
6
11
  def initialize(config, path)
7
12
  @config = config
8
13
  @path = path
9
14
  @src_path = path.relative_path_from config.src_dir
10
- dest_filename, @layout = parse_name
11
15
  @dest_path = src_path.dirname.join(dest_filename)
12
16
  @outfile = config.dest_dir.join(dest_path)
17
+ @size = File.stat(path).size
18
+
19
+ @front_matter, @content = parse_content
20
+ @title = @front_matter.delete "title" if front_matter.key? "title"
21
+ @layout_name = @front_matter.delete "layout" if front_matter.key? "layout"
22
+ end
23
+
24
+ def layout
25
+ return nil if @layout_name == false
26
+
27
+ ext = dest_path.extname
28
+ config.layout_cache["#{@layout_name}#{ext}"] || config.layout_cache["default#{ext}"]
13
29
  end
14
30
 
15
31
  def title
32
+ return @title if @title
33
+
16
34
  fname = dest_path.basename.sub(/\..+$/, "").to_s
17
35
  fname = src_path.dirname.basename.to_s if fname == "index"
18
36
  fname = "Home" if fname == "."
19
- fname.sub(/[_-]+/, " ").split(/ +/).map(&:capitalize).join(" ")
37
+ @title = fname.gsub(/[_-]+/, " ").split(/ +/).map(&:capitalize).join(" ")
20
38
  end
21
39
 
22
- def dynamic? = !!(/\.(liquid|md)(\..+)?$/ =~ path.basename.to_s || layout)
40
+ def dynamic? = !!(/\.(liquid|md)(\..+)?$/ =~ path.basename.to_s || layout || @has_front_matter)
41
+
42
+ def content = @content ||= path.read
23
43
 
24
44
  private
25
45
 
26
- def parse_name
46
+ def dest_filename
27
47
  name, exts = path.basename.to_s.split(".", 2)
28
- return name, nil if exts.nil?
29
-
30
- exts = exts.split(".").map { |x| EXT_CONVERSIONS[x] || x } - %w[liquid]
31
- return "#{name}.#{exts[0]}", config.layout_cache["default.#{exts[0]}"] if exts.size == 1
48
+ exts = (exts || "").split(".").map { |x| EXT_CONVERSIONS[x] || x } - %w[liquid]
49
+ [name, *exts].join(".")
50
+ end
32
51
 
33
- layout = config.layout_cache["#{exts[-2..].join(".")}"]
34
- exts.delete_at(-2) if layout
35
- layout ||= config.layout_cache["default.#{exts[-1]}"]
52
+ def parse_content
53
+ @has_front_matter = YAML_HEADER.match? path.read(10)
54
+ return {}, nil unless @has_front_matter
36
55
 
37
- return "#{name}.#{exts.join "."}", layout
56
+ @has_front_matter = true
57
+ captures = FRONT_MATTER.match(path.read).named_captures
58
+ return YAML.safe_load(captures["matter"].to_s), captures["content"].to_s
59
+ rescue Psych::SyntaxError => e
60
+ config.stderr.puts "Error parsing front matter for #{path}: #{e.message}"
61
+ return {}, ""
38
62
  end
39
63
  end
40
64
  end
data/lib/yass/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Yass
2
- VERSION = "0.6.1".freeze
2
+ VERSION = "0.7.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Hollinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-12 00:00:00.000000000 Z
11
+ date: 2025-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: filewatcher
@@ -69,8 +69,9 @@ files:
69
69
  - docs-src/site/assets/highlight.min.js
70
70
  - docs-src/site/assets/highlightjs-atom-one-dark.min.css
71
71
  - docs-src/site/assets/main.css.liquid
72
+ - docs-src/site/favicon.png
72
73
  - docs-src/site/helpers/index.md.liquid
73
- - docs-src/site/index.splash.md.liquid
74
+ - docs-src/site/index.md.liquid
74
75
  - docs-src/site/layouts-templates/index.md.liquid
75
76
  - docs-src/templates/asset_tags.liquid
76
77
  - docs-src/templates/nav.liquid