sqliki 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: