diff --git a/csspre.textile b/csspre.textile
new file mode 100644
index 0000000..0250de9
--- /dev/null
+++ b/csspre.textile
@@ -0,0 +1,387 @@
+title: CSS Next - CSS Preprocessors
+
+h1. CSS Next - CSS Preprocessors
+
+Lightning Talk, May 2012 - Gerald Bauer
+
+
+h1. What's CSS?
+
+CSS => Cascading Style Sheets
+
+Ice Breakers:
+
+* What's missing in CSS?
+* Are you using any CSS preprocessors?
+
+
+
+h1. Dynamic CSS
+
+CSS preprocessors extend "standard" CSS with:
+
+* Variables
+* Functions and Operations
+* Nested Rules
+* Mixins
+* And much more (Interpolation, Conditionals, Looping, Imports, Keyword Arguments, etc.)
+
+
+h1. CSS Variables
+
+Define variables:
+
+{{{
+$bingo-text: white;
+$bingo-background: green;
+}}}
+
+Use variables:
+
+{{{
+.bingo {
+ background-color: $bingo-background;
+ color: $bingo-text;
+}
+}}}
+
+Becomes (compiled to "standard" CSS):
+
+{{{
+.bingo {
+ background-color: white;
+ color: green;
+}
+}}}
+
+Not just colors:
+
+{{{
+$base-font-size: 18px;
+$base-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+}}}
+
+
+
+h1. CSS Functions and Operations
+
+Yes, you can. Use standard math operations (+, -, *, /, and %) for numbers - even with units.
+For colors, use functions for changing the lightness, hue, saturation, and more.
+
+
+{{{
+#navbar {
+ $navbar-width: 800px;
+ $navbar-items: 5;
+ $navbar-color: #ce4dd6;
+
+ width: $navbar-width;
+ border-bottom: 2px solid $navbar-color;
+
+ li {
+ float: left;
+ width: $navbar-width/$navbar-items - 10px;
+
+ background-color: lighten($navbar-color, 20%);
+ &:hover {
+ background-color: lighten($navbar-color, 10%);
+ }
+ }
+}
+}}}
+
+Becomes (compiled to "standard" CSS):
+
+{{{
+#navbar {
+ width: 800px;
+ border-bottom: 2px solid #ce4dd6;
+}
+
+#navbar li {
+ float: left;
+ width: 150px;
+ background-color: #e5a0e9;
+}
+
+#navbar li:hover { background-color: #d976e0; }
+}}}
+
+
+
+h1. CSS Nested Rules
+
+{{{
+#header {
+ h1 {
+ font-size: 26px;
+ font-weight: bold;
+ }
+ p { font-size: 12px;
+ a { text-decoration: none;
+ &:hover { border-width: 1px }
+ }
+ }
+}
+}}}
+
+Becomes (compiled to "standard" CSS):
+
+{{{
+#header h1 {
+ font-size: 26px;
+ font-weight: bold;
+}
+#header p {
+ font-size: 12px;
+}
+#header p a {
+ text-decoration: none;
+}
+#header p a:hover {
+ border-width: 1px;
+}
+}}}
+
+
+h1. CSS Mixins
+
+{{{
+.slide {
+ background-image: -webkit-linear-gradient(top left, #FFFFFF 0%, #00A3EF 100%); /* Webkit (Chrome 11+) */
+ background-image: -moz-linear-gradient(top left, #FFFFFF 0%, #00A3EF 100%); /* Mozilla Firefox */
+ background-image: -ms-linear-gradient(top left, #FFFFFF 0%, #00A3EF 100%); /* IE 10+ */
+ background-image: -o-linear-gradient(top left, #FFFFFF 0%, #00A3EF 100%); /* Opera */
+ background-image: linear-gradient(top left, #FFFFFF 0%, #00A3EF 100%); /* Proposed W3C Markup */
+}
+}}}
+
+Use mixin for vendor "prefix-free" code:
+
+{{{
+.slide {
+ @include linear-gradient(top left, #FFFFFF, #00A3EF);
+}
+}}}
+
+Define mixin for reuse:
+
+{{{
+@mixin linear-gradient($pos, $start-color, $end-color) {
+ background-image: -webkit-linear-gradient($pos, $start-color 0%, $end-color 100%);
+ background-image: -moz-linear-gradient($pos, $start-color 0%, $end-color 100%);
+ background-image: -ms-linear-gradient($pos, $start-color 0%, $end-color 100%);
+ background-image: -o-linear-gradient($pos, $start-color 0%, $end-color 100%);
+ background-image: linear-gradient($pos, $start-color 0%, $end-color 100%);
+}
+}}}
+
+
+h1. Reuse - yes you can. Use pre-built Mixin libraries
+
+Bourbon includes pre-built mixins for:
+
+* Animations
+* Background Image
+* Background Size
+* Border Image
+* Border Radius
+* Box Shadow
+* Box Sizing
+* Columns
+* Flex Box
+* Inline Block
+* Linear Gradient
+* Radial Gradient
+* Transform
+* Transitions
+* And many more
+
+What is Bourbon?
+
+Bourbon is a free, open source mixin library (see "@github.com/thoughtbot/bourbon@":https://github.com/thoughtbot/bourbon).
+
+
+
+h1. Imports
+
+Use @import@ directive to include libraries or your own stylesheets. Example:
+
+{{{
+@import "bourbon"; // 3rd party css mixin library
+
+@import "settings"; // global color settings using variables
+
+@import "flash";
+@import "navbar";
+@import "button";
+@import "breadcrumb";
+
+...
+}}}
+
+
+h1. Yes, you can. CSS Programming
+
+Simple Button:
+
+{{{
+@mixin simple($base-color, $grayscale: false) {
+ $color: hsl(0, 0, 100%);
+ $border: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
+ $inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%);
+ $stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%);
+ $text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%);
+
+ @if lightness($base-color) > 70% {
+ $color: hsl(0, 0, 20%);
+ $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
+ }
+
+ @if $grayscale == true {
+ $border: grayscale($border);
+ $inset-shadow: grayscale($inset-shadow);
+ $stop-gradient: grayscale($stop-gradient);
+ $text-shadow: grayscale($text-shadow);
+ }
+
+ border: 1px solid $border;
+ @include border-radius (3px);
+ @include box-shadow (inset 0 1px 0 0 $inset-shadow);
+ color: $color;
+ display: inline-block;
+ font-size: 11px;
+ font-weight: bold;
+ @include linear-gradient ($base-color, $stop-gradient);
+ padding: 7px 18px;
+ text-decoration: none;
+ text-shadow: 0 1px 0 $text-shadow;
+ -webkit-background-clip: padding-box;
+
+ &:hover {
+ $base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
+ $inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%);
+ $stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%);
+
+ @if $grayscale == true {
+ $base-color-hover: grayscale($base-color-hover);
+ $inset-shadow-hover: grayscale($inset-shadow-hover);
+ $stop-gradient-hover: grayscale($stop-gradient-hover);
+ }
+
+ @include box-shadow (inset 0 1px 0 0 $inset-shadow-hover);
+ cursor: pointer;
+ @include linear-gradient ($base-color-hover, $stop-gradient-hover);
+ }
+
+ &:active {
+ $border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
+ $inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%);
+
+ @if $grayscale == true {
+ $border-active: grayscale($border-active);
+ $inset-shadow-active: grayscale($inset-shadow-active);
+ }
+
+ border: 1px solid $border-active;
+ @include box-shadow (inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active, 0 1px 1px 0 #eee);
+ }
+}
+}}}
+
+
+
+h1. Alternative CSS Preprocessors
+
+* Sass => "@sass-lang.com@":http://sass-lang.com
+
+* Less => "@lesscss.org@":http://lesscss.org
+
+* Stylus => "@learnboost.github.com/stylus@":http://learnboost.github.com/stylus
+
+* Others
+
+
+
+h1. Usage - Server Side and Client Side
+
+h3. Server
+
+{{{
+$ sass styles.sass styles.css
+}}}
+
+or
+
+{{{
+$ lessc styles.less > styles.css
+}}}
+
+
+h3. Browser (Client-Side)
+
+1) Link @.less@ stylesheets with the @rel@ set to @stylesheet/less@:
+
+{{{
+
+}}}
+
+2) Add @less.js@ library:
+
+{{{
+
+}}}
+
+
+
+
+
+
+
+h1. "Official" CSS3 Variables
+
+Upcoming Module for CSS3 Variables => "@dev.w3.org/csswg/css-variables@":http://dev.w3.org/csswg/css-variables
+
+Example:
+
+Define variables:
+
+{{{
+:root { var-color: blue; }
+div { var-color: green; }
+#alert { var-color: red; }
+}}}
+
+
+Use variables:
+
+{{{
+* { color: var(color); }
+}}}
+
+Includes calculations:
+
+{{{
+one { var-foo: 10px; }
+two { var-bar: calc(var(foo) + 10px); }
+three { var-foo: calc(var(bar) + 10px); }
+}}}
+
+
+
+h1. Examples in the Wild
+
+* Twitter Bootstrap (HTML/CSS/JS Templates) => "@twitter.github.com/bootstrap@":http://twitter.github.com/bootstrap
+
+See "Using LESS with Bootstrap Page":http://twitter.github.com/bootstrap/less.html
+
+
+* Wettpool
+
+See "Style Page":http://wettpool.herokuapp.com/style
+
+
+
+h1. The End - Thank You
+
+Questions? Comments?
\ No newline at end of file
diff --git a/facebook.textile b/facebook.textile
new file mode 100644
index 0000000..954bfea
--- /dev/null
+++ b/facebook.textile
@@ -0,0 +1,259 @@
+title: Why Facebook Matters - Stats, Numbers, Web OS vs. Desktop OS, News
+gradient-colors: #0e1f5b #3b5998
+
+
+h1. Facebook Profile Questions - Ice Breakers
+
+* Are you on Facebook?
+* How many apps have you installed on Facebook? Zero? Less than Five? Five+? Ten+?
+* Name your two top (recommended) Facebook apps
+* Why? Fun? Utility? Other?
+
+* Have you already developed a Facebook app? In PHP, Ruby, Java, C#.NET, Python?
+
+Sample:
+
+* No / Zero
+* Fifty+ / Pirate vs. Ninja, What Disney Princess Are You? / Fun
+* Five+ / WordPress, Twitter / Utility
+
+
+h1. What's Facebook?
+
+* Facebook is "Addictive"
+* Facebook is "So, Distracting, Companies Must Ban It"
+* Facebook is "God's Gift to Developers"
+* Facebook is "Nirvana for Direct Marketers"
+* Facebook is the first "Word of Mouse" Engine
+* Facebook is "Bloomberg Terminal for Your Life"
+* Facebook is the "Lowest Cost Customer Acquisition Vehicle on the Planet"
+
+Source: Adonomics - Why Facebook Is Worth $100 Billion
+
+
+h1. Facebook Stats
+
+* More than 70+ million active users
+* More than 200,000+ new registrations/day since January 2007
+* Users spend on average 20 minutes/day on Facebook (Source: comScore)
+* #1 photo sharing site on the Web (Source: comScore)
+* More than 14 million photos uploaded/day
+* More than 6 million active user groups
+
+Source: "Facebook Statistics":http://www.facebook.com/press/info.php?statistics
+
+
+h1. Canadian Facebook Stats
+
+More than 8+ million Facebookers (top outside the US followed by 8+ in the UK)
+
+Metros/Networks
+
+* Greater Toronto Metro, Ontario - 1,161,114 Facebookers
+* Greater Vancouver Metro, British Columbia - 703,382 Facebookers
+* Greater Montreal Metro, Quebec - 591,215 Facebookers
+* Greater Calgary Metro, Alberta - 383,558 Facebookers
+
+Canadian University Networks
+
+* University of British Columbia (UBC) - 31,595 Facebookers
+* Simon Fraser University (SFU) - 24,142 Facebookers
+* University of Victoria (UVic) - 16,416 Facebookers
+* University of Toronto (UofT) - 57,360 Facebookers
+
+Source: "Facebook Networks":http://www.facebook.com/networks/networks.php (Apr/14/2008)
+
+
+h1. Facebook vs. MySpace
+
+Facebook:
+
+* One Person - One Profile (No Multiple Personas Allowed)
+* No Fake or Anonymous Profiles Allowed
+
+MySpace (100+ Million Profiles):
+
+* One Spam King - 500,000 MySpace Profiles
+* Fake and Anonymous Profiles Allowed - William Shakespeare, Hamlet, Chair, Butter, etcetera
+
+
+
+h1. Facebook Apps
+
+* 20,000+ apps
+* 100+ new apps/day added
+* More than 95% of Facebookers installed (and used) at least one Facebook app
+
+Top Categories
+
+* Just for Fun Applications (9000+) - Top Friends, Movies, Likeness, Scrabulous, Graffiti, Vampires
+* Gaming (2400+) - Scrabulous, Texas HoldEm Poker, (fluff)Friends, PetrolHead, Oregon Trail, WarBook
+* Sports Applications (1900+) - Sport Bets, Hockey Pool, Premier League Picks, Toronto Maple Leafs Fans
+* Utility Applications (1800+) - Bumper Sticker, Advanced Wall, Cities I've Visited, Where I've Been, Books iRead
+
+More Categories
+
+Education (1600+), Dating (1500+), Music (1100+), Events (900+), Business (900+), Money (300+) and many more
+
+Source: "Facebook Application Catalog":http://www.facebook.com/apps
+
+h1. Best of the West - Top Facebook Apps Made in British Columbia
+
+# Scratch and Win (Backstage) / 449,900 / 71,984 (16%)
+# Hockey Pool (Ben Nevile) / 347,793 / 48,691 (14%)
+# Are You Normal? (Kinzin) / 572,300 / 5,723 (1%)
+# I'm Reading (Garth Shoemaker) / 61,400 / 614 (1%)
+# Hockey Pool Pro (Jason Bailey, $uper Rewards) / 20,300 / 203 (1%)
+# The Snow Report (Jeremy Holland and Dean Halford ) / 18,200 / 182 (1%)
+# Eat-A-Rama (ActiveState) / 17,800 / 30 (0%)
+# Green Gifts (Social Signal) / 7,400 / 74 (1%)
+# These Are My Kids (Kinzin) / 4,200 / 126 (3%)
+# Mixx Maker (Project Opus/Donat Group) / 1,000 / 20 (2%)
+
+Source: "Vancouver Ajax & Web 2.0 (3.0) Developer Group":http://vanajax.com
+
+"Adonomics Chart - Scratch and Win / Are You Normal? / Hockey Pool":http://adonomics.com/display/5274916578+2389617504+5173067945
+
+
+h1. Facebook Developers
+
+* More than 300,000+ Facebook Developers World Wide
+* Vancouver Facebook (& Social Network) Developers Group (200+)
+
+Facebook Developer Garage Events Around the World:
+
+San Francisco, New York, Boston, Toronto, Vancouver, London, Singapore, Sydney
+ and in many more cities (Source: Facebook Developer Garage Calendar)
+
+* "Vancouver's 1st Facebook Developer Garage":http://barcamp.org/FacebookCampVancouver2007
+* "Vancouver's 2nd Facebook Developer Garage":http://barcamp.org/FacebookCampVancouver2008
+
+
+h1. Facebook App Analytics / Stats - Adonomics Leaderboard
+
+* There are 886,320,511 installs across 21,822 apps on Facebook with over 200,000 developers currently evaluating the platform.
+* These applications were used 34,175,797 times in the last 24 hours and have a combined valuation of $428,182,197..
+
+h3. Top Facebook Applications
+
+"Adonomics Facebook Application Leaderboard":http://adonomics.com/leaderboard/apps
+
+Metrics:
+
+* Installs
+* Active Users (%)
+* Valuation (Estimated) in $$$
+
+
+h1. Graphical OS vs. Social OS
+
+Windows OS vs. Facebook OS / Desktop OS vs Web OS
+
+h3. Founders
+
+Harvard drop-out and his former roommate
+vs.
+Harvard drop-out and his former roommate
+
+h3. Initial Launch
+
+1984 vs. 2004
+
+h3. Critical Mass Achieved
+
+1995 vs. 2007
+
+h3. Competitors
+
+Digital Research's GEM, IBM's OS/2 Presentation Manager, VisiCorp's VisiON, Sun xWindows, Apple's Mac
+
+vs.
+
+MySpace, LinkedIn, Orkut, Friendster, OpenSocial
+
+
+h3. Focus
+
+* Windows SDK Ã Developers / Developers / Developers!!!
+* 80,000 employees
+* 4+ million 3rd party developers
+
+vs.
+
+* F8 Platform à Developers / Developers / Developers!!!
+* 450 employees
+* 200,000+ 3rd party developers
+
+h3. Lock-in
+
+OEM PC companies bundled Windows; Developers' apps and API knowledge; Consumer investment in apps, file system and user interface
+
+vs.
+
+Consumer investment in Profile Data, Notes, Photos, e-Mail history, Groups, Apps, and Friend Network; developers' apps and API knowledge
+
+h3. Killer Apps
+
+Word, Excel, Powerpoint, Access, Outlook, Browser
+
+vs.
+
+Photos, Events, Friends, Newsfeed, Inbox, Groups, Profile Page
+Calendar, Dining, Travel, Gifting, Shopping, Turn-based Games, Super Groups
+
+
+Source: Adonomics - Why Facebook is Worth $100 Billion
+
+
+
+h1. Web Site Registration vs. Facebook App Install
+
+h3. User Actions Required to Accomplish Registration
+
+Select Registration Button, Enter E-mail, Enter & Re-Enter Password, Enter other app related profile data
+
+vs.
+
+Select Add Application, Select Continue
+
+h3. Source of New Users
+
+Cost Per Click Advertising (typically $0.25 to $1.00 to get a visitor), Cost Per Impression Advertising, Search Engine Optimization, PR, Offline Advertising, Blogs
+
+vs.
+
+Friend Invites, Friend Newsfeeds
+
+
+h3. Site Reminders
+
+Bookmarking (<1%)
+vs.
+Profile page
+
+h3. Post Registration Marketing Methods
+
+e-mail
+
+vs.
+
+e-mail, newsfeed, profile page, friends' interactions
+
+h3. Hurdles to Re-using Site/App
+
+Remember e-mail/password
+vs.
+Find app/icon on Profile Page and Click
+
+Source: Adonomics - Why Facebook is Worth $100 Billion
+
+h1. Tracking Facebook News
+
+Facebook Blogs/News
+
+* "All Facebook Blog":http://allfacebook.com
+* "Inside Facebook Blog":http://insidefacebook.com
+
+Facebook Blogs/News in and around Vancouver, B.C.
+
+* "Vancouver Ajax & Web 2.0 (3.0) Developer Blog":http://vanajax.com
\ No newline at end of file
diff --git a/facebooker.textile b/facebooker.textile
new file mode 100644
index 0000000..6311cbb
--- /dev/null
+++ b/facebooker.textile
@@ -0,0 +1,326 @@
+title: Facebook App Development w/ Ruby on Rails
+gradient-colors: #0e1f5b #3b5998
+
+h1. Q: How can I create a Friends Badge using the Facebook API?
+
+!rfacebook-friendsbadge.png!
+
+* Step 1: Get your friends' ids (calling the @friends.get@ Facebook API using rfacebook).
+* Step 2: Get all your friends' square profile pic links (calling @users.getInfo@ asking for the @pic_square@ field).
+
+h3. "Facebook API Test Console":http://developer.facebook.com/tools.php?api - Demo
+
+
+h1. Q: How can I create a Friends Badge using the Facebook API? Continued
+
+* Step 1: Get your friends' ids (calling the @friends.get@ Facebook API using rfacebook).
+* Step 2: Get all your friends' square profile pic links (calling @users.getInfo@ asking for the @pic_square@ field).
+
+{{{
+def badge
+
+ # get your friends' ids
+ friendsIds = fbsession.friends_get.uid_list
+
+ # use your friends' ids to get square profile pic links
+ friendsInfo = fbsession.users_getInfo(
+ :uids => friendsIds,
+ :fields => ["pic_square"] )
+
+ # store all your friends profile pic links
+ @friendsPics = []
+ friendsInfo.user_list.each do |user|
+ @friendsPics << user.pic_square unless user.pic_square.blank?
+ end
+
+end
+}}}
+
+h1. Q: How can I create a Friends Badge using the Facebook API? Continued
+
+And add a matching view (web page template):
+
+{{{
+
Open Web Friends Badge Sample
+
+
+
+
+
+<% @friendsPics.each do |pic| -%>
+ <%= image_tag pic, :class => 'badge'-%>
+<% end %>
+
+
+}}}
+
+That's all.
+
+!rfacebook-friendsbadge.png!
+
+
+h1. 10-Minute Quick Start Guide for Facebooker
+
+Create a Facebook app in 7 easy steps from scratch
+displaying a Twitter-like “What are you doing?” status message.
+
+# Create a Rails application
+# Install the Facebooker Rails plugin
+# Log on to Facebook and set up a new application
+# Add your API key and secret to the @facebooker.yml@ configuration file
+# Create Rails controller (and view scaffolds)
+# Configure default route and remove public/index.html page
+# Use Facebooker to get your name, profile pic and status
+
+
+h1. Step 1: Create a Rails application
+
+Note: Facebook applications require unique names. This Quick Start Guide uses @openweb@.
+Replace @openweb@ everywhere with your own unique name.
+
+Use Rails to create your web application. Type on the command line:
+
+{{{
+$ rails openweb
+}}}
+
+h1. Step 2: Install the Facebooker Rails plugin
+
+To turn your Rails application into a Facebook application
+add the Facebooker Rails plugin. Change into your Rails folder and type on the command line:
+
+{{{
+$ cd railsadvance
+$ script/plugin install http://facebooker.rubyforge.org/svn/trunk/facebooker/
+}}}
+
+h1. Step 3: Log on to Facebook and set up a new application
+
+Log on to Facebook and set up your new application. Browse to the Facebook Developers
+page (@facebook.com/developers@) and click "Set Up New Application".
+
+Fill in the new application form:
+
+* Use "Open Web on Facebook" for your Application Name.
+* Check that you have read and agree to the terms of service.
+* Set your Callback URL to http://localhost:3000/ (note: do not forget the trailing slash /)
+* Set the Canvas Page URL to http://apps.facebook.com/openweb/
+* We build a web application using inline frames (iframe). Check (X) Use iframe and (X) Website for Application Type.
+
+!rfacebook-config2.png!
+
+That's it. Hit submit to get your API key and secret created.
+Write down your API key and secret for the next step.
+
+* API Key: @47013ae80a97cc151707961fc03bc9bf@
+* Secret: @7f296d598f9c79a5f439289e1240dc69@
+
+
+h1. Step 4: Add your API key and secret to the facebooker.yml configuration file
+
+The Facebooker plugin creates the @facebooker.yml@ configuration file during installation
+in the config folder. Open the @config/facebooker.yml@ file and add your own API key, secret
+and canvas page name:
+
+{{{
+development:
+ key: 47013ae80a97cc151707961fc03bc9bf
+ secret: 7f296d598f9c79a5f439289e1240dc69
+ canvas_page_name: /openweb/
+}}}
+
+
+h1. Step 5: Create Rails controller and (view scaffolds)
+
+Lets create a Rails controller with an index action/view. Type on the command line:
+
+{{{
+$ script/generate controller workshop index
+}}}
+
+h1. Step 7: Use Facebooker to get your name, profile pic and status
+
+Add some code to our workshop controller and views. Add a @ensure_authenticated_to_facebook@
+to the top of your workshop controller to ask Facebookers using your application to login.
+
+@app/controllers/workshop_controller.rb@:
+
+{{{
+class WorkshopController < ApplicationController
+
+ ensure_authenticated_to_facebook
+
+ def index
+ end
+
+end
+}}}
+
+
+h1. Step 7 Continued: Tap into Facebook using the API
+
+Facebooker hides all the Facebook API requests.
+To get your name, profile pic and status using the Facebook API
+just store a referene to the Facebooker user from the Facebook session
+in @user in your controller
+
+@app/controllers/workshop_controller.rb@:
+
+{{{
+def index
+ @user = session[:facebook_session].user
+end
+}}}
+
+and use @user.name, @user.pic_square and @user.status.message in your view
+
+
+@app/views/workshop/index.html.erb@:
+
+{{{
+
What are you doing?
+
+<%= image_tag @user.pic_square, :align => 'left' %>
+
+<%= @user.name %>
+<%= @user.status.message %>
+}}}
+
+
+h1. That's it - Log in to the Open Web Facebook application
+
+Start up your web server (@script/server@)
+and surf with your browser to @http://localhost:3000/@.
+If all works you will get redirected to Facebook asking you to login to your Facebook application.
+
+!rfacebook-login.png!
+
+To have your inline frame Facebook application hosted inside Facebook
+surf to @http://apps.facebook.com/openweb@ Voila!
+
+!rfaceboo-status.png!
+
+
+h1. Facebook and Ruby
+
+What's rfacebook? What's Facebooker?
+
+Open-Source Ruby libraries/gems for using the Facebook API
+
+h3. What's the difference between rfacebook and Facebooker?
+
+In a nutshell rfacebook is more or less a straight Ruby port of the Facebook PHP client libraries. Facebooker wraps the Facebook API into classes and methods with the goal of designing an API that follows the Ruby Way and is, thus, more intuitive for a typical Ruby developer to pick up and work with than a straight port from PHP.
+
+Chad Fowler - the Facebooker project lead - has a posting titled "Writing APIs to Wrap APIs" discussing the difference in design and goals of rfacebook vs. Facebooker.
+
+Paul Prescod of (Are You Normal? fame) comments: I prefer the rfacebook design because:
+
+* It makes it crystal clear exactly which methods are doing network transactions, and network transactions are really, really expensive (especially into Facebook!).
+* It is easy to read Facebook's documentation and see exactly how that applies to rfacebook. It isn't as clear for Facebooker.
+
+Source: "facebook for ruby // questions & answers / more site":http://rfacebook.wordpress.com
+
+
+h1. Facebook Application Types
+
+* Web Applications
+** Running Inside Inline Frames (iframes) using "Classic" HTML/JavaScript/CSS
+** Running Inside Facebook Canvas using FBML (Facebook Markup Language) and FBJS (Facebook JavaScript)
+
+* Desktop Applications
+
+h1. What's FBML?
+
+FBML = Facebook Markup Language
+
+{{{
+
+ true) %>">
+ Add a New Goal
+
+
+
+
+ true) %>"
+ title="All Goals" />
+
+
+<% if flash[:notice] %>
+
+ <%= flash[:notice] %>
+
+<% end %>
+}}}
+
+!showgoal.png!
+
+h1. What's FBJS? What's FQL?
+
+FBJS = Facebook JavaScript (Sandboxed JavaScript)
+
+FQL = Facebook Query Language (SQL-like Database Query Language)
+
+{{{
+SELECT name, pic FROM user WHERE uid=211031 OR uid=4801660
+}}}
+
+
+h1. Learn more about Facebook Development w/ Ruby
+
+Online Tutorials
+
+* Facebooker Tutorial on Facebook by David Clements
+* More see @rfacebook.wordpress.com@
+
+Books
+
+* Pragmatic Programmer Book (Available in Beta - PDF Download) Developing Facebook Apps
+with Rails (Facebooker) by Michael J. Mangino
+
+Getting Help
+
+* "Facebook for Ruby Forum/Mailing List":http://groups.google.com/group/rfacebook
+* "Facebooker Mailing List on RubyForge":http://rubyforge.org/mailman/listinfo/facebooker-talk
+* "Official Facebook Forum":http://forum.developers.facebook.com
+
+
+h1. What's Bebo?
+
+"Bebo":http://bebo.com is (another) social network that has licensed the Facebook API.
+Thus, Facebook widgets run on Bebo with little change.
+
+What's Beboist?
+
+Open-Source Ruby library/gem for using the Facebook API w/ Bebo
+
+
+h1. What's Lovd by Less? What's Insoshi?
+
+What's Lovd by Less?
+
+Open Source Social Network with Activity (News) Feed in Ruby on Rails.
+
+What's Insoshi
+
+Another Open Source Social Network based originally on the RailsSpace
+book and code. Now a venture funded startup.
+
+h1. That's it. Thanks.
+
+Questions? Comments?
+
+See Facebook applications live in action at today's App Nite starting at 5ish
+ including British Columbia's #1 Facebook hit Scratch and Win.
+
+The $uper Rewards folks invite you to free beer[1] at the
+Vancouver Facebook Developers Pub Nite @ Steamworks Brewery.
+
+fn1. Redeem your Hockey Pool Pro Puck Points or sign-up for Win a Free
+Wii Contest or install the Glitterati Toolbar to qualify. Just kidding ;-)
\ No newline at end of file
diff --git a/friends.textile b/friends.textile
new file mode 100644
index 0000000..1fb5b22
--- /dev/null
+++ b/friends.textile
@@ -0,0 +1,339 @@
+title: Adding Semantics to Your Web Site - RDF, RDFa, Microformats - Web 3.0 in Action
+gradient-colors: green lime
+
+h1. Adding Semantics to Your Web Site - RDF, RDFa, Microformats - Web 3.0 in Action
+
+"Gerald Bauer":http://geraldbauer.ca @ "RDF Vancouver/Semantic Web Group":http://rdfvancouver.org,
+Vancouver, B.C., November 2008
+
+
+("Source":http://slideshow.rubyforge.org/svn/samples/friends.textile)
+
+*Slide Show Keyboard Controls (Help)*
+
+| Action | Key |
+| Go to next slide | Space Bar, Right Arrow, Down Arrow, Page Down |
+| Go to previous slide | Left Arrow, Up Arrow, Page Up |
+| Toggle between slideshow and outline view (Ø) | T |
+| Show/hide slide controls (Ø « ») | C, Move mouse to bottom right corner |
+
+
+h1. Agenda
+
+* Part I: Contact Info/Business Card
+** Plain Old "Classic" Web Markup
+** Using RDF
+** Using Microformats
+** Using RDFa - RDF The Microformats Way, Sort Of
+
+* Part II: Adding Friends
+** Using RDF
+** Using Microformats
+
+
+h1. Contact Info/Business Card
+
+Example:
+
+{{{
+Gerald Bauer
+Internet Professional
+Vancouver, B.C.
+Web: GeraldBauer.ca
+Email: gerald@vanbeta.com
+}}}
+
+What?
+* Name
+* Title
+* City
+* Web Site
+* Email
+
+h1. Plain Old "Classic" Web Markup
+
+Web markup tags such as @h2@ (heading2) and @p@ (paragraph) and @br@ (break)
+are kind of meaningless (without semantics).
+
+{{{
+
Gerald Bauer
+
+
Internet Professional
+Vancouver, B.C.
+
+Web: GeraldBauer.ca
+Email: gerald@vanbeta.com
+
+}}}
+
+
+
Gerald Bauer
+
Internet Professional
+Vancouver, B.C.
+Web: GeraldBauer.ca
+Email: gerald@vanbeta.com
+
+
+
+h1. Semantic Web - Web 3.0
+
+Semantic Web - add semantics to your web page by marking up events, people, locations, resumes, listings, feeds and much more.
+
+How? The "official" semantic web led by Tim Berners-Lee (the inventor of the "classic" web)
+proposes new extension to web markup such as Resource Description Framework(RDF) or eXtensible Markup Language (XML)
+
+The "pragmatic" semantic web led by the Microformats initiative proposes - let's just use conventions and best practices for today's web markup and today's browsers.
+
+
+h1. Using RDF (Resouce Description Framework) plus Friend of a Friend (FOAF) Vocabulary
+
+@gerald.rdf@:
+
+{{{
+
+
+ Gerald Bauer
+ Internet Professional
+ Vancouver, B.C.
+
+
+
+
+}}}
+
+Add to your web page header:
+
+{{{
+
+}}}
+
+What's different?
+
+* Machine-Readable Only
+* Requires Namespaces
+* Standalone Document (Web Feed-like)
+
+
+
+h1. FOAF Tools - FOAF-a-matic, FOAF Explorer
+
+FOAF-a-matic:
+
+Fill out a form to create your FOAF file using "FOAF-a-matic":http://www.ldodds.com/foaf/foaf-a-matic.html
+
+FOAF Explorer:
+
+Browse and explore FOAF data displayed as web pages using "FOAF Explorer":http://xml.mfd-consult.dk/foaf/explorer
+
+
+
+h1. Using Microformats and hCard
+
+Plain Old "Classic" Web Markup:
+
+{{{
+
Gerald Bauer
+
+
Internet Professional
+Vancouver, B.C.
+
+Web: GeraldBauer.ca
+Email: gerald@vanbeta.com
+
+}}}
+
+Adding Semantics Using Microformats:
+
+{{{
+
+
Gerald Bauer
+
+ Internet Professional
+
+ Vancouver,
+ B.C.
+
+
+ Web: GeraldBauer.ca
+ Email: gerald@vanbeta.com
+
+
+}}}
+
+
+
Gerald Bauer
+
+ Internet Professional
+
+ Vancouver,
+ B.C.
+
+
+ Email: gerald@vanbeta.com
+ Web: GeraldBauer.ca
+
+
+
+h1. Using Microformats and hCard Continued
+
+What's different?
+
+* Human-Readable First, Machine-Readable Second
+* No Namespaces Required
+* Semantics Added to Web Page
+* (Builts on vCard Internet Standard)
+
+vs. Using RDF (Resouce Description Framework) plus Friend of a Friend (FOAF) Vocabulary
+
+* Machine-Readable Only
+* Requires Namespaces
+* Standalone Document (Web Feed-like)
+
+h1. Microformats Tools - hCard-o-matic, Operator
+
+hCard-o-matic:
+
+Fill out a form to create your hCard markup using "hCard-o-matic":http://microformats.org/code/hcard/creator
+
+Operator:
+
+Free, open source browser addon lets you add hCards to Yahoo address book or
+export hCards as vCards and much more - "Install Operator Firefox Browser Addon":https://addons.mozilla.org/en-US/firefox/addon/4106
+
+h1. Using RDFa - RDF The Microformats Way, Sort Of
+
+Classic RDF - @gerald.rdf@:
+
+{{{
+
+
+ Gerald Bauer
+ Internet Professional
+ Vancouver, B.C.
+
+
+
+
+}}}
+
+RDFa Version:
+
+{{{
+
+...
+
+
Gerald Bauer
+
+ Internet Professional
+ Vancouver, B.C.
+
+ Email: gerald@vanbeta.com
+ Web: GeraldBauer.ca
+
+
+}}}
+
+
+h1. Using RDFa - RDF The Microformats Way
+
+What's different (vs. Microformats)?
+
+* Namespace required
+* New web markup extensions required (@typeof@, @property@)
+
+RDFa Version:
+
+{{{
+
+...
+
+
Gerald Bauer
+
+ Internet Professional
+ Vancouver, B.C.
+
+ Email: gerald@vanbeta.com
+ Web: GeraldBauer.ca
+
+
+}}}
+
+Microformats Version:
+
+{{{
+
+
Gerald Bauer
+
+ Internet Professional
+
+ Vancouver,
+ B.C.
+
+
+ Web: GeraldBauer.ca
+ Email: gerald@vanbeta.com
+
+
+}}}
+
+
+h1. Using RDF (Resouce Description Framework) plus Friend of a Friend (FOAF) Vocabulary
+
+Adding Friends
+
+@jim.rdf@:
+
+{{{
+
+ Jim Pick
+ Freelance Software Developer
+
+
+}}}
+
+Use unique identifier (such as @mbox@, @mbox_sha1sum@, @weblog@)
+plus @seeAlso@ with link to FOAF file.
+
+@gerald.rdf@:
+
+{{{
+
+ Gerald Bauer
+
+
+
+
+
+
+
+
+}}}
+
+
+
+h1. Using Microformats and XFN (XHTML Friends Network)
+
+Just add a link with a relationship (@rel@) value of @contact@ from your site to your friends site.
+Sample:
+
+{{{
+Jim Pick
+}}}
+
+
+h1. Links - Learn More
+
+* FOAF (Friend of a Friend) - "foaf-project.org":http://foaf-project.org
+* Microformats - "microformats.org":http://microformats.org
+* RDF Vancouver - "rdfvancouver.org":http://rdfvancouver.org
+
+h1. That's it - Thanks
+
+Questions? Comments?
+
+Send them along to the "Vancouver Ajax & Web 3.0 Developer Forum/Mailing List":http://forum.vanajax.com.
+Thanks!
+
+
diff --git a/groovy.textile b/groovy.textile
new file mode 100644
index 0000000..85e8385
--- /dev/null
+++ b/groovy.textile
@@ -0,0 +1,1123 @@
+%%%%%%%
+% Slide Show Headers
+
+title: Groovy - Java for the 21st Century - Do More With Less (Code)
+gradient-colors: blue aqua
+
+%%%%%%%%%%%%%
+% Slides Start Here
+
+h1. What is Groovy?
+
+Groovy is a *dynamic object-oriented (scripting) language* that combines the best from Smalltalk, Python and Ruby
+in an all-in-one package using a *Java-like syntax*. Groovy is *100 % Java* and compiles scripts
+straight to Java bytecode that *run on any Java virtual machine*.
+Groovy offers seamless and smooth Java integration: from Groovy you can *access all Java libraries*,
+you can build applets or Java beans, you can derive from Java classes in Groovy and vice versa.
+
+* Groovy is the Next Generation Java
+* Groovy is Java for the 21st Century
+
+
+
+h1. First Impression - Servus Groovy Example
+
+Groovy
+
+{{{
+$ groovy -e "print 'Servus Groovy'"
+
+=> Servus Groovy
+}}}
+
+Java (@ServusGroovy.java@):
+
+{{{
+public class ServusGroovy
+{
+ public static void main( String args[] )
+ {
+ System.out.println( "Servus Groovy" );
+ }
+}
+}}}
+
+{{{
+$ javac ServusGroovy.java
+$ java ServusGroovy
+
+=> Servus Groovy
+}}}
+
+
+
+
+h1. Second Impression - Higher-Level Functions, Loops and Data Types
+
+Groovy (@HelloWorld.groovy@):
+
+{{{
+ 1. def country = [ "Canada", "Austria", "Brazil" ]
+ 2.
+ 3. country.sort()
+ 4.
+ 6. country.each { it -> println "Hello ${it}" }
+}}}
+
+{{{
+$ groovy HelloWorld.groovy
+
+=> Hello Austria
+=> Hello Brazil
+=> Hello Canada
+}}}
+
+or
+
+{{{
+$ groovyc HelloWorld.groovy
+$ java HelloWorld
+}}}
+
+
+Java (@HelloWorld.java@):
+
+{{{
+ 1. import java.util.*;
+ 2.
+ 3. public class HelloWorld
+ 4. {
+ 5. public static void main( String args[] )
+ 6. {
+ 7. List country = new ArrayList();
+ 8. country.add( "Canada" );
+ 9. country.add( "Austria" );
+10. country.add( "Brazil" );
+11.
+12. Collections.sort( country );
+13.
+14. for( Iterator it = country.iterator(); it.hasNext(); )
+15. System.out.println( "Hello " + it.next() );
+16. }
+17. }
+}}}
+
+
+h1. Third Impression - Groovy Beans vs Java Beans
+
+Groovy
+
+{{{
+ 1. class Country
+ 2. {
+ 3. String name
+ 4. String capital
+ 5. }
+ 6.
+ 7. def world = [new Country(name:"Austria", capital:"Vienna"),
+ 8 new Country(name:"Canada", capital:"Ottawa")]
+ 9.
+10. world.each { country -> println "The capital of ${country.name} is ${country.capital}." }
+}}}
+
+
+Java
+
+{{{
+ 1. import java.util.*;
+ 2.
+ 3. public class Country
+ 4. {
+ 5. private String name;
+ 6. private String capital;
+ 7.
+ 8. public String getName() { return name; }
+ 9. public String getCapital() { return capital; }
+10.
+11. public void setName( String name ) { this.name = name; }
+12. public void setCapital( String capital ) { this.capital = capital; }
+13.
+14. public static void main( String args[] )
+15. {
+16. Country austria = new Country();
+17. austria.setName( "Austria" );
+18. austria.setCapital( "Vienna" );
+19.
+20. Country canada = new Country();
+21. canada.setName( "Canada" );
+22. canada.setCapital( "Ottawa" );
+23.
+24. List world = new ArrayList();
+25. world.add( austria );
+26. world.add( canada );
+27.
+28. for( Iterator it = world.iterator(); it.hasNext(); )
+29. {
+30. Country country = (Country) it.next();
+31. System.out.println( "The capital of " + country.getName() + " is " + country.getCapital() + "." );
+32. }
+33. }
+34. }
+}}}
+
+
+h1. Why Groovy? What's wrong with Ruby (JRuby), Python (Jython), or Smalltalk (Bistro)?
+
+
+Why yet another scripting language?
+
+# Groovy uses a Java-like syntax; easy to switch from Java to Groovy or from Groovy to Java
+# Groovy builds on (reuses) the Java standard class library; Ruby, Python or Smalltalk include their own batteries (that is, standard libraries)
+# Groovy compiles straight to standard Java bytecode; you can use @groovyc@ as an alternative compiler to @javac@
+
+What is Java?
+
+# Java is a (systems) programming language (syntax).
+# Java is a "standard" class library.
+# Java is a bytecode runtime (virtual machine).
+
+=> Groovy is Java
+
+
+h1. Application vs. Systems (Hard-Core) Programming / Groovy vs. Java
+
+Groovy does *not* replace Java. Groovy complements Java and doesn't compete head-on. Groovy is a
+ dynamic (scripting) language for application development.
+Java is a programming language for (hard-core) systems development.
+
+* *No compilation* (Fast Build-Cycle Turnaround)
+* *Dynamic Typing* (No Need to Declare Variables For Use)
+* *Easy Syntax* (Higher Level Datatypes, Functions and Loops, Semicolons and Return Optional, and more)
+* *Embedabble* (Scripting Power for Your Apps)
+* *Interactive* (Create, View, Change Objects At Run-Time)
+
+* *50 % less code*
+* *2 to 3 times higher productivity (that is, less development time)*
+
+
+
+h1. Groovy is Java
+
+Groovy Standard Class Library Types == Java Standard Class Library Types
+
+* A Groovy String is a Java String
+
+{{{
+$ hello = "Hello"
+$ hello.class
+
+=> java.lang.String
+}}}
+
+* A Groovy List is a Java List
+
+{{{
+$ list = [ "Vancouver", "Ottawa" ]
+$ list.class
+
+=> java.util.ArrayList
+}}}
+
+* A Groovy Map is a Java Map
+
+{{{
+$ map = [ "Vancouver":"British Columbia", "Ottawa":"Ontario" ]
+$ map.getClass()
+
+=> java.util.LinkedHashMap
+}}}
+
+* A Groovy Regex is a Java Regex
+
+{{{
+$ regex = ~/[a-zA-Z_0-9]+/
+$ regex.class
+
+=> java.util.regex.Pattern
+}}}
+
+
+h1. Groovy is Java Continued: Annotations
+
+{{{
+@Entity
+@Name("hotel")
+class Hotel implements Serializable
+{
+ @Id @GeneratedValue
+ Long id
+
+ @Length(max=50) @NotNull
+ String name
+
+ @Length(max=100) @NotNull
+ String address
+
+ @Length(max=40) @NotNull
+ String city
+
+ @Length(min=2, max=10) @NotNull
+ String state
+
+ @Length(min=4, max=6) @NotNull
+ String zip
+
+ @Length(min=2, max=40) @NotNull
+ String country
+
+ @Column(precision=6, scale=2)
+ BigDecimal price
+
+ @Override
+ String toString() {
+ return "Hotel(${name}, ${address}, ${city}, ${zip})"
+ }
+}
+}}}
+
+(Source: "What's New in Groovy 1.5":http://www.infoq.com/articles/groovy-1.5-new)
+
+h1. Groovy is Java Continued: Enums, Static Imports, Generics
+
+{{{
+class Talk {
+ String title
+}
+
+class Speaker {
+ String name
+ List talks = []
+}
+
+def me = new Speaker(
+ name: 'Guillaume Laforge',
+ talks: [
+ new Talk(title: 'Groovy'),
+ new Talk(title: 'Grails')
+ ])
+
+def talksField = me.class.getDeclaredField('talks')
+assert talksField.genericType.toString() == 'java.util.List'
+}}}
+
+(Source: "What's New in Groovy 1.5":http://www.infoq.com/articles/groovy-1.5-new)
+
+h1. Groovy Joint Compiler
+
+Compiles Groovy and Java code; can handle any dependency cycles
+
+Use the @-j@ compiler switch to enable the joint compilation. Example:
+
+Country.groovy:
+
+{{{
+class Country
+{
+ String name
+ String capital
+
+ String toString() { return "The capital of ${name} is ${capital}." }
+}
+}}}
+
+World.java:
+
+{{{
+public class World
+{
+ public static void main( String args[] )
+ {
+ Country canada = new Country();
+
+ canada.setName( "Canada" );
+ canada.setCapital( "Ottawa" );
+
+ System.out.println( canada.toString() );
+ }
+}
+}}}
+
+Let's joint compile the Groovy and Java source.
+
+{{{
+$ groovyc -j Country.groovy World.java
+}}}
+
+That's it. Run it.
+
+{{{
+$ java World
+
+=> The capital of Canada is Ottawa.
+}}}
+
+Voila.
+
+h1. Groovy Goodies Missing In Java
+
+
+* built-in syntax for lists, maps, regex and ranges (e.g (@1..1000@)) (=higher level data types)
+* built-in syntax for markup (XML)
+* higher-level functions and loops (=closures/code blocks)
+* built-in Velocity-style/XPath-style expression for Java bean acess (e.g. @${movie.director.name}@)
+* many new helper methods added to core Java classes (e.g. @any@, @each@, @findAll@, @print@ and more)
+* operator overloading (e.g. @[1,2,3]+[3,4,5]@, @map['one']@)
+* everything is an object (e.g. no need for boxing and unboxing)
+* metaprogamming (MOP - Meta Object Protocol e.g. @method_missing@) (="easy" on-the-fly code generation)
+* and much more!
+
+h1. Groovy Lists: Built-In Syntax for Lists
+
+Groovy
+
+{{{
+list = [1, 2, 3]
+}}}
+
+Java
+
+{{{
+List list = new LinkedList();
+list.add( new Integer( 1 ) );
+list.add( new Integer( 2 ) );
+list.add( new Integer( 3 ) );
+}}}
+
+
+h1. Groovy Maps: Built-In Syntax for Maps
+
+Groovy
+
+{{{
+map = [ 'one' : 1, 'two' : 2, 'three': 3 ]
+print map[ 'one' ]
+print map.one // works too
+}}}
+
+Java
+
+{{{
+Map map = new HashMap();
+map.put( "one", new Integer( 1 ) );
+map.put( "two", new Integer( 2 ) );
+map.put( "three", new Integer( 3 ) );
+
+System.out.println( map.get( "one" ) );
+}}}
+
+
+h1. More Groovy List and Map Examples
+
+Empty List
+
+{{{
+list = []
+}}}
+
+Empty Map
+
+{{{
+map = [:]
+}}}
+
+Nested Lists
+
+{{{
+list = [1, 2, [4, 5], 'hello']
+}}}
+
+Negative (Reverse) Index
+
+{{{
+last = list[-1]
+}}}
+
+Ranges
+
+{{{
+list = 1..100
+sub = list[1..20]
+sub = list[-5..-1]
+sub = list[1,5..10,15]
+}}}
+
+Operator Overloading
+
+{{{
+[1,2,3] + [4,5,6] // returns [1,2,3,4,5,6]
+[1,2,3,4] - [2,4,6] // returns [1,3]
+map[ 'one' ]
+}}}
+
+Many Helper Methods
+
+{{{
+[1,2,3,1,2,3].count(3) // return 2
+['one', 'two', 'three'].join( '+' )
+[3,2,1].sort()
+}}}
+
+
+h1. Groovy Loops: Higher-Level Loops Using Closures (Code Blocks)
+
+Java
+
+{{{
+for( int i=1; i<=1000; i++ )
+ System.out.println( "The lucky number is" + i + "today" );
+}}}
+
+Groovy
+
+each
+
+{{{
+(1..1000).each { i -> println "The lucky number is ${i} today" }
+}}}
+
+or
+
+{{{
+(1..1000).each { println "The lucky number is ${it} today" }
+}}}
+
+upto
+
+{{{
+1.upto(1000) { println "The lucky number is ${it} today" }
+}}}
+
+step
+
+{{{
+1.step(1001,1) { println "The lucky number is ${it} today" }
+}}}
+
+times
+
+{{{
+1000.times { println "Groovy rocks big time!" }
+}}}
+
+
+h1. What is a Closure (Code Block/Anonymous Function)?
+
+Closures are a powerful way of passing around blocks of executable code (code blocks/functions).
+Think of a closure as an anonymous inner method/function that can accept parameters.
+
+{{{
+{ x -> println x } // closure with parameter x
+{ println it } // closure with default parameter it
+{ x, y -> x > y } // closure with parameter x, y
+{ println "Hello" } // closure without parameters
+
+squared_closure = { x -> x * x } // store closure in a variable
+
+squared_closure.call( 2 ) // call closure like a method; returns 4
+squared_closure( 2 ) // v2.0: call closure like a method
+}}}
+
+Functions (Closures/Code Blocks) as First-Class Citizens:
+
+* Store functions in variables
+* Pass functions to functions as arguments
+* Call functions stored in variables (or passed in as arguments)
+
+
+
+h1. Closures In Action: Groovy Collections vs. Plain Old Java Collections
+
+Groovy
+
+{{{
+ 1. def names = ["Ted", "Fred", "Jed", "Ned"]
+ 2. println names
+ 3.
+ 4. def shortNames = names.findAll { it.size() <= 3 }
+ 5. println shortNames.size()
+ 6. shortNames.each { println it }
+}}}
+
+Java
+
+{{{
+ 1. import java.util.*;
+ 2.
+ 3. public class Erase {
+ 4. public static void main(String[] args) {
+ 5. List names = new ArrayList();
+ 6. names.add("Ted");
+ 7. names.add("Fred");
+ 8. names.add("Jed");
+ 9. names.add("Ned");
+ 10. System.out.println(names);
+ 11. Erase e = new Erase();
+ 12. List shortNames = e.filterLongerThan(names, 3);
+ 13. System.out.println (shortNames.size());
+ 14. for (Iterator i = shortNames.iterator(); i.hasNext(); ) {
+ 15. String s = (String) i.next();
+ 16. System.out.println(s);
+ 17. }
+ 18. }
+ 19.
+ 20. public List filterLongerThan (List strings, int length) {
+ 21. List result = new ArrayList();
+ 22. for (Iterator i = strings.iterator(); i.hasNext(); ) {
+ 23. String s = (String) i.next();
+ 24. if (s.length() < length+1) {
+ 25. result.add(s);
+ 26. }
+ 27. }
+ 28. return result;
+ 29. }
+ 30. }
+}}}
+
+Java Refactored
+
+{{{
+ 1. import static java.lang.System.out;
+ 2. import static java.util.Arrays.asList;
+ 3. import java.util.ArrayList;
+ 4. import java.util.List;
+ 5. import org.apache.commons.collections.CollectionUtils;
+ 6. import org.apache.commons.collections.Predicate;
+ 7.
+ 8. public class ListTests {
+ 9. public static void main( String[] args ) {
+ 10. List names = asList( "Ted", "Fred", "Jed", "Ned" );
+ 11. out.println( names );
+ 12. List shortNames = new ArrayList();
+ 13. shortNames.addAll( names );
+ 14. CollectionUtils.filter( shortNames, new Predicate(){
+ 15. public boolean evaluate( Object input ) {
+ 16. return ((String) input).length() < 4;
+ 17. }
+ 18. } );
+ 19. out.println( shortNames.size() );
+ 20. for( String s : shortNames )
+ 21. out.println( s );
+ 22. }
+ 23. }
+}}}
+
+(Source: "From Java to Groovy, Part 2: Closures and Built-In Syntax For Lists":http://groovy.dzone.com/news/java-groovy-part-2-closures-an)
+
+
+h1. Higher-Level Loops and Functions For Maps And Lists
+
+each
+
+{{{
+[5, 9, 1, 6].each { println it }
+}}}
+
+find
+
+{{{
+[5, 9, 1, 6].find { x -> x > 5 } // returns 9
+}}}
+
+findAll
+
+{{{
+[5, 9, 1, 6].findAll { x -> x > 5 } // returns [9, 6]
+}}}
+
+map
+
+{{{
+[5, 9, 1, 6].map { x -> x * 2 } // returns [10, 18, 2, 12]
+}}}
+
+min / max
+
+{{{
+[5, 9, 1, 6].min() // returns 1
+[5, 9, 1, 6].max() // returns 9
+}}}
+
+reverse
+
+{{{
+[1,2,3].reverse() // returns [3,2,1]
+}}}
+
+
+h1. Groovy JDK - Groovy Adds New Methods To Core Java Classes
+
+Groovy adds new methods to the core Java classes to help productivity and polymorphism
+e.g. new closure methods: @each@, @select@, @filter@, @collect@
+
+h3. java.util.Collection
+
+| int | *count*(java.lang.Object value) |
+| void | *each*(groovy.lang.Closure closure) |
+| java.lang.Object | *find*(groovy.lang.Closure closure) |
+| java.util.List | *findAll*(groovy.lang.Closure closure) |
+| java.util.List | *getAt*(java.lang.String property) |
+| java.lang.String | *join*(java.lang.String separator) |
+| java.util.List | *map*(groovy.lang.Closure closure) |
+| java.lang.Object | *max*(java.util.Collection self) |
+| java.lang.Object | *max*(java.util.Comparator comparator) |
+| java.lang.Object | *max*(groovy.lang.Closure closure) |
+| java.lang.Object | *min*(java.util.Collection self) |
+| java.lang.Object | *min*(java.util.Comparator comparator) |
+| java.lang.Object | *min*(groovy.lang.Closure closure) |
+| java.util.List | *plus*(java.util.Collection right) |
+| java.util.List | *plus*(java.lang.Object right) |
+
+and many more
+
+h3. java.io.File
+
+| void | *eachByte*(groovy.lang.Closure closure) |
+| void | *eachFile*(groovy.lang.Closure closure) |
+| void | *eachLine*(groovy.lang.Closure closure) |
+| void | *splitEachLine*(java.lang.String sep, groovy.lang.Closure closure) |
+| void | *withOutputStream*(groovy.lang.Closure closure) |
+| void | *withPrintWriter*(groovy.lang.Closure closure) |
+| void | *withReader*(groovy.lang.Closure closure) |
+| void | *withWriter*(groovy.lang.Closure closure) |
+
+and many more
+
+h3. java.lang.Number
+
+| java.lang.Number | *minus*(java.lang.Number right) |
+| java.lang.Number | *multiply*(java.lang.Number right) |
+| java.lang.Number | *plus*(java.lang.Number right) |
+| java.lang.Number | *power*(java.lang.Number exponent) |
+| void | *step*(java.lang.Number to, java.lang.Number stepNumber, groovy.lang.Closure closure) |
+| void | *times*(groovy.lang.Closure closure) |
+| void | *upto*(java.lang.Number to, groovy.lang.Closure closure) |
+
+and many more
+
+h3. java.lang.Object
+
+| boolean | *any*(groovy.lang.Closure closure) |
+| void | *each*(groovy.lang.Closure closure) |
+| boolean | *every*(groovy.lang.Closure closure) |
+| java.lang.Object | *find*(groovy.lang.Closure closure) |
+| java.lang.Object | *findAll*(groovy.lang.Closure closure) |
+| java.lang.Object | *invokeMethod*(java.lang.String method, java.lang.Object arguments) |
+| java.util.List | *map*(groovy.lang.Closure closure) |
+| void | *print*(java.lang.Object value) |
+
+and many more
+
+(Source: "Groovy Class Library Reference (Groovy JDK)":http://groovy.codehaus.org/groovy-jdk/)
+
+
+h1. Groovy Template Strings: Expressions In Strings
+
+You can put Groovy expressions (including method calls) inside strings using the @${expression}@ syntax
+similar to Velocity or JSTL-EL.
+
+Groovy
+
+{{{
+movie = "Lost in Translation"
+director = "Sofia Coppola"
+
+println "${director} directed the movie ${movie}."
+}}}
+
+Java Flashback
+
+{{{
+String movie = "Lost in Translation";
+String director = "Sofia Coppola";
+
+System.out.println( director + " directed the movie " + movie + "." );
+}}}
+
+Groovy
+
+{{{
+num = 4
+
+println "${num} squared equals ${num*num}"
+
+class Movie
+{
+ String title
+ Person director
+}
+
+class Person
+{
+ String name
+}
+
+person = new Person( name:'Sofia Coppola' )
+movie = new Movie( title:'Lost in Translation', director:person )
+
+println "${movie.director.name} directed the movie ${movie.title}"
+
+// ${movie.director.name} is the same as movie.getDirector().getName() in Java
+}}}
+
+
+
+h1. Groovy Strings: Multi-Line/Here-Doc Strings And More
+
+In Groovy you can start and end strings with single or double quotes
+and use the other kind of quote without escaping inside the string. Example:
+
+{{{
+println "Alice says, 'Groovy rocks.'"
+println 'Alice says, "Groovy rocks."'
+}}}
+
+Multi-Line Strings/Here-Doc Strings
+
+In Groovy you can create multi-line strings
+using the triple quote (@"""@ or @'''@) syntax that
+lets you paste blocks of text into your source without any need for quotes.
+Example:
+
+{{{
+out = """
+
+
+ Groovy Servlet
+
+
+ Hello, ${request.remoteHost}: ${session.counter}! ${new Date()}
+
+
+"""
+}}}
+
+
+h1. Groovy Path Expression Language
+
+To avoid the risk of @NullPointerException@ when walking object hierachies
+you can use the "@?.@"operator instead of "@.@".
+
+{{{
+class Movie
+{
+ String title; Person director
+}
+
+class Person
+{
+ String name
+}
+
+movie = new Movie( title:'Leaving Las Vegas' )
+
+// Doesn't throw NullPointerException
+println "${movie.director?.name} directed the movie ${movie.title}"
+
+// Throws NullPointerException
+println "${movie.director.name} directed the movie ${movie.title}"
+}}}
+
+Not for Groovy strings only. You can use the Groovy path expression language (including closures) everywhere. Example:
+
+{{{
+if( customers.orders.any { it.amount > 1000 && it.product.type == "citrus" } )
+{
+ doSomething()
+}
+}}}
+
+or
+
+{{{
+for( order in customers.findAll { it.country.code == "AT" }.orders )
+{
+ println "order ${order.id} has value ${order.value}"
+}
+}}}
+
+h1. Groovy Markup (XML) Syntax
+
+Alternative XML syntax similar to Groovy map and list syntax but for trees of anything. Example:
+
+{{{
+import groovy.xml.MarkupBuilder;
+
+xml = new MarkupBuilder()
+
+xml.xul() {
+ menubar( id:"main" ) {
+ menu( label:"Bookmarks" ) {
+ menuitem( label:"Vancouver Groovy/Grails User Group", link:"http://groovyvan.com" )
+ menuitem( label:"Gerald Bauer's Blog", link:"http://geraldbauer.wordpress.com" )
+ menuitem( label:"Gerald Bauer's Tumblelog", link:"http://geraldbauer.tumblr.com" )
+ menuitem( label:"Slide Show (S9)", link:"http://slideshow.rubyforge.org" )
+ }
+ }
+}
+
+println xml
+}}}
+
+generates the following XML markup:
+
+{{{
+
+
+
+
+
+}}}
+
+Note that you can mix and match Groovy markup with Groovy script
+(e.g. loops, method calls, variables, expressions, conditionals and so on).
+
+h1. Groovy SQL
+
+
+Groovy Script using Groovy SQL and Groovy Markup
+
+{{{
+import groovy.xml.MarkupBuilder;
+import groovy.sql.Sql
+import java.sql.DriverManager
+
+Class.forName( "org.hsqldb.jdbcDriver" )
+con = DriverManager.getConnection( "jdbc:hsqldb:.", "sa", "" )
+sql = new Sql( con )
+
+xml = new MarkupBuilder()
+xml.xul() {
+ menubar( id:'main' ) {
+ menu( label:'Bookmarks' )
+
+ sql.queryEach( 'select title, link from bookmark' ) { row ->
+ menuitem( label:"${row.title}", link:"${row.link}" )
+ }
+ }
+}
+
+println xml
+}}}
+
+Output
+
+{{{
+
+
+
+
+
+}}}
+
+h1. Scripting Ant Using Groovy Markup (Gant)
+
+Using Gant you can use Ant tasks and mix and match markup with scripts
+(e.g. you can pass on variables to Ant tasks and use Groovy code anywhere within the markup).
+
+{{{
+sourceDirectory = 'source'
+buildDirectory = 'build'
+includeTargets << gant.targets.Clean
+cleanPattern << '**/*~'
+cleanDirectory << buildDirectory
+Ant.taskdef ( name : 'groovyc' , classname : 'org.codehaus.groovy.ant.Groovyc' )
+target ( compile : 'Compile source to build directory.' ) {
+ javac ( srcdir : sourceDirectory , destdir : buildDirectory , debug : 'on' )
+ groovyc ( srcdir : sourceDirectory , destdir : buildDirectory )
+}
+}}}
+
+(Source: "Gant Project Site":http://gant.codehaus.org)
+
+
+h1. Building Swing Desktop Apps Using Groovy Markup
+
+Groovy snippet:
+
+{{{
+ 1. swing = new SwingBuilder()
+ 2.
+ 3. frame = swing.frame( title:'Counter', size:[200,100]) {
+ 4. panel(layout:new FlowLayout() ) {
+ 5. display = textField( preferredSize:[200,30], horizontalAlignment:SwingConstants.CENTER )
+ 6. button( text:"Inc", size:[65,70], actionPerformed:{ value++; setDisplay() } )
+ 7. button( text:"Clear", size:[65,70], actionPerformed:{ value=0; setDisplay() } )
+ 8. button( text:"Dec", size:[65,70], actionPerformed:{ value--; setDisplay() } )
+ 9. }
+10. }
+}}}
+
+Java edition:
+
+{{{
+ 1. frame = new JFrame( "Counter" );
+ 2. frame.getContentPane().setLayout( new FlowLayout() );
+ 3. frame.setSize( 200, 100 );
+ 4.
+ 5. display = new JTextField();
+ 6. display.setPreferredSize( new Dimension( 200, 300 );
+ 7. display.setHorizontalAlignment( SwingConstants.CENTER );
+ 8. frame.getContentPane().add( display );
+ 9.
+10. increment = new JButton( "Inc" );
+11. increment.setSize( 65, 70 );
+12. increment.addActionListener( new ActionListener() {
+13. public void actionPerformed( ActionEvent ev )
+14. {
+15. onIncrement();
+16. }
+17. } );
+18. frame.getContentPane().add( increment );
+19.
+20. clear = new JButton( "Clear" );
+21. clear.setSize( 65, 70 );
+22. clear.addActionListener( new ActionListener() {
+23. public void actionPerformed( ActionEvent ev )
+24. {
+25. onClear();
+26. }
+27. } );
+28. frame.getContentPane().add( clear );
+29.
+30. decrement = new JButton( "Dec" );
+31. decrement.setSize( 65, 70 );
+32. decrement.addActionListener( new ActionListener() {
+33. public void actionPerformed( ActionEvent ev )
+34. {
+35. onDecrement();
+36. }
+37. } );
+38. frame.getContentPane().add( decrement );
+}}}
+
+
+h1. Groovy in Action
+
+From Industry Giants...
+
+* "IBM Project Zero":http://projectzero.org (WebSphere for the 21st Century/The Next Generation WebSphere)
+* "SAP NetWeaver - Composition On Grails":https://wiki.sdn.sap.com/wiki/display/Community/Composition+on+Grails
+
+...to Let's Build a Blog in 5 Minutes
+
+* "GroovyBlogs.org":http://code.google.com/p/groovyblogs/ - Open Source Groovy Powered Collective Blog Engine by Glen Smith
+* "Gravl":http://code.google.com/p/gravl - Open Source Groovy Powered Blog Engine by Glen Smith
+
+
+
+h1. Groovy Heroes - G2One Inc. - The Groovy/Grails Startup
+
+G2One Inc. - "G2One.com":http://g2one.com
+
+Founders include:
+
+* Guillaume Laforge (Groovy Project Lead)
+* Graeme Rocher (Grails Project Lead)
+
+Similar to Sun (Java), SpringSource (Spring), RedHat (JBoss), IBM (Eclipse), etcetera
+
+
+
+h1. Groovy/Grails in Print - Books
+
+* *The Definitive Guide to Grails* (Apress) by Graeme Rocher (384 pages, ISBN: 1-59059-758-3), December 2006
+* *Groovy in Action* (Manning) by Dierk Koenig with Andrew Glover, Paul King, Guillaume Laforge and Jon Skeet (696 pages, ISBN: 1-932394-84-2), January 2007
+* *Groovy Recipes*: Greasing the Wheels of Java (Pragmatic Bookshelf) by Scott Davis (264 pages,
+ISBN: 978-0-9787392-9-4), February 2008
+* *Programming Groovy*: Dynamic Productivity for the Java Developer (Pragmatic Bookshelf) by Venkat Subramaniam (200 pages, ISBN: 978-1-9343560-9-8), March 2008
+
+Upcoming
+
+* *Practical Grails Projects* (Apress) by Christopher M. Judd , Joseph Faisal Nusairat, Jim Shingler (350 pages, ISBN: 1-59059-974-8)
+* *The Definite Guide to Grails*, 2nd Edition (Apress) by Graeme Rocher, Scott Davis (600 pages, ISBN: 1-59059-995-0)
+
+
+h1. Groovy/Grails Articles & Blogs
+
+* IBM DeveloperWorks Series: Mastering Grails by Scott David
+** "Build your first Grails application":http://www.ibm.com/developerworks/java/library/j-grails01158
+** "GORM: Funny name, serious technology":http://www.ibm.com/developerworks/web/library/j-grails02128 - Understanding databases and Grails
+
+* IBM DeveloperWorks Series: Practically Groovy by Andrew Glover
+** "Mark it up with Groovy Builders":http://www.ibm.com/developerworks/java/library/j-pg04125
+** "Reduce code noise with Groovy":http://www.ibm.com/developerworks/java/library/j-pg09196.html
+** "JDBC programming with Groovy":http://www.ibm.com/developerworks/java/library/j-pg01115.html
+** "Unit test your Java code faster with Groovy":http://www.ibm.com/developerworks/java/library/j-pg11094
+
+* "Groovy Dzone":http://groovy.dzone.com
+** "From Java to Groovy in a Few Easy Steps":http://groovy.dzone.com/news/java-groovy-few-easy-steps by Guillaume Laforge
+** "Introduction to Groovy":http://groovy.dzone.com/articles/introduction-groovy by Andres Almiray
+** "GraphicsBuilder Tutorial: Paints & Colors":http://groovy.dzone.com/articles/graphicsbuilder-tutorial-iii-p by Andres Almiray
+** "EasyB: Introducing Conversational Unit Tests for Java":http://groovy.dzone.com/news/easyb-introducing-conversation - Q&A with Andrew Glover
+** "Groovy & Eclipse: Lead Plugin Developer Speaks":http://groovy.dzone.com/news/groovy-eclipse-lead-plugin-dev - Q&A with Ed Povazan
+
+* "InfoQ Groovy":http://infoq.com/groovy
+** "What's New in Groovy 1.5":http://www.infoq.com/articles/groovy-1.5-new by Guillaume Laforge
+** "Securing a Grails Application with Acegi Security":http://www.infoq.com/articles/grails-acegi-integration by Fadi Shami
+** "Getting Started with Grails":http://www.infoq.com/minibooks/grails by Jason Rudolph
+
+* "GroovyBlogs":http://groovyblogs.org
+
+
+h1. Groovy/Grails Experience (2GX) Conference
+
+Talk Highlights
+
+* Powerful Metaprogramming Techniques With Groovy by Jeff Brown
+* The Whole 9 Yards: Things you can do in 10 Minutes w/ Grails that will Make Users Love You by Glen Smith
+* Five Groovy/Grails Web Applications You Can Write in Two Days by Steven Devijver
+* The Grails Plug-in System: Plug into Productivity by Graeme Rocher
+* Empowering Spring with Groovy Domain-Specific Languages (DSLs) by Graeme Rocher
+* GORM - Object Relational Mapping with Hibernate De-mystified Graeme Rocher
+* Testing with Groovy by Venkat Subramaniam
+* Easy Behavior-Driven Development (BDD) with EasyB by Andrew Glover
+* and many more
+
+Next "Groovy/Grails Experience":http://groovygrails.com (2GX) Conference in San Jose (California) in Fall 2008
+
+
+h1. Getting Started - Installing Groovy - 1-2-3 Steps
+
+# Download and unzip Groovy archive from "@groovy.codehaus.org@":http://groovy.codehaus.org/Download
+# Set @GROOVY_HOME@ environment variable
+# Add @%GROOVY_HOME%/bin@ to @PATH@
+
+h1. Hello Groovy
+
+{{{
+$ groovy --version
+
+=> Groovy Version: 1.5.4 JVM: 10.0-b19
+}}}
+
+{{{
+$ groovy -e "println 'Servus Groovy'"
+
+=> Servus Groovy
+}}}
+
+Hello.groovy:
+
+{{{
+println "Servus Groovy"
+}}}
+
+{{{
+$ groovy Hello.groovy
+
+=> Servus Groovy
+}}}
+
+h1. The End - Q&A - Thanks
+
+{{ google_analytics :code => 'UA-397343-10' }}
diff --git a/i/build-reddit-in-ruby.png b/i/build-reddit-in-ruby.png
new file mode 100644
index 0000000..7628fd4
Binary files /dev/null and b/i/build-reddit-in-ruby.png differ
diff --git a/i/end_of_history.jpg b/i/end_of_history.jpg
new file mode 100644
index 0000000..f49878b
Binary files /dev/null and b/i/end_of_history.jpg differ
diff --git a/i/epub-logo.gif b/i/epub-logo.gif
new file mode 100644
index 0000000..213970e
Binary files /dev/null and b/i/epub-logo.gif differ
diff --git a/i/football-js.png b/i/football-js.png
new file mode 100644
index 0000000..edb646c
Binary files /dev/null and b/i/football-js.png differ
diff --git a/i/hallosinatra.png b/i/hallosinatra.png
new file mode 100644
index 0000000..9fb9b1a
Binary files /dev/null and b/i/hallosinatra.png differ
diff --git a/i/jetty-container-less.png b/i/jetty-container-less.png
new file mode 100644
index 0000000..39dbde5
Binary files /dev/null and b/i/jetty-container-less.png differ
diff --git a/i/jruby-html-print-sample-pdf.png b/i/jruby-html-print-sample-pdf.png
new file mode 100644
index 0000000..58dce91
Binary files /dev/null and b/i/jruby-html-print-sample-pdf.png differ
diff --git a/i/jruby-html-print-sample.png b/i/jruby-html-print-sample.png
new file mode 100644
index 0000000..75e97c8
Binary files /dev/null and b/i/jruby-html-print-sample.png differ
diff --git a/i/jump_start_sinatra.gif b/i/jump_start_sinatra.gif
new file mode 100644
index 0000000..b563051
Binary files /dev/null and b/i/jump_start_sinatra.gif differ
diff --git a/i/markdown-book-github.png b/i/markdown-book-github.png
new file mode 100644
index 0000000..76f1316
Binary files /dev/null and b/i/markdown-book-github.png differ
diff --git a/i/markdown-book.png b/i/markdown-book.png
new file mode 100644
index 0000000..1cc05bd
Binary files /dev/null and b/i/markdown-book.png differ
diff --git a/i/markdown-note.png b/i/markdown-note.png
new file mode 100644
index 0000000..453ef11
Binary files /dev/null and b/i/markdown-note.png differ
diff --git a/i/markdown-presentation.png b/i/markdown-presentation.png
new file mode 100644
index 0000000..7ae2cde
Binary files /dev/null and b/i/markdown-presentation.png differ
diff --git a/i/markdown-retext.png b/i/markdown-retext.png
new file mode 100644
index 0000000..318289d
Binary files /dev/null and b/i/markdown-retext.png differ
diff --git a/i/markdown-uberwriter.png b/i/markdown-uberwriter.png
new file mode 100644
index 0000000..cc73588
Binary files /dev/null and b/i/markdown-uberwriter.png differ
diff --git a/i/markdown-website-github.png b/i/markdown-website-github.png
new file mode 100644
index 0000000..5a9ca5f
Binary files /dev/null and b/i/markdown-website-github.png differ
diff --git a/i/markdown-website.png b/i/markdown-website.png
new file mode 100644
index 0000000..7c52338
Binary files /dev/null and b/i/markdown-website.png differ
diff --git a/i/planet-viennarb-ii.png b/i/planet-viennarb-ii.png
new file mode 100644
index 0000000..d04967a
Binary files /dev/null and b/i/planet-viennarb-ii.png differ
diff --git a/i/planet-viennarb.png b/i/planet-viennarb.png
new file mode 100644
index 0000000..9734506
Binary files /dev/null and b/i/planet-viennarb.png differ
diff --git a/i/pluto-logo.png b/i/pluto-logo.png
new file mode 100644
index 0000000..5778a88
Binary files /dev/null and b/i/pluto-logo.png differ
diff --git a/i/scala_book.png b/i/scala_book.png
new file mode 100644
index 0000000..13383bd
Binary files /dev/null and b/i/scala_book.png differ
diff --git a/i/sinatra_up_and_running.gif b/i/sinatra_up_and_running.gif
new file mode 100644
index 0000000..29325de
Binary files /dev/null and b/i/sinatra_up_and_running.gif differ
diff --git a/i/web-feed-icon.png b/i/web-feed-icon.png
new file mode 100644
index 0000000..2eeaf23
Binary files /dev/null and b/i/web-feed-icon.png differ
diff --git a/java_end_of_history.md b/java_end_of_history.md
new file mode 100644
index 0000000..1880157
--- /dev/null
+++ b/java_end_of_history.md
@@ -0,0 +1,258 @@
+title: Java and the End of History - Learn Some New Languages and Concepts
+
+
+# Java and the End of History
+
+Learn Some New Languages and Concepts
+
+
+
+
+## Java, Java, Java - 10,000,000,000 % Java
+
+> "When all you have is a hammer, everything looks like a nail."
+
+> "Java is like violence - if it doesn't solve your problems, you are not using enough of it."
+
+
+# Web Architecture - All Java? Really?
+
+* What about HTML5?
+
+* What about CSS3?
+
+* What about JavaScript?
+
+* What about HTTP/REST? e.g ETag, Cache Headers, Cookie-Less Requests for Static Resources, etc.
+
+* What about SQL/NoSQL?
+
+* What about Web Server Configuration Settings? e.g Gzip, Static Resources across Applications, etc.
+
+* What about Memory Caching (MemCache)?
+
+-> All Java? Really?
+
+
+# The March of Progress
+
+1980: C
+
+```
+printf("%10.2f", x);
+```
+
+1988: C++
+
+```
+cout << setw(10) << setprecision(2) << showpoint << x;
+```
+
+1996: Java (Enterprise Edition)
+
+```
+java.text.NumberFormat formatter = java.text.NumberFormat.getNumberInstance();
+formatter.setMinimumFractionDigits(2);
+formatter.setMaximumFractionDigits(2);
+String s = formatter.format(x);
+for (int i = s.length(); i < 10; i++) System.out.print(' ');
+System.out.print(s);
+```
+
+
+# The March of Progress Continued
+
+2004: Java
+
+```
+System.out.printf("%10.2f", x);
+```
+
+2008: Scala and Groovy
+
+```
+printf("%10.2f", x)
+```
+
+Flashback: 1980 C
+
+```
+printf("%10.2f", x);
+```
+
+Note the lack of semi-colon. Improvement!!
+
+Question: Ideas on how to progess?
+
+
+# The March of Progress - Example Ruby
+
+Flashback: 1980 C
+
+```
+printf("%10.2f", x);
+```
+
+Ruby Version I:
+
+```
+printf("%10.2f", x);
+```
+
+or
+
+```
+printf "%10.2f", x
+```
+
+Semi-colon **and parenthesis optional**. Improvement!!
+
+Ruby Version II:
+
+```
+puts "10.2f" % x
+```
+
+Make formatting an expression, that is, independant of printf (works everywhere). Example:
+
+```
+str = "10.2f" % x
+```
+
+
+# Anyways, the point is...
+
+Java is not the End of History. Open your mind. Learn some new concepts and languages.
+
+Scala:
+
+```
+class Person(name: String, age: Int) {
+ def description = name + " is " + age + " years old"
+}
+```
+
+
+Java:
+
+```
+public class Person {
+ private String _name;
+ private int _age;
+
+ public Person( String name, int age ) { _name = name; _age = age; }
+
+ public String getName() { return _name; }
+ public void setName( String name ) { _name = name; }
+
+ public int getAge() { return _age; }
+ public void setAge( int age ) { _age = age; }
+
+ public String getDescription() { return name + " is " + age + " years old"; }
+}
+```
+
+
+# What's missing in Java? What's wrong with Java?
+
+Anyone?
+
+# 10 Scala One Liners - Possible in Java?
+
+%%% todo: escape numbered list in markdown how?
+
+1) Multiple Each Item in a List by 2
+
+```
+(1 to 10) map { _ * 2 }
+```
+
+2) Sum a List of Numbers
+
+```
+(1 to 1000).sum
+```
+
+3) Verify if Exists in a String
+
+```
+val wordList = List("scala", "akka", "play framework", "sbt", "typesafe")
+val tweet = "This is an example tweet talking about scala and sbt."
+
+wordList.exists(tweet.contains)
+```
+
+4) Read in a File
+
+```
+val fileText = io.Source.fromFile("data.txt").mkString
+val fileLines = io.Source.fromFile("data.txt").getLines.toList
+```
+
+5) Happy Birthday to You!
+
+```
+(1 to 4).map { i => "Happy Birthday " + (if (i == 3) "dear NAME" else "to You") }.foreach { println }
+```
+
+
+# 10 Scala One Liners Continued
+
+6) Filter list of numbers
+
+```
+val (passed, failed) = List(49, 58, 76, 82, 88, 90) partition ( _ > 60 )
+```
+
+
+7) Fetch and Parse an XML web service
+
+```
+val results = XML.load("http://search.twitter.com/search.atom?&q=scala")
+```
+
+
+8) Find minimum (or maximum) in a List
+
+```
+List(14, 35, -7, 46, 98).min
+List(14, 35, -7, 46, 98).max
+```
+
+9) Parallel Processing
+
+```
+val result = dataList.par.map(line => processItem(line))
+```
+
+10) Sieve of Eratosthenes
+
+```
+(n: Int) => (2 to n) |> (r => r.foldLeft(r.toSet)((ps, x) => if (ps(x)) ps -- (x * x to n by x) else ps))
+```
+
+Source: [mkaz.com/solog/scala/10-scala-one-liners-to-impress-your-friends.html](http://mkaz.com/solog/scala/10-scala-one-liners-to-impress-your-friends.html)
+
+
+
+# More 10 One Liners
+
+* 10 Ruby One Liners
+* 10 CoffeeScript One Liners
+* 10 Python One Liners
+* 10 Clojure One Liners
+* and so on
+
+
+# Tip: Some Books
+
+
+* Learn You a Haskell - Free Online Book -> [learnyouahaskell.com](http://learnyouahaskell.com)
+
+* Scala for the Impatient (Java Pro) - Free Online Book Chapters -> [horstmann.com/scala](http://horstmann.com/scala)
+
+* 7 Languages in 7 Weeks (Ruby, Io, Prolog, Scala, Erlang, Clojure, Haskell) -> [pragprog.com/book/btlang/seven-languages-in-seven-weeks](http://pragprog.com/book/btlang/seven-languages-in-seven-weeks)
+
+
+
+That's it. Thanks.
diff --git a/jruby_html_print.text b/jruby_html_print.text
new file mode 100644
index 0000000..5323c09
--- /dev/null
+++ b/jruby_html_print.text
@@ -0,0 +1,677 @@
+title: (J)Ruby in Action: Generating PDF Documents from HTML Templates
+
+# (J)Ruby in Action: Generating PDF Documents from HTML Templates
+
+## Agenda
+
+* HTML Print Pilot Demo
+* HTML Templates w/ Embedded Ruby (Conditions, Loops, Methods)
+* Ruby in Action
+ * Reading XML Documents Using `xml_simple` Library
+ * OpenStructs
+ * Open Class Concept
+ * `method_missing`
+ * Using Embedded Ruby Templates (ERB)
+* Ruby in a Java World - `jruby-complete.jar`
+* HTML to PDF Conversion
+ * `wkhtmltopdf` and Alternatives
+ * HTML5 Goodies for Print
+ * CSS3 Paged Media and Alternatives
+* The End
+
+
+# Dynlang/Scripting Profile Questions – Ice Breakers
+
+* Are you using any Scripting Languages for Java?
+* What? Python? Groovy? Ruby?
+* Why? / What for? -> Production? Testing? Configuration? Templates? Other?
+
+
+* Bonus: Have you developed a web application in a scripting language on a Java infrastructure/stack?
+ (e.g. JRuby on Rails, Google App Engine w/ Groovy, etc.)
+
+
+Sample:
+
+%% todo: check why redcarpet uses list item (li) wrapped in paragraph (p) for some items
+
+* Yes / Many
+* Ruby, Groovy
+* Production, Templates, Testing
+
+* No / Zero
+* 10000 % Java!! Java Rules!! Java Java
+
+
+# HTML Print Pilot
+
+Idea: Make design of documents as easy as possible
+
+* Use HTML for document templates (use CSS for styling and positioning)
+* Use a scripting language for conditions, placeholders, loops, etc. (-> Ruby)
+
+
+# HTML Print Pilot in Action
+
+Command Line:
+
+ $ jruby print.rb samples/BUFT/BUFT_Angebot_Master.html samples/BUFT/BUFT1.xml > o/BUFT1.html
+ $ jruby print.rb samples/BUFT/BUFT_Angebot_Master.html samples/BUFT/BUFT2.xml > o/BUFT2.html
+
+Result:
+
+
+
+
+# HTML to PDF Conversion
+
+ $ wkhtmltopdf --use-print-stylesheet o/BUFT1.html o/BUFT1.pdf
+
+Result:
+
+
+
+
+# HTML Templates Using Embedded Ruby (`erb`) - 1st Impression
+
+Example: `QP_Antrag.html`
+
+```
+
Mein mobiles ServicePaket:
+
Portal mySanssouci: Jederzeit online Zugriff auf alle Informationen rund
+ um meine QualitätsPartnerschaft
+
Sanssouci Unwetterwarnung: Örtlich und zeitlich exakte Vorhersagen per SMS
+ und/oder E-Mail
+
+
+
Ich beantrage die QualitätsPartnerschaft und bitte um Verrechnung meiner
+Versicherungsverträge, bei denen ich alleiniger Prämienzahler und Verbraucher im Sinne
+des Konsumentenschutzgesetzes (KSchG) bin, über das PartnerConto und nehme zustimmend
+zur Kenntnis, dass bei Umstellung auf die QualitätsPartnerschaft die Serviceleistungen
+aus einem eventuell vorhandenen StarConto, mit Ausnahme der Verrechnungsfunktion für
+Verträge von Kooperationsunternehmen, durch die Serviceleistungen der
+QualitätsPartnerschaft ersetzt werden.
+
+
+
Ich beauftrage
+ <% if benutzer.geschlecht == 1 %>
+ Herrn
+ <% end %>
+ <% if benutzer.geschlecht == 2 %>
+ Frau
+ <% end %>
+<%= benutzer.titel %> <%= benutzer.vorName %> <%= benutzer.zuName %>
+mich als persönlicher Betreuer in sämtlichen Versicherungsangelegenheiten meiner Verträge
+des ExklusivVertriebs zu beraten, zu betreuen und zu unterstützen. Ich ermächtige sie/ihn
+hiermit gleichzeitig, alle dafür relevanten Vertrags- und Schadendaten in meinem Namen
+zu erheben bzw. in diese Einsicht zu nehmen.
+```
+
+# Why Ruby? Why Not Groovy?
+
+Ruby Pros:
+
+* Write Ruby Once, Runs Anywhere! .Net Runtime – Yes, Java Runtime – Yes, C-Runtime – Yes
+* Easier To Use and Learn for Non-Java Programmers (e.g. Casual Developers such as Designers/Analysts)
+* Better Documentation (More Books, etc.)
+* More Innovations (Different Culture – Enterprise-y? Ethos -Programmer Happiness, Simple, etc.)
+* Works Great as Template Language e.g. for Web Views (No `{}`, method `()` optional, etc.)
+* Better Meta-Progamming
+* Much More!
+
+Groovy Pros:
+
+* Better Java Integration
+* Easier To Use and Learn for Java Programmers
+
+
+# HTML Templates – Conditions, Loops
+
+Conditions (`if`):
+
+```
+<% if o.sparten.registrierungUnwetter.vorhanden? %>
+
ja
+<% else %>
+
nein
+<% end %>
+```
+
+
+Loops (`each`):
+
+```
+<% o.vertraegeUntergeordnet.each do |qpsub| %>
+
+
<%= qpsub.vereinbarungQP.status %>
+
<%= qpsub.vereinbarungQP.polizzenNr %>
+
<%= qpsub.vereinbarungQP.antragsID %>
+
<%= qpsub.vereinbarungQP.prodkurzname %>
+
<%= qpsub.vereinbarungQP.praemieAlt %>
+
<%= qpsub.vereinbarungQP.praemieNeu %>
+
<%= qpsub.vereinbarungQP.praemieDiff %>
+
+<% end %>
+```
+
+# HTML Templates – Macros, Functions
+
+Definition:
+
+```
+<%
+def vertragVorhanden?
+ o.vertraegeUntergeordnet.each do |v|
+ vQP = v.vereinbarungQP
+ if vQP.markierungCode == 1 || vQP.markierungCode == 2
+ return true
+ end
+ end
+ false
+end
+%>
+```
+
+Usage:
+
+```
+<% if vertragVorhanden? %>
+ Verträge/Anträge, die nur über das PartnerConto verrechnet werden und nicht zur
+ Bereichswertung zählen
+ (alle Prämien in EUR, inkl. Steuern, exkl. motorbezogener Versicherungssteuer)
+<% end %>
+```
+
+# Easy XML Data Access Using Dot-Notation
+
+## Access XML Data using Dot-Notation (C-Struct-Like):
+
+```
+o.besondereHinweise
+o.sparten.registrierungUnwetter.registrierungMobil.firma
+```
+
+## Define Short-Cuts:
+
+```
+sparten = o.vereinbarung.sparten
+vn = sparten.versichertePersonBuft.vereinbarungZuPartner.find{ |v| v.zuordnungsTyp == 1801 }.partner
+pz = vn
+```
+
+## Using Short-Cuts:
+
+```
+vn.hauptWohnsitz.strasse
+pz.bankverbindungen.bankKontoNr
+```
+
+## Arrays:
+
+```
+vn.kuvPartnerInnen[0].vertriebsKuv.kundenverbindung.vtbSchiene
+```
+
+
+# Ruby in Action - Reading XML Documents Using `xml_simple` Library
+
+XML Source:
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ...
+
+
+
+ ...
+
+
+ ...
+```
+
+
+Ruby Code – `xml_simple` Library in Action:
+
+```
+# step 1: read xml soruce into memory as string
+
+ xml = File.read( 'samples/BUFT/BUFT1.xml' )
+
+# step 2: parse xml using XmlSimple Lib (result stored in variable @o)
+
+ @o = XmlSimple.xml_in( xml )
+
+# step 3: pretty print (dump) internal structure
+
+ pp @o
+```
+
+
+Internal Structure (JSON-like; just Values, Arrays and Hashes):
+
+```
+{"value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "vereinbarung"=>
+ {"value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "systemKlasse"=>
+ {"value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "vpmsModellVersNr"=>
+ {"value"=>"20100312",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "text"=>"\n\t\t\t"}},
+ "vereinbarungTyp"=>
+ {"value"=>"163",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "text"=>"\n\t\t"},
+ "sparten"=>
+ {"value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "versichertePersonBuft"=>
+ {"value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "vereinbarungZuPartner"=>
+ [{"index"=>"0",
+ "value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "partner"=>
+ {"index"=>"0",
+ "value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "geburtsDatum"=>
+ {"index"=>"0",
+ "value"=>"12.11.1970",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "text"=>"\n\t\t\t\t\t\t"},
+ "geschlecht"=>
+ {"index"=>"0",
+ "value"=>"2",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "choice"=>
+ {"item"=>
+ [{"key"=>"0", "value"=>"Organisation"},
+ {"key"=>"1", "value"=>"m\303\244nnlich"},
+ {"key"=>"2", "value"=>"weiblich"}]}},
+ "berufsTitel"=>
+ {"index"=>"0",
+ "value"=>"",
+ "type"=>"java.lang.Object",
+ "desc"=>"null",
+ "choice"=>
+ {"item"=>
+ [{"key"=>"44", "value"=>"Dipl.Arch. Dkfm."},
+```
+
+Allows Access Using Hash:
+
+```
+@o['vereinbarung']['systemKlasse']['vmpsModellVersNr']['value'] => 20100312
+@o['vereinbarung']['sparten']['versichertePersonBuft']['vereinbarungZuPartner']['partner']['geburtsDatum'] => 12.11.1970
+```
+
+
+# Ruby in Action – OpenStructs – Easy Dot Access
+
+Convert Hash Access to Dot Access Using OpenStructs
+
+Classic Access using Hash Access:
+
+```
+@o['vereinbarung']['systemKlasse']['vmpsModellVersNr']['value'] => 20100312
+@o['vereinbarung']['sparten']['versichertePersonBuft']['vereinbarungZuPartner']['partner']['geburtsDatum'] => 12.11.1970
+```
+
+Easy Dot-Access using OpenStruct:
+
+```
+@o.vereinbarung.systemKlasse.vmpsModellVersNr.value => 20100312
+@o.vereinbarung.sparten.versichertePersonBuft.vereinbarungZuPartner.partner.geburtsDatum => 12.11.1970
+```
+
+What is an OpenStruct?
+
+Usage:
+
+```
+hash = { "key"=>"0", "value"=>"Organisation" }
+item = OpenStruct.new(hash)
+item.key => "0"
+item.value => "Organisation"
+```
+
+
+# Ruby in Action – Open Class Concept – Extend Existing Classes
+
+Let's make the conversion recursive (that is, for complete parsed data tree):
+
+```
+class Object
+ def to_openstruct
+ self
+ end
+end
+
+class Array
+ def to_openstruct
+ map{ |el| el.to_openstruct }
+ end
+end
+
+class Hash
+ def to_openstruct
+ mapped = {}
+ each{ |key,value| mapped[key.to_s] = value.to_openstruct }
+ OpenStruct.new(mapped)
+ end
+end
+```
+
+
+That’s it. Usage:
+
+```
+@o = @o.to_openstruct
+```
+
+# Ruby in Action - `method_missing` - Accessing Non-Existing Fields
+
+Accessing Non-Existing Fields in OpenStruct:
+
+```
+class MyOpenStruct
+ def initialize( hash )
+ @hash = hash
+ end
+ ...
+ def method_missing(mn,*a)
+ mn = mn.to_s
+ if @hash.has_key?(mn)
+ @hash[mn]
+ else
+ STDERR.puts "*** warning: field '#{mn}' not found in hash; returning OpenStructNil"
+ MyOpenStructNil.new( self, mn )
+ end
+ end
+```
+
+Accessing Non-Existing Fields in Non-Existing Hash:
+
+```
+class MyOpenStructNil
+ def initialize( parent, field )
+ @parent = parent
+ @field = field
+ end
+ ...
+ def method_missing(mn,*a)
+ mn = mn.to_s
+ STDERR.puts "*** warning: field '#{mn}' not found (parent is nil)"
+ MyOpenStructNil.new( self, mn )
+ end
+```
+
+
+# Ruby in Action - Using Embedded Ruby Templates (ERB)
+
+```
+# step 1: read template source into memory as string
+
+ rhtml = File.read( 'samples/BUFT/BUFT_Master.html' )
+
+# step 2: make string into a template object
+
+ template = ERB.new( rhtml )
+
+# step 3: merge (fill in) template using variables from binding
+
+ result = template.result( binding() )
+
+# step 4: write out results in new file
+
+ File.open( 'o/BUFT1.html', 'w') {|f| f.write( result ) }
+```
+
+
+# Ruby in a Java World - `jruby-complete.jar`
+
+Command Line:
+
+ $ jruby print.rb samples/BUFT/BUFT_Angebot_Master.html samples/BUFT/BUFT1.xml > o/BUFT1.html
+
+Using jruby-complete.jar:
+
+ $ java -jar jruby-complete.jar print.rb samples/BUFT/BUFT_Angebot_Master.html samples/BUFT/BUFT1.xml > o/BUFT1.html
+
+What is `jruby-complete.jar`?
+
+* All-in-one Java-Archive (jar) for JRuby (also includes Ruby standard libs plus some extras).
+* No installation needed; just add `jruby-complete.jar` to your classpath.
+
+
+# HTML to PDF Conversion - `wkhtmltopdf`
+
+What is `wkhtmltopdf?`
+
+* Open Source C++ Code
+* Builds on Qt Library and WebKit (`wk`)
+* Adds some extras for page breaking, headers & footers, table of contents, etc.
+
+[More Info](http://code.google.com/p/wkhtmltopdf), [Source](https://github.com/antialize/wkhtmltopdf)
+
+Example:
+
+ $ wkhtmltopdf --use-print-stylesheet o/BUFT1.html o/BUFT1.pdf
+
+
+# HTML to PDF Conversion – Options/Alternatives
+
+**HTML/CSS Parser using iText API** - Flying Saucer - 100 % Java (Open Source) - [More Info](http://code.google.com/p/flying-saucer), [Article](http://today.java.net/pub/a/today/2007/06/26/generating-pdfs-with-flying-saucer-and-itext.html)
+
+**HTML to FO** (using XSLT-Templates)
+
+**HTML plus CSS3 (plus Paged Media!)** - PrinceXML (Commercial, $3000/license) - [More Info](http://princexml.com)
+
+
+# HTML5 Goodies for Print
+
+CSS3:
+
+* @font-face
+* multi columns
+* table layout using CSS
+* backgrounds, gradients
+* much more
+
+SVG:
+
+* Scalable Vector Graphics (SVG)
+
+CSS3 Paged Media Module:
+
+* Not (yet) supported in any browser (planned for Google Chromium Milestone 6!)
+* Supported by commercial HTML to PDF converter (PrinceXML)
+
+What is the CSS3 Page Media Module About?
+
+* Page Breaking
+* Page Layout (Headers, Footers, Size)
+* Page Counter
+* And More
+
+Example:
+
+```
+@page {
+ size: 210mm 297mm; /* A4 */
+ margin: 27mm 16mm 27mm 16mm; /* top, right, bottom, left */
+}
+@page :left {
+ @top-left {
+ content: "HTML Print Pilot";
+ }
+ @bottom-left {
+ content: counter(page);
+ }
+}
+@page :right {
+ @top-right {
+ content: string(header);
+ }
+}
+```
+
+[More Info](http://www.w3.org/TR/css3-page), [Article](http://www.alistapart.com/articles/boom)
+
+
+# CSS3 Paged Media Alternative - Use JavaScript
+
+* Use JavaScript for Breaking Document into Pages (Pagination)
+* Use JavaScript for Adding Headers & Footers to Pages and Replace Place Holders such as `{page}`/`{pages}`
+
+
+In HTML Print Pilot less than 100 lines of JavaScript (using jQuery Library)
+
+Page Breaking Plus Adding Headers & Footers:
+
+```
+var pages = 1; // page counter
+var runHeight = 0; // in pixel
+var pageHeight = 580; // in pixel
+
+// find header and footer
+var header = $('.kopf:first');
+var footer = $('.fuss:first');
+
+var buildAll = $( "" );
+var buildPage = buildNewPage( header, footer ).appendTo( buildAll );
+var buildAntrag = buildPage.find( '.angebot:first' );
+
+$( '.angebot' ).children().each( function() {
+ var width = $(this).width();
+ var height = $(this).height();
+
+ debug( runHeight + ' - tag:' + this.tagName + '['+ width + ' x ' + height +']' );
+
+ if( (runHeight+height) > pageHeight )
+ {
+ debug( '** adding page break' );
+ runHeight = 0;
+ pages += 1;
+ buildAll.append( "" );
+ buildPage = buildNewPage( header, footer ).appendTo( buildAll );
+ buildAngebot = buildPage.find( '.angebot:first' );
+ }
+ runHeight += height;
+ buildAngebot.append( $(this).clone() );
+});
+```
+
+Replace Variables/Place Holders in Headers & Footers:
+
+```
+var page = 1;
+buildAll.find( '.seitea4' ).each( function() {
+ debug( '** processing page ' + page + '/' + pages );
+ var header = $(this).find( '.kopf:first' );
+ var footer = $(this).find( '.fuss:first' );
+ header.html( header.html().replace( '{{page}}', page ).replace( '{{pages}}', pages ) );
+ footer.html( footer.html().replace( '{{page}}', page ).replace( '{{pages}}', pages ) );
+ page += 1;
+});
+```
+
+# The End - Q&A – Thanks
+
+
+# Ruby Books
+
+Ruby:
+
+* Programming Ruby 1.9: The Pragmatic Programmers’ Guide, by Dave Thomas, Chad Fowler, and Andy Hunt, 2009
+* The Ruby Programming Language by David Flanagan (O’Reilly), 2008
+* Ruby Cookbook (O’Reilly), by Lucas Carlson and Leonard Richardson 2006
+* Practical Ruby Gems by David Berube (Apress), 2007
+* Many Others
+
+JRuby (Ruby Meets Java):
+
+* Using JRuby: Bringing Ruby to Java by Charles O Nutter, Thomas Enebo, Nick Sieger, Ola Bini, and Ian Dees, 2010
+* JRuby Cookbook (O’Reilly) by JRuby Cookbook by Justin Edelson and Henry Liu, 2008
+
+
+# Getting Started - Installing JRuby - 1-2-3 Steps
+
+1. Download and unzip JRuby archive from `jruby.org/download`
+2. Set `JRUBY_HOME` environment variable
+3. Add `%JRUBY_HOME%/bin` to `PATH`
+
+
+# Hello Ruby
+
+```
+$ jruby -v
+
+=> jruby 1.5.0 (ruby 1.8.7 patchlevel 249) (2010-05-12 6769999) (Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
+
+$ jruby -S gem list
+
+=> *** LOCAL GEMS ***
+=>
+=> columnize (0.3.1)
+=> rake (0.8.7)
+=> rspec (1.3.0)
+=> ruby-debug (0.10.3)
+=> ruby-debug-base (0.10.3.2)
+=> sources (0.0.1)
+
+$ jruby -e "puts 'Ruby Meets Java'"
+
+=> Ruby Meets Java
+```
+
+hello.rb:
+
+```
+puts 'Ruby Meets Java'
+
+$ jruby hello.rb
+
+=> Ruby Meets Java
+```
+
+
diff --git a/jruby_web_apps.md b/jruby_web_apps.md
new file mode 100644
index 0000000..f4b026e
--- /dev/null
+++ b/jruby_web_apps.md
@@ -0,0 +1,835 @@
+title: (J)Ruby in Action - Web Apps & Services w/ Rails n Jetty
+
+
+
+%css
+
+pre {
+ padding: 4px 4px 4px 4px;
+ border-top: #bbb 1px solid;
+ border-bottom: #bbb 1px solid;
+ background: #f3f3f3;
+}
+
+%end
+
+
+
+
+# Ice Breakers
+
+* Friends of Ruby (Rails)? - Anyone?
+
+* Friends of Functional Programming (Haskell, Yesod) - Anyone?
+
+* Friends of Scala, Play! - Anyone?
+
+* Friends of Server-Side JavaScript (Node.js) - Anyone?
+
+* Friends of Dart - Anyone?
+
+
+
+# Factories, Factories, Factories
+
+Java Enterprise Architecture
+
+- Factories, Factories, Factories
+- Over-engineering, Cult of Complexity
+- The COBOL of the 21st Century (Java is Old technology, No Longer Hot Java or the New New Thing => Innovation Happens Elsewhere)
+- There is only Java, Java, Java - 1,000,0000,000 % Java, The End of History, Java Rules the World Hybris
+
+
+
+# Why Ruby?
+
+- Code Blocks (Lambda Expressions) - 20 years in Ruby! Coming to Java 8 in 2014
+- Open Classes
+- Mixins
+- Everything is a Object
+- Meta Programming (e.g. Ruby Code Creates Code at Runtime on Demand)
+- List, Tree, Map Data Structures in Ruby
+- Templates in Ruby
+- Culture - Programmer Happiness (Productivity, Keep it Simple), Innovation
+
+
+
+- Open, Free World (Not a Product and Trademark of Oracle, Inc.)
+
+
+
+# Keep it Simple - Web Apps Case Study
+
+1. No Enterprise Java Application Server
+ * Use Embedded Jetty Library to Run Container-Less
+2. No Enterprise Java Database Server
+ * Use Embedded SQLite Library
+3. No Enterprise Java Application Framework
+ * Use Embedded Ruby Library
+4. No Enterprise Java IDE
+ * Use Command Line, Programmer's Editor
+
+
+
+# Case Study: How to Install Container-Less Jetty Web Server
+
+
+Step 1: Copy `jetty-webapp-7.x.jar` (~ 1 Meg)
+
+Step 2: There is no step 2.
+
+
+
+# Think Different - What's Container-Less?
+
+
+
+Container-Less? Run your web application as a plain old Java process.
+
+Why:
+
+* Simpler Development
+* Simpler Testing
+* Simpler Packaging
+* Simpler Deployment
+
+
+
+# A Simple Web App using Jetty
+
+The simplest possible Jetty server:
+
+```
+import org.eclipse.jetty.server.Server;
+
+public class SimpleServer
+{
+ public static void main(String[] args) throws Exception
+ {
+ Server server = new Server(8080);
+ server.start();
+ server.join();
+ }
+}
+```
+
+
+# A Simple Web App using Jetty (Cont.)
+
+
+```
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.webapp.WebAppContext;
+
+public class AppServer
+{
+
+ public static void main(String[] args) throws Exception
+ {
+ Server server = new Server(8080);
+
+ WebAppContext webapp = new WebAppContext();
+ webapp.setContextPath("/");
+ webapp.setWar( "./links.war");
+ server.setHandler(webapp);
+
+ server.start();
+ server.join();
+ }
+}
+```
+
+## Compile
+
+
+ javac -cp .;./jetty-webapp-7.x.jar AppServer.java
+
+
+
+# Let's Build a Link Bookmarking and Voting Web App
+
+* Post links
+* Vote links up or down
+* Sort links by the newest or hot
+
+
+
+
+
+# Create a Web App using Ruby on Rails
+
+## Create Web App Structure
+
+ $ rails links
+
+## Create SQLite Schema (`db/migrate/create_db.rb`)
+
+```
+create_table :links do |t|
+ t.string :title, :null => false
+ t.string :url, :null => false
+ t.integer :points, :default => 0
+ t.timestamps # note: macro adds created_at, updated_at
+end
+```
+
+## Create SQLite DB
+
+ $ rake db:setup # note: rake is ruby make (simple build tool)
+
+
+
+# Model / View / Controller (MVC)
+
+## Model (`models/link.rb`)
+
+```
+class Link < ActiveRecord::Base
+
+ # self.table_name = 'links'
+
+ attr_accessor :score
+
+ def recalc_score
+ time_elapsed = (Time.now - self.created_at) / 36000 # in hours
+ self.score = ((self.points-1) / (time_elapsed+2)**1.8)
+ end
+
+ def self.hot
+ self.all.each { |rec| rec.recalc_score }.sort { |l,r| l.score <=> r.score }.reverse
+ end
+
+end
+```
+
+
+# Model / View / Controller (MVC)
+
+## Controller (`controllers/links_controller.rb`)
+
+```
+class LinksController < ApplicationController
+
+ # GET /
+ def index
+ @links = Link.order( 'created_at desc' ).all
+ end
+
+ # GET /hot
+ def hot
+ @links = Link.hot
+ render :index
+ end
+
+ # POST /
+ def create
+ l = Link.new( params[:link] )
+ l.save!
+ redirect_to :back
+ end
+
+ # PUT /:id/vote/:type
+ def vote
+ l = Link.find( params[:id] )
+ l.points += params[:type].to_i
+ l.save!
+ redirect_to :back
+ end
+
+end
+```
+
+# Model / View / Controller (MVC)
+
+## View (`views/links/index.html.erb`)
+
+```
+
+```
+
+
+# Zip Up and Run It
+
+
+## Zip Up as Java Web Archive (links.war)
+
+ $ rake war # warble
+
+## Run it
+
+ $ java -cp .;./jetty-webapp-7.x.jar AppServer
+
+## Surprise ??
+
+=> One Plain Old Java Process - Embedded Jetty, Embedded SQLite, Embedded Ruby
+
+
+
+# Case Study: How to Install Embedded Ruby
+
+
+Step 1: Copy `jruby-complete-1.7.x.jar`
+
+Step 2: There is no step 2.
+
+
+# Java Web Archive (`.war`) Directory Structure
+
+```
+links.war
+
+|_ images
+| | _
+|_ stylesheets
+| |_ application.css
+|_ javascripts
+| | _
+|_ WEB-INF
+ |_ app
+ | |_ controllers
+ | | |_ links_controller.rb
+ | |_ models
+ | | |_ link.rb
+ | |_ views
+ | |_ layouts
+ | | |_ application.html.erb
+ | |_ links
+ | |_ index.html.erb
+ |_ config
+ | |_ database.yml
+ | |_ routes.rb
+ |_ db
+ | |_ links.sqlite3
+ |_ lib
+ |_ jruby-complete-1.7.x.jar
+ |_ jruby-rack-1.x.jar
+ |_ gems.jar
+```
+
+
+
+# What's missing in Java? What's wrong with Java?
+
+Anyone?
+
+
+# Simple Data Structures (Maps, Arrays)
+
+Example:
+
+```
+{ customer:
+ { id: '12345',
+ first_name: 'Carlos',
+ last_name: 'Lafata',
+ address:
+ [
+ { typ: 'home',
+ line1: 'Burgring 11',
+ city: 'Wien',
+ zip_code: '1010' },
+ { typ: 'work',
+ line1: 'Nestroyplatz 12',
+ city: 'Wien',
+ zip_code: '1020' }
+ ] }
+}
+```
+
+## Quiz: Built into what modern languages?
+
+`[ X ]` JavaScript
+
+`[ X ]` Ruby
+
+`[ X ]` Scala
+
+`[ ]` ~~Java~~
+
+`[ ]` ~~COBOL~~
+
+
+
+# Simple Code Blocks (Higher Order Functions, Functions as First Class Types)
+
+Example:
+
+```
+// Assign Function to Variable
+
+var greet = function() { document.write( 'Welcome. Benvenuti. Willkommen.' ); }
+
+// Call Function Stored in Variable
+
+greet();
+
+// Function as Function Parameter
+
+function say( what )
+{
+ what();
+ what();
+ what();
+}
+
+// Pass Function Stored in Variable to Function
+
+say( greet );
+```
+
+## Quiz: Built into what modern languages?
+
+`[ X ]` JavaScript
+
+`[ X ]` Ruby
+
+`[ X ]` Scala
+
+`[ ]` ~~Java~~
+
+`[ ]` ~~COBOL~~
+
+
+# Part II
+
+
+Building Web Services (HTTP APIs) with Ruby (and Sinatra)
+
+## Agenda
+
+- What's Sinatra?
+- Let a Thousand Sinatra Clones Bloom
+- Why Sinatra? Goodies
+- Example Web Service (HTTP API) - Routes
+- Sinatra in Action - `get '/beer/:key'`
+- What's JSON?
+- What's JSONP?
+- Serializers - From Ruby Objects to JavaScript Objects
+- Appendix: Sinatra Styles - Classic or Modern (Modular)
+- Appendix: Database Connection Management
+- Appendix: Sinatra Books
+- Appendix: What's Rack?
+
+
+
+# What's Sinatra?
+
+Simple (yet powerful and flexible) micro webframework.
+
+~~~
+require 'sinatra'
+
+get '/' do
+ 'Hallo Wien!'
+end
+~~~
+
+Sinatra itself [less than 2000 lines of code](https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb).
+
+
+Installation. Type in your terminal (shell):
+
+~~~
+$ gem install sinatra
+~~~
+
+
+
+# What's Sinatra? (Continued)
+
+Example - `hallo.rb`:
+
+~~~
+require 'sinatra'
+
+get '/' do
+ 'Hallo Wien!'
+end
+~~~
+
+Run script (server):
+
+~~~
+$ ruby hallo.rb
+
+>> Sinatra has taken the stage...
+>> Listening on 0.0.0.0:4567, CTRL+C to stop
+~~~
+
+Open browser:
+
+
+
+
+
+# Let a Thousand Sinatra Clones Bloom
+
+Micro Frameworks Inspired by Sinatra
+
+
+Express.js (in Server-Side JavaScript w/ Node.js):
+
+~~~
+var express = require( 'express' );
+var app = express();
+
+app.get( '/', function( req, res ) {
+ res.send( 'Hallo Wien!' );
+});
+
+app.listen( 4567 );
+~~~
+
+
+Scotty (in Haskell):
+
+~~~
+import Web.Scotty
+
+main :: IO ()
+main = scotty 4567 $ do
+ get "/" $ text "Hallo Wien!"
+~~~
+
+Dancer (Perl), Fitzgerald (PHP), Ratpack (Groovy),
+Zappa (CoffeeScript), Mercury (Lua), Frank (F#), Nancy (C#/.NET),
+Bogart (C), Flask (Python), and [many more](http://en.wikipedia.org/wiki/Sinatra_(software)#Frameworks_inspired_by_Sinatra).
+
+
+
+# Why Sinatra? Goodies
+
+1) Single file scripts
+
+
+2) Easy to package up into a gem. Example:
+
+ $ gem install beerdb # Yes, the beerdb includes a Sinatra app.
+
+
+3) Lets you build command line tools. Example:
+
+ $ beerdb serve # Startup web service (HTTP API).
+
+
+4) Lets you mount app inside app (including Rails). Example:
+
+ mount BeerDb::Server, :at => '/api/v1'
+
+
+
+# Example Web Service (HTTP API) - Routes
+
+Lets build a beer and brewery API.
+
+Get beer by key `/beer/:key`. Examples:
+
+- `/beer/guinness`
+- `/beer/murphysred`
+- `/beer/brooklynlager`
+- `/beer/ottakringerhelles`
+
+Get brewery by key `/brewery/:key`. Examples:
+
+- `/brewery/guinness`
+- `/brewery/fullers`
+- `/brewery/brooklyn`
+- `/brewery/ottakringer`
+
+Bonus:
+
+Get random beer `/beer/rand` and random brewery `/brewery/rand`.
+
+
+
+# Sinatra in Action - `get '/beer/:key'`
+
+`beerdb/server.rb`:
+
+~~~
+get '/beer/:key' do |key|
+
+ beer = Beer.find_by_key!( key )
+ json_or_jsonp( beer.as_json )
+
+end
+
+get '/brewery/:key' do |key|
+
+ brewery = Brewery.find_by_key!( key )
+ json_or_jsonp( brewery.as_json )
+
+end
+~~~
+
+That's it.
+
+
+Bonus:
+
+~~~
+get '/beer/:key' do |key|
+
+ if ['r', 'rnd', 'rand', 'random'].include?( key )
+ beer = Beer.rnd.first
+ else
+ beer = Beer.find_by_key!( key )
+ end
+
+ json_or_jsonp( beer.as_json )
+end
+
+get '/brewery/:key' do |key|
+
+ if ['r', 'rnd', 'rand', 'random'].include?( key )
+ brewery = Brewery.rnd.first
+ else
+ brewery = Brewery.find_by_key!( key )
+ end
+
+ json_or_jsonp( brewery.as_json )
+end
+~~~
+
+
+
+# What's JSON?
+
+JSON = JavaScript Object Notation
+
+
+Example - `GET /beer/ottakringerhelles`:
+
+~~~
+{
+ key: "ottakringerhelles",
+ title: "Ottakringer Helles",
+ synonyms: "16er Blech|16er Hüs'n",
+ abv: "5.2",
+ og: "11.8",
+ tags: [ "lager" ],
+ brewery: {
+ key: "ottakringer",
+ title: "Ottakringer Brauerei"
+ },
+ country: {
+ key: "at",
+ title: "Austria"
+ }
+}
+~~~
+
+
+# What's JSONP?
+
+JSONP = JSON with Padding. Why?
+
+Call Home Restriction. Cross-Domain Browser Requests Get Blocked.
+
+Hack: Wrap JSON into a JavaScript function/callback
+e.g. `functionCallback( )`
+and serve as plain old JavaScript.
+
+
+Example - `Content-Type: application/json`:
+
+~~~
+{
+ key: "ottakringerhelles",
+ title: "Ottakringer Helles",
+ synonyms: "16er Blech|16er Hüs'n",
+ abv: "5.2",
+ ...
+}
+~~~
+
+becomes `Content-Type: application/javascript`:
+
+~~~
+functionCallback(
+ {
+ key: "ottakringerhelles",
+ title: "Ottakringer Helles",
+ synonyms: "16er Blech|16er Hüs'n",
+ abv: "5.2",
+ ...
+ }
+);
+~~~
+
+Bonus: Little Sinatra helper for JSON or JSONP response (depending on callback parameter).
+
+~~~
+def json_or_jsonp( json )
+ callback = params.delete('callback')
+
+ if callback
+ content_type :js
+ response = "#{callback}(#{json})"
+ else
+ content_type :json
+ response = json
+ end
+end
+~~~
+
+
+# Serializers - From Ruby Objects (in Memory) to JavaScript Object (in Text)
+
+JSON built into Ruby 2.0 as a standard library. Example:
+
+~~~
+require 'json'
+
+hash =
+{
+ key: "ottakringerhelles",
+ title: "Ottakringer Helles"
+}
+~~~~
+
+### 1) `JSON.generate`
+
+~~~
+puts JSON.generate( hash )
+
+>> {"key":"ottakringerhelles","title":"Ottakringer Helles"}
+~~~
+
+### 2) `#to_json`
+
+~~~
+puts hash.to_json
+
+>> {"key":"ottakringerhelles","title":"Ottakringer Helles"}
+~~~
+
+
+
+# Serializers - From Ruby Objects (in Memory) to JavaScript Object (in Text) Continued
+
+Serializers for your Models. Example:
+
+~~~
+class BeerSerializer
+
+ def initialize( beer )
+ @beer = beer
+ end
+
+ attr_reader :beer
+
+ def as_json
+ data = { key: beer.key,
+ title: beer.title,
+ synonyms: beer.synonyms,
+ abv: beer.abv,
+ ...
+ }
+ data.to_json
+ end
+
+end # class BeerSerializer
+~~~
+
+And add `as_json` to your Model. Example:
+
+~~~
+class Beer < ActiveRecord::Base
+
+ def as_json_v2( opts={} )
+ BeerSerializer.new( self ).as_json
+ end
+
+end # class Beer
+~~~
+
+
+# Appendix: What's Rack?
+
+Lets you mix 'n' match servers and apps.
+
+Lets you stack apps inside apps inside apps inside apps inside apps.
+
+Good News: A Sinatra app is a Rack app.
+
+Learn more about Rack @ [`rack.github.io`](http://rack.github.io).
+
+
+# Appendix: Sinatra Books
+
+ Sinatra: Up and Running by Alan Harris, Konstantin Haase;
+November 2011, O'Reilly, 122 Pages
+
+ Jump Start Sinatra by Darren Jones;
+January 2013, SitePoint, 150 Pages
+
+
+
+
+# What's vienna.rb? Ruby User Group Vienna
+
+Next meetup: Fri, October 11th @ Sektor5
+
+Talks (*)
+
+Jakob Sommerhuber - sponsor talk
+
+Martin Schürrer - Erlang/OTP in production for highly-available, scalable systems
+
+Markus Prinz - How to improve your code
+
+Gerald Bauer - working with Sinatra
+
+Kathrin Folkendt - 'Chapter one' (lightning talk on getting started with Rails, and building her first web app)
+
+(*) preliminary program
+
+
+
+# That's it. Thanks.
+
+1) Don't put yourself in the Java ghetto (or Java rules the world hybris)
+
+=> Learn new concepts or languages
+
+2) Web architecture is more than Java enterprise architecture
+
+=> Learn HTML, JS, CSS, HTTP (REST), SQL/NoSQL, etc.
+
+
+### Questions? Comments?
+
+
diff --git a/markdown.md b/markdown.md
new file mode 100644
index 0000000..65b99d0
--- /dev/null
+++ b/markdown.md
@@ -0,0 +1,687 @@
+title: Using Markdown for Websites, Presentations, or Books
+
+%css
+
+pre {
+ padding: 4px 4px 4px 4px;
+ border-top: #bbb 1px solid;
+ border-bottom: #bbb 1px solid;
+ background: #f3f3f3;
+}
+
+%end
+
+
+# Using Markdown for Websites, Presentations, or Books
+
+Agenda
+
+* What's Markdown?
+* Syntax - Text Formatting
+* Syntax - Header Formatting
+* Syntax - Hyperlink
+* What is Markdown good for?
+* Example - Website
+* Example - Presentation
+* Example - Book
+* Markdown Parsers in Ruby
+* What's the `markdown` Gem?
+* Tooling - Websites
+* Tooling - Presentations
+* Tooling - Books
+
+
+
+# What's Markdown? What's Markup?
+
+Markdown is a wiki-style markup language that's
+
+* easy-to-write and
+* easy-to-read
+
+and that lets you author web pages in __plain text__.
+
+
+# What's Markdown? Example
+
+~~~
+# What's Markdown?
+
+Markdown is a wiki-style markup language that's
+
+* easy-to-write and
+* easy-to-read
+
+and that lets you author web pages in __plain text__.
+~~~
+
+becomes
+
+~~~
+
What's Markdown?
+
+
+Markdown is a wiki-style markup language that's
+
+
+
+
easy-to-write and
+
easy-to-read
+
+
+
+and that lets you author web pages in plain text.
+
+~~~
+
+
+# Live Demo - Markdown Note
+
+
+
+Try [`note.herokuapp.com`](http://note.herokuapp.com)
+
+
+# More Plain Text Wiki-Style Markup Languages
+
+Many languages including:
+
+- Bulletin Board Code (BBCode) - used in PHP forums
+- MediaWiki Markup - used in Wikipedia
+- Org-mode - used in Emacs Editor
+- reStructuredText (reST) - used in Python docs
+- Textile
+- AsciiDoc
+
+and many more
+
+
+# Syntax - Text Formatting - **Bold**, *Italic*, `Monospaced (Code)`
+
+### Markdown
+
+~~~
+**bold text** or __bold text__
+
+*italic text* or _italic text_
+
+Inline `monospaced` text.
+~~~
+
+
+### Bulletin Board Code
+
+~~~
+[b]bold text[/b]
+
+[i]italic text[/i]
+
+[code]monospace text[/code]
+~~~
+
+
+### Wikipedia
+
+~~~
+'''bold text'''
+
+''italic text''
+
+monospace text
+~~~
+
+
+
+# Syntax - Header Formatting
+
+### Markdown
+
+~~~
+# Level 1 Header
+
+## Level 2 Header
+
+or
+
+Level 1 Header
+==============
+
+Level 2 Header
+--------------
+~~~
+
+
+### Bulletin Board Code
+
+Does not support headers
+
+
+### Wikipedia
+
+~~~
+= Level 1 Header =
+
+== Level 2 Header ==
+~~~
+
+
+
+# Syntax - Hyperlink
+
+### Markdown
+
+~~~
+
+
+or
+
+[Link text](http://www.example.com "optional title attribute")
+
+or
+
+[Link text][id]
+and elsewhere
+[id]: http://www.example.com "optional title attribute"
+~~~
+
+
+### Bulletin Board Code
+
+~~~
+[url]http://www.example.com[/url]
+[url=http://www.example.com]Link text[/url]
+~~~
+
+
+### Wikipedia
+
+~~~
+[[Internal page]]
+[[Internal page|Displayed text]]
+[http://www.example.com]
+[http://www.example.com External link]
+~~~
+
+
+
+# What is Markdown good for?
+
+- Websites
+- Presentations
+- Books
+
+
+### Who is using Markdown?
+
+- GitHub
+- Stack Overflow
+- Reddit
+- You?
+- And many more
+
+
+
+# Website Example - `vienna.rb`
+
+
+`2013-04-13-the-slides-of-our-second-meetup-are-online.markdown`:
+
+~~~
+---
+layout: post
+title: The slides of our second meetup are online
+date: 2013-04-13 17:00
+author: Floor Drees (@floordrees)
+categories: [slides, meetup]
+---
+
+## ALL the slides
+
+Hi there, we just pushed the slides of the second meetup to our [repository][1].
+Feel free to check them out.
+
+##### Floor Drees, introducing the Coders without Borders project
+##### Gerald Bauer on his beer.db and world.db gem
+##### Tomáš Kramár on 'open' data in Slovakia
+##### Anton Bangratz opened up his big o' bag of tricks
+
+Like what you see? Join us for our next [meetup][2] on May the 9th at Sektor5!
+
+
+[1]: https://github.com/vienna-rb/slides
+[2]: http://www.meetup.com/vienna-rb/events/102695522/
+~~~
+
+
+
+Source: [`vienna-rb.at/blog/2013/04/13/the-slides-of-our-second-meetup-are-online`](http://vienna-rb.at/blog/2013/04/13/the-slides-of-our-second-meetup-are-online/)
+
+
+
+# Website Example - `vienna.rb` (Cont.)
+
+List of posts in Markdown. Yeah!
+
+~~~
+_posts/
+ 2013-02-14-vienna-dot-rb-brings-rubyists-together.markdown
+ 2013-03-19-second-meetup-to-take-place-at-co-working-space-sektor5.markdown
+ 2013-03-22-rubyslava-number-26-ruby-meet-up-in-bratislava.markdown
+ 2013-03-26-the-slides-of-our-first-meetup-are-online.markdown
+ 2013-03-27-new-about-page.markdown
+ 2013-04-13-the-slides-of-our-second-meetup-are-online.markdown
+ 2013-04-15-picks.markdown
+ ....
+~~~
+
+
+
+Source: [`github.com/vienna-rb/vienna-rb.github.com/_posts`](https://github.com/vienna-rb/vienna-rb.github.com/tree/source/source/_posts)
+
+
+
+
+# Presentation Example - Slide Show (S9) 10-Minute Tutorial
+
+`talks/tutorial.markdown`:
+
+~~~
+# Slide Show (S9) 10-Minute Tutorial
+
+Agenda
+
+* What's Slide Show (S9)?
+* Wiki-Style Markup Language - Markdown, Textile
+* How it works - Just press F11!
+* What's S5? What's S6?
+* Gradient Themes Using "Loss-Free" Vector Graphics in S9
+* Turn Your Online Wiki Pages into Slide Shows
+
+
+# What's Slide Show (S9)?
+
+A Free Web Alternative to PowerPoint and Keynote in Ruby
+
+### Getting Started in 1-2-3 Easy Steps
+
+* Step 1: Author your slides in plain text using a wiki-style markup language
+* Step 2: Generate your slide show using the `slideshow` gem
+* Step 3: Open up your slide show in your browser and hit the space bar to flip through your slides
+* That's it. Showtime
+
+...
+
+# Thanks - Learn More - Questions? Comments?
+
+Gerald Bauer designed and developed the Slide Show (S9) Ruby gem.
+Find out more @ [`slideshow-s9.github.io`](http://slideshow-s9.github.io)
+
+Questions? Comments? Send them along to the
+[Free Web Slide Show Alternatives Forum](http://groups.google.com/group/webslideshow).
+Thanks!
+~~~
+
+
+
+
+
+# Book Example - Pro Git - Distributed is the New Centralized
+
+
+`progit/en/01-introduction/01-chapter1.markdown`:
+
+~~~
+## A Short History of Git ##
+
+As with many great things in life, Git began with a bit of creative destruction and fiery controversy.
+The Linux kernel is an open source software project of fairly large scope. For most of the lifetime
+of the Linux kernel maintenance (1991–2002), changes to the software were passed around as patches and
+archived files. In 2002, the Linux kernel project began using a proprietary DVCS system called BitKeeper.
+
+In 2005, the relationship between the community that developed the Linux kernel and the commercial
+company that developed BitKeeper broke down, and the tool’s free-of-charge status was revoked.
+This prompted the Linux development community (and in particular Linus Torvalds, the creator of Linux)
+to develop their own tool based on some of the lessons they learned while using BitKeeper.
+Some of the goals of the new system were as follows:
+
+* Speed
+* Simple design
+* Strong support for non-linear development (thousands of parallel branches)
+* Fully distributed
+* Able to handle large projects like the Linux kernel efficiently (speed and data size)
+
+Since its birth in 2005, Git has evolved and matured to be easy to use and yet retain these initial qualities.
+It's incredibly fast, it's very efficient with large projects, and it has an incredible branching system
+for non-linear development (See Chapter 3).
+~~~
+
+
+
+
+# Book Example - Pro Git - Distributed is the New Centralized (Cont.)
+
+~~~
+01-introduction/
+ 01-chapter1.markdown
+02-git-basics/
+ 01-chapter2.markdown
+03-git-branching/
+ 01-chapter3.markdown
+04-git-server/
+ 01-chapter4.markdown
+05-distributed-git/
+ 01-chapter5.markdown
+06-git-tools/
+ 01-chapter6.markdown
+07-customizing-git/
+ 01-chapter7.markdown
+08-git-and-other-scms/
+ 01-chapter8.markdown
+09-git-internals/
+ 01-chapter9.markdown
+~~~
+
+
+
+Source: [github.com/progit/en](https://github.com/progit/progit/tree/master/en)
+
+
+# Markdown Parsers in Ruby
+
+Many options!
+
+- kramdown (Made in Vienna by Thomas Leitner)
+- redcarpet
+- bluecloth
+- maruku
+- rpeg-markdown
+- rdiscount
+- pandoc-ruby
+- and more!
+
+Usage in Ruby:
+
+~~~
+require 'markdown'
+
+Markdown.new( 'Servus Wien' ).to_html
+
+# => "
Servus Wien
\n"
+~~~~
+
+
+
+# What's the `markdown` Gem?
+
+The Markdown Engine Wrapper (`markdown`) gem lets you use your Ruby markdown library of choice. Example:
+
+~~~
+$ set MARKDOWN_LIB=kramdown
+~~~
+
+or
+
+`~/markdown.yml`:
+
+~~~
+## Let's use the Redcarpet library
+
+lib: redcarpet
+
+redcarpet:
+ extensions:
+ - no_intra_emphasis
+ - fenced_code_blocks
+ - tables
+ - strikethrough
+~~~
+
+
+Tip: The `markdown` gem includes a little command line tool. Try `markdown -h` for details.
+Note - The markdown command line tool includes a server and little online markdown editor!
+Try `markdown serve` to start your own web service / HTTP (JSON) API.
+
+Source: [`github.com/geraldb/markdown`](https://github.com/geraldb/markdown)
+
+
+
+# Tooling - Websites
+
+Many static site compilers/builders options! Let's use Jekyll. Example:
+
+`mypage.markdown`:
+
+~~~
+---
+title: My Page
+---
+
+## Page Header
+
+Some text here.
+
+## Another Page Header
+
+More text here.
+
+Some code:
+
+ 10 PRINT "BASIC ROCKS!"
+ 20 GOTO 10
+~~~
+
+To build your site (pages) issue:
+
+~~~
+$ jekyll build
+~~~
+
+That's it. More options:
+
+- Ace
+- Bonsai
+- Frank
+- nanoc
+- Middleman
+- StaticMatic
+- Statis
+- ZenWeb
+- and many more!
+
+
+
+
+# Tooling - Presentations
+
+Many presentation builders options! Let's use Slide Show (S9). Example:
+
+`mytalk.markdown`:
+
+~~~
+# My Slide Title
+
+* Bullet Point One
+* Bullet Point Two
+
+# Another Slide Title
+
+Some text here.
+~~~
+
+To build your presentation issue:
+
+~~~
+$ slideshow mytalk.markdown
+~~~
+
+That's it. More options:
+
+- deck.rb
+- KeyDown
+- Parade
+- ShowOff
+- Slidedown
+- Slide'em up
+- and many more!
+
+
+
+# Tooling - Books
+
+Let's use Pandoc. Note: It's Haskell (not Ruby). Example:
+
+`mybook.txt`:
+
+~~~
+Title: My Book
+Author: Ruby Rubacuori
+
+This is my book.
+
+# Chapter One
+
+Chapter one is over.
+
+# Chapter Two
+
+Chapter two has just begun.
+~~~
+
+To build your book issue:
+
+~~~
+$ pandoc mybook.txt -o mybook.epub
+~~~
+
+That's it.
+
+
+
+# That's it. Thank you.
+
+Questions? Comments?
+
+
+
+
+# Appendix: What's EPUB?
+
+
+
+EPUB (short for Electronic PUBlication) is a free and open e-book standard.
+Files are zipped up archives with the extension `.epub.` Example:
+
+~~~
+title_page.html
+ch01.html
+ch02.html
+ch03.html
+styles.css
+~~~
+
+Plus some extras (defined in the Open Container Format - OCF):
+
+~~~
+mimetype # identification as epub - application/epub+zip
+META-INF/container.xml # contents of the book (in XML)
+content.opf # .opf - Open Packaging Format (in XML)
+toc.ncx # .ncs - Navigation Control file for XML (in XML)
+nav.html
+~~~
+
+
+# Appendix: Zen Writing - Zen Text Editor
+
+What's Zen Writing?
+
+Extremely stripped down text editor - leaving you alone with your thoughts
+and your words - lets you focus on your text.
+
+
+### Linux
+
+- ReText (Free, Open Source)
+- UberWriter (Free, Open Source)
+
+### Windows
+
+- WriteMonkey (Free, Open Source)
+- MarkPad (Free, Open Source)
+
+### Apple / Mac / iPad
+
+- Byword ($9.99)
+- Marked ($2.99)
+- IA Writer ($9.99)
+- Elements ($4.99)
+
+Many more
+
+
+
+# Appendix: What's Markdown Extra?
+
+Adds more "extras" to Markdown. Example:
+
+- Inline HTML
+- Markdown Inside HTML Blocks
+- Header Id Attribute
+- Fenced Code Blocks
+- Tables
+- Definition Lists
+- Footnotes
+- Abbreviations
+- Emphasis
+- Backslash Escapes
+
+Table Example:
+
+~~~
+| Item | Value |
+| --------- | -----:|
+| Computer | $1600 |
+| Phone | $12 |
+| Pipe | $1 |
+~~~
+
+becomes
+
+~~~
+
+
+
+
Item
+
Value
+
+
+
+
+
Computer
+
$1600
+
+
+
Phone
+
$12
+
+
+
Pipe
+
$1
+
+
+
+~~~
+
+
+
+# Appendix: What's Babelmark2? What's Markdown Dingus?
+
+Markdown Dingus - very first online Markdown converter; uses original
+Markdown Perl script)
+
+- [`daringfireball.net/projects/markdown/dingus`](http://daringfireball.net/projects/markdown/dingus)
+
+Babelmark2 - modern version of Markdown Dingus; lets you compare
+many Markdown services via HTTP (JSON) API
+
+- [`johnmacfarlane.net/babelmark2`](http://johnmacfarlane.net/babelmark2/)
+
diff --git a/microformats.text b/microformats.text
new file mode 100644
index 0000000..32c081b
--- /dev/null
+++ b/microformats.text
@@ -0,0 +1,263 @@
+
+Microformats Outline
+====================
+
+Agenda
+
+- What is the Semantic Web? What's Web 3.0?
+- What are Microformats? Why do Microformats matter?
+- Microformats and Browser Plugins and JavaScript APIs
+- Microformats and Ruby on Rails
+- Adding semantics to your web pages (marking up people, events, locations and more using Microformats) and enabling Google Map listings, exporting contacts to your address book and more.
+- Creating RESTful web services using Microformats
+
+
+What is the Semantic Web? What's Web 3.0?
+=========================================
+
+What's HTML?
+
+- The world's most popular markup language.
+- About 50 tags to markup hypertext documents.
+
+Less than 50 tags -> lots of meaning (that is, semantics) gets lost when marking up documents.
+
+Example:
+
+
Intermed. Ruby on Rails Workshop (Incl. Facebook and Mobile Web)
+
+
Friday, January 25, 2008
+
+ BCIT Downtown Campus
+ 555 Seymour Street
+ Vancouver, British Columbia
+
+
+HTML tags such as `h1` (heading1) and `p` (paragraph) and `br` (break) are kind of meaningless (without semantics).
+
+
+Semantic Web - Web 3.0
+======================
+
+Semantic Web - add semantics to your web page by marking up events, people, locations, resumes, listings, feeds and much more.
+
+How? The "official" semantic web proposes new extension to web markup such as Resource Description Framework(RDF) or eXtensible Markup Language (XML)
+
+The "pragmatic" semantic web proposes - let's just use conventions and best practices for today's web markup and today's browsers.
+
+
+Semantic Web Example Using Microformats
+=======================================
+
+Let's add semantics using Microformats to the event example:
+
+
+
Intermed. Ruby on Rails Workshop (Incl. Facebook and Mobile Web)
+
+
Friday, January 25, 2008
+
+
+
+That's all there's is to it.
+
+Why use attributes such as `vevent`, `summary` and `dtstart`?
+
+Microformats build on existing standards! The event Microformat known as hCalendar builds on the existing internet standard called iCalendar (used by Apple's iCal and others) published by the Internet Society/Internet Engineering Task Force (IETF) as Request for Comments (RFC)#2445.
+
+The same event marked-up in "classic" iCalendar format looks like:
+
+ BEGIN:VCALENDAR
+ VERSION:2.0
+ PRODID:-//RailsAdvance//NONSGML Workshop Calendar Version 1.0//EN
+ BEGIN:VEVENT
+ SUMMARY:Intermed. Ruby on Rails Workshop (Incl. Facebook and Mobile Web)
+ DTSTAMP:20080125T000000Z
+ END:VEVENT
+ END:VCALENDAR
+
+
+Now Microformat parsers in Ruby or JavaScript or built-into the browser (such as in Firefox 3) or using a browser plugin (such as in Firefox 1.x/2.x) can find out more about the event and offer mashup services such as export to your calendar, etctera by simply reading (and parsing) the web page.
+
+
+Who's using Microformats?
+=========================
+
+- Google Maps
+- Yahoo! Upcoming Event Listings
+- Flickr Photos
+
+How do I know? Let's try some mashups using Microformats.
+
+
+Firefox Microformat Browser Plugins
+===================================
+
+- Hello Operator - Install Operator
+
+
+Operator Actions / Mashup Samples
+=================================
+
+- Export Contact
+- Add to Google Calendar
+- Find with Google Maps
+- Find photos on flickr
+- Find bookmarks on del.icio.us
+- Find blogs on Technorati
+
+
+Microformat Mashups Demos
+=========================
+
+1. geo Microformat + Google Maps
+2. rel-tag Microformat + Flickr
+3. hCalendar Microformat + Google Calendar
+4. hCard Microformat + Contact Adress Book Export/Import
+
+
+Mashup #1 w/ Maps - Geo Microformat
+====================================
+
+Flickr 2.3 million photos geotagged this month
+
+- Arc the Triumph -> `http://flickr.com/photos/cuellar/244449798/`
+- Golden Bricks - Fall in Vancouver -> `http://flickr.com/photos/januszbc/1776184496/`
+- Vancouver Sculpture Biennale -> `http://flickr.com/photos/pandoras_box/487848863/`
+- New Westminster, SkyTrain Bridge -> `http://flickr.com/photos/januszbc/2100964102/`
+- North Vancouver's Lynn Canyon -> `http://flickr.com/photos/januszbc/2211044973/`
+- Last Day in Paris -> `http://flickr.com/photos/danorbit/346563918/`
+- Grand Canyon -> `http://flickr.com/photos/leviathor/220065623/`
+
+Many more: `http://flickr.com/photos/tags/geotagged/interesting/`
+
+
+Behind the scenes - Geo Microformat Code
+========================================
+
+
+ 49.205486
+ -122.892036
+
+
+Alternative geo Microformat:
+
+
+ North Vancouver's Lynn Canyon
+
+
+Yes. That's it. That's all. A real-word geo microformat from Flickr (a Yahoo! service).
+
+
+Mashup #2 - rel-tag Microformat Demos
+=====================================
+
+`http://rubybook.wordpress.com`
+
+Mashup Actions for microformats tag:
+
+- Find bookmarks on del.icio.us
+- Find photos on flickr -> Get your microformats tatoo!
+- Find events on upcoming
+- Find videos on YouTube -> Bill Gates: "We need microformats" video!
+
+
+Behind the scenes - rel-tag Microformat Code
+============================================
+
+
+ microformats,
+ giantglobalgraph
+
+Yes. That's all, hence, the name rel-tag!
+
+
+Mashup #3 - hCalendar Microformat + Google Calendar
+====================================================
+
+`http://upcoming.yahoo.com/event/390146/`
+
+Demo Tails Export - Click on HTML
+
+
+Mashup #4 - hCard Microformat + Contact Adress Book Export/Import
+==================================================================
+
+Create a hcard sample using hcard creator and save it to your disk
+
+- hCard creator -> http://microformats.org/code/hcard/creator
+
+
+Microformats and REST
+=====================
+
+REST - Best practices for existing protocols and formats
+
+- protocols -> HTTP (Hypertext Transfer Protocol)
+- formats -> HTML (Hypertext Markup Language)
+
+Microformats -> Best Practices for HTML (Add Semantics to web pages using today's browsers)
+
+
+Microformats and Ruby - What is Mofo?
+=====================================
+
+Mofo - Ruby Microformat Parser Project @ mofo.rubyforge.org
+
+- Getting Started w/ Mofo (see "[Online Tutorial](http://rubybook.wordpress.com/2008/01/18/microformats/)")
+- Try hcard - create hcard using hcard creator and parse it using mofo
+
+
+Creating RESTful web services using Microformats
+================================================
+
+Turn your web page into an API.
+
+Instead of asking for the user's address, ask for a web page (URL/URI) and use Microformats to get the address.
+
+Instead of asking for the event details, ask for a web page (URL/URI) to includes all the event details marked up using Microformats.
+
+Subscribe to an event, contact card using a web page (similar to a web feed) and the event, contact card stays up-to-date.
+
+Microformats in a way is a "legalized" and standardized way for screen scrapping.
+
+The Ruby Mofo library is - surprise, surprise - built on Hpricot.
+
+
+Microformats Line-Up
+====================
+
+- hCalendar -> events
+- hCard -> people, contacts (business cards)
+- hResume -> resumes (including skills)
+- hReview -> movie reviews, wine reviews, you name it reviews
+- hListing -> product listing, classifieds
+
+The rel family (link rel=relationship attribute)
+
+
+
+ Create Commons Attribution Non-Commercial 3.0
+
+- rel-license -> license type (creative commons, cc)
+- rel-tag -> tagging
+- XFN (XHTML Friend Network) -> friends
+
+Sample:
+
+
+ Gerald Bauer's Blog
+
+`http://gmpg.org/xfn/creator`
+
+
+Microformat Support Built Into Firefox 3
+========================================
+
+JavaScript API - Intro @ `developer.mozilla.org/en/docs/Using_microformats`
+
+
+More Microformats and Ruby Links
+================================
+
+Article: Me and uformats (Microformats) - err.the_blog (Chris Wanstrath)
+@ `http://errtheblog.com/posts/35-me-and-uformats`
diff --git a/microformats.textile b/microformats.textile
new file mode 100644
index 0000000..05b2274
--- /dev/null
+++ b/microformats.textile
@@ -0,0 +1,267 @@
+title: Microformats - Adding Semantics to Your Web Site - Web 3.0 in Action
+gradient-colors: green lime
+
+
+h1. Microformats Outline
+
+Agenda
+
+* What is the Semantic Web? What's Web 3.0?
+* What are Microformats? Why do Microformats matter?
+* Microformats and Browser Plugins and JavaScript APIs
+* Microformats and Ruby on Rails
+* Adding semantics to your web pages (marking up people, events, locations and more using Microformats) and enabling Google Map listings, exporting contacts to your address book and more.
+* Creating RESTful web services using Microformats
+
+
+h1. What is the Semantic Web? What's Web 3.0?
+
+What's HTML?
+
+* The world's most popular markup language.
+* About 50 tags to markup hypertext documents.
+
+Less than 50 tags -> lots of meaning (that is, semantics) gets lost when marking up documents.
+
+Example:
+
+{{{
+
VanDev: Microformats - Adding Semantics to Your Web Site
+
+
Wednesday, April 16, 2008
+
+UBC Robson Square
+800 Robson St.
+Vancouver, British Columbia
+
+}}}
+
+HTML tags such as @h1@ (heading1) and @p@ (paragraph) and @br@ (break) are kind of meaningless (without semantics).
+
+
+h1. Semantic Web - Web 3.0
+
+Semantic Web - add semantics to your web page by marking up events, people, locations, resumes, listings, feeds and much more.
+
+How? The "official" semantic web proposes new extension to web markup such as Resource Description Framework(RDF) or eXtensible Markup Language (XML)
+
+The "pragmatic" semantic web proposes - let's just use conventions and best practices for today's web markup and today's browsers.
+
+
+h1. Semantic Web Example Using Microformats
+
+Let's add semantics using Microformats to the event example:
+
+{{{
+
+
VanDev: Microformats - Adding Semantics to Your Web Site
+
+
Wednesday, April 16, 2008
+
+
+}}}
+
+That's all there's is to it.
+
+Why use attributes such as @vevent@, @summary@ and @dtstart@?
+
+Microformats build on existing standards! The event Microformat known as hCalendar builds on the existing internet standard called iCalendar (used by Apple's iCal and others) published by the Internet Society/Internet Engineering Task Force (IETF) as Request for Comments (RFC)#2445.
+
+The same event marked-up in "classic" iCalendar format looks like:
+
+{{{
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//VanDev//NONSGML Calendar Version 1.0//EN
+BEGIN:VEVENT
+SUMMARY:VanDev: Microformats - Adding Semantics to Your Web Site
+DTSTAMP:20080416T000000Z
+END:VEVENT
+END:VCALENDAR
+}}}
+
+Now Microformat parsers in Ruby or JavaScript or built-into the browser (such as in Firefox 3) or using a browser plugin (such as in Firefox 1.x/2.x) can find out more about the event and offer mashup services such as export to your calendar, etctera by simply reading (and parsing) the web page.
+
+
+h1. Who's using Microformats?
+
+* Google Maps
+* Yahoo! Upcoming Event Listings
+* Flickr Photos
+
+How do I know? Let's try some mashups using Microformats.
+
+
+h1. Firefox Microformat Browser Plugins
+
+* Hello Operator - "Install Operator Firefox Browser Addon":https://addons.mozilla.org/en-US/firefox/addon/4106
+
+h3. What's Operator?
+
+Operator is a free, open source Firefox browser addon that lets you interact with semantic data on web pages,
+including Microformats, RDFa and eRDF.
+
+
+
+h1. Operator Actions / Mashup Samples
+
+* Export Contact
+* Add to Google Calendar
+* Find with Google Maps
+* Find photos on flickr
+* Find bookmarks on del.icio.us
+* Find blogs on Technorati
+
+
+h1. Microformat Mashups Demos
+
+# geo Microformat + Google Maps
+# rel-tag Microformat + Flickr
+# hCalendar Microformat + Google Calendar
+# hCard Microformat + Contact Adress Book Export/Import
+
+
+h1. Mashup #1 w/ Maps - Geo Microformat
+
+Flickr 2.3 million photos geotagged this month
+
+* Arc the Triumph -> http://flickr.com/photos/cuellar/244449798/
+* Golden Bricks - Fall in Vancouver -> http://flickr.com/photos/januszbc/1776184496/
+* Vancouver Sculpture Biennale -> http://flickr.com/photos/pandoras_box/487848863/
+* New Westminster, SkyTrain Bridge -> http://flickr.com/photos/januszbc/2100964102/
+* North Vancouver's Lynn Canyon -> http://flickr.com/photos/januszbc/2211044973/
+* Last Day in Paris -> http://flickr.com/photos/danorbit/346563918/
+* Grand Canyon -> http://flickr.com/photos/leviathor/220065623/
+
+Many more: http://flickr.com/photos/tags/geotagged/interesting/
+
+
+h1. Behind the scenes - Geo Microformat Code
+
+{{{
+
+ 49.205486
+ -122.892036
+
+}}}
+
+Alternative geo Microformat:
+
+{{{
+
+ North Vancouver's Lynn Canyon
+
+}}}
+
+Yes. That's it. That's all. A real-word geo microformat from Flickr (a Yahoo! service).
+
+
+h1. Mashup #2 - rel-tag Microformat Demos
+
+http://rubybook.wordpress.com
+
+Mashup Actions for microformats tag:
+
+* Find bookmarks on del.icio.us
+* Find photos on flickr -> Get your microformats tatoo!
+* Find events on upcoming
+* Find videos on YouTube -> Bill Gates: "We need microformats" video!
+
+
+h1. Behind the scenes - rel-tag Microformat Code
+
+{{{
+microformats,
+giantglobalgraph
+}}}
+
+Yes. That's all, hence, the name rel-tag!
+
+
+h1. Mashup #3 - hCalendar Microformat + Google Calendar
+
+http://upcoming.yahoo.com/event/448518/
+
+Demo Tails Export - Click on HTML
+
+
+h1. Mashup #4 - hCard Microformat + Contact Adress Book Export/Import
+
+Create a hcard sample using hcard creator and save it to your disk
+
+* hCard creator -> http://microformats.org/code/hcard/creator
+
+
+h1. Microformats and REST
+
+REST - Best practices for existing protocols and formats
+
+* protocols -> HTTP (Hypertext Transfer Protocol)
+* formats -> HTML (Hypertext Markup Language)
+
+Microformats -> Best Practices for HTML (Add Semantics to web pages using today's browsers)
+
+
+h1. Microformats and Ruby - What is Mofo?
+
+Mofo - Ruby Microformat Parser Project @ mofo.rubyforge.org
+
+# Getting Started w/ Mofo (see "Online Tutorial":http://rubybook.wordpress.com/2008/01/18/microformats/)
+# Try hcard - create hcard using hcard creator and parse it using mofo
+
+h3. More Microformats and Ruby Links
+
+Article: Me and uformats (Microformats) - err.the_blog (Chris Wanstrath)
+@ http://errtheblog.com/posts/35-me-and-uformats
+
+
+h1. Creating RESTful web services using Microformats
+
+Turn your web page into an API.
+
+Instead of asking for the user's address, ask for a web page (URL/URI) and use Microformats to get the address.
+
+Instead of asking for the event details, ask for a web page (URL/URI) to includes all the event details marked up using Microformats.
+
+Subscribe to an event, contact card using a web page (similar to a web feed) and the event, contact card stays up-to-date.
+
+Microformats in a way is a "legalized" and standardized way for screen scrapping.
+
+The Ruby Mofo library is - surprise, surprise - built on Hpricot.
+
+
+h1. Microformats Line-Up
+
+* hCalendar -> events
+* hCard -> people, contacts (business cards)
+* hResume -> resumes (including skills)
+* hReview -> movie reviews, wine reviews, you name it reviews
+* hListing -> product listing, classifieds
+
+The rel family (link rel=relationship attribute)
+
+{{{
+
+ Create Commons Attribution Non-Commercial 3.0
+}}}
+
+* rel-license -> license type (creative commons, cc)
+* rel-tag -> tagging
+* XFN (XHTML Friend Network) -> friends
+
+{{{
+
+ Gerald Bauer's Blog
+}}}
+
+http://gmpg.org/xfn/creator
+
+
+h1. Microformat Support Built Into Firefox 3
+
+JavaScript API - Intro @ developer.mozilla.org/en/docs/Using_microformats
+
+
+h1. That's it - Thanks - Questions?
+
+{{ google_analytics :code => 'UA-397343-10' }}
\ No newline at end of file
diff --git a/mobile.textile b/mobile.textile
new file mode 100644
index 0000000..501079a
--- /dev/null
+++ b/mobile.textile
@@ -0,0 +1,364 @@
+%%%%%%%
+% Slide Show Headers
+
+title: Create Mobile Web Apps with the iUI JavaScript Library
+gradient: top_bottom blue navy
+
+
+%%%%%%%%%%%%%
+% Slides Start Here
+
+h1. Create Mobile Web Apps with the iUI JavaScript Library
+
+"Gerald Bauer":http://geraldbauer.ca @ "MobileCampVancouver2":http://barcamp.org/MobileCampVancouver2, Vancouver, British Columbia, September 2008
+
+---
+("Source":http://slideshow.rubyforge.org/svn/samples/mobile.textile)
+
+{{help}}
+
+
+h1. What's the Mobile Web?
+
+The mobile web is just like the regular web but you access it on the go using mobile devices
+such as mobile phones, mobile music/media players, mobile internet tablets etcetera.
+
+Related Terms:
+
+"One Web" - Before the Apple iPhone popularized the mobile web
+the industry used different "standards"
+for web access on mobile devices such as Wireless Markup Language (WML)
+or Wireless Access Protocoll (WAP) or XHTML Basic.
+
+One Web = Use "classic" HTML, CSS, JavaScript, etcetera on the mobile web.
+No need for different "standards".
+
+
+h1. Why does the mobile web matter?
+
+* Billions of mobile phones.
+* More and more "smart" phones have built-in industry-strength browsers.
+
+
+h1. How does the mobile web differ from the "classic" web?
+
+h3. Usually smaller screen
+
+e.g. Apple's iPhone screen size is 320x480 pixel or 480x320 pixel.
+
+Note, iPhone's browser lets you zoom in and zoom out. By default for non-mobile
+web screen size optimized sites iPhone will zoom out
+to make the screen appear to have a size of 980 pixels (instead of the actual 320).
+
+h3. Limited keyboard for text entry and limited clicking (no mouse)
+
+Use accesskey for links allowing you to "click" links using your phone key numbers (
+such as 1,2,3,4,5,etc.)
+
+h3. Limited connectivity/offline
+
+h3. Special links for phone numbers
+
+{{{
+1-604-555-5555
+}}}
+
+
+h1. What's iUI?
+
+iUI is an open-source framework (really just one @iui.js@ - JavaScript file,
+one @iui.css@ - style sheet and many graphics)
+created by Joe Hewitt (of Firebug fame) and now working at Facebook (and responsible for - surprise, surprise - the mobile web version of Facebook).
+
+* "iUI Project Site":http://code.google.com/p/iui
+* "iUI Intro":http://www.joehewitt.com/blog/introducing_iui.php by Joe Hewitt
+
+
+h1. iUI Design
+
+* Single-Page Web Application (Clicking on link fires off an Ajax/JavaScript request -> Page gets updated w/ animation effect!)
+* Ajax/JavaScript Machinery Hidden - Just use plain HTML list tags (@ul@, [@li@]), links ([@a@]) and it works; no JavaScript coding required.
+* Back button still works.
+
+h1. iUI - Getting Started in Three Minutes
+
+Step 1: Download and Unzip iUI Package @ "code.google.com/p/iui":http://code.google.com/p/iui
+
+Step 2: Try the Music Example or the Theaters Search Example (Open Up Page in a WebKit Browser)
+
+That's it. No Developer $$$ Fee. No F!?#!ing Non-Disclosure Agreement (NDA).
+
+
+h1. iUI - Lists
+
+!iui-hoods.png!
+
+{{{
+
+}}}
+
+Add @class='group'@ to mark list item for grouping. That's it.
+
+h1. iUI - Panels
+
+!iui-panel.png!
+
+{{{
+
+
About RoomieNATOR
+
Sample Mobile Web App using the iUI JavaScript Library w/ Ruby on Rails
+
+}}}
+
+Add @class='panel'@ to mark @div@ block as a panel. That's it.
+
+h1. iUI - Link Types
+
+* Intra-Page iUI Link (@#artists@)
+* iUI Link (@/stats@)
+* Plain Old Link (Reload New Page) (@target='_self'@)
+
+!iui-links.png!
+
+{{{
+
+...
+}}}
+
+h1. iUI - Forms
+
+!iui-form.png!
+
+{{{
+
+}}}
+
+Mark @div@ block with @class='row'@ for form rows and submit button with @class='whiteButton'@.
+
+h1. All Together Now
+
+* Single-Page Web Application (Clicking on link fires off an Ajax/JavaScript request -> Page gets updated w/ animation effect)
+
+{{{
+
+
+ RoomieNATOR
+
+
+
+
+
+
+
+
+
+
+~~~
+
+
+# Example 2 - `` - Usage
+
+~~~
+
+
+
+
+ football.js
+
+
+
+
+
+
+
+~~~
+
+
+
+That's it.
+
+
+# Thanks - Questions? Comments?
+
diff --git a/webfeeds.md b/webfeeds.md
new file mode 100644
index 0000000..134b3e8
--- /dev/null
+++ b/webfeeds.md
@@ -0,0 +1,561 @@
+title: Using Web Feeds to Build Planet Sites in Ruby
+
+%css
+
+pre {
+ padding: 4px 4px 4px 4px;
+ border-top: #bbb 1px solid;
+ border-bottom: #bbb 1px solid;
+ background: #f3f3f3;
+}
+
+%end
+
+
+# Using Web Feeds to Build Planet Sites in Ruby
+
+Agenda
+
+
+* What's a Web Feed?
+* What's a Planet?
+* Why Planet? What's Planet Planet?
+* What's Pluto?
+* Reading Web Feeds in Ruby - `RSS::Rss`
+* Reading Web Feeds in Ruby - `RSS::Atom::Feed`
+* Who Cares? Let's Normalize - A Web Feed is a Web Feed is a Web Feed
+* Planet Feed Reader in 20 Lines of Ruby
+* Production-Ready? Real-World World Feed Reader?
+* `planet.rb` - Using the Pluto Gem w/ Sinatra
+
+
+
+# What's a Web Feed?
+
+
+
+A web feed (or news feed) is a simple document/data format
+that 1) lets you publish a list of
+status updates, blog postings, articles, pictures, cartoons, recordings, etc
+and that 2) lets others subscribe to your updates.
+
+
+# What's a Web Feed? (Cont.)
+
+Example:
+
+~~~
+
+ Floor Drees » blog
+
+ 2013-10-23T13:54:22Z
+
+ DevFest Vienna, Day 1 & 2: Talks, Presentations and Hacking
+
+ 2013-10-23T13:54:22Z
+ A tad overdue, but still: my recap of this years Vienna DevFest...
+ ...
+
+
+ Time for a new adventure at CheckiO
+
+ 2013-10-21T07:00:07Z
+ It's time for a personal announcement - I heard that's what a blog is for anyway...
+ ...
+
+~~~
+
+[(Source: `1stfloorgraphics.nl/blog/feed`)](http://www.1stfloorgraphics.nl/blog/feed/atom/)
+
+
+
+# What's a Planet?
+
+It's a kind of Do-It-Yourself Facebook News Feed:
+
+Step 1) Read a list of web feeds.
+
+Step 2) Mix up all postings in a new page.
+
+Step 3) Serve and enjoy.
+
+
+
+# What's a Planet? (Cont.)
+
+
+Example: Planet Vienna.rb
+
+
+
+
+
+# What's a Planet? (Cont.)
+
+Example: Planet Vienna.rb - Alternative Design / Style
+
+
+
+
+
+# Why Planet? What's Planet Planet?
+
+In an age long before Facebook in the year 2004:
+
+Planet Planet [(`planetplanet.org`)](http://www.planetplanet.org) - very first
+free planet scripts and templates (by Scott James Remnant and Jeff Waugh) in Python
+for reading web feeds and building new web pages;
+used for Planet Gnome [(`planet.gnome.org`)](https://planet.gnome.org) ([Hackergotchi Heads](https://planet.gnome.org/heads/))
+and Planet Debian [(`planet.debian.org`)](http://planet.debian.org/) (still running today!).
+
+
+More Planets:
+
+[Planet Ubuntu](http://planet.ubuntu.com) •
+[Planet Fedora](http://planet.fedoraproject.org) •
+[Planet Free Desktop](http://planet.freedesktop.org) •
+[Planet KDE](http://planetkde.org) •
+[Planet Mozilla](http://planet.mozilla.org) •
+[Planet Firefox](http://planet.firefox.com) •
+[Planet Document Foundation](http://planet.documentfoundation.org) •
+[Planet Apache](http://planet.apache.org/committers) •
+[Planet WordPress](http://planet.wordpress.org) •
+[Planet Drupal](http://drupal.org/planet) •
+[Planet Django](http://www.planetdjango.org) •
+[Planet Parrot](http://planet.parrotcode.org) •
+[Planet Haskell](http://planet.haskell.org) •
+[Planet Ruby](http://plutolive.herokuapp.com/ruby) •
+[Planet JavaScript](http://plutolive.herokuapp.com/js) •
+[Planet Dart](http://plutolive.herokuapp.com/dart) •
+[Planet Vienna.rb](http://viennarb.herokuapp.com) •
+and many many more.
+
+Your Planet?
+
+
+# What's Pluto?
+
+
+
+A [free planet site generator](http://feedreader.github.io) in Ruby (Yes!)
+that lets you build web pages from published web feeds.
+
+Use the `pluto` command line tool and pass in one or more planet configuration files.
+Example:
+
+~~~
+$ pluto build viennarb.ini
+~~~
+
+This will
+
+1) fetch all feeds listed in `viennarb.ini` and
+
+2) store all entries in a local database, that is, `viennarb.db` in your working folder and
+
+3) generate a planet web page, that is, `viennarb.html` using the blank template pack in your working folder using all feed entries from the local database.
+
+Open up `viennarb.html` to see your planet web page. Voila!
+
+
+# What's Pluto? (Cont.)
+
+Appendix: `viennarb.ini`
+
+~~~
+title = Planet Vienna.rb
+
+[viennarb]
+ title = Vienna.rb Blog
+ link = http://vienna-rb.at
+ feed = http://vienna-rb.at/atom.xml
+
+[viennarbmeetup]
+ title = Vienna.rb Meetups
+ link = http://www.meetup.com/vienna-rb
+ feed = http://www.meetup.com/vienna-rb/events/rss/vienna.rb/
+
+[floor]
+ title = Floor Drees's Blog
+ link = http://www.1stfloorgraphics.nl/blog/
+ feed = http://www.1stfloorgraphics.nl/blog/feed/
+
+[pxlpnk]
+ title = Andreas Tiefenthaler's Blog
+ link = http://lab.an-ti.eu
+ feed = http://lab.an-ti.eu/atom.xml
+
+[abangratz]
+ title = Anton Bangratz's Blog
+ link = http://abangratz.github.io
+ feed = http://abangratz.github.io/atom.xml
+
+...
+~~~
+
+
+
+# Reading Web Feeds in Ruby - `RSS::Rss`
+
+
+## 1) RSS - Really Simple Syndication / Rich Site Summary
+
+~~~
+require 'rss'
+require 'open-uri'
+
+xml = open( 'http://www.1stfloorgraphics.nl/blog/feed' ).read
+
+feed = RSS::Parser.parse( xml )
+
+puts "feed.class.name: #{feed.class.name}"
+
+puts "== #{feed.channel.title} =="
+
+feed.items.each do |item|
+ puts "- #{item.title}"
+ puts " (#{item.link})"
+ puts
+end
+~~~
+
+
+# Reading Web Feeds in Ruby - `RSS::Rss` (Cont.)
+
+Prints:
+
+~~~
+feed.class.name: RSS::Rss
+
+== Floor Drees » blog ==
+
+- DevFest Vienna, Day 1 & 2: Talks, Presentations and Hacking
+ (http://www.1stfloorgraphics.nl/2013/10/23/devfest-vienna-day-1-2-talks-presentations-and-hacking/)
+
+- Time for a new adventure at CheckiO
+ (http://www.1stfloorgraphics.nl/2013/10/21/time-for-a-new-adventure-at-checkio/)
+
+- DevFest Vienna Day 0, 18 October
+ (http://www.1stfloorgraphics.nl/2013/10/19/devfest-vienna-day-0-18-october/)
+
+- Can we talk about programming again?
+ (http://www.1stfloorgraphics.nl/2013/10/18/can-we-talk-about-programming-again/)
+
+- Ruby resources for those getting started
+ (http://www.1stfloorgraphics.nl/2013/10/17/ruby-resources-for-those-getting-started/)
+
+- RuPy Budapest 2013 – the day after
+ (http://www.1stfloorgraphics.nl/2013/10/14/rupy-budapest-2013-the-day-after/)
+
+- Arrrrcamp 2013 – a recap
+ (http://www.1stfloorgraphics.nl/2013/10/10/arrrrcamp-2013-a-recap/)
+
+- WordCamp Europe 2013 – a recap
+ (http://www.1stfloorgraphics.nl/2013/10/06/wordcamp-europe-2013-a-recap/)
+
+- Working towards great version control for content creators / talk excerpt #wceu 2013
+ (http://www.1stfloorgraphics.nl/2013/10/06/working-towards-great-version-control-for-content-creators-talk-excerpt
+
+- How to survive the holidays as a Techie
+ (http://www.1stfloorgraphics.nl/2013/10/05/how-to-survive-the-holidays-as-a-techie/)
+~~~
+
+
+
+# Reading Web Feeds in Ruby - `RSS::Atom::Feed`
+
+## 2) ATOM
+
+~~~
+require 'rss'
+require 'open-uri'
+
+xml = open( 'http://www.1stfloorgraphics.nl/blog/feed/atom' ).read
+
+feed = RSS::Parser.parse( xml )
+
+puts "feed.class.name: #{feed.class.name}"
+
+puts "== #{feed.title.content} =="
+
+feed.entries.each do |entry|
+ puts "- #{entry.title.content}"
+ puts " (#{entry.link.href})"
+ puts
+end
+~~~
+
+
+
+# Reading Web Feeds in Ruby - `RSS::Atom::Feed` (Cont.)
+
+Prints:
+
+~~~
+feed.class.name: RSS::Atom::Feed
+
+== Floor Drees » blog ==
+- DevFest Vienna, Day 1 & 2: Talks, Presentations and Hacking
+ (http://www.1stfloorgraphics.nl/2013/10/23/devfest-vienna-day-1-2-talks-presentations-and-hacking/)
+
+- Time for a new adventure at CheckiO
+ (http://www.1stfloorgraphics.nl/2013/10/21/time-for-a-new-adventure-at-checkio/)
+
+- DevFest Vienna Day 0, 18 October
+ (http://www.1stfloorgraphics.nl/2013/10/19/devfest-vienna-day-0-18-october/)
+
+- Can we talk about programming again?
+ (http://www.1stfloorgraphics.nl/2013/10/18/can-we-talk-about-programming-again/)
+
+- Ruby resources for those getting started
+ (http://www.1stfloorgraphics.nl/2013/10/17/ruby-resources-for-those-getting-started/)
+
+- RuPy Budapest 2013 – the day after
+ (http://www.1stfloorgraphics.nl/2013/10/14/rupy-budapest-2013-the-day-after/)
+
+- Arrrrcamp 2013 – a recap
+ (http://www.1stfloorgraphics.nl/2013/10/10/arrrrcamp-2013-a-recap/)
+
+- WordCamp Europe 2013 – a recap
+ (http://www.1stfloorgraphics.nl/2013/10/06/wordcamp-europe-2013-a-recap/)
+
+- Working towards great version control for content creators / talk excerpt #wceu 2013
+ (http://www.1stfloorgraphics.nl/2013/10/06/working-towards-great-version-control-for-content-creators-talk-excerpt-wceu-2013/)
+
+- How to survive the holidays as a Techie
+ (http://www.1stfloorgraphics.nl/2013/10/05/how-to-survive-the-holidays-as-a-techie/)
+~~~
+
+
+# What's the difference? RSS vs ATOM
+
+| RSS | ATOM |
+| --------------------- | ----------------------- |
+| `feed.channel.title` | `feed.title.content` |
+| `item.title` | `entry.title.content` |
+| `item.link` | `entry.link.href` |
+
+
+RSS:
+
+~~~
+
+
+ Floor Drees » blog
+ http://www.1stfloorgraphics.nl
+ Wed, 23 Oct 2013 13:54:22 +0000
+
+ DevFest Vienna, Day 1 & 2: Talks, Presentations and Hacking
+ http://www.1stfloorgraphics.nl/2013/10/23/devfest-vienna-day-1-2-talks-presentations-and-hacking/
+ Wed, 23 Oct 2013 13:54:22 +0000
+ A tad overdue, but still: my recap of this years Vienna DevFest...
+
+ ...
+
+
+~~~
+
+[(Source: `1stfloorgraphics.nl/blog/feed`)](http://www.1stfloorgraphics.nl/blog/feed/)
+
+ATOM:
+
+~~~
+
+ Floor Drees » blog
+
+ 2013-10-23T13:54:22Z
+
+ DevFest Vienna, Day 1 & 2: Talks, Presentations and Hacking
+
+ 2013-10-23T13:54:22Z
+ A tad overdue, but still: my recap of this years Vienna DevFest...
+
+ ...
+
+~~~
+
+[(Source: `1stfloorgraphics.nl/blog/feed/atom`)](http://www.1stfloorgraphics.nl/blog/feed/atom/)
+
+
+
+# Who Cares? Let's Normalize - A Web Feed is a Web Feed is a Web Feed
+
+Uniform title, link, summary, content, etc. (for standard case):
+
+~~~
+require 'feedutils'
+require 'open-uri'
+
+xml = open( 'http://www.1stfloorgraphics.nl/blog/feed' ).read
+# xml = open( 'http://www.1stfloorgraphics.nl/blog/feed/atom' ).read
+
+feed = FeedUtils::Parser.parse( xml )
+
+puts "feed.class.name: #{feed.class.name}"
+
+puts "== #{feed.title} =="
+
+feed.items.each do |item|
+ puts "- #{item.title}"
+ puts " (#{item.url})"
+ puts
+end
+
+~~~
+
+
+
+# Who Cares? Let's Normalize - A Web Feed is a Web Feed is a Web Feed (Cont.)
+
+Prints:
+
+~~~
+feed.class.name: FeedUtils::Feed
+
+== Floor Drees » blog ==
+
+- DevFest Vienna, Day 1 & 2: Talks, Presentations and Hacking
+ (http://www.1stfloorgraphics.nl/2013/10/23/devfest-vienna-day-1-2-talks-presentations-and-hacking/)
+
+...
+~~~
+
+More Ruby gems feed options:
+
+- [feedutils](http://rubygems.org/gems/feedutils)
+- [feed-normalizer](http://rubygems.org/gems/feed-normalizer)
+- [simple-rss](http://rubygems.org/gems/simple-rss)
+- [feedzirra](http://rubygems.org/gems/feedzirra)
+- and others
+
+
+
+# Planet Feed Reader in 20 Lines of Ruby
+
+`planet.rb`:
+
+~~~
+require 'open-uri'
+require 'feedutils'
+require 'erb'
+
+# step 1) read a list of web feeds
+
+FEED_URLS = [
+ 'http://vienna-rb.at/atom.xml',
+ 'http://www.meetup.com/vienna-rb/events/rss/vienna.rb/',
+ 'http://www.1stfloorgraphics.nl/blog/feed/',
+ 'http://lab.an-ti.eu/atom.xml',
+ 'http://abangratz.github.io/atom.xml'
+]
+
+items = []
+
+FEED_URLS.each do |url|
+ feed = FeedUtils::Parser.parse( open( url ).read )
+ items += feed.items
+end
+
+# step 2) mix up all postings in a new page
+
+FEED_ITEM_TEMPLATE = <
+
In a series on this website we'll entertain YOU with our picks...
+ ...
+~~~
+
+
+# Production-Ready? Real-World Planet Feed Reader? Almost
+
+1) Cache (Store) Feed Items in Database
+
+e.g. lets you use `items.latest.limit(24)` and so on (SQL queries)
+
+2) Use Conditional GETs When Fetching Feeds
+
+e.g. use HTTP Header `If-Modified-Since` for last modified dates and `If-None-Match` for etags
+
+3) Schedule Feed Auto Update Every Hour
+
+e.g. use `rake update` w/ cron job, for example
+
+
+That's it. Goodies ready for (re)use in pluto gem.
+
+
+
+# `planet.rb` - Using the Pluto Gem w/ Sinatra
+
+`planet.rb`:
+
+~~~
+class Planet < Sinatra::Base
+
+ include Pluto::Models # Models e.g. Feed, Item, Site, etc.
+
+ get '/' do
+ erb :index, locals: { items: Items.latest.limit(24) }
+ end
+
+end
+~~~
+
+`index.erb`:
+
+~~~
+<%% items.each do |item| %>
+
+