SCSS styles not being shown in the Sinatra app from "Jump Start Sinatra" book - ruby

I was following along to the tutorial in the book Jump Start Sinatra and I have looked over the file for typos. But for some reason the styles wont show up.
Here are the instructions
This is what I have
main.rb
require 'sass'
require 'sinatra'
require 'slim'
require 'sinatra/reloader' if development?
get('/styles.css'){ scss :styles }
get '/' do
slim :home
end
get '/about' do
#title = "All about this website"
slim :about
end
get '/contact' do
slim :contact
end
not_found do
slim :not_found
end
require 'sass'
get('/styles.css'){ scss :styles }
The book said to delete the old styles.css from the public folder, which I did (and that was previously working fine). And the book did say to included the styles.scss in the views directory. Here is my structure and styles.css file
Does this imply that I should also remove the reference to the CSS file that I had in the layout.slim file? This is what I have there now
layout.slim
doctype html
html lang="en"
head
title== #title || "Songs by Sinatra"
meta charset="utf-8"
body
header
h1 Songs by Sinatra
== slim :nav
section
== yield
What I am missing? is it a typo? am I forgetting to do something? does the book have a gap in information that it assumes that a reader would know to do? I added the code, then ran gem install sass and restarted the server. So what could i possibly be missing?

Ok so this had multiple errors. Hopefully my explanation can prompt you to improve your problem solving skills.
I did have some typographical errors in my styles.css file as pointed out in comments. So to test it I visited their repo on github. Then copy/pasted into my file.
Then I did notice that the author did a poor job in explaining what should be done in the layout file. So I checked his file in the repo (by the way,what is written in the book's previous chapter was not accurate). Anyways here is the layout file that worked
layout.slim
doctype html
html lang="en"
head
title== #title || "Songs by Sinatra"
meta charset="utf-8"
link rel="stylesheet" href="/styles.css"
body
header
h1 Songs by Sinatra
== slim :nav
section
== yield
What was needed was the modification to refence the CSS file
link rel="stylesheet" href="/styles.css"

Related

Using ERB for Nesta layout and page templates

I'm trying to get Nesta to use .erb templates for layout and page templates, but confused as to how to go about it.
With partials, it's easy:
= haml :header, :layout => false
becomes:
= erb :header, :layout => false
However, I can't figure out how to have all my pages point to a layout.erb file instead of a layout.haml file.
According to this, .erb templates seem fully supported, though they only describe how to apply them for individual routes. While confusingly in this post it says that "features include support for Erb templates (in the views folder only, not for pages)"?
Does anyone have a better understanding of this?

Am I loading scripts correctly in sinatra?

I have never done anything in sinatra before and decided to try it out on a project. I am confused on how script loading works. It seems to be intermittently working. Sometimes 2 scripts/css files will have internal server errors, and sometime they will all have errors.
This is my layout.erb :
<!doctype html>
<html>
<head>
<title>An HTML5 box of sand</title>
<meta charset="utf-8" />
<link href='http://fonts.googleapis.com/css?family=Arvo' rel='stylesheet' type='text/css'>
<link rel="stylesheet/less" type="text/css" href="/assets/stylesheets/style.less">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script><!--loads jquery-->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script><!--loads jquery ui-->
<script type="text/javascript" src="/assets/js/lib/handlebars.js"></script>
<script src="/assets/js/lib/less-1.3.0.min.js" type="text/javascript"></script>
<script type="text/javascript" src="/assets/js/script.js"></script><!--This is the place where you play!!!-->
</head>
<body>
<%= yield %>
</body>
</html>
I have the assets folder inside of the public folder /public/assets. It is weird because sometimes it will load the assets/js/script.js file, and not load the handlebars file. Other times it will load the handlebars and not the script.js file. I am not sure what is going on.
~~~~~~~~~~~~~~~~~UPDATE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Discovered the problem but don't know how to fix it.
So, it seems that because I am using data mapper the auto_migrate! method is somehow screwing with how the assets are being loaded. Is there something I can do about this. Here is what I have in my app.rb file:
require 'rubygems'
require 'sinatra'
require 'data_mapper'
# Include the models
require './models/User'
# Connect to mysql
DataMapper.setup(:default, "mysql://root#localhost/dev_landing")
#This line is what is messing everything up.
DataMapper.auto_migrate!
set :public_folder, 'public'
get '/' do
erb :home
end
I set up data mapper like this because I read in a tutorial that this is how you get it to automatically create the tables you specify in your models. Is there a better way to do this so that it is not messing up the loading of my scritps and css?
DataMapper.auto_migrate! deletes existing tables in case they exist and creates them again.
So calling this function means: you lose all your data. (That's why there is an exclamation mark at the end, meaning: watch out!) In case your schema is still under heavy development, I suggest you to replace DataMapper.auto_migrate! by DataMapper.auto_upgrade!. It does not wipe your old data, instead it tries to modify the underlying tables while trying to keep the data. The exclamation mark is still there because your data might still get slightly damaged because changing the schema without corrupting the data is not always possible.
Another thing, the order of calls must be changed. Currently it is:
Model definitions
DataMapper.Setup
DataMapper.auto_migrate!
Your route definitions etc.
But it should be instead:
DataMapper.Setup
Model definitions
DataMapper.auto_migrate! DataMapper.auto_upgrade!
DataMapper.finalize (you forgot that one)
Your route definitions etc.
When something is screwed up with datamapper, the error messages can be weird/misleading. By the way, make sure that there are no calls to the database from inside your views. These calls belong into the controller, without any exception in my opinion. This way your app naturally follows the MVC pattern. (After all Sinatra hardly enforces any other structure... ;))

HAML layout.haml and Sinatra not working with url parameters

My index.haml is working fine with, for example:
get '/about' do
haml :about
end
But if I try to use a user parameter like:
get ':user/add' do
haml :add_item
end
The layout.haml is ignored.
I was trying to get this to work using subdirectories in my view folder like:
/view/contact/add.haml
While it inserts the =yield content, it will not show the layout.haml css styles, etc.
So I thought using subdirectories was the issue and put all my hamls in the base views directory. However it seems that anything using a url parameter like get ':user/add' does not incude the layout.haml regardless. Currently this is a test I did:
myapp.rb
require "rubygems"
require "sinatra"
require "haml"
require "data_mapper"
require "pony"
get '/' do #works fine
haml :index
end
get '/:user_id/dashboard' do #recognizes the content but ignores layout.haml
haml :dashboard
end
my layout.haml looks like this:
views/layout.haml
!!!
%html
%head
%title Testing haml and sinatra
%link(rel="stylesheet" href="css/style.css")
%body
#wrapper
#header
%h1 HAML Test Template
%h2 Made with Sinatra and HAML!
#navigation
%h1 Navigation
#sidebar
%h1 Sidebar
#content
=yield
#footer
%p
This is the footer.
Any help would be much appreciated. Thanks.
I don't know if it matters but I'm using shotgun for development
I fixed this by using the following in layout.haml:
layout.haml
Instead of:
%link(rel="stylesheet" href="css/style.css")
Replaced (fixed version):
%link(rel="stylesheet" href="/css/style.css")
Works fine! Hopefully this helps someone.
If it helps, when I view source, it appears that it's trying to access my style.css in the wrong place based on the url parameter ":user_id" like so:
http://127.0.0.1:4567/test/myapp/css/style.css
So I need to get it to grab the style sheet form the same place it would if I was hitting 127.0.0.1/about which would look like this in the html source:
http://127.0.0.1:4567/css/style.css
In the actual code both stylesheet links are identical, but since I'm in a subdirectory it cannot find the stylesheet style.css
http://127.0.0.1:4567/css/style.css *(exists in public/css/style.css)*
-vs-
http://127.0.0.1:4567/test/myapp/css/style.css *(doesn't exist)*
I am still seeing an issue now with url parameters using a variable in the url path with sinatra and Haml.
When using these I am seeing the css becoming embedded into the post processed html instead of creating a link to the style.css file. The processed html is as follows (even the doctype is messed up and title isn't included):
I see this now with url parameters in the path (e.g. localhost:4567/user/add):
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body { text-align:center;font-family:helvetica,arial;font-size:22px;
color:#888;margin:20px}
#c {margin:0 auto;width:500px;text-align:left}
</style>
</head>
Instead of this (e.g. localhost:4567/about):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Test app</title>
<link href='/css/style.css' rel='stylesheet' />
</head>
What am I missing here??

Sinatra not loading layout file when URL has 2 sublevels

I have this code:
# Users page
get '/admin/users' do
#title = "Admin - Users"
erb :admin_users
end
When the view is rendered, I get the HTML in the ERB file but the layout file does not render. If I change the route to just '/users' everything renders fine. What gives? I originally put the users ERB page in a subdirectory 'views/admin' after finding sample code on how to do that and hit this issue. I thought that was the reason but rather it seems its the URL causing the problem. Anyone else hit this or know a work around?
All my other views work fine as well. This is the first view I've tried the URL pattern with. I also tried this but it didn't affect anything.
# Users page
get '/admin/users' do
#title = "Admin - Users"
erb :admin_users, :layout => :layout
end
Any help is appreciated. Thanks.
I've got the same problem, check paths to yours assets in the layout. You should add / before.
<link href='/stylesheets/application.css' rel='stylesheet' type='text/css'> is correct.
If you use a subdirectory for the admin_users view, you should really save it as views/admin/users.erb and then render it with
get '/admin/users' do
erb :'admin/users'
end
Maybe this will already address your issue. Let me know, if you need more help.
I guess you can get into trouble when you set the view directory for the admin views different from the location of the layout.erb file. Have you tried putting a dummy layout.erb in the views/admin/ folder?
You did not showed the exact error your are getting. I assume it is "No such file or directory" for the template "admin_users.erb".
An option is missing on your "erb" call and you should tell Sinatra where to find the template. This has just worked for me:
# Users page
get '/admin/users' do
#title = "Admin - Users"
erb :'admin/admin_users', :layout_options => { :views => 'views/admin' }
end
It renders the template on views/admin/admin_users.erb using the layout from views/admin/layout.erb

Getting all the domains a page depends on using Nokogiri

I'm trying to get all of the domains / ip addresses that a particular page depends on using Nokogiri. It can't be perfect because of Javascript dynamically loading dependencies but I'm happy with a best effort at getting:
Image URLs <img src="..."
Javascript URLs <script src="..."
CSS and any CSS url(...) elements
Frames and IFrames
I'd also want to follow any CSS imports.
Any suggestions / help would be appreciated. The project is already using Anemone.
Here's what I have at the moment.
Anemone.crawl(site, :depth_limit => 1) do |anemone|
anemone.on_every_page do |page|
page.doc.xpath('//img').each do |link|
process_dependency(page, link[:src])
end
page.doc.xpath('//script').each do |link|
process_dependency(page, link[:src])
end
page.doc.xpath('//link').each do |link|
process_dependency(page, link[:href])
end
puts page.url
end
end
Code would be great but I'm really just after pointers e.g. I have now discovered that I should use a css parser like css_parser to parse out any CSS to find imports and URLs to images.
Get the content of the page, then you can extract an array of URIs from the page with
require 'uri'
URI.extract(page)
After that it's just a matter of using a regular expression to parse each link and extract the domain name.

Resources