Class: Bridgetown::Rack::Routes

Inherits:
Object
  • Object
show all
Includes:
Prioritizable
Defined in:
bridgetown-core/lib/bridgetown-core/rack/routes.rb

Direct Known Subclasses

Bridgetown::Routes::ManifestRouter

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Prioritizable

#<=>, included

Constructor Details

#initialize(roda_app) ⇒ Routes

Returns a new instance of Routes.

Parameters:



151
152
153
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 151

def initialize(roda_app)
  @_roda_app = roda_app
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name) ⇒ Object

Any missing methods are passed along to the underlying Roda app if possible



164
165
166
167
168
169
170
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 164

def method_missing(method_name, ...)
  if @_roda_app.respond_to?(method_name.to_sym)
    @_roda_app.send(method_name.to_sym, ...)
  else
    super
  end
end

Class Attribute Details

.router_blockProc

Returns:

  • (Proc)


52
53
54
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 52

def router_block
  @router_block
end

Class Method Details

.<=>(other) ⇒ Integer

Spaceship is priority [higher -> lower]

Parameters:

  • other (Class(Routes))

    The class to be compared.

Returns:

  • (Integer)

    -1, 0, 1.



58
59
60
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 58

def <=>(other)
  "#{priorities[priority]}#{self}" <=> "#{priorities[other.priority]}#{other}"
end

.load_all(roda_app) ⇒ void

This method returns an undefined value.

Set up live reload if allowed, then run through all the Routes blocks.

Parameters:



98
99
100
101
102
103
104
105
106
107
108
109
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 98

def load_all(roda_app)
  if Bridgetown.env.development? &&
      !Bridgetown::Current.preloaded_configuration.skip_live_reload
    setup_live_reload roda_app
  end

  Bridgetown::Rack::Routes.sorted_subclasses&.each do |klass|
    klass.merge roda_app
  end

  nil # required for proper 404 handling
end

.merge(roda_app) ⇒ Object

Initialize a new Routes instance and execute the route as part of the Roda app request cycle

Parameters:



88
89
90
91
92
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 88

def merge(roda_app)
  return unless router_block

  new(roda_app).handle_routes
end

rubocop:disable Bridgetown/NoPutsAllowed, Metrics



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 18

def print_routes
  # TODO: this needs to be fully documented
  routes = begin
    JSON.parse(
      File.read(
        File.join(Bridgetown::Current.preloaded_configuration.root_dir, ".routes.json")
      )
    )
  rescue StandardError
    []
  end

  puts "Routes:".bold.green
  puts

  if routes.empty?
    puts "No routes found. Have you commented all of your routes?"
    puts "Documentation: https://github.com/jeremyevans/roda-route_list#label-Basic+Usage"
  end

  routes.group_by { _1["file"] }.each do |file, file_routes|
    file_routes.each_with_index do |route, index|
      puts [
        (route["methods"]&.join("|") || "GET").cyan,
        route["path"],
        file && index == file_routes.length - 1 ? "\n  #{"File:".yellow} #{file}" : nil,
      ].compact.join(" ")
    end
    puts
  end
end

.route(&block) ⇒ Object

Add a router block via the current Routes class

Example:

class Routes::Hello < Bridgetown::Rack::Routes route do |r| r.get “hello”, String do |name| { hello: “friend #name” } end end end

Parameters:

  • block (Proc)


80
81
82
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 80

def route(&block)
  self.router_block = block
end

.setup_live_reload(app) ⇒ Object

Parameters:



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 112

def setup_live_reload(app) # rubocop:disable Metrics
  sleep_interval = 0.5
  file_to_check = Bridgetown.live_reload_path
  errors_file = Bridgetown.build_errors_path

  app.request.get "_bridgetown/live_reload" do
    @_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0
    event_stream = proc do |stream|
      Thread.new do
        loop do
          new_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0

          if @_mod < new_mod
            stream.write "data: reloaded!\n\n"
            break
          elsif File.exist?(errors_file)
            stream.write "event: builderror\ndata: #{File.read(errors_file).to_json}\n\n"
          else
            stream.write "data: #{new_mod}\n\n"
          end

          sleep sleep_interval
        rescue Errno::EPIPE # User refreshed the page
          break
        end
      ensure
        stream.close
      end
    end

    app.request.halt [200, {
      "Content-Type"  => "text/event-stream",
      "cache-control" => "no-cache",
    }, event_stream,]
  end
end

.sorted_subclassesArray<Class(Routes)>

Returns:



63
64
65
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 63

def sorted_subclasses
  Bridgetown::Rack::Routes.descendants.sort
end

Instance Method Details

#handle_routesObject

Execute the router block via the instance, passing it the Roda request

Returns:

  • (Object)

    whatever is returned by the router block as expected by the Roda API



159
160
161
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 159

def handle_routes
  instance_exec(@_roda_app.request, &self.class.router_block)
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 172

def respond_to_missing?(method_name, include_private = false)
  @_roda_app.respond_to?(method_name.to_sym, include_private) || super
end