GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Description: the 4k pocket full-of-gags web microframework
Homepage: http://code.whytheluckystiff.net/camping/
Clone URL: git://github.com/why/camping.git
judofyr (author)
Tue May 20 22:52:52 -0700 2008
commit  243ef1a8b56f62cda6f6b26875e50142f5956719
tree    38f1d47f2abcad18dbf722f6a5b290cc50e6fb1d
parent  1dcec1197078720661ff932d4496b1a558372714
camping / examples / tepee.rb
100755 243 lines (214 sloc) 6.713 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#!/usr/bin/ruby
$:.unshift File.dirname(__FILE__) + "/../lib"
%w(rubygems redcloth camping camping/db acts_as_versioned).each { |lib| require lib }
 
Camping.goes :Tepee
 
module Tepee::Models
 
  class Page < Base
    PAGE_LINK = /\[\[([^\]|]*)[|]?([^\]]*)\]\]/
    validates_uniqueness_of :title
    before_save { |r| r.title = r.title.underscore }
    acts_as_versioned
  end
 
  class CreateTepee < V 1.0
    def self.up
      create_table :tepee_pages do |t|
        t.column :title, :string, :limit => 255
        t.column :body, :text
      end
      Page.create_versioned_table
      Page.reset_column_information
    end
    def self.down
      drop_table :tepee_pages
      Page.drop_versioned_table
    end
  end
 
end
 
module Tepee::Controllers
  class Index < R '/'
    def get
      redirect Show, 'home'
    end
  end
 
  class Show < R '/(\w+)', '/(\w+)/(\d+)'
    def get page_name, version = nil
      redirect(Edit, page_name, 1) and return unless @page = Page.find_by_title(page_name)
      @version = (version.nil? or version == @page.version.to_s) ? @page : @page.versions.find_by_version(version)
      render :show
    end
  end
 
  class Edit < R '/(\w+)/edit', '/(\w+)/(\d+)/edit'
    def get page_name, version = nil
      @page = Page.find_or_create_by_title(page_name)
      @page = @page.versions.find_by_version(version) unless version.nil? or version == @page.version.to_s
      render :edit
    end
    
    def post page_name
      Page.find_or_create_by_title(page_name).update_attributes :body => input.post_body and redirect Show, page_name
    end
  end
 
  class Versions < R '/(\w+)/versions'
    def get page_name
      @page = Page.find_or_create_by_title(page_name)
      @versions = @page.versions
      render :versions
    end
  end
 
  class List < R '/all/list'
    def get
      @pages = Page.find :all, :order => 'title'
      render :list
    end
  end
 
  class Stylesheet < R '/css/tepee.css'
    def get
@headers['Content-Type'] = 'text/css'
File.read(__FILE__).gsub(/.*__END__/m, '')
    end
  end
end
 
module Tepee::Views
  def layout
    html do
      head do
        title 'test'
        link :href=>R(Stylesheet), :rel=>'stylesheet', :type=>'text/css'
      end
      style <<-END, :type => 'text/css'
body {
font-family: verdana, arial, sans-serif;
}
h1, h2, h3, h4, h5 {
font-weight: normal;
}
p.actions a {
margin-right: 6px;
}
END
      body do
        p do
          small do
            span "welcome to " ; a 'tepee', :href => "http://code.whytheluckystiff.net/svn/camping/trunk/examples/tepee.rb"
            span '. go ' ; a 'home', :href => R(Show, 'home')
            span '. list all ' ; a 'pages', :href => R(List)
          end
        end
        div.content do
          self << yield
        end
      end
    end
  end
 
  def show
    h1 @page.title
    div { _markup @version.body }
    p.actions do
      _button 'edit', :href => R(Edit, @version.title, @version.version)
      _button 'back', :href => R(Show, @version.title, @version.version-1) unless @version.version == 1
      _button 'next', :href => R(Show, @version.title, @version.version+1) unless @version.version == @page.version
      _button 'current', :href => R(Show, @version.title) unless @version.version == @page.version
      _button 'versions', :href => R(Versions, @page.title)
    end
  end
 
  def edit
    h1 @page.title
    form :method => 'post', :action => R(Edit, @page.title) do
      p do
        textarea @page.body, :name => 'post_body', :rows => 50, :cols => 100
      end
      input :type => 'submit', :value=>'change'
    end
    _button 'cancel', :href => R(Show, @page.title, @page.version)
    a 'syntax', :href => 'http://hobix.com/textile/', :target=>'_blank'
  end
 
  def list
    h1 'all pages'
    ul { @pages.each { |p| li { a p.title, :href => R(Show, p.title) } } }
  end
 
  def versions
    h1 @page.title
    ul do
      @versions.each do |page|
        li do
          span page.version
          _button 'show', :href => R(Show, page.title, page.version)
          _button 'edit', :href => R(Edit, page.title, page.version)
        end
      end
    end
  end
 
  def _button(text, options={})
    form :method=>:get, :action=>options[:href] do
      input :type=>'submit', :name=>'submit', :value=>text
    end
  end
 
  def _markup body
    return '' if body.blank?
    body.gsub!(Tepee::Models::Page::PAGE_LINK) do
      page = title = $1
      title = $2 unless $2.empty?
      page = page.gsub /\W/, '_'
      if Tepee::Models::Page.find(:all, :select => 'title').collect { |p| p.title }.include?(page)
        %Q{<a href="#{self/R(Show, page)}">#{title}</a>}
      else
        %Q{<span>#{title}<a href="#{self/R(Edit, page, 1)}">?</a></span>}
      end
    end
    RedCloth.new(body, [ :hard_breaks ]).to_html
  end
end
 
def Tepee.create
  Tepee::Models.create_schema :assume => (Tepee::Models::Page.table_exists? ? 1.0 : 0.0)
end
__END__
/** focus **/
/*
a:hover:active {
color: #10bae0;
}
 
a:not(:hover):active {
color: #0000ff;
}
 
*:focus {
-moz-outline: 2px solid #10bae0 !important;
-moz-outline-offset: 1px !important;
-moz-outline-radius: 3px !important;
}
 
button:focus,
input[type="reset"]:focus,
input[type="button"]:focus,
input[type="submit"]:focus,
input[type="file"] > input[type="button"]:focus {
-moz-outline-radius: 5px !important;
}
 
button:focus::-moz-focus-inner {
border-color: transparent !important;
}
 
button::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner,
input[type="button"]::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner,
input[type="file"] > input[type="button"]::-moz-focus-inner {
border: 1px dotted transparent !important;
}
textarea:focus, button:focus, select:focus, input:focus {
-moz-outline-offset: -1px !important;
}
input[type="radio"]:focus {
-moz-outline-radius: 12px;
-moz-outline-offset: 0px !important;
}
a:focus {
-moz-outline-offset: 0px !important;
}
*/
form { display: inline; }
 
/** Gradient **/
small, pre, textarea, textfield, button, input, select {
color: #4B4B4C !important;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAeCAMAAAAxfD/2AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAtUExURfT09PLy8vHx8fv7+/j4+PX19fn5+fr6+vf39/z8/Pb29vPz8/39/f7+/v///0c8Y4oAAAA5SURBVHjaXMZJDgAgCMDAuouA/3+uHPRiMmlKzmhCFRorLOakVnpnDEpBBDHM8ODs/bz372+PAAMAXIQCfD6uIDsAAAAASUVORK5CYII=) !important;
background-color: #FFF !important;
background-repeat: repeat-x !important;
border: 1px solid #CCC !important;
}
 
button, input { margin: 3px; }