sqliki 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/USAGE ADDED
@@ -0,0 +1,30 @@
1
+ NAME
2
+ sqliki - creates a SQL-based wiki within a rails application
3
+
4
+ SYNOPSIS
5
+ sqliki [Controller name]
6
+
7
+ Good names are Sqliki, Wiki, Chalkboard, Elmo, ...
8
+
9
+ DESCRIPTION
10
+ This generator creates a rudimentary SQL-based wiki.
11
+
12
+ EXAMPLE
13
+ ./script/generate sqliki Wiki
14
+
15
+ This will generate a Wiki controller which provides users:
16
+ /wiki/index (==list) -- list all pages (alphabeticaly)
17
+ /wiki/wanted -- ..pages with no content
18
+ /wiki/orphaned -- ..pages that aren't linked to
19
+ /wiki/recently_revised -- ..pages in reverse order of edits
20
+ /wiki/show/(page) -- Show an existing page
21
+ /wiki/create/(page) -- Create a new page
22
+ /wiki/edit/(page) -- Edit an existing page
23
+ ...and additional methods for control flow / internal use:
24
+ /wiki/raw
25
+ /wiki/html
26
+ /wiki/inplace_edit
27
+ /wiki/destroy
28
+ /wiki/rollback/(draft)
29
+
30
+ The tables are always called pages, drafts, and links
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+
3
+ SPEC = Gem::Specification.new do |s|
4
+ s.name = %q{sqliki}
5
+ s.version = "0.0.3"
6
+ s.date = %q{2005-08-25}
7
+ s.summary = %q{[Rails] SQL-based wiki generator.}
8
+ s.require_paths = ["."]
9
+ s.email = %q{Markus@reality.com}
10
+ s.homepage = %q{http://www.rubyonrails.org/show/Generators}
11
+ s.description = %q{Generates code for (primative) a SQL-based wiki within your Rails app.}
12
+ s.authors = ["Markus J. Q. Roberts"]
13
+ s.files = %w{
14
+ USAGE
15
+ templates/lib_sanitize_html.rb
16
+ templates/README
17
+ templates/model_draft.rb
18
+ templates/view_edit.rhtml
19
+ templates/view__form.rhtml
20
+ templates/view_inplace_edit.rhtml
21
+ templates/view_list.rhtml
22
+ templates/view_create.rhtml
23
+ templates/view_rollback.rhtml
24
+ templates/view_show.rhtml
25
+ templates/model_link.rb
26
+ templates/model_page.rb
27
+ templates/controller_sqliki_controller.rb
28
+ sqliki_generator.rb
29
+ sqliki_generator-0.0.3.gemspec
30
+ }
31
+ s.add_dependency('rails', [">= 0.13.1"])
32
+ s.add_dependency('RedCloth')
33
+ end
34
+
35
+ if $0 == __FILE__
36
+ Gem::manage_gems
37
+ Gem::Builder.new(SPEC).build
38
+ end
39
+
@@ -0,0 +1,32 @@
1
+ class SqlikiGenerator < Rails::Generator::NamedBase
2
+ def manifest
3
+ record do |m|
4
+
5
+ # Models.
6
+ %w{page draft link}.each do |x|
7
+ m.template "model_#{x}.rb",File.join("app/models", class_path, "#{x}.rb")
8
+ end
9
+
10
+ # Views.
11
+ m.directory File.join("app/views", class_path, file_name)
12
+ %w{edit _form inplace_edit list create rollback show }.each do |x|
13
+ m.template "view_#{x}.rhtml",File.join("app/views", class_path, file_name, "#{x}.rhtml")
14
+ end
15
+
16
+ m.template "controller_sqliki_controller.rb",File.join("app/controllers", class_path, "#{file_name}_controller.rb")
17
+
18
+ # Libs.
19
+ %w{sanitize_html}.each do |x|
20
+ m.template "lib_#{x}.rb",File.join("lib", class_path, "#{x}.rb")
21
+ end
22
+
23
+ m.template "README", "README_SQLIKI"
24
+ end
25
+ end
26
+
27
+ attr_accessor :controller_class_name
28
+
29
+ end
30
+
31
+
32
+
data/templates/README ADDED
@@ -0,0 +1,95 @@
1
+ == Installation
2
+
3
+ NOTE: THIS IS THE VERY FIRST ALPHA VERSION OF SQLIKI!!!
4
+
5
+ Done generating SQLiki. but there are still a few things you have to
6
+ do manually.
7
+
8
+ * You will need a login system of some kind. I have been using the simple
9
+ login generator.
10
+
11
+ * SQLiki needs to know the current user; it looks for this in
12
+ User.current_user. If your login system provides this, fine. The simple
13
+ login generator does not, but you can add it reasonably easily. Just add
14
+ something like the following to your application.rb:
15
+
16
+ class << User
17
+ cattr_accessor :current_user unless self.respond_to? :current_user
18
+ end
19
+
20
+ class ApplicationController < ActionController::Base
21
+ before_filter :note_the_current_user
22
+ def note_the_current_user
23
+ User.current_user = @session[:user] if User.respond_to? :current_user=
24
+ end
25
+ end
26
+
27
+
28
+ * You will need Why T.L.S.'s RedCloth (which you probably already have)
29
+
30
+ * You will need three tables (pages, drafts, and links):
31
+
32
+ --
33
+ -- Table structure for table 'pages'
34
+ -- These are just the headers (page names); the text is in
35
+ -- the draft identified by "current_draft_id"
36
+ --
37
+
38
+ CREATE TABLE pages (
39
+ id int(10) unsigned NOT NULL auto_increment,
40
+ type varchar(80) NOT NULL default '',
41
+ created_on datetime default NULL,
42
+ updated_on datetime default NULL,
43
+ lock_version int(11) default '0',
44
+ current_draft_id int(11) NOT NULL default '0',
45
+ title varchar(80) NOT NULL default '',
46
+ created_by int(11) NOT NULL default '0',
47
+ PRIMARY KEY (id)
48
+ ) TYPE=MyISAM;
49
+
50
+ --
51
+ -- Table structure for table 'drafts'
52
+ -- These are were the text is stored. Note that drafts make
53
+ -- a tree, since each derived-draft knows which draft it was
54
+ -- based on.
55
+ --
56
+
57
+ CREATE TABLE drafts (
58
+ id int(10) unsigned NOT NULL auto_increment,
59
+ type varchar(80) NOT NULL default '',
60
+ created_on datetime default NULL,
61
+ draft_of_page_id int(11) default '0',
62
+ based_on_draft_id int(11) default '0',
63
+ body text NOT NULL,
64
+ created_by int(11) NOT NULL default '0',
65
+ PRIMARY KEY (id)
66
+ ) TYPE=MyISAM;
67
+
68
+ --
69
+ -- Table structure for table 'links'
70
+ -- These just keep track of which drafts refer to which pages;
71
+ -- that is, whenever a draft of one page contains a WikiWord that
72
+ -- generates a link to another page, that fact is noted here.
73
+ --
74
+
75
+ CREATE TABLE links (
76
+ draft_id int(11) NOT NULL default '0',
77
+ page_id int(11) NOT NULL default '0'
78
+ ) TYPE=MyISAM;
79
+
80
+
81
+ == How to use it
82
+
83
+ == Tips & Tricks
84
+
85
+ == Changelog
86
+
87
+ 0.0.1
88
+ First gem release
89
+ 0.0.2
90
+ Made the name of the controller changeable
91
+ Removed the system specific path for RedCloth
92
+ Implemented Orphaned/Wanted/Recently_revised
93
+ Cleaned up the controller interface (w. the the
94
+ trick from Tobias Luetke's Postback Generator)
95
+
@@ -0,0 +1,76 @@
1
+ class <%= class_name %>Controller < ApplicationController
2
+ model :draft
3
+ include LoginSystem
4
+ before_filter :login_required
5
+ def identify_page
6
+ @page ||= Page.find_by_title(params[:id])
7
+ end
8
+ def index
9
+ list
10
+ render :action => 'list'
11
+ end
12
+ def raw
13
+ render_text identify_page.current_draft.raw
14
+ end
15
+ def html
16
+ render_text identify_page.current_draft.html
17
+ end
18
+ def rollback
19
+ identify_page
20
+ #@page.current_draft = ???
21
+ render :action => 'show'
22
+ end
23
+ def wanted
24
+ list :wanted
25
+ render :action => 'list'
26
+ end
27
+ def orphaned
28
+ list :orphaned
29
+ render :action => 'list'
30
+ end
31
+ def recently_revised
32
+ list :recently_revised
33
+ render :action => 'list'
34
+ end
35
+ def list(condition=:all)
36
+ @page_pages, @pages = paginate :page, {:per_page => 20}.merge(case condition
37
+ when :wanted then {:conditions => 'current_draft_id IS NULL'}
38
+ when :orphaned then {
39
+ :join => 'p LEFT JOIN links l ON l.page_id = p.id left join drafts dx on dx.id = l.draft_id left join pages px on px.current_draft_id = dx.id',
40
+ :conditions => 'page_id IS NULL'
41
+ }
42
+ when :recently_revised then {:order_by => 'updated_on DESC'}
43
+ else {:order_by => 'title'}
44
+ end)
45
+ end
46
+ def show
47
+ identify_page || redirect_to(:action => 'create', :id => @params[:id])
48
+ end
49
+ def create
50
+ @page = Page.new_page(@params[:id])
51
+ if @request.post? and @page.update_attributes(params[:page]) and @page.save
52
+ flash[:notice] = 'Page was successfully created.'
53
+ redirect_to :action => 'show', :id => @page.title
54
+ end
55
+ end
56
+ def inplace_edit
57
+ if not identify_page
58
+ redirect_to(:action => 'create', :id => @params[:id])
59
+ elsif @request.post? and @page.update_attributes(params[:page])
60
+ redirect_to :action => 'html', :id => @page.title
61
+ end
62
+ end
63
+ def edit
64
+ if not identify_page
65
+ redirect_to(:action => 'create', :id => @params[:id])
66
+ elsif @request.post? and @page.update_attributes(params[:page])
67
+ flash[:notice] = 'Page was successfully updated.'
68
+ redirect_to :action => 'show', :id => @page.title
69
+ end
70
+ end
71
+ def destroy
72
+ identify_page.destroy if @request.post?
73
+ redirect_to :action => 'list'
74
+ end
75
+ end
76
+
@@ -0,0 +1,143 @@
1
+ #
2
+ # Written from scratch to address specific problems I was having with instiki/RedCloth
3
+ #
4
+ # * Mismatched tags (especially DIVs) seriously messed up the page layout
5
+ # * View Changes made code blocks hard to read (lost line breaks)
6
+ # * Inserting/deleting block-level tags caused messed up page layout
7
+ #
8
+ # See An_html_janitor.initialze for a birds-eye view of the algorithm.
9
+ #
10
+ # (c) 2005 By Markus J. Q. Roberts
11
+ # Usage, modification, etc. of this program is permitted under the GPL, Ruby's License, Rail's
12
+ # License, or Instiki's License (your choice)
13
+ #
14
+ require 'ostruct'
15
+ require 'cgi'
16
+
17
+ class An_html_janitor < String
18
+ Tags_we_dont_expect_to_close = %w{ area br img input keygen li link meta p param td th thead tr }
19
+ Priority = Hash.new( 0 ).update({ 'ins' => 10, 'del' => 10 })
20
+ def initialize(raw_html)
21
+ replace raw_html
22
+ @safe_house = []
23
+ sequester!("previous protected zone",/@protected \w+ \d+@/)
24
+ sequester!("html comment", /<!--.*?-->/m )
25
+ #To do: sequester attributes that contain "<" and/or ">"
26
+ spiff_up('ins')
27
+ spiff_up('del')
28
+ ballance_tags
29
+ remove_empty_spans
30
+ unseal!("html comment","previous protected zone")
31
+ end
32
+ def stash(text)
33
+ @safe_house << [[],text.to_s,[]]
34
+ @safe_house.length - 1
35
+ end
36
+ def token_for(group,id)
37
+ "@protected #{group} #{id}@"
38
+ end
39
+ def sequester!(group,reg_exp)
40
+ gsub!(reg_exp) { |match| token_for(group,stash(match)) }
41
+ end
42
+ def unseal!(*groups)
43
+ gsub!(/@protected (?:#{groups.join('|')}) (\d+)@/) { |n| @safe_house[$1.to_i] }
44
+ end
45
+ def wrap(token,new_pre,new_post)
46
+ pre,core,post = @safe_house[token]
47
+ @safe_house[token].replace [pre+[new_pre],core,[new_post]+post]
48
+ end
49
+ def escape_core(token)
50
+ pre,core,post = @safe_house[token]
51
+ @safe_house[token].replace [[],CGI.escapeHTML(core),[]]
52
+ end
53
+ def spiff_up(tag)
54
+ gsub!(%r{<#{tag}(.*?)>(.*?)</#{tag}>}) {
55
+ "<#{tag}#{$1}>#{CGI.escapeHTML($2.gsub(%r{<(/?\w+).*?>}) {"<#{$1}>"})}</#{tag}>"
56
+ }
57
+ end
58
+ def ballance_tags
59
+ stack = []
60
+ gsub!(%r{<(.*?)>}) { |chunk| case $1
61
+ when %r{/$} #self-closing tag
62
+ chunk
63
+ when %r{^(\w+)} #opening tag
64
+ tag = $1.downcase
65
+ #print "opening #{tag} \n #{stack.collect {|q| q.desc}.inspect}\n #{@safe_house.inspect}#\n"
66
+ if Tags_we_dont_expect_to_close.include? tag
67
+ chunk
68
+ else
69
+ stack.push OpenStruct.new(
70
+ :tag => tag,
71
+ :priority => Priority[tag],
72
+ :text => chunk,
73
+ :start_tag => stash(chunk),
74
+ :expected_close => "</#{tag}>",
75
+ :desc => "#{chunk}...</#{tag}>"
76
+ )
77
+ token_for("start tag",stack.last.start_tag)
78
+ end
79
+ when %r{^/(\w+)} #closing tag
80
+ tag = $1.downcase
81
+ #print "closing #{tag}\n #{stack.collect {|q| q.tag}.inspect}\n #{@safe_house.inspect}\n"
82
+ if Tags_we_dont_expect_to_close.include? tag
83
+ mode = :ignore
84
+ else
85
+ pre = []
86
+ priority = Priority[tag]
87
+ outranked = false
88
+ while s = stack.pop and tag != s.tag
89
+ outranked ||= s.priority > priority
90
+ pre << s
91
+ end
92
+ mode = if !s or outranked
93
+ :escape_it
94
+ elsif tag != 'div'
95
+ :breaking_this_one
96
+ else
97
+ :breaking_others
98
+ end
99
+ stack.push *pre.reverse
100
+ end
101
+ case mode
102
+ when :breaking_this_one
103
+ pre.collect {|s| s.expected_close }.join + chunk + pre.reverse.collect {|s| s.text }.join
104
+ when :breaking_others
105
+ this_head = s.text
106
+ pre.each { |s| wrap(s.start_tag,chunk,this_head) }
107
+ chunk
108
+ when :ignore
109
+ ''
110
+ else
111
+ escape_core(s.start_tag) if s
112
+ CGI.escapeHTML(chunk)
113
+ end
114
+ else
115
+ chunk
116
+ end }
117
+ replace self+stack.reverse.collect { |open_tag| open_tag.expected_close }.join
118
+ unseal!("start tag")
119
+ end
120
+ def remove_empty_spans
121
+ while gsub!(%r{<(\w+)[^>]*?></\1>},''); end
122
+ end
123
+ def remove_attributes(*attributes_to_remove)
124
+ return self if attributes_to_remove.length == 0
125
+ kill_pattern = /(#{attributes_to_remove.join('|')})(=(".*?"|\S*))?/i
126
+ gsub!(%r{<(\w+) +(.*?)>}) { |match| "<#{$1} #{$2.gsub(kill_pattern,'')}>" }
127
+ self
128
+ end
129
+ def remove_styles(*styles_to_remove)
130
+ return self if styles_to_remove.length == 0
131
+ style_kill_pattern = /(#{styles_to_remove.join('|')}).*?(;|$)/i
132
+ gsub!(%r{<(\w+) +(.*?)>}i) { |match|
133
+ "<#{$1} #{$2.gsub!(%r{style="(.*?)"}) { |match| "style=""#{$1.gsub(style_kill_pattern,'')}""" }}>"
134
+ }
135
+ self
136
+ end
137
+ end
138
+
139
+ def sanitize_html(raw_html)
140
+ An_html_janitor.new(raw_html)
141
+ end
142
+
143
+
@@ -0,0 +1,141 @@
1
+ require 'sanitize_html'
2
+ require 'redcloth'
3
+
4
+ class Draft < ActiveRecord::Base
5
+ acts_as_tree :foreign_key => 'based_on_draft_id'
6
+ has_and_belongs_to_many :links,:class_name => 'Page',:join_table => 'links'
7
+ belongs_to :author, :class_name => 'User', :foreign_key => :created_by
8
+ belongs_to :page, :foreign_key => :draft_of_page_id
9
+ def before_create
10
+ html #this updates the cross reference (link) table
11
+ true
12
+ end
13
+ def raw
14
+ body
15
+ end
16
+ class RopaRojo < RedCloth
17
+ def hard_break(text)
18
+ @rules.each do |rule_name|
19
+ method( rule_name ).call( text ) if rule_name.to_s.match /^pre_/
20
+ end
21
+ super
22
+ end
23
+ def to_html(*rules,&callback)
24
+ @callback = callback
25
+ rules = DEFAULT_RULES if rules.empty?
26
+ text = super(*([:pre_wiki_words,:pre_make_divs,:post_add_toggle]+rules))
27
+ end
28
+ def htmlesc(str,mode)
29
+ super
30
+ str
31
+ end
32
+ # Bracket free text consists of either
33
+ # characters that are not "{" or "}",
34
+ # one or two "{"s, not followed by a third "{",
35
+ # one or two "}"s, not followed by a third "}",
36
+ #
37
+ BRACKET_FREE_TEXT = "((:?[^{}]|[{]{1,2}(?![{])|[}]{1,2}(?![}]))*?)"
38
+ DIV_BRACKETS = /\{\{\{#{BRACKET_FREE_TEXT}\}\}\}/m
39
+ ALT_TEXT = /
40
+ (
41
+ ([\s\[{(]|[#{PUNCT}])? # $pre
42
+ " # start
43
+ (#{C}) # $atts
44
+ ([^"]+?) # $text
45
+ \s?
46
+ (?:\(([^)]+?)\)(?="))? # $title
47
+ ":
48
+ )?
49
+ /mx
50
+ XDIV_RE = /
51
+ (
52
+ ([\s\[{(]|[#{PUNCT}])? # $pre
53
+ " # start
54
+ (#{C}) # $atts
55
+ ([^"]+?) # $text
56
+ \s?
57
+ (?:\(([^)]+?)\)(?="))? # $title
58
+ ":
59
+ )?
60
+ #{DIV_BRACKETS} # $div_block
61
+ /mx
62
+ DIV_RE = /#{ALT_TEXT}#{DIV_BRACKETS}/m
63
+
64
+ def pre_make_divs( text )
65
+ ## break the text into <div> blocks based on {{{ ... }}}
66
+ while text.gsub!( DIV_RE ) { |m|
67
+ has_link,pre,atts,link_text,title,div_block = $~.captures
68
+ if has_link
69
+ @need_toggle_function = true
70
+ id = "div_#{rand(100000)}"
71
+ atts = shelve(" onclick=\"toggle('#{id}'); return false;\" #{ pba(atts) } title=\"#{ title||'more...' }\"")
72
+ "#{ pre }<a#{ atts }>#{ link_text }</a><div id=\"#{id}\" style=\"display:none\">#{div_block}</div>"
73
+ else
74
+ "<div #{shelve(attrs) }>#{div_block}</div>"
75
+ end
76
+ }; end
77
+ text
78
+ end
79
+ def post_add_toggle(text)
80
+ text << %q{
81
+ <script type="text/javascript" language="JavaScript">
82
+ <!--
83
+ function toggle(name) {
84
+ q=document.getElementById(name);
85
+ if (q.style.display == 'none')
86
+ {q.style.display = 'block';}
87
+ else
88
+ {q.style.display = 'none';};
89
+ }
90
+ //-->
91
+ </script>
92
+ } if @need_toggle_function
93
+ end
94
+ NOT_WIKI_WORD = /\\(([A-Z]+[a-z0-9]+){2,})/
95
+ WIKI_WORD = /#{ALT_TEXT}(([A-Z]+[a-z1-9]+){2,})/
96
+ WIKI_PHRASE = /#{ALT_TEXT}\[\[(.*?)\]\]/m
97
+ def split_wiki_word(ww)
98
+ ww.gsub(/([a-z0-9])([A-Z])/,'\1 \2');
99
+ end
100
+ def clean_wiki_word(ww)
101
+ ww.gsub(/[^A-Za-z0-9$-_.+!*'(),]/,'')
102
+ end
103
+ include ActionView::Helpers::TagHelper
104
+ include ActionView::Helpers::UrlHelper
105
+ def wiki_link(link_text,ww)
106
+ (@callback && @callback.call(:wiki_link,link_text,ww)) ||
107
+ (link_to link_text, "/<%= file_name %>/show/#{clean_wiki_word(ww)}")
108
+ end
109
+ def pre_wiki_words(text)
110
+ text.gsub!(NOT_WIKI_WORD) { |m| shelve $1 }
111
+ [WIKI_PHRASE,WIKI_WORD].each {|pattern|
112
+ text.gsub!(pattern) { |m|
113
+ has_link,pre,atts,link_text,title,ww = $~.captures
114
+ ww = split_wiki_word(ww) if pattern == WIKI_WORD
115
+ (pre||'') + shelve(wiki_link("<span #{pba(atts)}>#{link_text||ww}</span>",ww))
116
+ }
117
+ }
118
+ text
119
+ end
120
+ end
121
+ def textilize(body) #html
122
+ if body.blank?
123
+ ""
124
+ else
125
+ RopaRojo.new(body, [:hard_breaks ]).to_html { |event,*details|
126
+ case event
127
+ when :wiki_link
128
+ link_text,ww = *details
129
+ page = (Page.find_by_title(ww) || Page.new_page(ww))
130
+ links << page unless links.include? page
131
+ nil
132
+ else
133
+ nil
134
+ end
135
+ }
136
+ end
137
+ end
138
+ def html
139
+ sanitize_html(textilize(body))
140
+ end
141
+ end
@@ -0,0 +1,2 @@
1
+ class Link < ActiveRecord::Base
2
+ end
@@ -0,0 +1,31 @@
1
+ class Page < ActiveRecord::Base
2
+ belongs_to :current_draft, :class_name => 'Draft', :foreign_key => :current_draft_id
3
+ has_many :drafts, :foreign_key => :draft_of_page_id
4
+ has_and_belongs_to_many :links,:class_name => "Draft",:join_table => 'links'
5
+ belongs_to :author, :class_name => 'User', :foreign_key => :created_by
6
+ validates_uniqueness_of :title, :on => :create
7
+ validates_length_of :title, :within => 1..80
8
+ validates_presence_of :title
9
+ def self.new_page(title)
10
+ p = Page.new :created_by => User.current_user, :title => title
11
+ p.raw = ''
12
+ p
13
+ end
14
+ def raw
15
+ current_draft && current_draft.raw
16
+ end
17
+ def raw=(new_text)
18
+ d = Draft.new(
19
+ :body => new_text || '',
20
+ :based_on_draft_id => self.current_draft && self.current_draft.id,
21
+ :created_by => User.current_user
22
+ );
23
+ d.save;
24
+ self.current_draft = d
25
+ self.drafts << d
26
+ new_text
27
+ end
28
+ def html
29
+ current_draft.html
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ <%%= error_messages_for 'page' %>
2
+
3
+ <!--[form:page]-->
4
+
5
+ <%% unless @page.title %>
6
+ <p><label for="page_title">Title</label><br/>
7
+ <%%= text_field 'page', 'title' %></p>
8
+ <%% end %>
9
+ <%%= text_area 'page', 'raw' %></p>
10
+
11
+ <!--[eoform:page]-->
12
+
@@ -0,0 +1,8 @@
1
+ <h1><%%= @page.title || "New page" %></h1>
2
+
3
+ <%%= start_form_tag :action => 'create', :id => @page.title %>
4
+ <%%= render_partial 'form' %>
5
+ <%%= submit_tag "Create" %>
6
+ <%%= end_form_tag %>
7
+
8
+ <%%= link_to 'Back', :action => 'list' %>
@@ -0,0 +1,9 @@
1
+ <h1><%%= @page.title %></h1>
2
+
3
+ <%%= start_form_tag :action => 'edit', :id => @page.title %>
4
+ <%%= render_partial 'form' %>
5
+ <%%= submit_tag 'Save changes' %>
6
+ <%%= link_to 'Cancle changes', :action => 'show', :id => @page.title %>
7
+ <%%= end_form_tag %>
8
+
9
+
@@ -0,0 +1,2 @@
1
+ <h1>Page#inplace_edit</h1>
2
+ <p>Find me in app/views/page/inplace_edit.rhtml</p>
@@ -0,0 +1,23 @@
1
+ <h1>Listing pages</h1>
2
+
3
+ <table>
4
+ <tr><th>Title</th><th>Created by</th><th>on</th><th>Revised by</th><th>on</th>
5
+ </tr>
6
+
7
+ <%% for page in @pages %>
8
+ <tr>
9
+ <td><%%= link_to page.title, :action => 'show', :id => page.title %></td>
10
+ <td><%%= page.author.login %></td>
11
+ <td><%%= page.created_on %></td>
12
+ <td><%%= page.current_draft.author.login %></td>
13
+ <td><%%= page.current_draft.created_on %></td>
14
+ </tr>
15
+ <%% end %>
16
+ </table>
17
+
18
+ <%%= link_to 'Previous page', { :page => @page_pages.current.previous } if @page_pages.current.previous %>
19
+ <%%= link_to 'Next page', { :page => @page_pages.current.next } if @page_pages.current.next %>
20
+
21
+ <br />
22
+
23
+ <%%= link_to 'New page', :action => 'create' %>
@@ -0,0 +1,2 @@
1
+ <h1>Page#rollback</h1>
2
+ <p>Find me in app/views/page/rollback.rhtml</p>
@@ -0,0 +1,18 @@
1
+ <h1><%%= @page.title %></h1>
2
+
3
+ <div style='background: #EFE; width: 80%; padding: 1ex 2ex 1ex 2ex'>
4
+ <%%= @page.html %>
5
+ </div>
6
+
7
+
8
+ Created by <%%= @page.author.login %> on <%%= @page.created_on %><br>
9
+ Revised by <%%= @page.current_draft.author.login %> on <%%= @page.current_draft.created_on %><br>
10
+ Referenced from: <%% @page.links.each do |link| %>
11
+ <%% if link.id == link.page.current_draft.id %>
12
+ <%%= link_to link.page.title, :action => 'show', :id => link.page.title %>
13
+ <%% end %>
14
+ <%% end %>
15
+ <br>
16
+ <%%= link_to 'Edit', :action => 'edit', :id => @page.title %> |
17
+ <%%= link_to 'List All Pages', :action => 'list' %>
18
+
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.10
3
+ specification_version: 1
4
+ name: sqliki
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.3
7
+ date: 2005-08-25
8
+ summary: "[Rails] SQL-based wiki generator."
9
+ require_paths:
10
+ - "."
11
+ email: Markus@reality.com
12
+ homepage: http://www.rubyonrails.org/show/Generators
13
+ rubyforge_project:
14
+ description: Generates code for (primative) a SQL-based wiki within your Rails app.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ authors:
28
+ - Markus J. Q. Roberts
29
+ files:
30
+ - USAGE
31
+ - templates/lib_sanitize_html.rb
32
+ - templates/README
33
+ - templates/model_draft.rb
34
+ - templates/view_edit.rhtml
35
+ - templates/view__form.rhtml
36
+ - templates/view_inplace_edit.rhtml
37
+ - templates/view_list.rhtml
38
+ - templates/view_create.rhtml
39
+ - templates/view_rollback.rhtml
40
+ - templates/view_show.rhtml
41
+ - templates/model_link.rb
42
+ - templates/model_page.rb
43
+ - templates/controller_sqliki_controller.rb
44
+ - sqliki_generator.rb
45
+ - sqliki_generator-0.0.3.gemspec
46
+ test_files: []
47
+ rdoc_options: []
48
+ extra_rdoc_files: []
49
+ executables: []
50
+ extensions: []
51
+ requirements: []
52
+ dependencies:
53
+ - !ruby/object:Gem::Dependency
54
+ name: rails
55
+ version_requirement:
56
+ version_requirements: !ruby/object:Gem::Version::Requirement
57
+ requirements:
58
+ -
59
+ - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.13.1
62
+ version:
63
+ - !ruby/object:Gem::Dependency
64
+ name: RedCloth
65
+ version_requirement:
66
+ version_requirements: !ruby/object:Gem::Version::Requirement
67
+ requirements:
68
+ -
69
+ - ">"
70
+ - !ruby/object:Gem::Version
71
+ version: 0.0.0
72
+ version: