use haml template in Sinatra framework - ruby

How to create a page using Sinatra which will use my prepared index.html.haml template.
Let's say i have following code:
require 'sinatra'
require 'sass'
require 'haml'
get '/' do
haml :index ???
end
my index.html.haml file is located in /sinatraapp/haml/index.html.haml

You need to tell sinatra where your views are located - see this
require 'sinatra'
require 'sass'
require 'haml'
set :views, "path/to/your/haml/dir"
get '/' do
haml :index
end

Related

Define sinatra request routes in included files

I am using Sinatra and I would like to have my project structed in a way that keeps all requests for a specific action in separated files.
The problem I'm running into is that the routes aren't registered with sinatra, and it always 404s and runs my not_found handler, even though I've included a file with the route.
Here's an example of what I'm trying to achieve; Rackup would start the Info app which requires user and post. Info only contains a error and not found handler, and the related routes go in the corresponding required file.
config.ru:
require 'rubygems'
require 'bundler'
Bundler.require
require 'rack'
require './info.rb'
run Info
info.rb:
require 'rubygems'
require 'bundler'
require 'sinatra'
class Info < Sinatra::Base
require './user.rb'
require './post.rb'
# 500 handler
error StandardError do
status 500
content_type :json
return '{"error": "Internal server error", "code": 500}'
end
not_found do
status 404
content_type :json
return '{"error": "Page not found", "code": 404}'
end
end
And user.rb (post.rb would look the same):
require 'rubygems'
require 'bundler'
require 'sinatra'
get '/1/user/:userid' do
# request stuff
end
require doesn’t work the way you seem to think it does. When you call require './user.rb', even though you do it inside the body of class Info < Sinatra::Base, its contents are not loaded as if they were inside that class. Instead they are parsed at the top level, and the routes are added to the default Sinatra::Application and not your application class.
You will have to have your user and post routes defined inside the same class body:
#info.rb
require 'sinatra/base' # Require 'sinatra/base' if you are using modular style.
class Info < Sinatra::Base
# It's a bit unusual to have require inside a class, but not
# wrong as such, and you might want to have the class defined
# before loading the other files.
require_relative 'user.rb' # require_relative is probably safer here.
require_relative 'post.rb'
# ... error handlers etc.
end
#user.rb
require 'sinatra/base'
# The routes need to be in the same class.
class Info < Sinatra::Base
get '/1/user/:userid' do
# request stuff
end
end

Sinatra I18n Fallbacks using Rack::Locale

I'm trying to set up a simple Sinatra app with I18n, following the recommended Sinatra recipe, and using Rack:Locale to determine the language.
My app.rb:
require 'rubygems'
require 'sinatra'
require 'rack/contrib'
require 'i18n'
require 'i18n/backend/fallbacks'
require 'tilt/haml'
use Rack::Locale
configure do
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
I18n.load_path = Dir[File.join(settings.root, 'locales', '*.yml')]
I18n.backend.load_translations
end
helpers do
def t(*args)
I18n.t(*args)
end
end
get '/' do
haml :index
end
My locales/en.yml:
en:
welcome: "Welcome!"
When I run rackup and visit the root path of my Sinatra app, I get the following:
I18n::InvalidLocale at /
"en-US" is not a valid locale
file: i18n.rb location: enforce_available_locales! line: 284
I thought that the I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks) would handle this, by not finding en-US and falling back to en (which I have), but apparently not. What am I missing?
Add:
I18n.enforce_available_locales = false

Sinatra is ignoring my layout.haml

Starting a basic Sinatra app. It doesn't seem to be using my layout template. If I put garbage in my layout.haml, I get the Sinatra 500 error page about it not being a properly formed haml file. Running Ruby 1.9.2. on Windows with the gem of Sinatra, Haml, and Rack installed this evening.
App Code:
require 'rubygems'
require 'sinatra'
require 'haml'
set :haml, :format => :html5
get '/' do
"Hello world, it's #{Time.now} at the server!"
end
App's Location / views / layout.haml
%html
%body
= yield
Source of Generated "http://localhost:4567/" Page
Hello world, it's 2011-11-05 02:25:48 -0400 at the server!
^Notice the lack of my layout.
For this purpose you have to say your template engine in action, something like this:
app code:
require 'sinatra'
require 'haml'
get '/' do
haml :hello
end
views/hello.haml:
%p= "Hello world, it's #{Time.now} at the server!"
views/layout.haml:
%html
%body
= yield

issues finding public folder when requiring sinatra/base

I have found that in my Sinatra app, when I require 'sinatra', I can access my public folder as expected, but when I require 'sinatra/base' I can't. Here is my relevant code (which works until I change to /base):
config.ru
root = ::File.dirname(__FILE__)
require ::File.join( root, 'app' )
run MyApp.new
app.rb
require 'sinatra'
require 'sinatra/namespace'
require 'haml'
class MyApp < Sinatra::Application
# ...
end
require_relative 'models/init'
require_relative 'helpers/init'
require_relative 'routes/init'
script.haml
%script(type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js")
%script(type="text/javascript" src="/js/table.js")
%link(rel="stylesheet" type="text/css" href="/css/table.css")
And yes, I have the correct directory structure in place. Like I said, it works using require sinatra. Anyone know why this is occurring and what I can do to fix it?
Requiring Sinatra::Base does not set any of the default configuration settings that requiring Sinatra does. You'll need to set :public_folder ... to a suitable value yourself, e.g:
set :public_folder, 'public'

deploy a sinatra app with passenger gives only 404, page not founds. Yet a simple rack app works

I have correctly (or prbably not) installed passenger on apache 2. Rack works, but sinatra keeps giving 404's.
Here is what works:
config.ru:
#app = proc do |env|
return [200, { "Content-Type" => "text/html" }, "hello <b>world</b>"]
end
run app
Here is what works too:
Running the app.rb (see below) with ruby app.rb and then looking at localhost:4567/about and /
restarting the app, gives me a correct hello world. w00t.
But then there is the sinatra entering the building:
config.ru
require 'rubygems'
require 'sinatra'
root_dir = File.dirname(__FILE__)
set :environment, ENV['RACK_ENV'].to_sym
set :root, root_dir
set :app_file, File.join(root_dir, 'app.rb')
disable :run
run Sinatra::Application
and an app.rb
require 'rubygems'
require 'sinatra'
get '/' do
"Hallo wereld!"
end
get '/about' do
"Hello world, it's #{Time.now} at the server!"
end
This keeps giving 404s.
/var/logs/apache2/error.log lists these correctly as "404" with something that worries me:
83.XXXXXXXXX - - [30/May/2010 16:06:52] "GET /about " 404 18 0.0007
83.XXXXXXXXX - - [30/May/2010 16:06:56] "GET / " 404 18 0.0007
The thing that worried me, is the space after the / and the /about. Would apache or sinatra go looking for /[space], like /%20?
If anyone knows what this problem relates to, maybe a known bug (that I could not find) or a known gotcha?
Maybe I am just being stupid and getting "it all wrong?"
Otherwise any hints on where to get, read or log more developers data on a running rack, sinatra or passenger app would be helpfull too: to see what sinatra is looking for, for example.
Some other information:
Running ubuntu 9.04, apache2-mm-prefork (deb), mod_php5, ruby 1.8.7, passenger 2.2.11, sinatra 1.0
You are not loading the routes in app.rb. To do this, replace require 'sinatra' with require File.join(File.dirname(__FILE__), 'app.rb') in config.ru.
root_dir = File.dirname(__FILE__)
app_file = File.join(root_dir, 'app.rb')
require app_file
set :environment, ENV['RACK_ENV'].to_sym
set :root, root_dir
set :app_file, app_file
disable :run
run Sinatra::Application
set :app_file won't load them for you.
Just substitute the require sinatra with a require 'app' and you're set to go.

Resources