Class: Bridgetown::Rack::Routes

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

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:



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

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



184
185
186
187
188
189
190
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 184

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

.tracked_subclassesHash<String, Class(Routes)>

Returns:

  • (Hash<String, Class(Routes)>)


49
50
51
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 49

def tracked_subclasses
  @tracked_subclasses
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

.inherited(base) ⇒ Object

Parameters:



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

def inherited(base)
  Bridgetown::Rack::Routes.track_subclass base
  super
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:



119
120
121
122
123
124
125
126
127
128
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 119

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
end

.merge(roda_app) ⇒ Object

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

Parameters:



109
110
111
112
113
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 109

def merge(roda_app)
  return unless router_block

  new(roda_app).handle_routes
end

rubocop:disable Bridgetown/NoPutsAllowed, Metrics/MethodLength



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
# 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
  puts "Routes:"
  puts "======="
  if routes.blank?
    puts "No routes found. Have you commented all of your routes?"
    puts "Documentation: https://github.com/jeremyevans/roda-route_list#basic-usage-"
  end

  routes.each do |route|
    puts [
      route["methods"]&.join("|") || "GET",
      route["path"],
      route["file"] ? "\n  File: #{route["file"]}" : nil,
    ].compact.join(" ")
  end
  puts
end

.reload_subclassesvoid

This method returns an undefined value.



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

def reload_subclasses
  Bridgetown::Rack::Routes.tracked_subclasses&.each_key do |klassname|
    Kernel.const_get(klassname)
  rescue NameError
    Bridgetown::Rack::Routes.tracked_subclasses.delete klassname
  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)


101
102
103
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 101

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

.setup_live_reload(app) ⇒ Object

Parameters:



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 131

def setup_live_reload(app) # rubocop:disable Metrics
  sleep_interval = 0.5
  file_to_check = File.join(Bridgetown::Current.preloaded_configuration.destination,
                            "index.html")
  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:



75
76
77
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 75

def sorted_subclasses
  Bridgetown::Rack::Routes.tracked_subclasses&.values&.sort
end

.track_subclass(klass) ⇒ Object

Parameters:



69
70
71
72
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 69

def track_subclass(klass)
  Bridgetown::Rack::Routes.tracked_subclasses ||= {}
  Bridgetown::Rack::Routes.tracked_subclasses[klass.name] = klass
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



179
180
181
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 179

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

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

Returns:

  • (Boolean)


192
193
194
# File 'bridgetown-core/lib/bridgetown-core/rack/routes.rb', line 192

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