class Integral::Middleware::PageRouter

Handles dynamic page routing. Checks all GET requests to see if the PATH matches an Integral::Page path If a match is found the PATH is rewritten from human readable into something Rails router understands. i.e. '/company/who-we-are' -> /pages/12

Public Class Methods

new(app) click to toggle source
# File lib/integral/middleware/page_router.rb, line 9
def initialize(app)
  @app = app
end

Public Instance Methods

call(env) click to toggle source

Handles dynamic Integral::Page routing.

# File lib/integral/middleware/page_router.rb, line 14
def call(env)
  request = Rack::Request.new(env)

  # Return early if request is not a GET
  return @app.call(env) unless request.get?

  # Return early if request is within backend area
  backend_path = "/#{Integral.backend_namespace}/"
  return @app.call(env) if request.path_info.starts_with?(backend_path)

  # Rewrites path if the request linked to an Integral::Page
  rewrite_path(env, request.path_info)

  @app.call(env)
end

Private Instance Methods

category_identifier(path) click to toggle source
# File lib/integral/middleware/page_router.rb, line 45
def category_identifier(path)
  return nil unless path.starts_with?("/#{Integral.blog_namespace}")

  Integral::Category.select(:id, :slug).all.map { |category| [category.id, "/#{Integral.blog_namespace}/#{category.slug}"] }.find { |category| category[1] == path }&.first
end
dynamic_homepage() click to toggle source

Homepage ID as defined by User within backend settings Possibly should add a fallback to return Page.first if settings is available

@return [String] Homepage ID

# File lib/integral/middleware/page_router.rb, line 75
def dynamic_homepage
  page_id = Integral::Settings['homepage_id']
  handle_nil_homepage if page_id.nil?

  page_id
end
handle_nil_homepage() click to toggle source

Handles if Dynamic Homepage is enabled & ID is not set

# File lib/integral/middleware/page_router.rb, line 88
def handle_nil_homepage
  Rails.logger.debug('IntegralMessage: Dynamic Homepage is nil. Set within Backend Settings.')
end
handle_rewrite_error(error) click to toggle source

Handles if an error occurs when rewriting path

# File lib/integral/middleware/page_router.rb, line 83
def handle_rewrite_error(error)
  Rails.logger.debug("IntegralMessage: #{error}")
end
page_identifier(path) click to toggle source

Checks to see if path is linked to a page TODO: Rather than hitting the DB on each request here a Redis solution could be implemented

@param path [String] Path the request is linked to

@return [Integer] ID of the Integral::Page the path is linked to

# File lib/integral/middleware/page_router.rb, line 38
def page_identifier(path)
  return dynamic_homepage if path == '/' && Integral.dynamic_homepage_enabled?

  # TODO: Speed this up by adding an index & unique constraint on path attribute
  Integral::Page.not_archived.find_by_path(path)&.id
end
rewrite_path(env, path) click to toggle source

Converts the request path from human readable into something Rails router understands i.e. '/company/who-we-are' -> /pages/12

@param env [Hash] Environment of the request @param path [String] Path the request is linked to

@return [String] Path Rails needs to link the request to the correct Integral::Page record

# File lib/integral/middleware/page_router.rb, line 58
def rewrite_path(env, path)
  page_id = page_identifier(path)
  if page_id
    env['PATH_INFO'] = "/pages/#{page_id}"
  else
    category_id = category_identifier(path)

    env['PATH_INFO'] = "/#{Integral.blog_namespace}/categories/#{category_id}" if category_id
  end
rescue StandardError => e
  handle_rewrite_error(e)
end