Sinatra static assets are not found when using rackup - ruby

I have a simple Sinatra app that is configured using the modular style. When I start the app using rackup -p 4567 as recommended in the readme file, the static assets in the public folder are not served. But when I start it using shotgun ./config.ru -p 4567 then they are served. Why does this happen? Could this happen in production?
Here is my code:
# config.ru
require 'rubygems'
require 'bundler'
require 'sinatra'
require 'jammit'
Bundler.require
Jammit.package!
require File.expand_path('./stick.rb')
run Stick
and this is the app ruby file
require 'sinatra/base'
class Stick < Sinatra::Base
get '/' do
haml :index
end
end

Looks like there are two good answers to this one (neither of the existing ones worked for me).
First off, in your config.ru file, you can include the following:
# Replace the directory names to taste
use Rack::Static, :urls => ['/stylesheets', '/javascripts'], :root => 'public'
Alternatively, if you're running your app via rackup, the :static option is set to false by default. You can remedy this by the following incantation:
class MyApp < Sinatra::Base
set :static, true
# ...
end

I had the same problem and i solved like this.
I have added this line in my config.ru .
map "/public" do
run Rack::Directory.new("./public")
end
And i use the static files in my views like this
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/reset.css'}
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/text.css'}
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/960.css'}
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/app.css'}

Not positive, but you may need to set :root, Stick.root?
(Based on How to deploy a modular Sinatra app to Heroku?)

In order for me to get this working on a new Sinatra app launched via config.ru, I had to do two of the things suggested in the other answers:
class MyApp < Sinatra::Base
set :static, true
set :root, File.dirname(__FILE__)
end

First create a folder named "public" in your sinatra project, then add a couple of folders
stylesheets
javascripts
images
Add your CSS, JS and or JPG,PNG (images) to each folder
Finally as #sirfilip says add below lines to config.ru file
map "/public" do
run Rack::Directory.new("./public")
end
If generic Sinatra (no framework default)
views/layout.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
...
<link rel="stylesheet" href="stylesheets/your_file.css">
<link rel="icon" type="image/ico" href="images/your_image.ico" />
</head>
<body>
<%= yield %>
...
<script src="javascripts/your_js.js"></script>
views/index.erb
<div class="margin-bottom-30">
<div class="row">
<div class="col-md-12">
<ul class="nav nav-pills">
<li class="active">Home <span class="badge">42</span></li>
<li>...</li>
</ul>
</div>
</div>
</div>
All of you images, stylesheets and javascripts will be available for any url registered in your Sinatra app , problem solved!

Related

javascript_include_tag not working in rails 2?

The rails tag to include javascript , and for browser caching:
<%= javascript_include_tag '/skin/js/html5.js', :cache => true %>
forget about caching simple javascript_include tag is also not working.
Ex:
<%= javascript_include_tag '/skin/js/html5.js', :cache => true %>
But the script tag below is working find stop working after doing this.
<script src="/skin/js/html5.js" type="text/javascript"></script>
using Rails 2 any reason for such a behavior or this tag did not even work in rails2?
Try
First make sure that you are including the tag inside the head
<% content_for :head do %>
<script src="skin/js/html5.js"></script>
<% end %>

wicked pdf rendering css / javascript in Ruby

I'm trying to convert html page with wicked pdf but the html / css / javascript are not displayed.
Here is my controller :
respond_to do |format|
format.html
format.pdf do
render :pdf => 'rapport_pdf',
:template => 'messages/template_load_pdf.pdf.erb',
:layout => 'rapport_load_pdf.html.erb',
:show_as_html => params[:debug].present?
end
end
Here is my rapport_load_pdf.html.erb :
<!DOCTYPE html>
<html>
<head>
<title>PDF</title>
<%= wicked_pdf_stylesheet_link_tag "application" -%>
</head>
<body>
<div class='container'>
<%= yield %>
</div>
</body>
Here is my gemfile :
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
I have tried different techniques to speedup my pdf generation. But these steps were pretty helpful.
Try using font-awesome-rails and bootstrap ruby gem
Use separate scss file to import necessary css/scss files. And, Try to avoid importing unnecessary css files. (Because loading external css files and images kills the server memory and delay the pdf process.)
Please see the sample code below
Import your stylesheet in the pdf layout file as bellow.
<%= wicked_pdf_stylesheet_link_tag "pdf_layout", media: "all" -%>
Please check more details here

How to print to web page using Ruby and Sinatra

I'm calling a ruby function in a post method and I'm trying to output the contents from the function to the web page but it prints the output in my console instead. How do I get it to print to the page?
I've tried
<%=rsg(params[:grammar_file])%> inside an erb file
and
rsg(params[:grammar_file])
inside of the post method and both just print to the console
require 'sinatra'
require 'sinatra/reloader' if development? #gem install sinatra-contrib
require './rsg.rb'
enable :sessions
get '/' do
erb :index
end
post '/' do
rsg(params[:grammar_file])
erb :index
end
<% title = "RANDOM SENTENCE GENERATOR" %>
<!doctype html>
<html lang="en">
<head>
<title><%= #title || "RSG" %></title>
<meta charset="UTF8">
</head>
<body>
<h1>RubyRSG Demo</h1>
<p>Select grammar file to create randomly generated sentence</p>
<form action="/" method="post">
<select name="grammar_file">
<option value="Select" hidden>Select</option>
<option value="Poem">Poem</option>
<option value="Insult">Insult</option>
<option value="Extension-request">Extension-request</option>
<option value="Bond-movie">Bond-movie</option>
</select>
<br><br>
<input type="submit" value="submit">
</form>
<section>
<p>Here</p>
<p><%= rsg(params[:grammar_file])%></p>
</section>
</body>
</html>
You need to tell your template what to do with the params.
This is what is happening:
post '/' do
rsg(params[:grammar_file])
# your rsg method produces some output. I guess you have a line the `puts` your params to stdout somewhere. Instead you should redirect the output into the template.
erb :index
end
Like this:
post '/' do
erb :index, :locals => {:rsg => rsg(params[:grammar_file])}
end
Then, in your :index template you have a line like:
<%=rsg%>
To output the generated String.
The problem might also be that you're tryng to return a puts statement instead of the plain string:
def rsg(p)
puts "I love my daily #{p}. Good luck to you"
end
This will just print to the console and nothing else (true to be precise)
Better:
def rsg(p)
"I love my daily #{p}. Good luck to you"
end
Here you will just return the String from your method and calling rsg("sandwich") will return:
# => "I love my daily sandwich. Good luck to you"

While learning Ruby, Sinatra, working on a project, yield error happened

In my project, I have a few files:
1. main.rb
require 'sinatra'
set :public_folder, 'public'
set :views, 'views'
set :erb, :layout => :base
get '/' do
erb :layout
end
get '/about' do
erb :about
end
get '/contact' do
erb :contact
end
2. layout.erb
<% title="Songs By Sinatra" %>
<!doctype html>
<html lang="en">
<head>
<title>
<%=title %>
</title>
<meta charset="utf-8">
</head>
<body>
<header>
<h1><%= title %></h1>
<nav>
<ul>
<li>Home
</li>
<li>About
</li>
<li>Contact
</li>
</ul>
</nav>
</header>
<section>
<%=yield %>
</section>
</body>
</html>
<p>Welcome to this website that's all about the songs of the great Frank Sinatra.</p>
<img src="/images/sinatra.jpg" alt="Frank Sinatra">
3. about.erb
<p>
This site is a demonstration of how to build a website using Sinatra.
</p>
When I go to http://localhost:4567/about everything is OK, page loads, but when I go to http://localhost:4567/, I get an error: no block given (yield).
Can anyone explain what is the problem, and possible solution.
Thank you very much in advance.
You need to pass a block in
erb :layout
For <%=yield %> in layout.erb to work, you need to pass a block whose output will be placed at the location of `yield. In its simplest form, you can do something like this:
erb :layout { "This is what I want in output" }
Typically, you render another template:
erb :layout do
erb :about
end
More details in documentation.
TLDR; what #wandmaker says - you need to pass a block to :layout.
Understanding yield is essential for understanding Ruby. Basically, yield passes control from one scope to another. All methods in Ruby accept blocks but they ignore them unless they explicitly yield or call them:
"A RUBY STRING".downcase { p "I'm in a block!" }
# => "a ruby string"
But if the method calls yield, control is passed to the block and then passed back to the calling scope:
def yield_me
yield
end
yield_me { p "I'm in a block!" }
# => "I'm in a block!"
Alternatively, you can catch blocks as arguments:
def catch_me(&block)
block.call
end
catch_me { p "I'm in a block" }
# => "I'm in a block!"
So with that in mind, it should be clearer what your Sinatra template is doing - it renders layout.erb but when it hits yield, it tries to yield control to a block - in this case a non-existent one.
So all your responses should supply a block or sub-template like:
erb :layout { "<p>This is the about page</p>" }
or
erb :index

Link shorthand application in Sinatra

This was my first Sinatra project - link shortener but I am stuck with some errors and to be honest sinatra's built-in debugger tells me literally nothing. I would like you to give me a clue or suggest a solution to problem.
http://min.us/mkBIVTh7p - screenshot, this happen when I submit my form with url: http://google.com and word google
require 'sinatra'
require 'shotgun'
require 'data_mapper'
require 'dm-migrations'
require 'dm-sqlite-adapter'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/form.db")
class Url
include DataMapper::Resource
property :id, Serial
property :url, String
property :suggestion, String
end
get '/' do
erb :index
end
post '/' do
Url.create(:url => params[:url], :suggestion=> params[:suggestion])
end
get '/Url.suggestion' do
query = request_path.slice!(0)
redirection = Url.first(:suggestion => query)
redirect redirection.url
end
index.rb
<!doctype html>
<html>
<head>
<title>Skracanie linków</title>
</head>
<body>
<form name="form" method="post" action="#">
<fieldset>
<legend>Wpisz co trzeba</legend>
<p><label> <input type="text" name="post[url]"/>Url:</label></p>
<p><label> <input type="text" name="post[suggestion]"/>Suggested name:</label></p>
</fieldset>
<p class="center">
<input type="reset" value="Wyczyść formularz"/>
<input type="submit" value="Wyślij"/>
</p>
</form>
</body>
</html>
This is because you need to finalize your models. See http://datamapper.org/getting-started.html under the heading "Finalize Models".
Add the finalize command after defining your models:
class Url
include DataMapper::Resource
property :id, Serial
property :url, String
property :suggestion, String
end
# add this line
DataMapper.finalize

Resources