These are the slides for the "Dynamic websites for Artists" workshop.
It's a workshop on quick-and-dirty dynamic websites for artists. The workshop covers how to build and host a basic website that accepts user data, saves it, manipulates it, and displays it back.
The workshop covers the basics of using Sinatra, Redis, and Heroku. It uses the Dropbox integration feature of Heroku to deploy sites quickly (and without using git).
Basic HTML knowledge is required, and a passing familiarity with the command line will be very useful.
For the code, see https://github.com/workergnome/dynamic-workshop
2. Who am I?
Lead Developer, Art Tracks, Carnegie Museums.
Ex-Lead Developer, American Eagle Outfitters.
Ex-Lead Developer, Iontank.
Dynamic websites for artists.
David Newbury — @workergnome 2
3. Who am I?
Lead Developer, Art Tracks, Carnegie Museums.
Ex-Lead Developer, American Eagle Outfitters.
Ex-Lead Developer, Iontank.
11 years of freelance web development.
18 years as a professional developer.
Dynamic websites for artists.
David Newbury — @workergnome 3
4. I can make a
real website.
Dynamic websites for artists.
David Newbury — @workergnome 4
5. Who am I?
I have BA in film production.
I build art installations.
I make robots that make cookies.
Dynamic websites for artists.
David Newbury — @workergnome 5
6. Who am I?
I have BA in film production.
I build art installations.
I make robots that make cookies.
I'm an artist.
Dynamic websites for artists.
David Newbury — @workergnome 6
7. This is not how to
make a real website.
Dynamic websites for artists.
David Newbury — @workergnome 7
8. This is not how to
make a real website.
This is how to
fake a website.
Dynamic websites for artists.
David Newbury — @workergnome 8
9. This is not how to
make a real website.
This is how to
fake a website.
Ya know, for art.
Dynamic websites for artists.
David Newbury — @workergnome 9
10. What we're going to do:
Teach you the fast, dirty, mostly free way
to build a website that can save user's data.
Dynamic websites for artists.
David Newbury — @workergnome 10
11. What we're going to do:
Show you how to:
—Use Sinatra
Dynamic websites for artists.
David Newbury — @workergnome 11
12. What we're going to do:
Show you how to:
—Use Sinatra
—Set up a local server
Dynamic websites for artists.
David Newbury — @workergnome 12
13. What we're going to do:
Show you how to:
—Use Sinatra
—Set up a local server
—Deploy to Heroku
Dynamic websites for artists.
David Newbury — @workergnome 13
14. What we're going to do:
Show you how to:
—Use Sinatra
—Set up a local server
—Deploy to Heroku
—Use Redis to store data
Dynamic websites for artists.
David Newbury — @workergnome 14
15. What we're NOT going to do:
—Learn HTML / CSS / Javascript
Dynamic websites for artists.
David Newbury — @workergnome 15
16. What we're NOT going to do:
—Learn HTML / CSS / Javascript
—Talk about relational databases
Dynamic websites for artists.
David Newbury — @workergnome 16
17. What we're NOT going to do:
—Learn HTML / CSS / Javascript
—Talk about relational databases
—Talk about security
Dynamic websites for artists.
David Newbury — @workergnome 17
18. What we're NOT going to do:
—Learn HTML / CSS / Javascript
—Talk about relational databases
—Talk about security
—Save personal, identifying information
Dynamic websites for artists.
David Newbury — @workergnome 18
19. Read along with me.
The code:
http://github.com/workergnome/dynamic-workshop
The slides:
http://www.slideshare.net/workergnome
Dynamic websites for artists.
David Newbury — @workergnome 19
21. Get ready.
1. Get a dropbox account.
http://www.dropbox.com
2. Get a heroku account.
http://www.heroku.com
3. Download Sublime Text 3 (optional)
http://www.sublimetext.com/3
Dynamic websites for artists.
David Newbury — @workergnome 21
22. Get set.
1. Install Ruby
* OSX 10.9/10.10 - !
* Old OSX - http://brew.sh
* Windows - http://rubyinstaller.org
2. Install Bundler
gem install bundler
Dynamic websites for artists.
David Newbury — @workergnome 22
23. Go.
1. Create a Heroku app
2. Link it to Dropbox
3. Open the app directory in Sublime Text
Dynamic websites for artists.
David Newbury — @workergnome 23
28. In the terminal:
cd ~/Dropbox/Apps/Heroku/[your_app_name]
bundle install
bundle exec rackup
In a browser:
http://localhost:9292
Dynamic websites for artists.
David Newbury — @workergnome 28
29. Blammo.
You now have a locally deployed server, hosting your
content.
Dynamic websites for artists.
David Newbury — @workergnome 29
30. Blammo.
You now have a locally deployed server, hosting your
content.
control-c will quit it.
Dynamic websites for artists.
David Newbury — @workergnome 30
31. Potential Problems:
on Windows, this error:
SSLv3 read server certificate B: certificate verify failed
Can be fixed with this:
http://git.io/AEqB
Dynamic websites for artists.
David Newbury — @workergnome 31
32. Deploy to the web.
This is the hard part.
Dynamic websites for artists.
David Newbury — @workergnome 32
33. Deploy to the web.
Go to:
https://dashboard.heroku.com/apps
Dynamic websites for artists.
David Newbury — @workergnome 33
34. Deploy to the web.
Click on your app.
Dynamic websites for artists.
David Newbury — @workergnome 34
35. Deploy to the web.
Click on .
Dynamic websites for artists.
David Newbury — @workergnome 35
36. Deploy to the web.
Type a message:
Dynamic websites for artists.
David Newbury — @workergnome 36
37. Deploy to the web.
Click
Dynamic websites for artists.
David Newbury — @workergnome 37
38. Deploy to the web.
Go to:
https://[your-app-name].herokuapp.com
Dynamic websites for artists.
David Newbury — @workergnome 38
39. Blammo.You're on the internet.
Dynamic websites for artists.
David Newbury — @workergnome 39
40. A quiet round of applause
for you.
Dynamic websites for artists.
David Newbury — @workergnome 40
41. A quiet round of applause
for you.
! ! ! ! ! ! ! ! !
Dynamic websites for artists.
David Newbury — @workergnome 41
46. Explanations.
Gemfile
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
A Gemfile lists dependencies.
External libraries that you'd like to use.
In ruby, these are called Gems.
Gemfiles are managed by Bundler.
Dynamic websites for artists.
David Newbury — @workergnome 46
48. Explanations.
Bundler
Bundler makes sure that the dependencies of your
dependencies don't conflict.
Dynamic websites for artists.
David Newbury — @workergnome 48
50. Explanations.
We want sinatra. sinatra wants rack.
sinatra also wants rack-protection.
rack-protection also wants rack.
We only want one copy of rack.
Dynamic websites for artists.
David Newbury — @workergnome 50
51. Don't worry about
all of this.
Dynamic websites for artists.
David Newbury — @workergnome 51
52. Don't worry about
all of this.
There's only 2 things you need to know:
Dynamic websites for artists.
David Newbury — @workergnome 52
53. #1Heroku uses the Gemfile to setup the server for you.
Dynamic websites for artists.
David Newbury — @workergnome 53
54. #2If you want to use a library, add it to Gemfile.
Dynamic websites for artists.
David Newbury — @workergnome 54
60. Ignore this file.
It's a Rack configuration file that handles the
interface between the webserver and the
framework while allowing middleware applications.
For more information, go to http://rack.github.io.
Dynamic websites for artists.
David Newbury — @workergnome 60
61. Ignore this file.
As long as it has the line
require './hello'
and you have a file named hello.rb
you're !
Dynamic websites for artists.
David Newbury — @workergnome 61
67. Explanations.
Hello.rb:
get '/' do
"Hello World!"
end
when there's a GET request to /,
return the string "Hello World!"
Dynamic websites for artists.
David Newbury — @workergnome 67
68. Two notes about Ruby:
1. Ruby uses do...end instead of {...}
2. Ruby returns the last line by default.
get '/' do
"Hello World!"
end
in Javascript:
function getIndex() {
return "Hello World!";
}
Dynamic websites for artists.
David Newbury — @workergnome 68
69. Let's make this more folksy.
in the terminal:
bundle exec rackup
in hello.rb:
require 'sinatra'
get '/' do
"Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 69
71. What happened?
The server is still running the original code.
Dynamic websites for artists.
David Newbury — @workergnome 71
72. What happened?
The server is still running the original code.
We could fix this by quitting and restarting.
Dynamic websites for artists.
David Newbury — @workergnome 72
73. What happened?
The server is still running the original code.
We could fix this by quitting and restarting.
BOOOORING.
Dynamic websites for artists.
David Newbury — @workergnome 73
74. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
Dynamic websites for artists.
David Newbury — @workergnome 74
75. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
Dynamic websites for artists.
David Newbury — @workergnome 75
76. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
in the terminal:
bundle install
Dynamic websites for artists.
David Newbury — @workergnome 76
77. Let's install a library.
hello.rb:
require 'sinatra'
get '/' do
str = "Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 77
78. Let's install a library.
hello.rb:
require 'sinatra'
require "sinatra/reloader"
get '/' do
str = "Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 78
79. Let's install a library.
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
str = "Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 79
80. Let's install a library.
in the terminal:
bundle exec rackup
and http://localhost:9292
Dynamic websites for artists.
David Newbury — @workergnome 80
82. Let's make this MORE folksy.
hello.rb:
require 'sinatra'
get '/' do
"Howdy, world!"
end
Dynamic websites for artists.
David Newbury — @workergnome 82
83. Let's make this MORE folksy.
hello.rb:
require 'sinatra'
get '/' do
"Howdy, all y'all."
end
Dynamic websites for artists.
David Newbury — @workergnome 83
85. Another quiet round of
applause for you.
Dynamic websites for artists.
David Newbury — @workergnome 85
86. Another quiet round of
applause for you.
! ! ! ! ! ! ! ! !
Dynamic websites for artists.
David Newbury — @workergnome 86
87. Plain text is boring.
Dynamic websites for artists.
David Newbury — @workergnome 87
88. Plain text is boring.
(Says the man with hevetica slides)
Dynamic websites for artists.
David Newbury — @workergnome 88
89. Create a public folder
within your application's folder
and put an image in it.
Dynamic websites for artists.
David Newbury — @workergnome 89
90. Create a public folder
within your application's folder
and put an image in it.
Dynamic websites for artists.
David Newbury — @workergnome 90
91. Create a public folder
within your application's folder
and put an image in it.
Dynamic websites for artists.
David Newbury — @workergnome 91
92. Let's make this EVEN MORE folksy.
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all."
end
Dynamic websites for artists.
David Newbury — @workergnome 92
93. Let's make this EVEN MORE folksy.
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all. <br> <img src='cowboy.png'>"
end
Dynamic websites for artists.
David Newbury — @workergnome 93
95. And if we want another URL?
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all. <br> <img src='cowboy.png'>"
end
get '/goodbye' do
"So long, partner."
end
Dynamic websites for artists.
David Newbury — @workergnome 95
99. Move our pages out of the code:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all. <br> <img src='cowboy.png'>"
end
get '/goodbye' do
"So long, partner."
end
Dynamic websites for artists.
David Newbury — @workergnome 99
100. Move our pages out of the code:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 100
101. And add them to a views folder:
views/index.erb:
<p>
Howdy, all y'all. <br>
<img src='cowboy.png'>
</p>
views/goodbye.erb:
<p>So long, partner.</p>
Dynamic websites for artists.
David Newbury — @workergnome 101
102. Let's make it dynamic!
Dynamic websites for artists.
David Newbury — @workergnome 102
114. Sometimes we want
statefullness.
We want a session.
Really, we just want a cookie.
Dynamic websites for artists.
David Newbury — @workergnome 114
115. Sometimes we want
statefullness.
We want a session.
Really, we just want a cookie.
!
Dynamic websites for artists.
David Newbury — @workergnome 115
117. Cookies let the
client and the server talk.
Dynamic websites for artists.
David Newbury — @workergnome 117
118. Cookies let the
client and the server talk.
!
Dynamic websites for artists.
David Newbury — @workergnome 118
119. For the client, we need jQuery...
layout.erb:
<!DOCTYPE html>
<html>
<head>
<title>Cowboys</title>
<script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
</head>
<body>
<%= yield %>
</body>
</html>
Dynamic websites for artists.
David Newbury — @workergnome 119
120. We also need jQuery Cookie.
Download this:
http://git.io/AEq1
and save it as this:
/public/jquery.cookie.js
Dynamic websites for artists.
David Newbury — @workergnome 120
121. ...and add it to the layout.
layout.erb:
<!DOCTYPE html>
<html>
<head>
<title>Cowboys</title>
<script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
<script src='/jquery.cookie.js'></script>
</head>
<body>
<%= yield %>
</body>
</html>
Dynamic websites for artists.
David Newbury — @workergnome 121
122. And our own javascript file
layout.erb:
<!DOCTYPE html>
<html>
<head>
<title>Cowboys</title>
<script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
<script src='/jquery.cookie.js'></script>
<script src='/application.js'></script>
</head>
<body>
<%= yield %>
</body>
</html>
Dynamic websites for artists.
David Newbury — @workergnome 122
123. Which we'll stick in /public
public/application.js:
$(function() {
$.cookie('you_seen_me', true);
});
Dynamic websites for artists.
David Newbury — @workergnome 123
124. For the server, we need "sinatra/cookies"
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 124
125. For the server, we need "sinatra/cookies"
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
require "sinatra/cookies"
get '/' do
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 125
126. For the server, we need "sinatra/cookies"
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
require "sinatra/cookies"
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 126
127. An aside: @variables
@something is a Ruby instance variable.
They exist in the ruby method and the view.
Dynamic websites for artists.
David Newbury — @workergnome 127
128. hello.rb:
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>
<img src='cowboy.png'>
</p>
Dynamic websites for artists.
David Newbury — @workergnome 128
129. First time you come to the site:
Dynamic websites for artists.
David Newbury — @workergnome 129
130. Second time you come to the site:
Dynamic websites for artists.
David Newbury — @workergnome 130
131. hello.rb:
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>
<img src='cowboy.png'>
</p>
application.js:
$(function() {
$.cookie('you_seen_me', true);
});
Dynamic websites for artists.
David Newbury — @workergnome 131
132. That's a dynamic website
that saves user data.
Dynamic websites for artists.
David Newbury — @workergnome 132
133. Let's push this to the internet.
Click
Dynamic websites for artists.
David Newbury — @workergnome 133
139. Redis is a Key/Value Store.
Dynamic websites for artists.
David Newbury — @workergnome 139
140. Redis is a Key/Value Store.
@redis.set("key","value") #saves the data
Dynamic websites for artists.
David Newbury — @workergnome 140
141. Redis is a Key/Value Store.
@redis.set("key","value") #saves the data
val = @redis.get("key") #val = "value"
Dynamic websites for artists.
David Newbury — @workergnome 141
142. Redis is a Key/Value Store.
@redis.set("key","value") #saves the data
val = @redis.get("key") #val = "value"
That's it.
Dynamic websites for artists.
David Newbury — @workergnome 142
143. Redis is a Key/Value Store.
$redis.set("key","value") #saves the data
val = $redis.get("key") #val = "value"
That's it.
(Not really. But pretend with me.)
Dynamic websites for artists.
David Newbury — @workergnome 143
144. Installing Redis on your computer
OSX:
brew install redis
Dynamic websites for artists.
David Newbury — @workergnome 144
145. Installing Redis on your computer
OSX:
brew install redis
Windows:
Dynamic websites for artists.
David Newbury — @workergnome 145
146. Installing Redis on your computer
OSX:
brew install redis
Windows:
http://git.io/AEq7
Dynamic websites for artists.
David Newbury — @workergnome 146
147. Installing Redis on Heroku
https://addons.heroku.com/rediscloud
Dynamic websites for artists.
David Newbury — @workergnome 147
148. Installing Redis on Heroku
Install it to your app.
Dynamic websites for artists.
David Newbury — @workergnome 148
149. Installing Redis on Heroku
Install it to your app.
Dynamic websites for artists.
David Newbury — @workergnome 149
150. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
Dynamic websites for artists.
David Newbury — @workergnome 150
151. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'redis'
Dynamic websites for artists.
David Newbury — @workergnome 151
152. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'redis'
in the terminal:
bundle install
Dynamic websites for artists.
David Newbury — @workergnome 152
154. hello.rb:
require "sinatra/cookies"
require 'redis'
configure do
if development?
uri = URI.parse("redis://localhost:6379")
else
uri = URI.parse(ENV["REDISCLOUD_URL"])
end
$redis = Redis.new(host: uri.host,
port: uri.port,
password: uri.password)
end
Dynamic websites for artists.
David Newbury — @workergnome 154
155. hello.rb:
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
Dynamic websites for artists.
David Newbury — @workergnome 155
156. hello.rb:
get '/' do
@visitors = $redis.get( 'number_of_visitors' ).to_i
@you_seen_me = cookies[:you_seen_me]
erb :index
end
Dynamic websites for artists.
David Newbury — @workergnome 156
157. hello.rb:
get '/' do
@visitors = $redis.get( 'number_of_visitors' ).to_i
$redis.set( 'number_of_visitors', (@visitors + 1).to_s)
@you_seen_me = cookies[:you_seen_me]
erb :index
end
Dynamic websites for artists.
David Newbury — @workergnome 157
158. index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>
<img src='cowboy.png'>
</p>
Dynamic websites for artists.
David Newbury — @workergnome 158
159. index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>You're visitor <%= @visitors %>!
<br>
<img src='cowboy.png'>
</p>
Dynamic websites for artists.
David Newbury — @workergnome 159
160. Start up Redis:
on OSX:
in a NEW terminal window:
redis-server /usr/local/etc/redis.conf
on Windows:
open the redis-srv.exe file you downloaded.
Dynamic websites for artists.
David Newbury — @workergnome 160
161. in the OLD terminal window:
bundle exec rackup
Dynamic websites for artists.
David Newbury — @workergnome 161
170. Let's create a form.
index.erb:
<img src='cowboy.png'>
</p>
<!--...-->
Dynamic websites for artists.
David Newbury — @workergnome 170
171. Let's create a form.
index.erb:
<img src='cowboy.png'>
</p>
<p>Let's play the classic Cowboy game Finger Guns!</p>
<p>Choose how many fingers to show, and you'll fire at the last person to play.</p>
<p>If the total number of fingers is odd, you win!</p>
<form action="/fire_at_will" method="post">
How Many Fingers?
<input id="fingers" type="text" name="fingers">
<input id='kaboom' type="submit" value="Kaboom">
</form>
Dynamic websites for artists.
David Newbury — @workergnome 171
174. Our post route.
hello.rb:
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 174
175. Our post route. rural, of course.
hello.rb:
get '/goodbye' do
erb :goodbye
end
post '/fire_at_will' do
params[:fingers]
end
Dynamic websites for artists.
David Newbury — @workergnome 175
178. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
end
Dynamic websites for artists.
David Newbury — @workergnome 178
179. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
last_fingers = $redis.get('last_fingers').to_i
end
Dynamic websites for artists.
David Newbury — @workergnome 179
180. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
last_fingers = $redis.get('last_fingers').to_i
$redis.set('last_fingers',fingers)
end
Dynamic websites for artists.
David Newbury — @workergnome 180
181. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
last_fingers = $redis.get('last_fingers').to_i
$redis.set('last_fingers',fingers)
if (fingers + last_fingers).odd?
"you win!"
else
"you lose!"
end
end
Dynamic websites for artists.
David Newbury — @workergnome 181
184. We've just made a game.
Dynamic websites for artists.
David Newbury — @workergnome 184
185. We've just made a game.
A terrible, terrible game.
Dynamic websites for artists.
David Newbury — @workergnome 185
186. We've just made a game.
A terrible, terrible game.
How could we make it better?
Dynamic websites for artists.
David Newbury — @workergnome 186
187. We've just made a game.
A terrible, terrible game.
How could we make it better?
Analytics.
Dynamic websites for artists.
David Newbury — @workergnome 187
188. hello.rb:
if (fingers + last_fingers).odd?
"you win!"
else
"you lose!"
end
Dynamic websites for artists.
David Newbury — @workergnome 188
189. hello.rb:
if (fingers + last_fingers).odd?
@result = "you win!"
else
@result = "you lose!"
end
erb :score
Dynamic websites for artists.
David Newbury — @workergnome 189
190. hello.rb:
if (fingers + last_fingers).odd?
@result = "you win!"
else
@result = "you lose!"
end
erb :score
views/score.erb:
<p><%= @result %></p>
<a href="/">Play again?</a>
Dynamic websites for artists.
David Newbury — @workergnome 190
198. This:
$redis.incr("wins")
Is the same as this:
wins = $redis.get("wins")
wins = wins + 1
$redis.set("wins", wins)
Dynamic websites for artists.
David Newbury — @workergnome 198
199. This:
$redis.incr("wins")
Is the same as this:
wins = $redis.get("wins")
wins = wins + 1
$redis.set("wins", wins)
Just shorter.
Dynamic websites for artists.
David Newbury — @workergnome 199
200. Let's add some math.
hello.rb:
if (fingers + last_fingers).odd?
@result = "you win!"
$redis.incr("wins")
else
@result = "you lose!"
$redis.incr("losses")
end
@wins = $redis.get('wins')
@losses = $redis.get('losses')
erb :score
Dynamic websites for artists.
David Newbury — @workergnome 200
215. CSS
AJAX
User counts
Personal scores
Cheat detection
Completely new experiences
Go out and make cool things.
Dynamic websites for artists.
David Newbury — @workergnome 215
216. CSS
AJAX
User counts
Personal scores
Cheat detection
Completely new experiences
Go out and make cool things.
(And show them to me.)
Dynamic websites for artists.
David Newbury — @workergnome 216
217. David Newbury
@workergnome
The code: http://github.com/workergnome/dynamic-
workshop
The slides: http://www.slideshare.net/workergnome/
dynamic-websites-for-artists
Dynamic websites for artists.
David Newbury — @workergnome 217
218. David Newbury
@workergnome
The code: http://github.com/workergnome/dynamic-
workshop
The slides: http://www.slideshare.net/workergnome/
dynamic-websites-for-artists
Thank you.
Dynamic websites for artists.
David Newbury — @workergnome 218