class: middle, center # Dynamic Web Sites [http://pjb3.me/bewd-dynamic-web-sites](http://pjb3.me/bewd-dynamic-web-sites) .footnote[ created with [remark](http://github.com/gnab/remark) ] --- # Static Web Page A static web page is an HTML file on a server 1. Browser requests http://example.com/something.html 2. Web server running on `example.com` gets the `something.html` file and returns it in the body of the HTTP response 3. Browser renders the HTML to display the web page --- # Rack Rack is the basis of all dynamic Ruby-based web applications and it is used by Rails. We can use Rack to setup a simple static web server though. To create a static web page server with Rack, put this code into a file named `config.ru`: ```ruby class MyServer def call(env) body = env['REQUEST_PATH'] [ 200, { 'Content-Type' => 'text/plain', 'Content-Length' => body.length.to_s }, [body] ] end end run MyServer.new ``` --- # Running Our Server Start up the server .terminal $ rackup >> Thin web server (v1.5.1 codename Straight Razor) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:9292, CTRL+C to stop It starts on port 9292 by default Hit our server .terminal $ curl http://localhost:9292/something.html /something.html See the request being logged .terminal 127.0.0.1 - - [11/Sep/2013 15:56:25] "GET /something.html HTTP/1.1" 200 16 0.0009 --- # Static File Server Right now, our server just returns the name of the file you requested. Let's make our Rack app serve static web pages. Update `config.ru` to look like this and restart rackup. _(press ctrl+c to stop the rackup process that is already running)_ ```ruby class MyServer def initialize(document_root) @document_root = document_root end def call(env) file_path = File.join(@document_root, env['REQUEST_PATH']) respond 200, File.read(file_path) end def respond(status_code, body) [ status_code, { 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s }, [body] ] end end run MyServer.new(File.dirname(__FILE__)) ``` --- # Serve a static HTML file Create a file named `something.html` in the same directory as the `config.ru` file. Put a basic HTML page into that file. Now you can fetch it through the server: .terminal $ curl http://localhost:9292/something.html
Something
Something
You can also load this page in your web browser: .terminal $ open http://localhost:9292/something.html --- # File not found What happens if we ask for a file that doesn't exist? .small[ .terminal $ curl http://localhost:9292/something_else.html
Errno::ENOENT at /something_else.html
... ] Stack trace .small[ .terminal Errno::ENOENT: No such file or directory - /Users/pbarry/dev/course/02_html_and_rails/something_else.html /Users/pbarry/dev/course/02_html_and_rails/config.ru:8:in `read' /Users/pbarry/dev/course/02_html_and_rails/config.ru:8:in `call' ... 127.0.0.1 - - [11/Sep/2013 16:02:49] "GET /something_else.html HTTP/1.1" 500 67449 0.0204 ] Response code is 500 instead of a 200 Should be a 404 --- # Static File Server With Not Found Update the `config.ru` again and restart rackup .small[ ```ruby class MyServer def initialize(document_root) @document_root = document_root end def call(env) file_path = File.join(@document_root, env['REQUEST_PATH']) if File.exists?(file_path) respond 200, File.read(file_path) else respond 404, File.read('not_found.html') end end def respond(status_code, body) [ status_code, { 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s }, [body] ] end end run MyServer.new(File.dirname(__FILE__)) ``` ] --- # Static File Server With Not Found Generate the error page .terminal $ echo '
Not Found
' > not_found.html Now try pages that exist and don't exist .terminal $ curl http://localhost:9292/something.html
Something
$ curl http://localhost:9292/something_else.html
Not Found
logs .small[ .terminal 127.0.0.1 - - [11/Sep/2013 16:05:11] "GET /something.html HTTP/1.1" 200 19 0.0010 127.0.0.1 - - [11/Sep/2013 16:05:13] "GET /something_else.html HTTP/1.1" 404 18 0.0007 ] --- # Dynamic Web Page A dynamic web page does not exist in an HTML file on the server, instead the HTML is produced on-demand, when requested 1. Browser requests http://example.com/something.html 2. Web server running on `example.com` generates the `something.html` HTML document and returns it in the body of the HTTP response 3. Browser renders the HTML to display the web page --- # Dynamic Web Page Update the `config.ru` and restart rackup: .small[ ```ruby class MyServer def call(env) path_name = File.basename(env['REQUEST_PATH'], '.html') body = "
#{path_name.to_s.capitalize}
\n" respond 200, body end def respond(status_code, body) [ status_code, { 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s }, [body] ] end end run MyServer.new ``` ] This server will generate a page based on whatever the path is .terminal $ curl http://localhost:9292/something.html
Something
$ curl http://localhost:9292/something_else.html
Something_else
--- # Uses for Dynamic Web Pages * Managing a catalog of products in a database * Personalizing the page to the users preferences * Time-sensitive content