staticky 0.1.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.
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