staticky 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +11 -0
  4. data/CHANGELOG.md +5 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +163 -0
  7. data/Rakefile +12 -0
  8. data/bin/staticky +7 -0
  9. data/lib/staticky/builder.rb +62 -0
  10. data/lib/staticky/cli.rb +71 -0
  11. data/lib/staticky/container.rb +26 -0
  12. data/lib/staticky/deps.rb +5 -0
  13. data/lib/staticky/environment.rb +8 -0
  14. data/lib/staticky/error.rb +5 -0
  15. data/lib/staticky/filesystem.rb +29 -0
  16. data/lib/staticky/generator.rb +63 -0
  17. data/lib/staticky/phlex/view_helpers.rb +16 -0
  18. data/lib/staticky/resource.rb +25 -0
  19. data/lib/staticky/router/definition.rb +49 -0
  20. data/lib/staticky/router.rb +35 -0
  21. data/lib/staticky/server.rb +48 -0
  22. data/lib/staticky/version.rb +5 -0
  23. data/lib/staticky/view_context.rb +17 -0
  24. data/lib/staticky.rb +51 -0
  25. data/site_template/.dockerignore +4 -0
  26. data/site_template/.gitignore +11 -0
  27. data/site_template/.prettierrc +6 -0
  28. data/site_template/.rspec +1 -0
  29. data/site_template/.rubocop.yml +8 -0
  30. data/site_template/.ruby-version +1 -0
  31. data/site_template/Dockerfile +47 -0
  32. data/site_template/Gemfile +33 -0
  33. data/site_template/Procfile.dev +3 -0
  34. data/site_template/README.md +98 -0
  35. data/site_template/Rakefile +18 -0
  36. data/site_template/app/views/errors/not_found.rb +14 -0
  37. data/site_template/app/views/errors/service_error.rb +14 -0
  38. data/site_template/app/views/layouts/error.rb +13 -0
  39. data/site_template/app/views/layouts/head.rb +60 -0
  40. data/site_template/app/views/layouts/site.rb +37 -0
  41. data/site_template/app/views/pages/home.rb +22 -0
  42. data/site_template/app/views/ui/.keep +0 -0
  43. data/site_template/app/views/ui/footer.rb +21 -0
  44. data/site_template/app/views/ui/navbar.rb +19 -0
  45. data/site_template/bin/console +11 -0
  46. data/site_template/bin/dev +12 -0
  47. data/site_template/bin/lint +18 -0
  48. data/site_template/bin/staticky +28 -0
  49. data/site_template/config/boot.rb +15 -0
  50. data/site_template/config/routes.rb +9 -0
  51. data/site_template/config/site.erb +12 -0
  52. data/site_template/config/vite.json +17 -0
  53. data/site_template/config.ru +8 -0
  54. data/site_template/content/.keep +0 -0
  55. data/site_template/content/demo.md +12 -0
  56. data/site_template/frontend/controllers/.keep +0 -0
  57. data/site_template/frontend/controllers/index.js +3 -0
  58. data/site_template/frontend/entrypoints/application.js +8 -0
  59. data/site_template/frontend/images/.keep +0 -0
  60. data/site_template/frontend/images/hero.jpg +0 -0
  61. data/site_template/frontend/stylesheets/application.css +61 -0
  62. data/site_template/frontend/stylesheets/syntax.css +151 -0
  63. data/site_template/frontend/tailwindcss/variable_font_plugin.js +103 -0
  64. data/site_template/frontend/turbo_transitions.js +54 -0
  65. data/site_template/lib/component.rb +32 -0
  66. data/site_template/lib/icon.rb +39 -0
  67. data/site_template/lib/layout.rb +4 -0
  68. data/site_template/lib/page.rb +11 -0
  69. data/site_template/lib/vite_helpers.rb +38 -0
  70. data/site_template/logs/.keep +0 -0
  71. data/site_template/nginx.conf +59 -0
  72. data/site_template/package.json +31 -0
  73. data/site_template/postcss.config.js +6 -0
  74. data/site_template/public/android-chrome-192x192.png +0 -0
  75. data/site_template/public/android-chrome-512x512.png +0 -0
  76. data/site_template/public/apple-touch-icon.png +0 -0
  77. data/site_template/public/favicon-16x16.png +0 -0
  78. data/site_template/public/favicon-32x32.png +0 -0
  79. data/site_template/public/favicon.ico +0 -0
  80. data/site_template/public/robots.txt.erb +1 -0
  81. data/site_template/public/site.webmanifest.erb +19 -0
  82. data/site_template/public/sitemap.xml +0 -0
  83. data/site_template/spec/spec_helper.rb +30 -0
  84. data/site_template/spec/views/pages/home_spec.rb +9 -0
  85. data/site_template/tailwind.config.js +83 -0
  86. data/site_template/vite.config.ts +14 -0
  87. metadata +273 -0
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Staticky
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Staticky
4
+ class ViewContext
5
+ def initialize(resource)
6
+ @resource = resource
7
+ end
8
+
9
+ def root?
10
+ @resource.root?
11
+ end
12
+
13
+ def current_path
14
+ @resource.url
15
+ end
16
+ end
17
+ end
data/lib/staticky.rb ADDED
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "phlex"
4
+ require "dry/system"
5
+ require "dry/configurable"
6
+ require "dry/logger"
7
+ require "uri"
8
+ require "tilt"
9
+
10
+ module Staticky
11
+ GEM_ROOT = Pathname.new(__dir__).join("..").expand_path
12
+ end
13
+
14
+ require_relative "staticky/container"
15
+
16
+ module Staticky
17
+ # DOCS: Module for static site infrastructure such as:
18
+ # - Defining routes
19
+ # - Compiling templates
20
+ # - Development server
21
+ # - Managing filesystem
22
+
23
+ module_function
24
+
25
+ extend Dry::Configurable
26
+
27
+ setting :env, default: :development
28
+ setting :build_path, default: Pathname.new("build")
29
+ setting :root_path, default: Pathname(__dir__)
30
+ setting :logger, default: Dry.Logger(:staticky, template: :details)
31
+ setting :server_logger, default: Dry.Logger(
32
+ :staticky_server,
33
+ template: :details,
34
+ formatter: :rack
35
+ )
36
+
37
+ def monitor(...) = container.monitor(...)
38
+ def server_logger =config.server_logger
39
+ def logger = config.logger
40
+ def build_path = config.build_path
41
+ def root_path = config.root_path
42
+ def resources = router.resources
43
+ def router = container[:router]
44
+ def builder = container[:builder]
45
+ def generator = container[:generator]
46
+ def container = Container
47
+
48
+ def env
49
+ @env ||= Environment.new container.env
50
+ end
51
+ end
@@ -0,0 +1,4 @@
1
+ spec/
2
+ Procfile.dev
3
+ README.md
4
+ node_modules/
@@ -0,0 +1,11 @@
1
+ /build/
2
+
3
+ # Vite Ruby
4
+ /public/vite*
5
+ node_modules
6
+ # Vite uses dotenv and suggests to ignore local-only env files. See
7
+ # https://vitejs.dev/guide/env-and-mode.html#env-files
8
+ *.local
9
+
10
+ .bundle
11
+ /tmp/
@@ -0,0 +1,6 @@
1
+ {
2
+ "trailingComma": "es5",
3
+ "tabWidth": 2,
4
+ "semi": false,
5
+ "singleQuote": false
6
+ }
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,8 @@
1
+ require:
2
+ - rubocop-inhouse
3
+ - rubocop-capybara
4
+
5
+ inherit_gem:
6
+ rubocop-inhouse:
7
+ - config/default.yml
8
+ - config/capybara.yml
@@ -0,0 +1 @@
1
+ 3.3.4
@@ -0,0 +1,47 @@
1
+ # Use an official Ruby runtime based on Alpine as a parent image
2
+ FROM ruby:3.3-alpine AS builder
3
+
4
+ ENV RACK_ENV="production" \
5
+ NODE_ENV="production" \
6
+ BUNDLE_DEPLOYMENT="1" \
7
+ BUNDLE_WITHOUT="development:test"
8
+
9
+ # Update gems and bundler
10
+ RUN gem update --system --no-document && \
11
+ gem install -N bundler
12
+
13
+ # Install necessary packages including Node.js and Yarn
14
+ RUN apk add --no-cache build-base nodejs npm git && \
15
+ npm install -g yarn
16
+
17
+ # Set the working directory
18
+ WORKDIR /app
19
+
20
+ # Copy Gemfile and other necessary files
21
+ COPY --link Gemfile Gemfile.lock .ruby-version package.json yarn.lock ./
22
+
23
+ # Install dependencies
24
+ RUN bundle install && \
25
+ yarn install --frozen-lockfile && \
26
+ rm -rf /root/.bundle/cache /usr/local/bundle/cache /var/cache/apk/*
27
+
28
+ # Copy the rest of the application code
29
+ COPY --link . .
30
+
31
+ # Build the static site (e.g., using Jekyll)
32
+ RUN bin/rake site:build
33
+
34
+ # Use an official Nginx image based on Alpine to serve the static site
35
+ FROM nginx:stable-alpine
36
+
37
+ # Copy the Nginx configuration file
38
+ COPY nginx.conf /etc/nginx/nginx.conf
39
+
40
+ # Copy the static site files to the Nginx HTML directory
41
+ COPY --from=builder /app/build /usr/share/nginx/html/
42
+
43
+ # Expose port 80 to the Docker host
44
+ EXPOSE 80
45
+
46
+ # Start Nginx when the container launches
47
+ CMD ["nginx", "-g", "daemon off;"]
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
+
6
+ ruby_version = Pathname.new(__dir__).join(".ruby-version")
7
+ ruby ruby_version.read.strip
8
+
9
+ gem "protos"
10
+ gem "protos-icon"
11
+ gem "protos-markdown"
12
+
13
+ gem "dry-inflector"
14
+ gem "front_matter_parser"
15
+ gem "rack"
16
+ gem "rackup"
17
+ gem "rake"
18
+ gem "rouge"
19
+ gem "staticky", github: "nolantait/staticky", branch: "master"
20
+ gem "vite_ruby"
21
+ gem "zeitwerk"
22
+
23
+ group :test do
24
+ gem "capybara", require: false
25
+ gem "debug"
26
+ gem "phlex-testing-capybara"
27
+ gem "rspec"
28
+ end
29
+
30
+ group :development do
31
+ gem "rerun"
32
+ gem "rubocop-inhouse", require: false
33
+ end
@@ -0,0 +1,3 @@
1
+ server: bin/bundle exec rackup
2
+ builder: rerun --dir app,lib,content --exit --verbose -- bin/rake site:build
3
+ vite: bin/vite dev
@@ -0,0 +1,98 @@
1
+ # Static starter
2
+
3
+ This is a minimal static site builder with [phlex](https://phlex.fun) and
4
+ [protos](https://github.com/inhouse-work/protos) component library.
5
+
6
+ [Vite](https://vite-ruby.netlify.app/) handles your javascript and your
7
+ assets by default and hooks into the build command defined in your `Rakefile`
8
+
9
+ Your development server runs with `bin/dev`
10
+
11
+ Everything is ruby, there is no html or erb. It outputs a static site to the
12
+ `build/` folder by default, but that can be configured.
13
+
14
+ ## Usage
15
+
16
+ First we need to install `staticky` if you have not already:
17
+
18
+ ```
19
+ gem install staticky
20
+ ```
21
+
22
+ Then we can use the CLI to generate a new template:
23
+
24
+ ```
25
+ staticky new my_blog
26
+ ```
27
+
28
+ Finally cd into your new site and run the development server:
29
+
30
+ ```
31
+ cd my_blog
32
+ bin/dev
33
+ ```
34
+
35
+ Your site should not be accessible at http://localhost:9292
36
+
37
+ ## Building
38
+
39
+ During development `rerun` watches your files and rebuilds the site when they
40
+ change by running `bin/rake site:build`. These files are served by a Roda app.
41
+
42
+ In production you simply output the files to a folder and serve them statically
43
+ on your website. We have included a `Dockerfile` with a working nginx setup that
44
+ can be tweaked however you like.
45
+
46
+ Building takes all the definitions inside your `config/routes` and outputs
47
+ static files to `./build` or wherever you have configured it.
48
+
49
+ ## Views
50
+
51
+ Views are defined in `app/views`. They should be phlex components and you can
52
+ choose how to render them inside your router.
53
+
54
+ ## Javascript
55
+
56
+ All javascript and images are handled via [Vite](https://vite-ruby.netlify.app/)
57
+
58
+ ## Router
59
+
60
+ Your routes are defined in `config/routes.rb` and determine the output for your
61
+ site. Everything gets built into the `./build` folder by default.
62
+
63
+ Here is an example of loading content for a blog:
64
+
65
+ ```ruby
66
+ # frozen_string_literal: true
67
+
68
+ require "date"
69
+ require "front_matter_parser"
70
+
71
+ loader = FrontMatterParser::Loader::Yaml.new(allowlist_classes: [Date])
72
+
73
+ Staticky.router.define do
74
+ root to: Pages::Home.new
75
+
76
+ # Link directly to components or their classes in your routes
77
+ match "404", to: Errors::NotFound.new
78
+ match "500", to: Errors::ServiceError.new(class: "bg-red-500")
79
+
80
+ # Write your own custom logic for parsing your markdown
81
+ Dir["content/**/*.md"].each do |file|
82
+ parsed = FrontMatterParser::Parser.parse_file(file, loader:)
83
+
84
+ match file.gsub("content/", "").gsub(".md", ""),
85
+ to: Pages::Post.new(
86
+ parsed.content,
87
+ front_matter: parsed.front_matter.transform_keys(&:to_sym)
88
+ )
89
+ end
90
+ end
91
+ ```
92
+
93
+ The router is your definition for how to build your static site.
94
+
95
+ ## Deployment
96
+
97
+ Deployment is done through a simple Dockerfile. This setup is optimized for
98
+ deploying onto Dokku servers.
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "vite_ruby"
4
+
5
+ ViteRuby.install_tasks
6
+
7
+ desc "Precompile assets"
8
+ task :environment do
9
+ require "./config/boot"
10
+ end
11
+
12
+ namespace :site do
13
+ desc "Precompile assets"
14
+ task build: :environment do
15
+ Rake::Task["vite:build"].invoke
16
+ Staticky.builder.call
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Errors
4
+ class NotFound < Page
5
+ include Protos::Typography
6
+
7
+ def self.layout = Layouts::Error
8
+
9
+ def view_template
10
+ h1 { "Page not found." }
11
+ link_to("Back to home", Pages::Home, class: "link")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Errors
4
+ class ServiceError < Page
5
+ include Protos::Typography
6
+
7
+ def self.layout = Layouts::Error
8
+
9
+ def view_template
10
+ h1 { "Something went wrong." }
11
+ link_to("Back to home", Pages::Home, class: "link")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Layouts
4
+ class Error < Layout
5
+ def view_template(&block)
6
+ render Layouts::Site.new do
7
+ div(class: "grid place-items-center h-[--main-scene]") do
8
+ section(class: "flex flex-col place-items-center gap-sm", &block)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Layouts
4
+ class Head < Component
5
+ option :title, default: -> { ::Site.title }, reader: false
6
+ option :description, default: -> { ::Site.description }, reader: false
7
+
8
+ def view_template
9
+ head do
10
+ title { @title }
11
+ meta name: "description", content: @description
12
+ meta charset: "utf-8"
13
+ meta name: "viewport",
14
+ content: "width=device-width,initial-scale=1,viewport-fit=cover"
15
+ meta name: "turbo-cache-control", content: "no-preview"
16
+ meta name: "turbo-refresh-method", content: "morph"
17
+ meta name: "turbo-refresh-scroll", content: "preserve"
18
+ meta name: "theme-color", content: "#61afef"
19
+ meta name: "mobile-web-app-capable", content: "yes"
20
+ meta name: "apple-touch-fullscreen", content: "yes"
21
+ meta name: "apple-mobile-web-app-capable", content: "yes"
22
+ meta name: "apple-mobile-web-app-status-bar-style", content: "default"
23
+ meta name: "apple-mobile-web-app-title", content: @title
24
+
25
+ link rel: "canonical", href: ::Site.url_for(helpers.current_path)
26
+ link rel: "apple-touch-icon", href: "/apple-touch-icon.png"
27
+ link rel: "icon",
28
+ type: "image/png",
29
+ sizes: "32x32",
30
+ href: "/favicon-32x32.png"
31
+ link rel: "icon",
32
+ type: "image/png",
33
+ sizes: "16x16",
34
+ href: "/favicon-16x16.png"
35
+ link rel: "manifest", href: "/site.webmanifest"
36
+
37
+ meta property: "og:title", content: @title
38
+ meta property: "og:type", content: "website"
39
+ meta property: "og:locale", content: "en_US"
40
+ meta property: "og:url", content: ::Site.url
41
+ meta property: "og:site_name", content: ::Site.title
42
+ meta property: "twitter:title", content: ::Site.title
43
+ meta name: "twitter:card", content: "summary"
44
+ meta name: "twitter:site", content: ::Site.twitter
45
+ meta name: "twitter:creator", content: ::Site.twitter
46
+
47
+ vite_client_tag unless ENV["RACK_ENV"] == "production"
48
+ javascript_tag "application"
49
+
50
+ yield if block_given?
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def javascript_tag(...)
57
+ vite_javascript_tag(...)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Layouts
4
+ class Site < Layout
5
+ include Phlex::DeferredRender
6
+
7
+ def view_template
8
+ html lang: "en_US", data: { theme: "onedark" } do
9
+ render Layouts::Head.new(&head)
10
+
11
+ body do
12
+ render UI::Navbar.new(class: css[:navbar])
13
+ main(class: css[:main], &content)
14
+ render UI::Footer.new(class: css[:footer])
15
+ end
16
+ end
17
+ end
18
+
19
+ def with_head(&block)
20
+ @head = block
21
+ end
22
+
23
+ def with_content(&block)
24
+ @content = block
25
+ end
26
+
27
+ private
28
+
29
+ def content
30
+ @content || proc {}
31
+ end
32
+
33
+ def head
34
+ @head || proc {}
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pages
4
+ class Home < Page
5
+ include Protos::Typography
6
+
7
+ def view_template
8
+ render Protos::Hero.new(
9
+ class: "h-96",
10
+ style: "background-image: url(#{asset_path("images/hero.jpg")})"
11
+ ) do |hero|
12
+ hero.overlay(class: "opacity-90")
13
+ hero.content(class: "flex-col text-white") do
14
+ h1 { "Ruby maximalism" }
15
+ p(margin: false) { "Zen vibes only" }
16
+
17
+ link_to("Learn more", Errors::NotFound)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
File without changes
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UI
4
+ class Footer < Component
5
+ def view_template
6
+ footer(**attrs) do
7
+ p(class: "opacity-80 text-sm") do
8
+ "All rights reserved. © #{Time.now.year}"
9
+ end
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def theme
16
+ {
17
+ container: "flex justify-center w-full py-lg text-center"
18
+ }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UI
4
+ class Navbar < Component
5
+ def view_template
6
+ header(**attrs) do
7
+ a(href: "/", class: "btn btn-ghost") { "MyApp" }
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def theme
14
+ {
15
+ container: "p-xs"
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "./config/boot"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ require "irb"
11
+ IRB.start(__FILE__)
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env sh
2
+
3
+ if command -v overmind &> /dev/null; then
4
+ overmind start -f Procfile.dev
5
+ else
6
+ if ! gem list foreman -i --silent; then
7
+ echo "Installing foreman..."
8
+ gem install foreman
9
+ fi
10
+
11
+ exec foreman start -f Procfile.dev "$@"
12
+ fi
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ require "fileutils"
3
+
4
+ # path to your application root.
5
+ APP_ROOT = File.expand_path("..", __dir__)
6
+
7
+ def system!(*args)
8
+ system(*args) || abort("\n== Command #{args} failed ==")
9
+ end
10
+
11
+ FileUtils.chdir APP_ROOT do
12
+ # This script is a way to set up or update your development environment automatically.
13
+ # This script is idempotent, so that you can run it at any time and get an expectable outcome.
14
+ # Add necessary setup steps to this file.
15
+
16
+ puts "== Running rubocop =="
17
+ system! "bundle exec rubocop --autocorrect-all --fail-level error"
18
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'staticky' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+ require "./config/boot"
27
+
28
+ load Gem.bin_path("staticky", "staticky")
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV["RACK_ENV"] ||= "development"
4
+
5
+ require "bundler"
6
+ Bundler.require(:default, ENV.fetch("RACK_ENV", nil))
7
+
8
+ loader = Zeitwerk::Loader.new
9
+ loader.inflector.inflect("ui" => "UI")
10
+ loader.push_dir("lib")
11
+ loader.push_dir("app/views")
12
+ loader.setup
13
+
14
+ require_relative "site"
15
+ require_relative "routes"
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ Staticky.router.define do
6
+ root to: Pages::Home
7
+ match "404", to: Errors::NotFound
8
+ match "500", to: Errors::ServiceError
9
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Site
4
+ module_function
5
+
6
+ def title = "<%= title %>"
7
+ def description = "<%= description %>"
8
+ def twitter = "<%= twitter %>"
9
+ def url = "<%= url %>"
10
+
11
+ def url_for(path) = URI.join(url, path)
12
+ end
@@ -0,0 +1,17 @@
1
+ {
2
+ "all": {
3
+ "publicDir": "build",
4
+ "sourceCodeDir": "frontend",
5
+ "watchAdditionalPaths": []
6
+ },
7
+ "development": {
8
+ "autoBuild": true,
9
+ "publicOutputDir": "vite-dev",
10
+ "port": 3036
11
+ },
12
+ "test": {
13
+ "autoBuild": true,
14
+ "publicOutputDir": "vite-test",
15
+ "port": 3037
16
+ }
17
+ }
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "./config/boot"
5
+ require "staticky/server"
6
+
7
+ use(ViteRuby::DevServerProxy, ssl_verify_none: true) if ViteRuby.run_proxy?
8
+ run Staticky::Server.app.freeze