How do I render a static haml template in padrino? - ajax

I want to do essentially the same thing: How do I automatically generate static HTML from HAML with Sinatra or Padrino?
This answer didn't quite go far enough for me. After I have caching setup, how would I send a particular haml file to the client?
E.g.
get '/foo', :cache => true do
expires 30
haml '/templates/foo.haml'
end

If you want to serve any file in templates you could do something like:
get '/*', :cache => true do |name|
expires 30
haml "/templates/#{name}.haml"
end
and they will all be cached.

Related

How can we render a random partial in a Slim template within a Sinatra application?

Given a really simple Sinatra application:
require 'sinatra'
require 'slim/include'
get '/' do
#specifically = %W(milk bread cheese).sample
slim :home
end
Where views/home.slim looks like this:
doctype html
html
head
title Don't forget the stuff
body
include reminder
We can see that reminder is included as a bare word (rather than a String).
In views/reminder.slim, I want to include the random partial represented by the variable #specifically:
p Remember the things!
include #specifically
This raises a Temple::FilterError at /: '#specifically.slim' not found.
How can I get Slim to render milk.slim (or whatever) here?
Rubber ducking this worked!
Instead of
include #specifically
Use
== slim #specifically.to_sym

How to not include layout.haml in sinatra app

I have a ruby sinatra app that uses haml. I use layout.haml for a common menu across all pages. Let's say I have login.haml, main.haml and reports.haml. I only want to use layout.haml for login.haml and main.haml. How do I exclude layout.haml from reports.haml? thanks
Two (and a somewhat) ways:
Global
class MyApp < Sinatra::Base
set :haml, :layout => false
get '/reports' do
haml :reports
end
end
Blacklisting
If the number of routes that do not require layouts are less, then this is a pattern:
class MyApp < Sinatra::Base
get '/reports' do
haml :reports, :layout => false
end
end
Whitelisting
If the routes that don't need a layout.haml file are more, however, Sinatra does not seem to support overriding the global declaration of set :haml, :layout => false. I've taken the liberty to open up an issue for this feature as it seems reasonable enough (Hope you won't mind).

routing to a static .md page in /public (ruby on rails 2.3.5)

this question was asked before, but the answer was for ruby on rails 3.0+
Basically I want to put my wiki pages (ie .md pages) inside my public folder in my 2.3.5 ruby on rails project. and I want users to access the home of the wiki page when they type mysite.com/wiki (ie this would map to /public/wiki/home.md)..
how do I do this in ruby on rails 2.3.5? (the routing documentation online wasn't very informative)
Also in general if for some reason I'm stuck with an RoR 2.3.5 project.. where do I go for documentation? It seems the official documentation only pertains to the latest RoR version (ie 3+)
I presume that you want the Markdown to be rendered. If you simply serve it up from your public directory, then Rails won't render it.
What you could do is an a new controller, say WikiController, which could render markdown files that you store somewhere like lib/wiki. I haven't tested any of this directly, so you should take it only as a guide, but it should work okay.
The controller might look like something like this:
# app/controllers/wiki_controller.rb
class WikiController < ApplicationController
def show
page = File.open(File.join(Rails.root, 'lib', 'wiki', "#{params[:page_id]}.md"), 'r') { |f| f.read }
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true)
render :html => markdown.render(File.join(Rails.root, 'lib', 'wiki', "#{params[:page_id]}.md"))
end
end
And you could add a route like this:
# config/routes.rb
map.connect 'wiki', :controller => 'wiki', :action => 'show', :page_id => 'home'
map.connect 'wiki/*page_id', :controller => 'wiki', :action => 'show', :as => :wiki
The first route handles your special case (home.md) and the second will allow you to structure your wiki however you like (including placing files in subdirectories, etc). Linking to /wiki/help/getting_started will try to render the file lib/wiki/help/getting_started.md.
You also have a link helper method, so that if you need to link to a wiki page from within your app you can call wiki_path(:page_id => 'help/getting_started').
This solution assumes you're using RedCarpet for Markdown rendering, however you could switch up any renderer you like.

Choosing different layout file for sinatra-authentication

sinatra-authentication expects a layout.haml for its pre-rolled authentication views.
How do I specify a different layout template that sinatra-authentication can use (e.g. auth_layout.haml) so that I can keep layout.haml for my app's views?
My current not-ideal approach to this is to:
Allow sinatra-authentication to use the standard layout.haml
Explicitly use another layout file (e.g. std_layout.haml) in all other parts of the app
e.g.
...
erb :home_page, :layout => :std_layout
...
I'd prefer it the other way around :)
You may read on Layout Engines or simply try:
get '/login' do
haml :login, layout: auth_layout
end
EDIT-1: your comment is Ok layout: auth_layout is ruby 1.9 syntax :layout => auth_layout is syntax used before 1.9
And if you are talking about this sinatra-authentication you must hack this file's app.get '/login/?' method regarding (Module::Helpers#use_layout?).
EDIT-2: I guess overwriting use_layout? method will help you, perhaps something like
Module Sinatra
Module Helpers
def use_layout?
request.xhr? ? false : :auth_layout
end
end
end

In Sinatra, best way to serve iPhone layout vs. normal layout?

I'm writing a Sinatra app which needs to render different layouts based on whether the user is using an iPhone or a regular browser. I can detect the browser type using Rack-Mobile-Detect but I'm not sure of the best way to tell Sinatra which layout to use.
Also, I have a feeling that how I choose to do this may also break page caching. Is that true?
Example code:
require 'sinatra/base'
require 'haml'
require 'rack/mobile-detect'
class Orca < Sinatra::Base
use Rack::MobileDetect
helpers do
def choose_layout
if request.env['X_MOBILE_DEVICE'] == :iPhone
# use iPhone layout
else
# use normal layout
end
end
end
before do
# should I use a before filter?
choose_layout()
end
get '/' do
haml :home # with proper layout
end
end #Class Orca
This is what I ended up doing:
require 'sinatra/base'
require 'haml'
require 'rack/mobile-detect'
class Orca < Sinatra::Base
use Rack::MobileDetect
# HAML template options
# Use HTML5 doctype
set :haml, {:format => :html5 }
helpers do
def get_layout
# For AJAX (XMLHttpRequest) requests, don't use a layout
if request.xhr? then
#layout = false
exit
end
# For non-AJAX (XMLHttpRequest) requests, choose correct layout
# For each mobile device, you will need a layout_<device>.haml file
# in the Views directory
#layout = case request.env['X_MOBILE_DEVICE']
when /iPhone|iPod/ then :layout_iphone
# when "Android" then :layout_android
else true # use default Sinatra layout
end
end
end # helpers
before do
get_layout()
end # before filter
get '/' do
# Will use iPhone layout for iPhone|iPod,
# Sinatra default layout for desktop browsers
haml :home, :layout => #layout
end
end # Class
I believe the standard way to handle specific user agents in Sinatra is directly on the route...
get '/', :agent => /iPhone/ do
# render for iPhone
end
get '/' do
# render standard layout
end
See The Sinatra Book.
Re: caching, I guess it would depend on what caching layers are fronting your site, but, yes, you may need to account for this.
I wrote a blog post about this topic that might be helpful to someone using Padrino with Sinatra. If you're not using Padrino, this still might be useful if you find the right place to extend Sinatra.
http://blog.joshdzielak.com/override-padrino-locale-based-template-resolu
http://dzello.com/blog/2011/06/22/override-padrino-locale-based-template-resolu/
The summary - I use rack-mobile-detect to tell me if a request is 'mobile', and I patch out Padrino's locale-based rendering support to render based on the mobile detection instead of the locale.
In this way I'm able to have foo.mobile.haml render for mobile and foo.haml for non-mobile, without any application code. As a bonus, it works both for the template file and the layout.
I had a similar problem always we cant relay on Routes . Sinatra provides filters to handle these kind of problems
#your_layout_name = ''
before :agent => /iPhone/ do
#your_layout_name = "initialize with desired iphone template"
end
get '/' do
# use #your_layout_name variable to initialize layout
end
I posting this since I had a problem where I was not in a position to filter at route level
so This may help others who are looking for similar solutions

Resources