static-site-builder 0.0.1 → 0.1.4
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 +4 -4
- data/CHANGELOG.md +61 -1
- data/README.md +38 -10
- data/lib/generator.rb +218 -15
- data/lib/static_site_builder/builder.rb +208 -49
- data/lib/static_site_builder/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ec7765f3cc618a791a6d655fed75fe39f43a09d9c697cc71135d17160dbd27f
|
|
4
|
+
data.tar.gz: 74ace48bd713ba712607509baf63a80095cd610395be622b59c3e552336f10df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 358643b7c2cb4bd56693c18fa4f57114da85b519a1423e319a55d1b4d7ee0d3190768985225539e6c65f9eed044d96fced689d5464d39fb0db85238dbcb4e6d4
|
|
7
|
+
data.tar.gz: a8ab43edfdac947a34e0222c181037213120eb1f9dea91c924f218e974908c51491135ce475aadde6552bedd65698cf05a54e18af60b73669b6c6fe7134cb84a
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,66 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.4] - 2025-11-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Generator now automatically creates `lib/page_helpers.rb` with `PageHelpers::PAGES` structure for page metadata
|
|
12
|
+
- Generator now automatically creates `config/sitemap.rb` for sitemap generation
|
|
13
|
+
- `sitemap_generator` gem is now automatically included in generated Gemfiles
|
|
14
|
+
- `build:sitemap` task is automatically added to generated Rakefiles
|
|
15
|
+
- Sitemap generation is integrated into `build:all` task
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Page metadata is now managed via `PageHelpers::PAGES` hash instead of frontmatter
|
|
19
|
+
- README updated to reflect `PageHelpers::PAGES` approach (frontmatter example removed)
|
|
20
|
+
- ActionView requirement changed from `>= 8.0` to `~> 7.1` for Ruby 3.1 compatibility
|
|
21
|
+
- Generated layouts now use `@title` and `@js_modules` instance variables instead of frontmatter
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Fixed `js_modules` variable reference in generated layouts (now uses `@js_modules`)
|
|
25
|
+
- Fixed PageHelpers metadata loading to occur before page content rendering, allowing partials to access `@title`, `@description`, etc.
|
|
26
|
+
- Removed all frontmatter parsing code and references
|
|
27
|
+
- Updated all specs to use `PageHelpers::PAGES` instead of frontmatter
|
|
28
|
+
|
|
29
|
+
## [0.1.3] - 2025-11-22
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- Integrated ActionView 8+ for proper Rails-style partial rendering
|
|
33
|
+
- Support for Rails-style render syntax: `render 'shared/header'` and `render partial: 'shared/header'`
|
|
34
|
+
- Support for passing locals to partials: `render partial: 'shared/header', locals: { title: 'Hello' }`
|
|
35
|
+
- Nested partial support (partials can render other partials)
|
|
36
|
+
- Multiple partials on the same page now work correctly
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Replaced raw ERB implementation with ActionView::Base for template rendering
|
|
40
|
+
- Render method now uses ActionView's rendering system, matching Rails behaviour exactly
|
|
41
|
+
- Partials automatically receive page variables (@js_modules, importmap_json, current_page)
|
|
42
|
+
- Improved error messages for missing partials (converted from ActionView format for backwards compatibility)
|
|
43
|
+
- Template annotations now preserve both page and layout annotations correctly
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
- Fixed issue where nested partials (partials rendering other partials) would fail or produce incorrect output
|
|
47
|
+
- Fixed issue where multiple partials on the same page would only render the last one
|
|
48
|
+
- Fixed template annotations being stripped when layout annotations were added
|
|
49
|
+
|
|
50
|
+
## [0.1.2] - 2025-11-22
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
- CSS directory is now always created when Tailwind handles CSS compilation, preventing 404 errors for stylesheets
|
|
54
|
+
- Build process now updates files in place instead of cleaning and recreating the dist directory, preventing 404 errors during rebuilds in development mode
|
|
55
|
+
- Fixed race condition where pages would return 404 when code changes triggered rebuilds
|
|
56
|
+
|
|
57
|
+
## [0.1.1] - 2025-11-21
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- `render` helper method for ERB templates to include partials
|
|
61
|
+
- Support for rendering partials from `app/views/shared/` directory
|
|
62
|
+
- Partial files should be named with `_` prefix (e.g., `_header.html.erb`)
|
|
63
|
+
- Partials have access to page variables (@js_modules, etc.)
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
- Improved ERB compilation to support partial rendering
|
|
67
|
+
|
|
8
68
|
## [0.0.1] - 2025-11-21
|
|
9
69
|
|
|
10
70
|
### Added
|
|
@@ -15,7 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
75
|
- Support for multiple JavaScript bundlers (Importmap, ESBuild, Webpack, Vite, None)
|
|
16
76
|
- Support for multiple CSS frameworks (TailwindCSS, shadcn/ui, Plain CSS)
|
|
17
77
|
- Support for multiple JavaScript frameworks (Stimulus, React, Vue, Alpine.js, Vanilla)
|
|
18
|
-
-
|
|
78
|
+
- Page metadata via `PageHelpers::PAGES` hash
|
|
19
79
|
- Layout support with nested layouts
|
|
20
80
|
- Importmap JSON generation
|
|
21
81
|
- Asset copying (JavaScript, CSS, vendor files, static files)
|
data/README.md
CHANGED
|
@@ -48,11 +48,12 @@ A clean project structure that depends on gems:
|
|
|
48
48
|
|
|
49
49
|
```
|
|
50
50
|
my-site/
|
|
51
|
-
├── Gemfile # Dependencies (static-site-builder,
|
|
51
|
+
├── Gemfile # Dependencies (static-site-builder, sitemap_generator, etc.)
|
|
52
52
|
├── package.json # JS dependencies (if needed)
|
|
53
|
-
├── Rakefile # Build tasks
|
|
53
|
+
├── Rakefile # Build tasks (includes sitemap generation)
|
|
54
54
|
├── config/
|
|
55
|
-
│
|
|
55
|
+
│ ├── importmap.rb # Importmap config (if using importmap)
|
|
56
|
+
│ └── sitemap.rb # Sitemap generation config
|
|
56
57
|
├── app/
|
|
57
58
|
│ ├── views/
|
|
58
59
|
│ │ ├── layouts/
|
|
@@ -61,7 +62,8 @@ my-site/
|
|
|
61
62
|
│ ├── javascript/
|
|
62
63
|
│ └── assets/
|
|
63
64
|
└── lib/
|
|
64
|
-
|
|
65
|
+
├── site_builder.rb # Compiles your site
|
|
66
|
+
└── page_helpers.rb # Page metadata (title, description, etc.)
|
|
65
67
|
```
|
|
66
68
|
|
|
67
69
|
## How It Works
|
|
@@ -109,18 +111,32 @@ my-site/
|
|
|
109
111
|
|
|
110
112
|
### Using ERB Templates
|
|
111
113
|
|
|
112
|
-
Create pages in `app/views/pages
|
|
114
|
+
Create pages in `app/views/pages/`:
|
|
113
115
|
|
|
114
116
|
```erb
|
|
115
|
-
---
|
|
116
|
-
title: My Page
|
|
117
|
-
description: A great page
|
|
118
|
-
---
|
|
119
|
-
|
|
120
117
|
<h1><%= @title %></h1>
|
|
121
118
|
<p><%= @description %></p>
|
|
122
119
|
```
|
|
123
120
|
|
|
121
|
+
Page metadata is automatically configured in `lib/page_helpers.rb` (generated automatically):
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
module PageHelpers
|
|
125
|
+
PAGES = {
|
|
126
|
+
'/' => {
|
|
127
|
+
title: 'My Page',
|
|
128
|
+
description: 'A great page',
|
|
129
|
+
url: 'https://example.com',
|
|
130
|
+
image: 'https://example.com/image.jpg',
|
|
131
|
+
priority: 1.0,
|
|
132
|
+
changefreq: 'weekly'
|
|
133
|
+
}
|
|
134
|
+
}.freeze
|
|
135
|
+
end
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The builder automatically loads metadata from `PageHelpers::PAGES` and sets `@title`, `@description`, `@url`, and `@image` instance variables for use in your templates. This metadata is also used by the `sitemap_generator` gem for generating sitemaps.
|
|
139
|
+
|
|
124
140
|
Use layouts in `app/views/layouts/application.html.erb`:
|
|
125
141
|
|
|
126
142
|
```erb
|
|
@@ -214,6 +230,18 @@ Install components and use them in your templates:
|
|
|
214
230
|
npx shadcn-ui@latest add button
|
|
215
231
|
```
|
|
216
232
|
|
|
233
|
+
### Generating Sitemaps
|
|
234
|
+
|
|
235
|
+
Sitemap generation is automatically configured when you generate a new site. The `sitemap_generator` gem is included in the Gemfile, and `config/sitemap.rb` is automatically created.
|
|
236
|
+
|
|
237
|
+
The sitemap is generated from your `PageHelpers::PAGES` metadata during `rake build:all`. Update `config/sitemap.rb` to set your domain:
|
|
238
|
+
|
|
239
|
+
```ruby
|
|
240
|
+
SitemapGenerator::Sitemap.default_host = 'https://yourdomain.com'
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The sitemap will be generated in `dist/sitemaps/sitemap.xml.gz` during the build process.
|
|
244
|
+
|
|
217
245
|
## Examples
|
|
218
246
|
|
|
219
247
|
### ERB + Importmap + Stimulus + TailwindCSS
|
data/lib/generator.rb
CHANGED
|
@@ -68,8 +68,11 @@ module StaticSiteBuilder
|
|
|
68
68
|
create_config_files
|
|
69
69
|
create_app_structure
|
|
70
70
|
create_build_files
|
|
71
|
+
create_page_helpers
|
|
72
|
+
create_sitemap_config
|
|
71
73
|
create_example_pages
|
|
72
74
|
create_readme
|
|
75
|
+
create_gitignore
|
|
73
76
|
|
|
74
77
|
puts "\n✓ Site generated successfully!"
|
|
75
78
|
puts "\nNext steps:"
|
|
@@ -103,7 +106,8 @@ module StaticSiteBuilder
|
|
|
103
106
|
gems = [
|
|
104
107
|
"rake",
|
|
105
108
|
"static-site-builder",
|
|
106
|
-
"webrick" # Required for dev server (removed from stdlib in Ruby 3.0+)
|
|
109
|
+
"webrick", # Required for dev server (removed from stdlib in Ruby 3.0+)
|
|
110
|
+
"sitemap_generator" # For generating sitemaps from PageHelpers::PAGES
|
|
107
111
|
]
|
|
108
112
|
gems << "importmap-rails" if @options[:js_bundler] == "importmap"
|
|
109
113
|
gems << "phlex-rails" if @options[:template_engine] == "phlex"
|
|
@@ -185,6 +189,78 @@ module StaticSiteBuilder
|
|
|
185
189
|
create_rails_config if @options[:edit_rails]
|
|
186
190
|
end
|
|
187
191
|
|
|
192
|
+
def create_page_helpers
|
|
193
|
+
content = <<~RUBY
|
|
194
|
+
# frozen_string_literal: true
|
|
195
|
+
|
|
196
|
+
module PageHelpers
|
|
197
|
+
# Page metadata configuration
|
|
198
|
+
# The builder automatically loads this and sets @title, @description, @url, and @image
|
|
199
|
+
# instance variables for use in your templates.
|
|
200
|
+
# This metadata is also used by sitemap_generator for generating sitemaps.
|
|
201
|
+
PAGES = {
|
|
202
|
+
'/' => {
|
|
203
|
+
title: 'Home',
|
|
204
|
+
description: 'Welcome to my site',
|
|
205
|
+
url: 'https://example.com',
|
|
206
|
+
image: 'https://example.com/image.jpg',
|
|
207
|
+
priority: 1.0,
|
|
208
|
+
changefreq: 'weekly'
|
|
209
|
+
}
|
|
210
|
+
}.freeze
|
|
211
|
+
|
|
212
|
+
def page_title(path = nil)
|
|
213
|
+
path ||= @current_page
|
|
214
|
+
PAGES[path]&.fetch(:title) || 'Site'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def page_description(path = nil)
|
|
218
|
+
path ||= @current_page
|
|
219
|
+
PAGES[path]&.fetch(:description) || 'A static site'
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def page_url(path = nil)
|
|
223
|
+
path ||= @current_page
|
|
224
|
+
PAGES[path]&.fetch(:url) || 'https://example.com'
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def page_image(path = nil)
|
|
228
|
+
path ||= @current_page
|
|
229
|
+
PAGES[path]&.fetch(:image) || 'https://example.com/image.jpg'
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
RUBY
|
|
233
|
+
|
|
234
|
+
write_file("lib/page_helpers.rb", content)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def create_sitemap_config
|
|
238
|
+
content = <<~RUBY
|
|
239
|
+
# frozen_string_literal: true
|
|
240
|
+
|
|
241
|
+
require 'sitemap_generator'
|
|
242
|
+
require_relative '../lib/page_helpers'
|
|
243
|
+
|
|
244
|
+
# Configure sitemap generator
|
|
245
|
+
# Update default_host to your actual domain
|
|
246
|
+
SitemapGenerator::Sitemap.default_host = 'https://example.com'
|
|
247
|
+
SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps'
|
|
248
|
+
SitemapGenerator::Sitemap.public_path = 'dist'
|
|
249
|
+
|
|
250
|
+
# Generate sitemap from PageHelpers::PAGES
|
|
251
|
+
SitemapGenerator::Sitemap.create do
|
|
252
|
+
PageHelpers::PAGES.each do |path, metadata|
|
|
253
|
+
add path,
|
|
254
|
+
lastmod: Time.now,
|
|
255
|
+
priority: metadata[:priority] || 0.5,
|
|
256
|
+
changefreq: metadata[:changefreq] || 'weekly'
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
RUBY
|
|
260
|
+
|
|
261
|
+
write_file("config/sitemap.rb", content)
|
|
262
|
+
end
|
|
263
|
+
|
|
188
264
|
def create_importmap_config
|
|
189
265
|
content = <<~RUBY
|
|
190
266
|
# frozen_string_literal: true
|
|
@@ -409,7 +485,7 @@ module StaticSiteBuilder
|
|
|
409
485
|
<head>
|
|
410
486
|
<meta charset="UTF-8">
|
|
411
487
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
412
|
-
<title><%=
|
|
488
|
+
<title><%= @title || 'Site' %></title>
|
|
413
489
|
<link rel="stylesheet" href="/assets/stylesheets/application.css">
|
|
414
490
|
</head>
|
|
415
491
|
<body>
|
|
@@ -469,8 +545,8 @@ module StaticSiteBuilder
|
|
|
469
545
|
case @options[:js_bundler]
|
|
470
546
|
when "importmap"
|
|
471
547
|
<<~ERB
|
|
472
|
-
<% if js_modules
|
|
473
|
-
<% js_modules.each do |module_name| %>
|
|
548
|
+
<% if @js_modules.present? %>
|
|
549
|
+
<% @js_modules.each do |module_name| %>
|
|
474
550
|
<script type="module">import "<%= module_name %>";</script>
|
|
475
551
|
<% end %>
|
|
476
552
|
<% else %>
|
|
@@ -580,6 +656,18 @@ module StaticSiteBuilder
|
|
|
580
656
|
@tailwind base;
|
|
581
657
|
@tailwind components;
|
|
582
658
|
@tailwind utilities;
|
|
659
|
+
|
|
660
|
+
@layer base {
|
|
661
|
+
html {
|
|
662
|
+
scroll-behavior: smooth;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
@layer utilities {
|
|
667
|
+
section[id] {
|
|
668
|
+
scroll-margin-top: 5rem;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
583
671
|
CSS
|
|
584
672
|
when "shadcn"
|
|
585
673
|
write_file("app/assets/stylesheets/application.css", <<~CSS)
|
|
@@ -614,6 +702,7 @@ module StaticSiteBuilder
|
|
|
614
702
|
require "webrick"
|
|
615
703
|
require "fileutils"
|
|
616
704
|
require "static_site_builder/websocket_server"
|
|
705
|
+
require "json"
|
|
617
706
|
|
|
618
707
|
port = ENV["PORT"] || 3000
|
|
619
708
|
ws_port = ENV["WS_PORT"] || 3001
|
|
@@ -629,13 +718,33 @@ module StaticSiteBuilder
|
|
|
629
718
|
ENV["WS_PORT"] = ws_port.to_s
|
|
630
719
|
Rake::Task["build:all"].invoke
|
|
631
720
|
|
|
721
|
+
# Check if we need to run Tailwind CSS watch (after initial build)
|
|
722
|
+
tailwind_pid = nil
|
|
723
|
+
package_json_path = Pathname.new(Dir.pwd).join("package.json")
|
|
724
|
+
if package_json_path.exist?
|
|
725
|
+
package_json = JSON.parse(File.read(package_json_path))
|
|
726
|
+
if package_json.dig("scripts", "watch:css")
|
|
727
|
+
puts "🎨 Starting Tailwind CSS watch mode..."
|
|
728
|
+
tailwind_pid = spawn("npm", "run", "watch:css", :err => File::NULL, :out => File::NULL)
|
|
729
|
+
# Touch the source file to trigger Tailwind watch to process CSS immediately
|
|
730
|
+
css_source = Pathname.new(Dir.pwd).join("app", "assets", "stylesheets", "application.css")
|
|
731
|
+
if css_source.exist?
|
|
732
|
+
FileUtils.touch(css_source)
|
|
733
|
+
end
|
|
734
|
+
# Give Tailwind a moment to process CSS
|
|
735
|
+
sleep 1.5
|
|
736
|
+
end
|
|
737
|
+
end
|
|
738
|
+
|
|
632
739
|
puts "\n🚀 Starting development server at http://localhost:#{port}"
|
|
633
740
|
puts "📡 WebSocket server at ws://localhost:#{ws_port}"
|
|
634
741
|
puts "📝 Watching for changes... (Ctrl+C to stop)"
|
|
635
742
|
puts "🔄 Live reload enabled - pages will auto-refresh on changes\n"
|
|
636
743
|
|
|
637
|
-
# Simple file watcher -
|
|
638
|
-
|
|
744
|
+
# Simple file watcher - rebuild HTML when non-CSS files change
|
|
745
|
+
# CSS changes are handled by Tailwind watch, so we skip rebuild for CSS files
|
|
746
|
+
# When HTML rebuilds, it cleans dist, so we need to rebuild CSS immediately after
|
|
747
|
+
watcher_code = %q{watched = ['app', 'config']; exts = ['.erb', '.rb', '.js']; mtimes = {}; loop do; changed = false; watched.each do |dir|; Dir.glob(File.join(dir, '**', '*')).each do |f|; next unless File.file?(f) && exts.any? { |e| f.end_with?(e) }; next if f.end_with?('.css'); mtime = File.mtime(f); if mtimes[f] != mtime; mtimes[f] = mtime; changed = true; end; end; end; if changed; system('rake build:html > /dev/null 2>&1 && rake build:css > /dev/null 2>&1'); end; sleep 0.5; end}
|
|
639
748
|
watcher_pid = spawn("ruby", "-e", watcher_code, :err => File::NULL)
|
|
640
749
|
|
|
641
750
|
# Start web server
|
|
@@ -648,6 +757,7 @@ module StaticSiteBuilder
|
|
|
648
757
|
trap("INT") do
|
|
649
758
|
puts "\n\nShutting down..."
|
|
650
759
|
Process.kill("TERM", watcher_pid) if watcher_pid
|
|
760
|
+
Process.kill("TERM", tailwind_pid) if tailwind_pid
|
|
651
761
|
ws_server.stop
|
|
652
762
|
server.shutdown
|
|
653
763
|
end
|
|
@@ -693,27 +803,61 @@ module StaticSiteBuilder
|
|
|
693
803
|
require "pathname"
|
|
694
804
|
|
|
695
805
|
namespace :build do
|
|
696
|
-
desc "Build everything (
|
|
697
|
-
task :all => [:
|
|
806
|
+
desc "Build everything (HTML + CSS + Sitemap)"
|
|
807
|
+
task :all => [:html, :css, :sitemap] do
|
|
698
808
|
puts "\\n✓ Build complete!"
|
|
699
809
|
end
|
|
700
810
|
|
|
701
|
-
desc "Build JavaScript
|
|
811
|
+
desc "Build JavaScript assets"
|
|
702
812
|
task :assets do
|
|
703
|
-
|
|
813
|
+
if File.exist?("package.json")
|
|
814
|
+
package_json = JSON.parse(File.read("package.json"))
|
|
815
|
+
build_script = package_json.dig("scripts", "build")
|
|
816
|
+
# Only run if build script exists and doesn't include CSS (CSS handled separately)
|
|
817
|
+
if build_script && !build_script.include?("build:css")
|
|
818
|
+
sh "npm run build"
|
|
819
|
+
end
|
|
820
|
+
end
|
|
704
821
|
end
|
|
705
822
|
|
|
706
823
|
desc "Compile all pages to static HTML"
|
|
707
|
-
task :html do
|
|
824
|
+
task :html => [:assets] do
|
|
708
825
|
load "lib/site_builder.rb"
|
|
709
826
|
end
|
|
710
827
|
|
|
828
|
+
desc "Build CSS (runs after HTML so dist directory exists)"
|
|
829
|
+
task :css do
|
|
830
|
+
if File.exist?("package.json")
|
|
831
|
+
package_json = JSON.parse(File.read("package.json"))
|
|
832
|
+
if package_json.dig("scripts", "build:css")
|
|
833
|
+
sh "npm run build:css"
|
|
834
|
+
end
|
|
835
|
+
elsif File.exist?("tailwind.config.js")
|
|
836
|
+
# Build CSS even if no package.json (standalone Tailwind)
|
|
837
|
+
if system("which tailwindcss > /dev/null 2>&1")
|
|
838
|
+
FileUtils.mkdir_p("dist/assets/stylesheets")
|
|
839
|
+
sh "tailwindcss -i ./app/assets/stylesheets/application.css -o ./dist/assets/stylesheets/application.css --minify"
|
|
840
|
+
end
|
|
841
|
+
end
|
|
842
|
+
end
|
|
843
|
+
|
|
711
844
|
desc "Clean dist directory"
|
|
712
845
|
task :clean do
|
|
713
846
|
dist_dir = Pathname.new(Dir.pwd).join("dist")
|
|
714
847
|
FileUtils.rm_rf(dist_dir) if dist_dir.exist?
|
|
715
848
|
puts "Cleaned \#{dist_dir}"
|
|
716
849
|
end
|
|
850
|
+
|
|
851
|
+
desc "Build for production/release (cleans dist directory first)"
|
|
852
|
+
task :production do
|
|
853
|
+
ENV["PRODUCTION"] = "true"
|
|
854
|
+
Rake::Task["build:all"].invoke
|
|
855
|
+
end
|
|
856
|
+
|
|
857
|
+
desc "Generate sitemap from PageHelpers::PAGES"
|
|
858
|
+
task :sitemap do
|
|
859
|
+
require './config/sitemap'
|
|
860
|
+
end
|
|
717
861
|
end
|
|
718
862
|
|
|
719
863
|
namespace :dev do
|
|
@@ -734,8 +878,8 @@ module StaticSiteBuilder
|
|
|
734
878
|
require "pathname"
|
|
735
879
|
|
|
736
880
|
namespace :build do
|
|
737
|
-
desc "Build everything (HTML)"
|
|
738
|
-
task :all => [:html] do
|
|
881
|
+
desc "Build everything (HTML + Sitemap)"
|
|
882
|
+
task :all => [:html, :sitemap] do
|
|
739
883
|
puts "\\n✓ Build complete!"
|
|
740
884
|
end
|
|
741
885
|
|
|
@@ -750,6 +894,17 @@ module StaticSiteBuilder
|
|
|
750
894
|
FileUtils.rm_rf(dist_dir) if dist_dir.exist?
|
|
751
895
|
puts "Cleaned \#{dist_dir}"
|
|
752
896
|
end
|
|
897
|
+
|
|
898
|
+
desc "Build for production/release (cleans dist directory first)"
|
|
899
|
+
task :production do
|
|
900
|
+
ENV["PRODUCTION"] = "true"
|
|
901
|
+
Rake::Task["build:all"].invoke
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
desc "Generate sitemap from PageHelpers::PAGES"
|
|
905
|
+
task :sitemap do
|
|
906
|
+
require './config/sitemap'
|
|
907
|
+
end
|
|
753
908
|
end
|
|
754
909
|
|
|
755
910
|
namespace :dev do
|
|
@@ -887,7 +1042,7 @@ module StaticSiteBuilder
|
|
|
887
1042
|
end
|
|
888
1043
|
|
|
889
1044
|
def build_script
|
|
890
|
-
case @options[:js_bundler]
|
|
1045
|
+
js_build = case @options[:js_bundler]
|
|
891
1046
|
when "esbuild"
|
|
892
1047
|
"node esbuild.config.js"
|
|
893
1048
|
when "webpack"
|
|
@@ -895,7 +1050,20 @@ module StaticSiteBuilder
|
|
|
895
1050
|
when "vite"
|
|
896
1051
|
"vite build"
|
|
897
1052
|
else
|
|
898
|
-
|
|
1053
|
+
nil
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1056
|
+
css_build = if needs_css_build?
|
|
1057
|
+
"npm run build:css"
|
|
1058
|
+
else
|
|
1059
|
+
nil
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
builds = [js_build, css_build].compact
|
|
1063
|
+
if builds.empty?
|
|
1064
|
+
"echo 'No bundling needed'"
|
|
1065
|
+
else
|
|
1066
|
+
builds.join(" && ")
|
|
899
1067
|
end
|
|
900
1068
|
end
|
|
901
1069
|
|
|
@@ -924,6 +1092,41 @@ module StaticSiteBuilder
|
|
|
924
1092
|
@options[:css_framework] == "tailwindcss" || @options[:css_framework] == "shadcn"
|
|
925
1093
|
end
|
|
926
1094
|
|
|
1095
|
+
def create_gitignore
|
|
1096
|
+
content = <<~GITIGNORE
|
|
1097
|
+
# Dependencies
|
|
1098
|
+
/.bundle/
|
|
1099
|
+
/vendor/bundle
|
|
1100
|
+
/node_modules/
|
|
1101
|
+
|
|
1102
|
+
# Build artifacts
|
|
1103
|
+
*.gem
|
|
1104
|
+
*.gemspec.bak
|
|
1105
|
+
/dist/
|
|
1106
|
+
/tmp/
|
|
1107
|
+
/coverage/
|
|
1108
|
+
|
|
1109
|
+
# Test artifacts
|
|
1110
|
+
/.rspec_status
|
|
1111
|
+
|
|
1112
|
+
# IDE
|
|
1113
|
+
/.idea/
|
|
1114
|
+
/.vscode/
|
|
1115
|
+
*.swp
|
|
1116
|
+
*.swo
|
|
1117
|
+
*~
|
|
1118
|
+
|
|
1119
|
+
# OS
|
|
1120
|
+
.DS_Store
|
|
1121
|
+
Thumbs.db
|
|
1122
|
+
|
|
1123
|
+
# Logs
|
|
1124
|
+
*.log
|
|
1125
|
+
GITIGNORE
|
|
1126
|
+
|
|
1127
|
+
write_file(".gitignore", content)
|
|
1128
|
+
end
|
|
1129
|
+
|
|
927
1130
|
def write_file(path, content)
|
|
928
1131
|
file_path = @app_path.join(path)
|
|
929
1132
|
FileUtils.mkdir_p(file_path.dirname)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "uri"
|
|
4
|
+
require "action_view"
|
|
5
|
+
require "action_view/helpers"
|
|
3
6
|
require "erb"
|
|
4
7
|
require "fileutils"
|
|
5
8
|
require "json"
|
|
@@ -49,18 +52,30 @@ module StaticSiteBuilder
|
|
|
49
52
|
def build
|
|
50
53
|
puts "Building static site..."
|
|
51
54
|
|
|
52
|
-
# Clean dist directory
|
|
53
55
|
dist_dir = @root.join("dist")
|
|
54
|
-
|
|
56
|
+
|
|
57
|
+
# Only clean dist directory for production/release builds
|
|
58
|
+
# In development, update files in place to prevent 404s during rebuilds
|
|
59
|
+
production_build = ENV["PRODUCTION"] == "true" || ENV["RELEASE"] == "true"
|
|
60
|
+
if production_build
|
|
61
|
+
if dist_dir.exist?
|
|
62
|
+
puts "Cleaning dist directory for production build..."
|
|
63
|
+
FileUtils.rm_rf(dist_dir)
|
|
64
|
+
else
|
|
65
|
+
puts "Dist directory does not exist, skipping clean"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Ensure dist directory exists
|
|
55
70
|
FileUtils.mkdir_p(dist_dir)
|
|
56
71
|
|
|
57
|
-
# Copy assets
|
|
72
|
+
# Copy assets (overwrites existing files)
|
|
58
73
|
copy_assets(dist_dir)
|
|
59
74
|
|
|
60
|
-
# Generate importmap JSON if using importmap
|
|
75
|
+
# Generate importmap JSON if using importmap (overwrites existing file)
|
|
61
76
|
generate_importmap(dist_dir) if @js_bundler == "importmap"
|
|
62
77
|
|
|
63
|
-
# Compile pages based on template engine
|
|
78
|
+
# Compile pages based on template engine (overwrites existing files)
|
|
64
79
|
case @template_engine
|
|
65
80
|
when "erb"
|
|
66
81
|
compile_erb_pages(dist_dir)
|
|
@@ -68,7 +83,7 @@ module StaticSiteBuilder
|
|
|
68
83
|
compile_phlex_pages(dist_dir)
|
|
69
84
|
end
|
|
70
85
|
|
|
71
|
-
# Copy static files
|
|
86
|
+
# Copy static files (overwrites existing files)
|
|
72
87
|
copy_static_files(dist_dir)
|
|
73
88
|
|
|
74
89
|
# Notify WebSocket server (always update, even if file doesn't exist yet)
|
|
@@ -78,6 +93,20 @@ module StaticSiteBuilder
|
|
|
78
93
|
puts "\n✓ Build complete! Output in #{dist_dir}"
|
|
79
94
|
end
|
|
80
95
|
|
|
96
|
+
# Public method to render partials - no longer needed as ActionView handles this directly
|
|
97
|
+
# ActionView's render method automatically finds and renders partials from app/views
|
|
98
|
+
# This method is kept for backwards compatibility but should not be called
|
|
99
|
+
def render_partial(partial_path, view_context, locals = {})
|
|
100
|
+
# ActionView handles partial rendering automatically through its render method
|
|
101
|
+
# When templates call render 'shared/header', ActionView finds _header.html.erb automatically
|
|
102
|
+
begin
|
|
103
|
+
view_context.render(partial: partial_path, locals: locals)
|
|
104
|
+
rescue ActionView::MissingTemplate => e
|
|
105
|
+
# Convert ActionView's error to our format for backwards compatibility
|
|
106
|
+
raise "Partial not found: #{partial_path} (looked for #{e.path})"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
81
110
|
private
|
|
82
111
|
|
|
83
112
|
def load_importmap_config
|
|
@@ -116,10 +145,18 @@ module StaticSiteBuilder
|
|
|
116
145
|
copy_vendor_files_from_node_modules(dist_dir)
|
|
117
146
|
end
|
|
118
147
|
|
|
119
|
-
# Copy CSS
|
|
148
|
+
# Copy CSS (skip if Tailwind is handling it - check for tailwind.config.js)
|
|
149
|
+
# Tailwind outputs directly to dist, so we don't want to overwrite with raw files
|
|
150
|
+
# But we still need to ensure the directory exists for Tailwind to write to
|
|
151
|
+
tailwind_config = @root.join("tailwind.config.js")
|
|
120
152
|
css_dir = @root.join("app", "assets", "stylesheets")
|
|
121
|
-
|
|
122
|
-
|
|
153
|
+
dist_css = dist_dir.join("assets", "stylesheets")
|
|
154
|
+
|
|
155
|
+
if tailwind_config.exist?
|
|
156
|
+
# Tailwind is handling CSS - ensure directory exists but don't copy raw files
|
|
157
|
+
FileUtils.mkdir_p(dist_css)
|
|
158
|
+
elsif css_dir.exist? && css_dir.directory?
|
|
159
|
+
# No Tailwind - copy CSS files normally
|
|
123
160
|
FileUtils.mkdir_p(dist_css)
|
|
124
161
|
Dir.glob(css_dir.join("*")).each do |item|
|
|
125
162
|
FileUtils.cp_r(item, dist_css, preserve: true)
|
|
@@ -223,30 +260,11 @@ module StaticSiteBuilder
|
|
|
223
260
|
def compile_erb_page(erb_file, page_name, dist_dir, importmap_json_str)
|
|
224
261
|
puts "Compiling #{page_name}..."
|
|
225
262
|
|
|
226
|
-
# Read
|
|
263
|
+
# Read ERB content - ActionView will process it directly
|
|
227
264
|
content = File.read(erb_file)
|
|
228
|
-
|
|
265
|
+
|
|
266
|
+
# Default layout
|
|
229
267
|
layout = "application"
|
|
230
|
-
js_modules = []
|
|
231
|
-
|
|
232
|
-
if content.match?(/^---\s*\n/)
|
|
233
|
-
match = content.match(/^---\s*\n(.*?)\n---\s*\n/m)
|
|
234
|
-
if match
|
|
235
|
-
frontmatter_text = match[1]
|
|
236
|
-
frontmatter_text.each_line do |line|
|
|
237
|
-
key, value = line.split(":", 2).map(&:strip)
|
|
238
|
-
case key
|
|
239
|
-
when "layout"
|
|
240
|
-
layout = value
|
|
241
|
-
when "js"
|
|
242
|
-
js_modules = value.split(",").map(&:strip)
|
|
243
|
-
else
|
|
244
|
-
frontmatter[key] = value
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
content = content.sub(/^---\s*\n.*?\n---\s*\n/m, "")
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
268
|
|
|
251
269
|
# Load layout - try .html.erb first, then .html
|
|
252
270
|
layout_file = @root.join("app", "views", "layouts", "#{layout}.html.erb")
|
|
@@ -277,14 +295,135 @@ module StaticSiteBuilder
|
|
|
277
295
|
end
|
|
278
296
|
end
|
|
279
297
|
|
|
280
|
-
#
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
298
|
+
# Set current_page based on the file being compiled
|
|
299
|
+
current_page_path = if page_name == 'index.html'
|
|
300
|
+
'/'
|
|
301
|
+
else
|
|
302
|
+
"/#{page_name.gsub(/\.html$/, '')}"
|
|
303
|
+
end
|
|
285
304
|
|
|
286
|
-
#
|
|
287
|
-
|
|
305
|
+
# Create ActionView lookup context with view paths
|
|
306
|
+
view_paths = ActionView::PathSet.new([@root.join("app", "views").to_s])
|
|
307
|
+
lookup_context = ActionView::LookupContext.new(view_paths)
|
|
308
|
+
|
|
309
|
+
# Create ActionView::Base instance for rendering using with_empty_template_cache
|
|
310
|
+
# This is the recommended way for standalone ActionView usage
|
|
311
|
+
view_class = ActionView::Base.with_empty_template_cache
|
|
312
|
+
view = view_class.new(lookup_context, {}, self)
|
|
313
|
+
|
|
314
|
+
# Include PageHelpers if available (look in project root)
|
|
315
|
+
# Only require once (first time)
|
|
316
|
+
unless defined?(@page_helpers_loaded)
|
|
317
|
+
begin
|
|
318
|
+
page_helpers_path = @root.join('lib', 'page_helpers.rb')
|
|
319
|
+
if page_helpers_path.exist?
|
|
320
|
+
require page_helpers_path.to_s
|
|
321
|
+
@page_helpers_loaded = true
|
|
322
|
+
end
|
|
323
|
+
rescue LoadError
|
|
324
|
+
# PageHelpers not available, continue without it
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Extend view with PageHelpers if available
|
|
329
|
+
if defined?(PageHelpers)
|
|
330
|
+
view.extend(PageHelpers) unless view.singleton_class.included_modules.include?(PageHelpers)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Set instance variables that will be available in templates
|
|
334
|
+
# Pages can set @title, @js_modules, etc. via ERB at the top
|
|
335
|
+
view.instance_variable_set(:@js_modules, [])
|
|
336
|
+
view.instance_variable_set(:@importmap_json, importmap_json_str) if importmap_json_str
|
|
337
|
+
view.instance_variable_set(:@current_page, current_page_path)
|
|
338
|
+
view.instance_variable_set(:@page_content, nil)
|
|
339
|
+
|
|
340
|
+
# Set title and metadata from PageHelpers BEFORE rendering page content
|
|
341
|
+
# This ensures partials rendered within the page have access to metadata
|
|
342
|
+
page_helpers_path = @root.join('lib', 'page_helpers.rb')
|
|
343
|
+
begin
|
|
344
|
+
if page_helpers_path.exist?
|
|
345
|
+
require page_helpers_path.to_s
|
|
346
|
+
pages = ::PageHelpers::PAGES rescue nil
|
|
347
|
+
if pages && pages.is_a?(Hash) && pages.key?(current_page_path)
|
|
348
|
+
metadata = pages[current_page_path]
|
|
349
|
+
view.instance_variable_set(:@title, metadata[:title])
|
|
350
|
+
view.instance_variable_set(:@description, metadata[:description])
|
|
351
|
+
view.instance_variable_set(:@url, metadata[:url])
|
|
352
|
+
view.instance_variable_set(:@image, metadata[:image])
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
rescue => e
|
|
356
|
+
# Silently continue if PageHelpers can't be loaded
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Override render to handle 'footer' -> 'shared/footer' conversion
|
|
360
|
+
# and ensure locals are passed to partials
|
|
361
|
+
view.define_singleton_method(:render) do |options = {}, locals = {}, &block|
|
|
362
|
+
begin
|
|
363
|
+
# Handle string/symbol partial names: render 'footer' -> render 'shared/footer'
|
|
364
|
+
if options.is_a?(String) || options.is_a?(Symbol)
|
|
365
|
+
partial_name = options.to_s
|
|
366
|
+
# If no path separator, assume it's in shared/
|
|
367
|
+
unless partial_name.include?('/')
|
|
368
|
+
partial_name = "shared/#{partial_name}"
|
|
369
|
+
end
|
|
370
|
+
# Merge page locals with any provided locals
|
|
371
|
+
merged_locals = {
|
|
372
|
+
importmap_json: importmap_json_str,
|
|
373
|
+
current_page: current_page_path
|
|
374
|
+
}.merge(locals.is_a?(Hash) ? locals : {})
|
|
375
|
+
super(partial: partial_name, locals: merged_locals, &block)
|
|
376
|
+
elsif options.is_a?(Hash)
|
|
377
|
+
# Handle hash options: render partial: 'footer', locals: {}
|
|
378
|
+
partial_path = options[:partial] || options['partial']
|
|
379
|
+
if partial_path
|
|
380
|
+
# Convert 'footer' to 'shared/footer' if no path
|
|
381
|
+
unless partial_path.to_s.include?('/')
|
|
382
|
+
partial_path = "shared/#{partial_path}"
|
|
383
|
+
end
|
|
384
|
+
# Merge page locals with provided locals
|
|
385
|
+
provided_locals = options[:locals] || options['locals'] || {}
|
|
386
|
+
merged_locals = {
|
|
387
|
+
importmap_json: importmap_json_str,
|
|
388
|
+
current_page: current_page_path
|
|
389
|
+
}.merge(provided_locals)
|
|
390
|
+
super(partial: partial_path, locals: merged_locals, &block)
|
|
391
|
+
else
|
|
392
|
+
# Other render options (template, etc.)
|
|
393
|
+
super(options, locals, &block)
|
|
394
|
+
end
|
|
395
|
+
else
|
|
396
|
+
super(options, locals, &block)
|
|
397
|
+
end
|
|
398
|
+
rescue ActionView::MissingTemplate => e
|
|
399
|
+
# Convert ActionView's error to our format for backwards compatibility
|
|
400
|
+
raise "Partial not found: #{partial_path || partial_name || 'unknown'} (looked for #{e.path})"
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# Render page content using ActionView
|
|
405
|
+
# Pages can set instance variables via ERB (e.g., <% @title = '...' %>)
|
|
406
|
+
page_template = ActionView::Template.new(
|
|
407
|
+
content,
|
|
408
|
+
"inline:page",
|
|
409
|
+
ActionView::Template::Handlers::ERB.new,
|
|
410
|
+
virtual_path: "pages/#{page_name.gsub(/\.html$/, '')}",
|
|
411
|
+
format: :html,
|
|
412
|
+
locals: [:importmap_json, :current_page]
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
begin
|
|
416
|
+
page_content = view.render(template: page_template, locals: {
|
|
417
|
+
importmap_json: importmap_json_str,
|
|
418
|
+
current_page: current_page_path
|
|
419
|
+
})
|
|
420
|
+
rescue ActionView::Template::Error => e
|
|
421
|
+
# Convert ActionView errors to our format
|
|
422
|
+
if e.cause.is_a?(ActionView::MissingTemplate)
|
|
423
|
+
raise "Partial not found: #{e.cause.path} (looked for #{e.cause.path})"
|
|
424
|
+
end
|
|
425
|
+
raise
|
|
426
|
+
end
|
|
288
427
|
|
|
289
428
|
# Annotate page content if enabled
|
|
290
429
|
if @annotate_template_file_names
|
|
@@ -292,20 +431,40 @@ module StaticSiteBuilder
|
|
|
292
431
|
page_content = annotate_template(page_content, relative_template_path.to_s)
|
|
293
432
|
end
|
|
294
433
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
434
|
+
# Render layout using ActionView
|
|
435
|
+
# Instance variables set in the page template are available in the layout
|
|
436
|
+
layout_template = ActionView::Template.new(
|
|
437
|
+
layout_content,
|
|
438
|
+
"inline:layout",
|
|
439
|
+
ActionView::Template::Handlers::ERB.new,
|
|
440
|
+
virtual_path: "layouts/#{layout}",
|
|
441
|
+
format: :html,
|
|
442
|
+
locals: [:page_content, :importmap_json, :current_page]
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
# Mark page_content as HTML safe to prevent escaping
|
|
446
|
+
# ActionView will escape strings by default in ERB, so we mark it as safe
|
|
447
|
+
safe_page_content = page_content.respond_to?(:html_safe) ? page_content.html_safe : page_content
|
|
448
|
+
|
|
449
|
+
rendered = view.render(template: layout_template, locals: {
|
|
450
|
+
page_content: safe_page_content,
|
|
451
|
+
importmap_json: importmap_json_str,
|
|
452
|
+
current_page: current_page_path
|
|
453
|
+
})
|
|
300
454
|
|
|
301
455
|
# Annotate layout if enabled
|
|
456
|
+
# Note: We wrap the rendered content without removing existing annotations
|
|
457
|
+
# This preserves page annotations that are already in the content
|
|
302
458
|
if @annotate_template_file_names && layout_file.exist?
|
|
303
459
|
relative_layout_path = Pathname.new(layout_file).relative_path_from(@root)
|
|
304
|
-
|
|
460
|
+
begin_comment = "<!-- BEGIN #{relative_layout_path} -->"
|
|
461
|
+
end_comment = "<!-- END #{relative_layout_path} -->"
|
|
462
|
+
rendered = "#{begin_comment}\n#{rendered}\n#{end_comment}"
|
|
305
463
|
end
|
|
306
464
|
|
|
307
465
|
output_path = dist_dir.join(page_name)
|
|
308
466
|
FileUtils.mkdir_p(output_path.dirname)
|
|
467
|
+
puts " Debug: Writing #{rendered.length} chars to #{output_path}"
|
|
309
468
|
File.write(output_path, rendered)
|
|
310
469
|
|
|
311
470
|
puts " ✓ Created #{page_name}"
|
|
@@ -371,16 +530,16 @@ module StaticSiteBuilder
|
|
|
371
530
|
<head>
|
|
372
531
|
<meta charset="UTF-8">
|
|
373
532
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
374
|
-
<title><%=
|
|
533
|
+
<title><%= @title || 'Site' %></title>
|
|
375
534
|
<link rel="stylesheet" href="/assets/stylesheets/application.css">
|
|
376
535
|
</head>
|
|
377
536
|
<body>
|
|
378
537
|
<%= page_content %>
|
|
379
|
-
<% if defined?(importmap_json) && importmap_json %>
|
|
380
|
-
<script type="importmap"><%= importmap_json %></script>
|
|
538
|
+
<% if defined?(@importmap_json) && @importmap_json %>
|
|
539
|
+
<script type="importmap"><%= @importmap_json %></script>
|
|
381
540
|
<% end %>
|
|
382
|
-
<% if js_modules &&
|
|
383
|
-
<% js_modules.each do |module_name| %>
|
|
541
|
+
<% if @js_modules && !@js_modules.empty? %>
|
|
542
|
+
<% @js_modules.each do |module_name| %>
|
|
384
543
|
<script type="module">import "<%= module_name %>";</script>
|
|
385
544
|
<% end %>
|
|
386
545
|
<% else %>
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: static-site-builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lukasz Czapiewski
|
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: actionview
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.1'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: base64
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
114
128
|
requirements:
|
|
115
129
|
- - ">="
|
|
116
130
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '3.
|
|
131
|
+
version: '3.1'
|
|
118
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
133
|
requirements:
|
|
120
134
|
- - ">="
|