Static web site generation - ruby

I need an easy way to generate static web pages so that I can serve them up with Apache or Nginx. Currently I am using SproutCore's build tool (Abbot) to generate static pages but that is a little bit cumbersome as it is designed for building SproutCore apps, not non-SproutCore HTML pages.
Here are my requirements:
Javascript must be combined and minified
CSS files must be combined
Each image / CSS / Javascript asset must have unique URL for better caching (query string isn't enough)
Asset URL should be different only when it really changes
Localization support thorough HTML, CSS, Javascript and image files
Nice template engine with layouts, partials etc.
Here are possible solutions I have found:
Create the site using Ruby on Rails, then get all resources using wget like http://usefulfor.com/ruby/2009/03/23/use-rails-to-create-a-static-site-rake-and-subversion/
Use Middleman: http://middlemanapp.com
Any thoughts on this?
After a longish evaluation process I have decided to use Middleman. It does the trick and I love its simplicity and the fact that I can use existing Rack components with it.
Best Regards,
Pekka Mattila

I'm the creator of Middleman and would be eager to help you get comfortable using Middleman. My main goal is to give users the power of Rails, but focused on static development. Some of the actual code of Middleman is simplified versions of Ab

Here's what I do:
Ruby on Rails 3 with the High Voltage Gem, which makes it easy
to serve a static page body using the common templates. It requires a
simple entry in the routes (and you can use namespaces to create a
hierarchy).
Apache reverse proxy to stand-alone Passenger (which uses nginx I
believe) to run the Rails app. This article describes how to
configure it.
Stand-alone passenger will read the URL, see if there is a corresponding file in /public with the .html on it, and serve that. If not found, it will invoke Rails and generate the page. In essence, page caching, with the option of publishing your URLs with or without the .html. There is a section in the Passenger docs about page caching specifically.
As far as combining and minifying js and css, here's a good stackoverflow thread.
Rails has excellent i18n/l10n support.
Rails template engine is very nice to work with. And you can use HAML if you prefer.
For your 3rd and 4th points, I'm a little confused. You want css and js combined, but then you want each to have it's own URL. In Rails, the "cache => true" directive on asset tags takes care of adding a query string parameter that changes when the content does, which is a fairly traditional scheme. I'm not sure what context you are working in where that would not work. Any CDN I've ever used works fine with that, as does an web server implementing the HTTP spec correctly. Anyway, changing the actual path or file in the URL would require changing all references to it. Maybe I'm misunderstanding?

Monkeyman has the template engine you need, I think. Think of it as Middleman's little Scala brother. Nowhere as mature or feature rich yet, but we'll get there eventually. The current incarnation supports HAML, Jade, SSP for layouts, Markdown for content and a couple of other things.

Without any special order
jekyll - quite simple
middleman - a lot of funcionalities
nanoc - a lot of funcionalities
stasis - use controllers
staticmatic
frank
gumdrop
ruby on rails + wget
ruby on rails + high voltage + apache reverse proxy

You should probably also checkout mod_pagespeed. It will at least give you this:
Javascript must be combined and minified
CSS files must be combined
Each image / CSS / Javascript asset must have unique URL for better caching (query string isn't enough)
Asset URL should be different only when it really changes
It won't give you this:
Localization support thorough HTML, CSS, Javascript and image files
Nice template engine with layouts, partials etc.

You can have a look at docpad. It's written in coffeescript and runs on Nodejs. It is document based, where you write some documents and layouts, it will compile them and write them in the out directory. You can write documents in a lot of languages via plugins
It also supports multiple level of file compilation. For example from eco to markdown to html.
Another great feature of it is that you can query on other documents being generated in a document. For example in the first page, you have something like this to get all blog posts:
database.findAll({url : /posts/})
Which will return all documents having posts in their url.

Related

generate html template engine i18n

I am searching for a solution to modularize static html files and to add multilanguage support. I want to generate static html files with gulp which are then served through an apache server.
I am now thinking about using the template engine marko to modularize html files and to prerender html files (handlebars would also be an option; jade is no option cause i don't like the syntax).
For multilanguage support i am thinking about to add an i18n plugin (for example https://www.npmjs.com/package/i18n). But this plugin needs an express server; also for multilanguage i want to prerender the files. Has anybody a hint for me which i18n plugin would best fit for me? Maybe also which one would best work together with marko and gulp?
The result should be html files generated inside /de and /en.
The following sample app might help: https://github.com/marko-js-samples/marko-koa-i18n
It is a server-based app that uses Koa and koa-i18n, but you can directly use i18n-2 to accomplish the same thing.
Disclaimer: I have not used i18n-2 or koa-i18n
A few things to note:
A custom tag is used to introduce a local variable that can be used to access the i18n bundle: (see: src/components/app-hello/template.marko and src/taglib/i18n-var-tag.js)
The i18n bundle is pulled out of out.global.i18n. See: Marko > Global Properties
The following Gulp plugin is currently out-of-date, but it might serve as a good starting point or you can submit a PR to improve it: https://github.com/viviangledhill/gulp-marko
In your case, you will want to prerender each template multiple times, each time with a different i18n bundle instance passed in as a global property.
If you would like more details please ask here or in the Gitter chat room: https://gitter.im/marko-js/marko
Hope that helps.

Static vs. dynamic content in docpad system - how to create dynamic content?

DocPad is described as being comparable to other static site generators, but it is also described as being "not limited to static site generation".
I've been browsing the DocPad website and other documentation and haven't yet been able to find anything that seems to explain how to incorporate dynamic content, and what types of limitations may be involved?
As a relative beginner, I am wondering if anyone can help me better understand the methodology whereby dynamic content would be incorporated into DocPad...? e.g. AJAX, and dynamic server-side scripts for doing things like dynamically loading pictures from Flickr into a webpage when a certain tag is clicked...
Thanks.
So there's a few ways DocPad facilitates dynamic content:
Via the regenerateEvery configuration option. This will regenerate your website every so often you specify. This great when combined with plugins like feedr for pulling in data from remote feed sources (like your latest social activity), as well as repocloner which clones out and keeps a git repository up to date inside your project. The benefit of this option is it's really easy to do and provides the illusion of a dynamic website. For instance the Benjamin Lupton Website applies this method to keep it's statistics on the home page, as well as the social data in the sidebar up to date. Every hour it regenerates with the latest information. Making it fast, and also illusively dynamic.
Via the dynamic meta-data property. When set to to true this tells the DocPad server we should re-render that document on each request, rather than just once. This works great inside the Kitchensink Skeleton for search pages and misc forms. This way is most similar to PHP development.
Via the serverExtend event. This event allows you to hook into and extend the DocPad server, allowing you to add extra server-side logic, handling, etc. Common use cases is to add extra routing to your server to handle route aliases, adding form processing such as a contact form, or to add a RESTULful interface for a Backbone.js application. The DocPad Website uses this to add extra routing and a regenerate post-receive hook for the documentation. The NodeChat Skeleton uses this to add the Socket.io server-side logic.
Via the API. This way is the most involved but can be quite rewarding if you just wish for DocPad to be a small part of an existing node.js application. With this, you can create a DocPad instance in your code and interact with it. The grunt-docs grunt task utilises this :)

AngularJS / AJAX app and search engine crawlers

I've got a web app which heavily uses AngularJS / AJAX and I'd like it to be crawlable by Google and other search engines. My understanding is that I need to do something special to make it work, as described here: https://developers.google.com/webmasters/ajax-crawling
Unfortunately, that looks quite nasty and I'd rather not introduce the hash tags. What I'd like to do is to serve a static page to Googlebot (based on the User-Agent), either directly or by sending it a 302 redirect. That way, the web app can be the same, and the whole Googlebot workaround is nicely isolated until it is no longer necessary.
My worry is that Google may mistakenly assume that I'm trying to trick Googlebot, while my goal is to help it. What do you guys think about this approach, and what would you recommend?
Recently I come upon this excellent post from yearofmoo, explaining in details how to make your Angular app SEO friendly. In essence, when bots see an uri with a hash tag they will know it's an ajaxed page and will try to reach the same uri by replacing '#!' in your uri with '?_escaped_fragment_='. This alternative uri instructs bots that they should expect to find a definitive static version of the page they were accessing.
Of course, to achieve this you'd have to introduce hash tags into your uris. I don't see why are you trying to avoid them. Isn't gmail using hash tags?
Yeah unfortunately, if you want to be indexed - you have to adhere to the scheme :( If your running a ruby app - there's a gem that implements the crawling scheme for any rack app....
gem install google_ajax_crawler
writeup of how to use it is at http://thecodeabode.blogspot.com.au/2013/03/backbonejs-and-seo-google-ajax-crawling.html, source code at https://github.com/benkitzelman/google-ajax-crawler
Have a look at these links and it will give you a good direction:
Set up your own Prerender service using Prerender.io open source code:
https://prerender.io/
Use a different existing service such as BromBone, Seo.js or SEO4AJAX:
http://www.brombone.com/
http://getseojs.com/
http://www.seo4ajax.com/
Create your own service for rendering and serving snapshots to search engines. Read this article. It will give you the big picture:
http://scotch.io/tutorials/javascript/angularjs-seo-with-prerender-io
As of May 2014 GoogleBot now executes JavaScript. Check WebmasterTools to see how Google sees your site.
http://googlewebmastercentral.blogspot.no/2014/05/understanding-web-pages-better.html
Edit: Note that this does not mean other crawlers (Bing, Facebook, etc.) will execute Javascript. You may still need to take additional steps to ensure that these crawlers can see your site.

Rails 3.1/Sprockets: Injecting controller variables (or helpers) into javascript assets

I have an action with
def new
#test_var = 'i want this to show'
end
All I want to do is inject that into the javascript called for that page. For example:
#app/assets/javascript/my_model.js.coffee.erb
$ ->
console.log('<%= #test_var %>')
I'm guessing this doesn't work because that the coffeescript/erb is compiled before the controller is accessed...so, if I wanted to inject controller variables into a JavaScript file (client side - NOT accessed via ajax) in 3.1, how should I go about doing it?
I believe the problem is that you're thinking about the asset pipeline all wrong...
asset being the operative word.
It's not a view pipeline. Other things which are assets? images & css files, things which can be preprocessed and then served as-is. The erb/preprocessing of your assets doesn't occur on each pageload/request, rather it occurs on startup/filechange so in production said assets can be optimised, cached and served statically.
You could probably figure out a way to achieve it using Live Compilation (see section 4.2 of http://guides.rubyonrails.org/asset_pipeline.html) but as the docs say:
This mode uses more memory and is lower performance than the default. It is not recommended.
The bad answer would be 'inject the javascript into your view', but decoupling your javascript from your rails controllers/views is a good idea.
A better answer would be to have an asset folder containing all of your controller javascripts, and use some "what page am I on?" javascript to determine whether to run the code or not.
Here's some answers that explain various approaches to this:
Rails 3.1 asset pipeline: how to load controller-specific scripts?
Using Rails 3.1, where do you put your "page specific" javascript code?

Does Wicket hamper SEO or search engines ability to crawl?

We're coming from GWT projects and because of problems with SEO not liking GWT for our next project we're going to move clear of GWT (mainly because seo is a high priority for this next project). In choosing a new framework, I'm looking at Wicket and liking what I've seen so far. I've only done a few tutorials, but in looking at the war layout (from these tutorials) it looks like most of the html pages are in the WEB-INF folder.
It this going to cause problems for SEO and search engines crawling through the sites files?
Ideally, I'd like to use Wicket with some AJAX and deploy to Google App Engine.
It does not matter if your .jsps (or whatever) are stored in /WEB-INF. It just means they cannot be accessed directly by going to http://webapp/path/to/jsp.
For SEO think about:
Meaningful URLs and link text (i.e. URLs should be similar to expected search engine queries)
Crawlable pages (make sure all your content can be reached by a non-JS enabled bot... i.e. don't make content only available through AJAX, for instance). A sitemap might help
Look into Wicket's Bookmarkable page links and UrlCodingStrategies for a very powerful combination to use in SEO. Basicly all your links and parameters can be encoded as/a/static/url, regardless of (changing) implementation on the backend.
if you project SEO is really important than you might reconsider using a lot of ajax since crawler wont execute javascript they are not gonna read all the return of your ajax calls... that being said the SEO quality of your site is not really based on the framework you will be using ... jsut always think about img alts, links, meta, title, h1 ... in every pages and you should be fine ... also always try to post links to your site on other websites to gain visibility and get importance for crawlers

Resources