How do I automatically generate static HTML from HAML with Sinatra or Padrino? - sinatra

I want to serve static HTML pages using nginx. Then, I will use jQuery to update DIVs, SPANs, etc via AJAX calls from a Padrino server.
I like creating my web pages in HAML because it's easier but in production, I don't want to serve HAML templates. Just raw, HTML at the speed of nginx.
Is there an easy way to do this?
What would be ideal would be a service that automatically renders HAML, partials, etc into the public folder that nginx could serve.

Simple,
add padrino-cache to your app
class SimpleApp < Padrino::Application
register Padrino::Cache
enable :caching
get '/foo', :cache => true do
expires_in 30 # expire cached version at least every 30 seconds
'Hello world'
end
end
Then save wherever you want to serve it:
set :cache, Padrino::Cache::Store::File.new(Padrino.root('public'))
You can read more here: http://www.padrinorb.com/guides/padrino-cache

First thing that pops to my mind would be Jekyll. Anyway I see it only as a matter or optimization, so if you already have a Sinatra, you could start by rendering HAML on every request, and than add caching.

Related

blank.html is downloaded multiple times

GWT is used and the application is deployed on WebLogic using HTTPS.
The performance is poor and with F12 Developer Tools, we could see that blank.html is downloaded multiple times. This is clearly related to GWT but we have not been able to figure out why.
The following is from javascript:
defineSeed(2613, 2614, makeCastMap([Q$BaseModelData, Q$ModelData, Q$Theme, Q$Serializable]), Slate_0);
var SLATE;
function $clinit_GXT(){
$clinit_GXT = nullMethod;
IMAGES = new XImages_generatedBundle_0;
MESSAGES = new XMessages__0;
SSL_SECURE_URL = getModuleBaseURL() + 'blank.html';
}
This is from GWT.java:
/**
* URL to a blank file used by GXT when in secure mode for iframe src to
* prevent the IE insecure content. Default value is 'blank.html'.
*/
public static String SSL_SECURE_URL = GWT.getModuleBaseURL() + "blank.html";
Does anyone know under what circumstances blank.html is called?
Thanks!
This is from GWT.java:
This is actually from GXT.java.
This is used in a few cases when creating an <iframe> element, so that IE won't give errors if your site is hosted from SSL. I can actually only find one case (as of GXT 3.1.1) which uses this, in Layer.java. Only IE pages loaded from https urls will make use of this.
The Layer class uses this as a "shim", a way to prop up some DOM elements above overs, and work around some browser bugs (typically plugin or iframe related). Menus and popup dialogs use this to ensure that they don't appear "underneath" content that they should be "above".
This file is very small - just enough HTML to convince IE than the iframe has correctly loaded, and no more. It never changes, and should load nearly instantly.
As far as performance goes, this should only happen when a Menu or Window/Dialog/Tooltip is shown - these shouldn't be happening on app startup usually, at least not more than a window or two. Additionally, the browser should recognize that it is loading the same element and cache it correctly, and not load it multiple times (though it might be listed several times as hitting the cache). If the server has instructed the browser to never cache the file, that is something you should look at changing.
In short, this is very unlikely to be the cause of any performance issues, at least in GXT itself. If somehow you have the shim enabled on every single widget in your project, this should not be required. If the file is loading slowly, something may be very wrong with your server configuration.
For reference, here is the entire file:
<html></html>

merge large existing web app into Sailjs site

I'm trying to merge large existing web app into sails.js. so I moved the folders into assets and build a custom route , 'GET /': '/assets/client/launch.html' and get 404 when I point my browser to http://localhost:1337/ as the / is correctly redirected to http://localhost:1337/assets/client/launch.html which produces the 404.
Now the file exists in the folder assets/client (and in .tmp), so I am thinking the Sails router is getting in the way.
I would leave the client (70K lines of JS) that generates all the UI dynamically and sailjs server that provides authentication separate and enable CORS but my customer wants client packaged with server. This type of operation is simple in frameworks like ASP.NET MVC but am wondering if Sails is up to the task.
Well, If everything you tried did not work out. There might be another solution ,
First of all since you are talking about sails app I am assuming other bundle must be sails as well ,
So here is what you do-
Change the port for another app that you want to attach to this.
Second whenever you want to go to page on another app simply redirect the client to another port ie
in html or esp put a href tag with different port.
<a href="localhost:PORT/route_to_file">
</a>
I got it working by placing my app into assets where we need to launch from assets/client/index.html as there would be too many dependencies to change. As I said above could not just add a route as Sails must getting in the way. However as in Chapter 3.2.2 of Sails in Action I generated a static asset npm install sails-generate-static --save. then I redirected to assets/client/index.html. As an aside that book is great and would highly recommend it.

Access to controller variable from CoffeeScript

I have #list value in my controller and i have view where i m adding products.Form looks like product_name and Add Button.I need to add all thees values to #list thought ajax request using coffe script or some other way, where i will not submit whole form.
How to achieve that? Thanks.
Your question sounds quite strange...
First, any CoffeScript source will be compiled to Javascript, which is downloaded on the client side (in the browser). Your controller is running server-side, so it is only addressable through HTTP requests.
Nevertheless, an #list attribute is not persistent between two HTTP requests, so you will have to persist any change if you need to accumulate data, as you state in your question.
To achieve the AJAX call, I would recommend to use JQuery's helpers: http://api.jquery.com/jQuery.ajax/, or shortcuts like http://api.jquery.com/jQuery.get/, http://api.jquery.com/jQuery.getJSON/, ...
The rest is Rails routing, as can be teached in http://guides.rubyonrails.org/action_controller_overview.html#methods-and-actions and http://guides.rubyonrails.org/routing.html.
Hope this helps.

How do I make a separate View path/directory for iPhone in Rails?

I'm making an iPhone version of an existing Rails app. I'd like to make the mobile version accessible via a subdomain such as iphone.mysite.com.
I know I can use formats and the respond_to block for individual erb files, such as index.iphone.erb as show here:
Creating an iPhone optimised version of your Rails site using iUI and Rails 2
But I'd like to keep entirely separate view directories for the mobile version and regular version such as this:
app/views/iphone
Here's what I've tried in my Application controller:
class ApplicationController < ActionController::Base
before_filter :set_site
def set_site
subdomain=self.request.subdomains[0]
ActionController::Base.prepend_view_path("app/views/#{subdomain}")
end
When testing this, however, the view switches to the view associated with the last requested subdomain by any user.
For example, if I visit http://iphone.mysite.com, then immediately go to http://www.mysite.com in another separate browser, I see the mobile version instead of the regular one. Refreshing it will correct this and bring up the right version. But if I go back to http://iphone.mysite.com in the other browser and refresh, it brings up the non-mobile site! I'm tearing my hair out and not understanding what's going on.
Any advice would be much appreciated.
Edit 1
Vlad below found a link with a possible solution however it is not working for me. Here is the code I tried. I made a file called subdomain_view.rb and placed it in config/initializers:
# Put all of this in a bootstrap-only initializer
ActionController::Base.class_eval do
APP_ONE_VIEW_PATH = "app/views/iphone"
APP_TWO_VIEW_PATH = "app/views/default"
cattr_accessor :application_view_path
self.view_paths = ["app/views", APP_ONE_VIEW_PATH, APP_TWO_VIEW_PATH]
# This is where you determine the switching mechanism for your application. Here, it is a simple GET parameter.
# You can probably argue that this specific piece SHOULD be in your actual app_controller class definition, as it is the only piece
# of info pertinent to the rest of your application.
before_filter do |controller|
ActionController::Base.application_view_path = request.subdomains[0]=="iphone" ? APP_TWO_VIEW_PATH : APP_ONE_VIEW_PATH
end
end
require 'aquarium'
ActionView::PathSet.class_eval do
include Aquarium::DSL
before :find_template do |join_point, object, *args|
object.each_with_index do |path,i|
object.unshift(object.delete_at(i)) if path.to_s == ActionController::Base.application_view_path
end
end
end
# I'll leave the exercise of testing this or implementing it for your particular app up to you.
With the above code, I am getting the same view no matter what subdomain I put in. Any suggestions on what might be wrong? Am I putting this code in the wrong place?
First, you have an error in your approach. You only 'set' a view path, you don't 'unset' it. When you do something like
ActionController::Base.prepend_view_path
this actually persists between your requests (internally, you are setting a class variable, and because classes are cached in production, this variable remains set between requests). Therefore, the current view path is the view path of your last request.
IMO, you should dynamically compute view_path for your current subdomain (this implies some ActionView hacking). A nice solution is provided here.
I was able to solve the problem by using a gem called themes_for_rails:
https://github.com/lucasefe/themes_for_rails
After installing the gem, here's what I added to my application files:
#application_controller.rb
class ApplicationController < ActionController::Base
theme :theme_resolver
def theme_resolver
current_subdomain=self.request.subdomains[0]
end
end
#routes.rb
MyAppName::Application.routes.draw do
themes_for_rails
end
#Gemfile
gem 'themes_for_rails'
I placed my themes in [application_root]/themes. Make sure you don't put it in [application_root]/app/themes.

Making GWT application crawlable by a search engine

I want to use the #! token to make my GWT application crawlable, as described here:
http://code.google.com/web/ajaxcrawling/
There is a GWT sample app available online that uses this, for example:
http://gwt.google.com/samples/Showcase/Showcase.html#!CwRadioButton
Will serve the following static webpage to the googlebot:
http://gwt.google.com/samples/Showcase/Showcase.html?_escaped_fragment_=CwRadioButton
I want my GWT app to do something similar. In short, I'd like to serve a different flavor of the page whenever the _escaped_fragment_ parameter is found in the URL.
What should I modify in order for the server to serve something else (a static page, or a page dynamically generated through a headless browser like HTML Unit)? I'm guessing it could be the web.xml file, but I'm not sure.
(Note: I thought of checking the Showcase app provided with the GWT SDK, but unfortunately it doesn't seem to support serving static files on _escaped_fragment_ and it doesn't use the #! token..)
If you want to use web.xml, then I think it won't work with a servlet-mapping, because the url-patterns ignore the get parameters. (Not 100% sure, if there is another way to make this possible.)
You could of course map Showcase.html to a servlet, and in that servlet decide what to do, based on the get parameter "_escaped_fragment_". But it's a little bit expensive to call a Servlet just to serve a static page for the majority of the requests (not too bad, but still. You could set cache headers, if you're sure that it doesn't change).
Or you could have an Apache or something in front of your server - but I understand, I wouldn't like to have to do that either. Maybe your JavaEE server (which one are you using BTW?) provides some mechanism for URL filtering before the request gets passed on to the web container - I'd like to know that, too!
Found my answer! The Showcase sample supporting crawlable hyperlinks is in the following branch:
http://code.google.com/p/google-web-toolkit/source/browse/branches/crawlability/samples/showcase/?r=7726
It defines a filter in the web.xml to redirect URLs with the _escaped_fragment_ token to the output of HTML Unit.