Jekyll site via Sinatra and Heroku - can't route to new posts - ruby

I created a 'Hello, World' app using Sinatra and then pushed to Heroku and all worked.
I've since created a basic Jekyll blog, and am trying to access it via Heroku using the following routes:
get '/?' do
file.read("_site/index.html")
end
get '/.*.*' do
file.read("_site/#{params[:splat]}")
end
not_found do
file.read("_site/error/index.html")
end
The route to the index works fine link to my site
but as soon as I click to the first post it always fails.
I have tried so many variations of different routes for the :splat and get, just can't seem to get it to work? Any ideas?

In the route that's failing, before the file.read statement, add warn "splat = #{params[:splat]}" and that will output the result to the terminal, and you can see what it's actually getting, e.g.
get '/.*.*' do
warn "splat = #{params[:splat]}"
file.read("_site/#{params[:splat]}")
end
You could also try using an absolute path to the files, though if you're getting the index page then it suggests it's not needed:
config do
set :statics, File.expand_path(File.join(settings.root, "_site"))
end
get '/.*.*' do
file.read( File.join settings.statics, params[:splat] )
end
Unless there's something else you were planning to use Sinatra's routes for, you could probably remove the Sinatra routes entirely and just make the "_site" folder the public_folder, and then Sinatra will do the serving of the static files for you:
config do
set :public_folder, File.expand_path(File.join(settings.root, "_site"))
end
# no more to do...

Related

serving static files on sinatra

I'm working on a Sinatra app for the first time and am stumbling into an issue with serving a javascript asset.
I am following the Sinatra convention of putting the static files in “public” folder and it works locally but when we create a Docker image, we get a 404 while this works with localhost.
I see where I can set the public_folder which I have tried like this:
http://sinatrarb.com/configuration.html
but still 404'ing. Is there a way to get the top-level object and ask it where it expects the public_folder to be (like Rails.env)?
You can check the settings object.
irb(main):001:0> require "sinatra"
=> true
irb(main):002:0> settings.public_folder
=> "/usr/lib/ruby/2.5.0/irb/public"
This allows you to create a route which returns the path, something like this
require 'sinatra'
get '/' do
settings.public_folder
end
Without more information I would guess that your public folder points to a wrong directory inside your docker because the project :root points to a different directory that what you expect.

What does this do in my routes.rb file?

I am looking at a gist showing me how to handle CORS request in a Rails app. My routes.rb needs to have this bit of code in it.
Rails.application.routes.draw do
controller :whatever, path: '/whatever' do
match 'post_action', via: [ :post, :options]
end
end
If I was looking at a post resource, could someone show me how to set this up? I mainly do not understand the match function.
It will match the /whatever/post_action with the Controller/Action whatever#post_action. One useful tool you could use to see what your routes.rb are doing is to run the command:
rake routes
That will display all the routing table of your Rails app.
You can find more info in the Rails guide http://guides.rubyonrails.org/routing.html
Take care!
Actually match is not the good way to handle routes.
In rails 4 also it removed.
You can use the following code to use it:-
resource :whatever do
post 'post_action'
end
To test your routes
rake routes

Modular Sinatra app returns 404's under Passenger

I have a modular Sinatra app which runs fine when executed with rackup. The config.ru file is defined as follows:
map '/' do
run My::Controllers::Default
end
map '/api' do
run My::Controllers::Api
end
When I run the app under nginx/passenger I get nothing but 404's, even for the '/' route. Suspecting that something was wrong with routing, I modified config.ru as follows:
run My::Controllers::Default
After restarting nginx, I was served the default page of the app. However, the default page of the app reaches into the api route to get some documentation to display, and that part returns a 404. Given that config.ru is able to run the Default controller, I'm sure that the issue has nothing to do with being able to load all of the relevant ruby files--which seems to be the problem in other related questions I've found on SO.
With that in mind I modified config.ru as follows:
map '/api' do
run My::Controllers::Api
end
run My::Controllers::Default
At this point I'm back to getting nothing but 404's, even for the '/' route. It seems that the map statement is confusing the webserver and making it unable to find the correct routes.
If I just run the app using rackup everything behaves as expected, so I'm really at a loss to explain what I'm seeing.
I remember this being the answer. Let me know if it works for you. If it does I'll "Accept" the answer so that others will find it.
Middleware
A bug in passenger prevents it from understanding the map statement in config.ru https://groups.google.com/forum/#!msg/phusion-passenger/PoEEp9YcWbY/1y0QL_i3tHYJ
class PassengerFix
def initialize(app)
#app = app
end
def call(env)
env["SERVER_NAME"] = env["HTTP_HOST"]
return #app.call(env)
end
end
config.ru
configure do
use PassengerFix
end

Sinatra error when handling .php routes

I'm creating a Sinatra app to replace a legacy PHP based app.
get '/page.php' do
# ... do something
end
I'm trying to define a route like this but I get "Sinatra doesn't know this ditty." error page.
At the top of the page, I have this
configure do
mime_type :php, 'text/html'
end
Any idea how to tell Sinatra to use the whole path including the file extension as part of it?

Static page routing in Sinatra (Ruby)

You can serve static files with Sinatra by placing them in public/ (by default) -- I have an index.html in there at the moment, but how can I make the root point to that file without having to parse it as a template?
To be clear, I can access /index.html successfully, and I'd like to route / to be the same static file, but without redirecting. Any idea how to do this?
Probably a better answer will eventually come, until then this is my shot at it.
If this is not what you want:
get '/' do
redirect '/index.html'
end
You might do something like this:
get '/' do
File.new('public/index.html').readlines
end
I'd go with the first one though, Not sure why you want to avoid that redirect
Just set enable :static inside of your app class. Like so:
class App < Sinatra::Base
# Set the app root; this is where the 'public' and 'views'
# directories are found (by default).
set :root, File.expand_path("#{File.dirname(__FILE__)}/../app")
# Allow the app to serve static files from the 'public' directory in :root
enable :static
end
require 'sinatra'
get '/' do
send_file File.join(settings.public_folder, 'index.html')
end
As described at Serving static files with Sinatra
using passenger this seems to work right out of the box. having an index.html file in the public directory and no routing brings up the index.html when accessing the root url.
I think this is only an issue because Sinatra/Rack doesn't have the concept of a default file to serve if you just go to /. In a webserver like Apache or Nginx this is taken care of for you and usually defaults to index.html index.htm (if either exists it will get served when going to a directory with no actual filename on the end).
When everyone says this is built into Passenger, I think they really mean that it's built into Apache/Nginx. Apache/Nginx will check if the static file exists and serve it if it does, the request will never get to Rack, which is awesome for performance.
I wouldn't want to set up a redirect to the 404 page as this sort of violates the whole idea of HTTP: there should be one endpoint for everything that end point should return the true state of that endpoint. Meaning that if you go to /asdf you want the webserver to report a 404 because that's what is actually going on. If you do a redirect, now your site is saying "I used to have something here, but it moved" and then the page it redirects you to, even though it says 404 in the text on the page, is actually reported by the web server as a 200, meaning "everything is fine with this page!"
There is a gem "sinatra-index" to solve this problem.
https://github.com/elitheeli/sinatra-index

Resources