root / trunk / examples / tepee.rb

Revision 210, 6.6 kB (checked in by zimbatm, 14 months ago)

Following _why's advise on #122, replacing [206]

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