frozen_rails 0.0.2 → 0.0.3
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/README.md +78 -2
- data/lib/frozen_rails/appendable.rb +14 -0
- data/lib/frozen_rails/bundleable.rb +11 -0
- data/lib/frozen_rails/generator.rb +14 -0
- data/lib/frozen_rails/taggable.rb +59 -0
- data/lib/frozen_rails/version.rb +1 -1
- data/lib/frozen_rails.rb +0 -1
- data/lib/generators/frozen/db_generator.rb +68 -0
- data/lib/generators/frozen/dx_generator.rb +41 -0
- data/lib/generators/frozen/md_generator.rb +119 -0
- data/lib/generators/frozen/rails_generator.rb +39 -0
- data/lib/generators/frozen/seo_generator.rb +109 -0
- data/lib/generators/frozen/ssg_generator.rb +36 -0
- data/lib/generators/frozen/templates/db/avo.rb +10 -0
- data/lib/generators/frozen/templates/db/friendly_id.rb +14 -0
- data/lib/generators/frozen/templates/db/sqlite_uuid.rb +31 -0
- data/lib/generators/frozen/templates/db/static_db.rb +6 -0
- data/lib/generators/frozen/templates/dx/lib/templates/erb/scaffold/_form.html.erb.tt +1 -0
- data/lib/generators/frozen/templates/dx/lib/templates/erb/scaffold/edit.html.erb.tt +1 -0
- data/lib/generators/frozen/templates/dx/lib/templates/erb/scaffold/index.html.erb.tt +14 -0
- data/lib/generators/frozen/templates/dx/lib/templates/erb/scaffold/new.html.erb.tt +1 -0
- data/lib/generators/frozen/templates/dx/lib/templates/erb/scaffold/partial.html.erb.tt +17 -0
- data/lib/generators/frozen/templates/dx/lib/templates/erb/scaffold/show.html.erb.tt +7 -0
- data/lib/generators/frozen/templates/dx/lib/templates/rails/scaffold_controller/api_controller.rb.tt +22 -0
- data/lib/generators/frozen/templates/dx/lib/templates/rails/scaffold_controller/controller.rb.tt +19 -0
- data/lib/generators/frozen/templates/md/controllers/categories_controller.rb +11 -0
- data/lib/generators/frozen/templates/md/controllers/pages_controller.rb +7 -0
- data/lib/generators/frozen/templates/md/helpers/markdown_helper.rb +16 -0
- data/lib/generators/frozen/templates/md/initializers/decant_extensions.rb +17 -0
- data/lib/generators/frozen/templates/md/models/category.rb +36 -0
- data/lib/generators/frozen/templates/md/models/concerns/linkable.rb +42 -0
- data/lib/generators/frozen/templates/md/models/page.rb +14 -0
- data/lib/generators/frozen/templates/md/pages/frozen-rails.md +12 -0
- data/lib/generators/frozen/templates/md/pages/rails-static/rails-static-logo.webp +0 -0
- data/lib/generators/frozen/templates/md/pages/rails-static.md +17 -0
- data/lib/generators/frozen/templates/md/views/categories/index.html.erb +5 -0
- data/lib/generators/frozen/templates/md/views/categories/show.html.erb +13 -0
- data/lib/generators/frozen/templates/md/views/pages/show.html.erb +5 -0
- data/lib/generators/frozen/templates/seo/_og_meta_tags.html.erb +3 -0
- data/lib/generators/frozen/templates/seo/robots_generatable.rb +14 -0
- data/lib/generators/frozen/templates/seo/sitemap.rb +15 -0
- data/lib/generators/frozen/templates/seo/sitemap_entry.rb +12 -0
- data/lib/generators/frozen/templates/ui/cable.yml +5 -0
- data/lib/generators/frozen/templates/ui/hotkey_controller.js +9 -0
- data/lib/generators/frozen/ui_generator.rb +81 -0
- metadata +61 -6
- data/lib/frozen_rails/railtie.rb +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a88e369b28d7f01071814ba007495f9a1d573d3b8c0b0c59b0e48decb22637d
|
|
4
|
+
data.tar.gz: ea76d23b0fcedf87e504189e8019e39d21dc6ffe7b203cac5446a07d84cebe97
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b8d60e302866a07592e7f2b1c5605583cffa49f2084c31a390441eb3f69a50859565ec0e0c72211ad551bb0715bc754d45be654552cea32e162f0afb99bb99dd
|
|
7
|
+
data.tar.gz: 2dd187e1d486d6b299fd731a7575d8e6560674ffe0e3e99479ff92fa0432c6c699c3d3085368d97a010bd63a8bf8527e79f37731d926ad03c92b697f2bd51679
|
data/README.md
CHANGED
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
# Frozen Rails
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
DISCLAIMER: I generated this repo with AI and haven't tested it yet.
|
|
8
|
+
I will verify manually verify the functionality and use AI to generate a test suite as soon as I get to it. Until then, use at your own risk.
|
|
9
|
+
|
|
10
|
+
This repo automates the instructions from [rails-static.com](https://rails-static.com) and some additional setup which was created by me.
|
|
11
|
+
|
|
12
|
+
Running the full setup `bin/rails g frozen:rails` should turn a fresh Rails application into a full static-site generator that supports Markdown AND structured data (SQLite). The SSG is very developer-focused and might be cumbersome to use for non-devs.
|
|
8
13
|
|
|
9
14
|
## Installation
|
|
10
15
|
|
|
@@ -33,7 +38,78 @@ gem "frozen_rails"
|
|
|
33
38
|
|
|
34
39
|
## Usage
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
The gem ships with Rails generators under the `frozen` namespace. After including `frozen_rails` in your Rails application the following generators will be available:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# ✅ passes, ✅ works correctly, ❌ has test suite
|
|
45
|
+
|
|
46
|
+
# - Adds `decant` with a custom extension.
|
|
47
|
+
# - Adds `kramdown`, `rouge` and ERB interpolation for `.md` files.
|
|
48
|
+
# - Adds application scaffold.
|
|
49
|
+
|
|
50
|
+
bin/rails g frozen:md
|
|
51
|
+
# - Prompts for a rouge theme. Pass `--rouge_theme=name` to run non-interactive.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# ✅ passes, ✅ works correctly, ❌ has test suite
|
|
56
|
+
|
|
57
|
+
# - Adds `parklife`
|
|
58
|
+
# - Adds `.gitlab-ci.yml` and tweaks parklife config.
|
|
59
|
+
|
|
60
|
+
bin/rails g frozen:ssg
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# ✅ passes, ❓ works correctly, ❌ has test suite
|
|
65
|
+
|
|
66
|
+
# - sqlite uuid patch
|
|
67
|
+
# - static_db initializer
|
|
68
|
+
# - friendly_id and Avo configuration
|
|
69
|
+
|
|
70
|
+
bin/rails g frozen:db
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# ✅ passes, ❓ works correctly, ❌ has test suite
|
|
75
|
+
|
|
76
|
+
# - SEO helpers
|
|
77
|
+
# - sitemap/robots skeleton
|
|
78
|
+
|
|
79
|
+
bin/rails g frozen:seo
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# ✅ passes, ❓ works correctly, ❌ has test suite
|
|
84
|
+
|
|
85
|
+
# - water.css
|
|
86
|
+
# - sample importmap pin
|
|
87
|
+
# - Hotwire Spark & Action Cable configuration
|
|
88
|
+
# - Stimulus hotkey controller
|
|
89
|
+
|
|
90
|
+
bin/rails g frozen:ui
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# ✅ passes, ❓ works correctly, ❌ has test suite
|
|
95
|
+
|
|
96
|
+
# - copy custom lib templates
|
|
97
|
+
# - add autoload/generator config to application.rb
|
|
98
|
+
|
|
99
|
+
bin/rails g frozen:dx
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# ✅ passes, ❓ works correctly, ❌ has test suite
|
|
104
|
+
|
|
105
|
+
# Full Rails setup (runs all frozen generators in order)
|
|
106
|
+
|
|
107
|
+
bin/rails g frozen:rails
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# FUTURE: frozen:meetup
|
|
112
|
+
```
|
|
37
113
|
|
|
38
114
|
## Contributing
|
|
39
115
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Appendable
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def append_to_application_config(content)
|
|
7
|
+
inject_into_file "config/application.rb", optimize_indentation("\n#{content}", 4), before: / end\nend(?:\n)\z/, verbose: false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def append_to_routes(content)
|
|
11
|
+
inject_into_file "config/routes.rb", optimize_indentation("\n#{content}", 2), before: /end(?:\n)\z/, verbose: false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "frozen_rails/appendable"
|
|
5
|
+
require "frozen_rails/bundleable"
|
|
6
|
+
require "frozen_rails/taggable"
|
|
7
|
+
|
|
8
|
+
module FrozenRails
|
|
9
|
+
class Generator < Rails::Generators::Base
|
|
10
|
+
include Appendable
|
|
11
|
+
include Bundleable
|
|
12
|
+
include Taggable
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Taggable
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
class_option :cleanup_frozen_tags, type: :boolean, default: true, hide: true
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def add_frozen_gems(content, env: nil)
|
|
11
|
+
add_frozen_gemfile_tags(env:)
|
|
12
|
+
insert_into_file "Gemfile", optimize_indentation("#{content}\n", env ? 2 : 0), before: frozen_end_tag(env:)
|
|
13
|
+
cleanup_frozen_tags!(env:)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def frozen_start_tag(env: nil)
|
|
17
|
+
env_attribute = env ? " env=\"#{env}\"" : ""
|
|
18
|
+
"# <frozen_rails#{env_attribute}>"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def frozen_end_tag(env: nil)
|
|
22
|
+
frozen_start_tag(env:).gsub('# <', '# </')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_frozen_gemfile_tags(env: nil)
|
|
26
|
+
unless File.read("Gemfile").include?(frozen_start_tag(env:))
|
|
27
|
+
newlines = env ? "\n" : "\n\n"
|
|
28
|
+
tags = "#{frozen_start_tag(env:)}#{newlines}#{frozen_end_tag(env:)}"
|
|
29
|
+
insert_into_file "Gemfile", tags, after: frozen_tags_after(env:)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def frozen_tags_after(env: nil)
|
|
34
|
+
case env
|
|
35
|
+
when nil
|
|
36
|
+
/frozen_rails[^\n]*\n/
|
|
37
|
+
when 'local'
|
|
38
|
+
"group :development, :test do\n"
|
|
39
|
+
when 'development'
|
|
40
|
+
"group :development do\n"
|
|
41
|
+
else
|
|
42
|
+
raise "Unsupported env!"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def cleanup_frozen_tags!(env: nil)
|
|
47
|
+
if options[:cleanup_frozen_tags]
|
|
48
|
+
gsub_file! "Gemfile", /[^\n]*#{frozen_start_tag(env:)}[^\n]*\n/, ''
|
|
49
|
+
gsub_file! "Gemfile", /[^\n]*#{frozen_end_tag(env:)}[^\n]*\n/, ''
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def cleanup_all_frozen_tags!
|
|
54
|
+
cleanup_frozen_tags!
|
|
55
|
+
cleanup_frozen_tags!(env: 'local')
|
|
56
|
+
cleanup_frozen_tags!(env: 'development')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
data/lib/frozen_rails/version.rb
CHANGED
data/lib/frozen_rails.rb
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "frozen_rails/generator"
|
|
4
|
+
|
|
5
|
+
module Frozen
|
|
6
|
+
module Generators
|
|
7
|
+
class DbGenerator < FrozenRails::Generator
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
desc "Prepare a Rails app for SQLite UUIDs, static_db, Avo and FriendlyId"
|
|
11
|
+
|
|
12
|
+
def add_gems
|
|
13
|
+
add_frozen_gems <<~RUBY
|
|
14
|
+
# frozen:db
|
|
15
|
+
gem "sqlite_extensions-uuid"
|
|
16
|
+
gem "static_db"
|
|
17
|
+
gem "friendly_id"
|
|
18
|
+
RUBY
|
|
19
|
+
|
|
20
|
+
add_frozen_gems <<~RUBY, env: "local"
|
|
21
|
+
# frozen:db
|
|
22
|
+
gem "avo", ">= 3.2"
|
|
23
|
+
RUBY
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def bundle_gems
|
|
27
|
+
bundle!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# configure database.yml for sqlite uuid extension
|
|
31
|
+
def configure_database_yml
|
|
32
|
+
return unless File.exist?("config/database.yml")
|
|
33
|
+
|
|
34
|
+
inject_into_file "config/database.yml", after: "adapter: sqlite3\n" do
|
|
35
|
+
<<~YML
|
|
36
|
+
extensions:
|
|
37
|
+
- <%= SqliteExtensions::UUID.to_path %>
|
|
38
|
+
YML
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# create initializer for sqlite uuid generator patch
|
|
43
|
+
def create_sqlite_uuid_initializer
|
|
44
|
+
template "db/sqlite_uuid.rb", "config/initializers/sqlite_uuid.rb"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# create initializer for static_db configuration
|
|
48
|
+
def create_static_db_initializer
|
|
49
|
+
template "db/static_db.rb", "config/initializers/static_db.rb"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# create friendly_id initializer
|
|
53
|
+
def create_friendly_id_initializer
|
|
54
|
+
template "db/friendly_id.rb", "config/initializers/friendly_id.rb"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# create a minimal avo initializer stub
|
|
58
|
+
def create_avo_initializer
|
|
59
|
+
template "db/avo.rb", "config/initializers/avo.rb"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# reminder to run generators
|
|
63
|
+
def post_install_reminders
|
|
64
|
+
say_status :info, "Run `rails generate friendly_id` to create slug migrations."
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "frozen_rails/generator"
|
|
4
|
+
|
|
5
|
+
module Frozen
|
|
6
|
+
module Generators
|
|
7
|
+
class DxGenerator < FrozenRails::Generator
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
desc "Install developer experience helpers: custom lib templates and generator config"
|
|
11
|
+
|
|
12
|
+
# copy over the lib folder content from static example
|
|
13
|
+
def copy_lib_templates
|
|
14
|
+
directory "dx/lib", "lib"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# inject configuration into config/application.rb
|
|
18
|
+
def configure_application
|
|
19
|
+
return unless File.exist?("config/application.rb")
|
|
20
|
+
|
|
21
|
+
inject_into_file "config/application.rb",
|
|
22
|
+
after: "class Application < Rails::Application\n" do
|
|
23
|
+
<<~RUBY
|
|
24
|
+
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
|
25
|
+
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
|
26
|
+
# Common ones are `templates`, `generators`, or `middleware`, for example.
|
|
27
|
+
config.autoload_lib(ignore: %w[assets tasks])
|
|
28
|
+
|
|
29
|
+
config.generators do |g|
|
|
30
|
+
g.orm :active_record, primary_key_type: :uuid
|
|
31
|
+
g.test_framework false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
config.active_storage.draw_routes = true
|
|
35
|
+
|
|
36
|
+
RUBY
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "frozen_rails/generator"
|
|
4
|
+
|
|
5
|
+
module Frozen
|
|
6
|
+
module Generators
|
|
7
|
+
class MdGenerator < FrozenRails::Generator
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
# When absent, the generator will prompt interactively (unless running non-interactively).
|
|
11
|
+
class_option :rouge_theme, type: :string, desc: "Rouge theme to install (runs non-interactive if provided)"
|
|
12
|
+
|
|
13
|
+
desc "Set up markdown-powered content with Decant, kramdown, ERB processing and Rouge highlighting"
|
|
14
|
+
|
|
15
|
+
def add_gems
|
|
16
|
+
add_frozen_gems <<~RUBY
|
|
17
|
+
# frozen:md
|
|
18
|
+
gem "decant"
|
|
19
|
+
gem "kramdown"
|
|
20
|
+
gem "kramdown-parser-gfm"
|
|
21
|
+
gem "rouge"
|
|
22
|
+
RUBY
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def bundle_gems
|
|
26
|
+
bundle!
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create_content_directory
|
|
30
|
+
empty_directory "content/pages"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def copy_files
|
|
34
|
+
app_files = [
|
|
35
|
+
"controllers/categories_controller.rb",
|
|
36
|
+
"controllers/pages_controller.rb",
|
|
37
|
+
"helpers/markdown_helper.rb",
|
|
38
|
+
"models/concerns/linkable.rb",
|
|
39
|
+
"models/category.rb",
|
|
40
|
+
"models/page.rb",
|
|
41
|
+
"views/categories/index.html.erb",
|
|
42
|
+
"views/categories/show.html.erb",
|
|
43
|
+
"views/pages/show.html.erb",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
app_files.each do |app_file|
|
|
47
|
+
copy_file "md/#{app_file}", "app/#{app_file}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
config_files = [
|
|
51
|
+
"initializers/decant_extensions.rb",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
config_files.each do |config_file|
|
|
55
|
+
copy_file "md/#{config_file}", "config/#{config_file}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
content_files = [
|
|
59
|
+
"pages/frozen-rails.md",
|
|
60
|
+
"pages/rails-static.md",
|
|
61
|
+
"pages/rails-static/rails-static-logo.webp",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
content_files.each do |content_file|
|
|
65
|
+
copy_file "md/#{content_file}", "content/#{content_file}"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def add_config
|
|
70
|
+
append_to_application_config <<~RUBY
|
|
71
|
+
# frozen:md
|
|
72
|
+
config.assets.paths << Rails.root.join("content")
|
|
73
|
+
config.action_dispatch.rescue_responses["Decant::FileNotFound"] = :not_found
|
|
74
|
+
RUBY
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Add routes for pages
|
|
78
|
+
def add_routes
|
|
79
|
+
append_to_routes <<~RUBY
|
|
80
|
+
# frozen:md
|
|
81
|
+
root "categories#index"
|
|
82
|
+
|
|
83
|
+
# Use `Regexp.union` instead of array for constraints!
|
|
84
|
+
# https://github.com/rails/rails/issues/47726
|
|
85
|
+
constraints slug: Regexp.union(Category.all.map(&:slug)) do
|
|
86
|
+
resources :categories, param: :slug, only: [:index, :show]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
resources :pages, param: :slug, only: [:show]
|
|
90
|
+
RUBY
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def generate_rouge_css_stylesheet
|
|
94
|
+
theme = options[:rouge_theme]
|
|
95
|
+
|
|
96
|
+
if theme.blank? && behavior == :invoke && $stdin.tty?
|
|
97
|
+
# Run in subshell so we pick up newly installed gem without needing to require it in the current process.
|
|
98
|
+
themes = `bundle exec ruby -e "require 'rouge'; puts Rouge::Theme.registry.keys.sort"`.split("\n")
|
|
99
|
+
|
|
100
|
+
say_status :info, "Available Rouge themes (#{themes.size}):", :blue
|
|
101
|
+
themes.each_with_index { |t, i| say " #{i + 1}. #{t}" }
|
|
102
|
+
|
|
103
|
+
answer = ask("Choose a theme (name or number) [github]")
|
|
104
|
+
|
|
105
|
+
theme = if /^\d+$/.match?(answer)
|
|
106
|
+
themes[answer.to_i - 1]
|
|
107
|
+
else
|
|
108
|
+
answer.presence
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
theme ||= "github"
|
|
113
|
+
|
|
114
|
+
say_status :info, "Generating Rouge CSS for theme #{theme}", :blue
|
|
115
|
+
run "rougify style #{theme} > app/assets/stylesheets/rouge.css"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "frozen_rails/taggable"
|
|
5
|
+
|
|
6
|
+
module Frozen
|
|
7
|
+
module Generators
|
|
8
|
+
# A meta-generator that runs the other frozen generators in a sensible order.
|
|
9
|
+
class RailsGenerator < Rails::Generators::Base
|
|
10
|
+
include Taggable
|
|
11
|
+
|
|
12
|
+
desc "Run all frozen setup generators (md, db, seo, ui, dx, ssg)"
|
|
13
|
+
|
|
14
|
+
# The method name doesn't matter much; Thor runs all public methods in
|
|
15
|
+
# order defined by source.
|
|
16
|
+
def run_all
|
|
17
|
+
say_status :info, "invoking frozen:md"
|
|
18
|
+
invoke "frozen:md", [], cleanup_frozen_tags: false
|
|
19
|
+
|
|
20
|
+
say_status :info, "invoking frozen:db"
|
|
21
|
+
invoke "frozen:db", [], cleanup_frozen_tags: false
|
|
22
|
+
|
|
23
|
+
say_status :info, "invoking frozen:seo"
|
|
24
|
+
invoke "frozen:seo", [], cleanup_frozen_tags: false
|
|
25
|
+
|
|
26
|
+
say_status :info, "invoking frozen:ui"
|
|
27
|
+
invoke "frozen:ui", [], cleanup_frozen_tags: false
|
|
28
|
+
|
|
29
|
+
say_status :info, "invoking frozen:dx"
|
|
30
|
+
invoke "frozen:dx", [], cleanup_frozen_tags: false
|
|
31
|
+
|
|
32
|
+
say_status :info, "invoking frozen:ssg"
|
|
33
|
+
invoke "frozen:ssg", [], cleanup_frozen_tags: false
|
|
34
|
+
|
|
35
|
+
cleanup_all_frozen_tags!
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "frozen_rails/generator"
|
|
4
|
+
|
|
5
|
+
module Frozen
|
|
6
|
+
module Generators
|
|
7
|
+
class SeoGenerator < FrozenRails::Generator
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
desc "Add SEO helpers, metadata partials and sitemap/robots models"
|
|
11
|
+
|
|
12
|
+
# add meta partial and update layout
|
|
13
|
+
def create_og_partial
|
|
14
|
+
template "seo/_og_meta_tags.html.erb", "app/views/layouts/_og_meta_tags.html.erb"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def inject_layout_tags
|
|
18
|
+
return unless File.exist?("app/views/layouts/application.html.erb")
|
|
19
|
+
|
|
20
|
+
inject_into_file "app/views/layouts/application.html.erb",
|
|
21
|
+
after: "<head>\n" do
|
|
22
|
+
<<~ERB
|
|
23
|
+
<%= render 'layouts/og_meta_tags', tags: {
|
|
24
|
+
title: title,
|
|
25
|
+
description: description,
|
|
26
|
+
image: image_url('og-image.jpg'),
|
|
27
|
+
author: author,
|
|
28
|
+
type: "website",
|
|
29
|
+
site_name: site_name,
|
|
30
|
+
url: canonical_url,
|
|
31
|
+
} %>
|
|
32
|
+
|
|
33
|
+
<%= tag :link, rel: "canonical", href: canonical_url %>
|
|
34
|
+
|
|
35
|
+
<%= favicon_link_tag 'favicon.ico', sizes: '32x32' %>
|
|
36
|
+
<%= favicon_link_tag 'icon.svg', type: 'image/svg+xml' %>
|
|
37
|
+
<%= favicon_link_tag 'apple-touch-icon.png', rel: 'apple-touch-icon' %>
|
|
38
|
+
|
|
39
|
+
<%= tag :meta, name: "robots", content: robots_content %>
|
|
40
|
+
|
|
41
|
+
ERB
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# helpers for meta tags
|
|
46
|
+
def add_application_helpers
|
|
47
|
+
unless File.exist?("app/helpers/application_helper.rb")
|
|
48
|
+
create_file "app/helpers/application_helper.rb", "module ApplicationHelper\nend\n"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
inject_into_file "app/helpers/application_helper.rb",
|
|
52
|
+
after: "module ApplicationHelper\n" do
|
|
53
|
+
<<~RUBY
|
|
54
|
+
def site_name
|
|
55
|
+
"Rails Static"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def title
|
|
59
|
+
[ @page&.title.presence, site_name ].uniq.compact.join(" · ")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def description
|
|
63
|
+
@page.frontmatter&.dig(:description)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def author
|
|
67
|
+
"François Catuhe"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def canonical_url
|
|
71
|
+
url_for(only_path: false)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def robots_content
|
|
75
|
+
Rails.env.production? ? "index, follow" : "noindex, nofollow"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def og_meta_tag(key, content)
|
|
79
|
+
case key
|
|
80
|
+
when :title, :description, :image
|
|
81
|
+
tag(:meta, name: key, property: "og:\#{key}", content: content)
|
|
82
|
+
when :author
|
|
83
|
+
tag(:meta, name: key, content: content)
|
|
84
|
+
else
|
|
85
|
+
tag(:meta, property: "og:\#{key}", content: content)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
RUBY
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def add_favicon_notice
|
|
94
|
+
say_status :info, "Add favicons (favicon.ico, icon.svg, apple-touch-icon.png) to app/assets/images and create og-image.jpg"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# sitemap models
|
|
98
|
+
def create_sitemap_models
|
|
99
|
+
template "seo/sitemap.rb", "app/models/sitemap.rb"
|
|
100
|
+
template "seo/sitemap_entry.rb", "app/models/sitemap/entry.rb"
|
|
101
|
+
template "seo/robots_generatable.rb", "app/models/sitemap/robots_generatable.rb"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def remove_default_robots
|
|
105
|
+
remove_file "public/robots.txt" if File.exist?("public/robots.txt")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "frozen_rails/generator"
|
|
4
|
+
|
|
5
|
+
module Frozen
|
|
6
|
+
module Generators
|
|
7
|
+
class SsgGenerator < FrozenRails::Generator
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
desc "Set up Parklife static site generation with CI workflows and helper scripts"
|
|
11
|
+
|
|
12
|
+
def add_gems
|
|
13
|
+
add_frozen_gems <<~RUBY
|
|
14
|
+
# frozen:ssg
|
|
15
|
+
gem "parklife-rails"
|
|
16
|
+
RUBY
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def bundle_gems
|
|
20
|
+
bundle!
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def run_parklife_init
|
|
24
|
+
unless system("bundle exec parklife init --rails --github-pages")
|
|
25
|
+
say_status :warn, "Unable to run parklife init. Please execute manually!"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def setup_gitlab_pages
|
|
30
|
+
copy_file "ssg/.gitlab-ci.yml", ".gitlab-ci.yml"
|
|
31
|
+
comment_lines "Parkfile", /config\.nested_index = false/
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# generated by frozen:db
|
|
4
|
+
# Minimal Avo configuration; adjust as needed.
|
|
5
|
+
Avo.configure do |config|
|
|
6
|
+
config.root_path = "/avo"
|
|
7
|
+
config.authorization_client = nil
|
|
8
|
+
config.explicit_authorization = true
|
|
9
|
+
config.click_row_to_view_record = true
|
|
10
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# generated by frozen:db
|
|
4
|
+
FriendlyId.defaults do |config|
|
|
5
|
+
# enable the most common modules
|
|
6
|
+
config.use :reserved
|
|
7
|
+
config.use :slugged
|
|
8
|
+
config.use :finders
|
|
9
|
+
config.use :history
|
|
10
|
+
|
|
11
|
+
# a UUID will be appended automatically when a unique slug cannot be generated
|
|
12
|
+
# suitable reserved words to avoid can be declared here.
|
|
13
|
+
config.reserved_words = %w[new edit index session login logout users admin]
|
|
14
|
+
end
|