Changesets can be listed by changeset number.
The Git repository is here.
Changeset 71
Start of upgrade to Typo 4.0.0, the latest stable release since
2.6.0. Note test/mocks/themes/azure changes from a file to a
directory, so the file has been removed in this revision and
the directory will be added in the next revision.
- Comitted by: adh
- Date: Monday August 07 22:18:11 2006 (over 18 years ago)
Affected files:
- rool/rails/typo/trunk/public/javascripts/typo.js (diff)
- rool/rails/typo/trunk/app/views/admin/feedback/
- rool/rails/typo/trunk/bin/
- rool/rails/typo/trunk/cache/
- rool/rails/typo/trunk/doc/
- rool/rails/typo/trunk/installer/
- rool/rails/typo/trunk/installer/rails-installer/
- rool/rails/typo/trunk/themes/scribbish/
- rool/rails/typo/trunk/themes/scribbish/images/
- rool/rails/typo/trunk/themes/scribbish/layouts/
- rool/rails/typo/trunk/themes/scribbish/stylesheets/
- rool/rails/typo/trunk/themes/scribbish/views/
- rool/rails/typo/trunk/themes/scribbish/views/articles/
- rool/rails/typo/trunk/tmp/
- rool/rails/typo/trunk/tmp/cache/
- rool/rails/typo/trunk/tmp/sessions/
- rool/rails/typo/trunk/tmp/sockets/
- rool/rails/typo/trunk/vendor/akismet/
- rool/rails/typo/trunk/vendor/ruby-mp3info/
- rool/rails/typo/trunk/vendor/ruby-mp3info/lib/
- rool/rails/typo/trunk/app/controllers/admin/feedback_controller.rb
- rool/rails/typo/trunk/app/helpers/admin/feedback_helper.rb
- rool/rails/typo/trunk/app/views/admin/feedback/_item.rhtml
- rool/rails/typo/trunk/app/views/admin/feedback/list.rhtml
- rool/rails/typo/trunk/app/views/shared/_search.rhtml
- rool/rails/typo/trunk/app/views/xml/_googlesitemap_item_article.rxml
- rool/rails/typo/trunk/app/views/xml/_googlesitemap_item_category.rxml
- rool/rails/typo/trunk/app/views/xml/_googlesitemap_item_page.rxml
- rool/rails/typo/trunk/app/views/xml/_googlesitemap_item_tag.rxml
- rool/rails/typo/trunk/app/views/xml/googlesitemap_feed.rxml
- rool/rails/typo/trunk/bin/typo
- rool/rails/typo/trunk/components/plugins/textfilters/textile_and_markdown_controller.rb
- rool/rails/typo/trunk/config/database.yml-pgsql
- rool/rails/typo/trunk/config/mail.yml
- rool/rails/typo/trunk/config/mongrel.conf
- rool/rails/typo/trunk/db/converters/mt-import.rb
- rool/rails/typo/trunk/db/converters/wordpress2.rb
- rool/rails/typo/trunk/db/migrate/047_add_content_state_field.rb
- rool/rails/typo/trunk/db/schema.rb
- rool/rails/typo/trunk/doc/Installer.txt
- rool/rails/typo/trunk/doc/typo-4.0-release-notes.txt
- rool/rails/typo/trunk/installer/apache13.conf.example.template
- rool/rails/typo/trunk/installer/apache20.conf.example.template
- rool/rails/typo/trunk/installer/lighttpd.conf.example.template
- rool/rails/typo/trunk/installer/rails-installer.rb
- rool/rails/typo/trunk/installer/rails-installer/commands.rb
- rool/rails/typo/trunk/installer/rails-installer/web-servers.rb
- rool/rails/typo/trunk/installer/rails_installer_defaults.yml
- rool/rails/typo/trunk/lib/sanitize.rb
- rool/rails/typo/trunk/test/functional/admin/feedback_controller_test.rb
- rool/rails/typo/trunk/themes/scribbish/CONTRIBUTORS
- rool/rails/typo/trunk/themes/scribbish/about.markdown
- rool/rails/typo/trunk/themes/scribbish/images/background.gif
- rool/rails/typo/trunk/themes/scribbish/images/gravatar.gif
- rool/rails/typo/trunk/themes/scribbish/images/header_shadow.gif
- rool/rails/typo/trunk/themes/scribbish/images/spinner.gif
- rool/rails/typo/trunk/themes/scribbish/layouts/default.rhtml
- rool/rails/typo/trunk/themes/scribbish/preview.png
- rool/rails/typo/trunk/themes/scribbish/stylesheets/application.css
- rool/rails/typo/trunk/themes/scribbish/stylesheets/content.css
- rool/rails/typo/trunk/themes/scribbish/stylesheets/layout.css
- rool/rails/typo/trunk/themes/scribbish/views/articles/_article.rhtml
- rool/rails/typo/trunk/themes/scribbish/views/articles/_comment.rhtml
- rool/rails/typo/trunk/themes/scribbish/views/articles/_comment_form.rhtml
- rool/rails/typo/trunk/themes/scribbish/views/articles/_search.rhtml
- rool/rails/typo/trunk/themes/scribbish/views/articles/_trackback.rhtml
- rool/rails/typo/trunk/themes/scribbish/views/articles/comment_preview.rhtml
- rool/rails/typo/trunk/themes/scribbish/views/articles/index.rhtml
- rool/rails/typo/trunk/themes/scribbish/views/articles/read.rhtml
- rool/rails/typo/trunk/vendor/akismet/akismet.rb
- rool/rails/typo/trunk/vendor/ruby-mp3info/lib/mp3info.rb
- rool/rails/typo/trunk/test/mocks/themes/azure
- rool/rails/typo/trunk/README (diff)
- rool/rails/typo/trunk/app/controllers/admin/content_controller.rb (diff)
- rool/rails/typo/trunk/app/controllers/articles_controller.rb (diff)
- rool/rails/typo/trunk/app/controllers/content_controller.rb (diff)
- rool/rails/typo/trunk/app/controllers/redirect_controller.rb (diff)
- rool/rails/typo/trunk/app/controllers/xml_controller.rb (diff)
- rool/rails/typo/trunk/app/helpers/application_helper.rb (diff)
- rool/rails/typo/trunk/app/helpers/xml_helper.rb (diff)
- rool/rails/typo/trunk/app/models/article.rb (diff)
- rool/rails/typo/trunk/app/models/blog.rb (diff)
- rool/rails/typo/trunk/app/models/comment.rb (diff)
- rool/rails/typo/trunk/app/models/content.rb (diff)
- rool/rails/typo/trunk/app/models/content_observer.rb (diff)
- rool/rails/typo/trunk/app/models/content_state/base.rb (diff)
- rool/rails/typo/trunk/app/models/content_state/factory.rb (diff)
- rool/rails/typo/trunk/app/models/ping.rb (diff)
- rool/rails/typo/trunk/app/models/text_filter.rb (diff)
- rool/rails/typo/trunk/app/models/trackback.rb (diff)
- rool/rails/typo/trunk/app/views/admin/content/_form.rhtml (diff)
- rool/rails/typo/trunk/app/views/admin/general/index.rhtml (diff)
- rool/rails/typo/trunk/app/views/admin/pages/_form.rhtml (diff)
- rool/rails/typo/trunk/app/views/articles/_comment.rhtml (diff)
- rool/rails/typo/trunk/app/views/articles/_comment_box.rhtml (diff)
- rool/rails/typo/trunk/app/views/articles/read.rhtml (diff)
- rool/rails/typo/trunk/app/views/layouts/administration.rhtml (diff)
- rool/rails/typo/trunk/app/views/notification_mailer/_mail_footer.rhtml (diff)
- rool/rails/typo/trunk/app/views/xml/itunes_feed.rxml (diff)
- rool/rails/typo/trunk/components/plugins/sidebars/archives_controller.rb (diff)
- rool/rails/typo/trunk/components/plugins/sidebars/delicious/content.rhtml (diff)
- rool/rails/typo/trunk/components/plugins/sidebars/xml_controller.rb (diff)
- rool/rails/typo/trunk/components/plugins/textfilters/amazon_controller.rb (diff)
- rool/rails/typo/trunk/components/plugins/textfilters/flickr_controller.rb (diff)
- rool/rails/typo/trunk/components/plugins/textfilters/sparkline_controller.rb (diff)
- rool/rails/typo/trunk/components/plugins/textfilters/textile_controller.rb (diff)
- rool/rails/typo/trunk/config/boot.rb (diff)
- rool/rails/typo/trunk/config/environment.rb (diff)
- rool/rails/typo/trunk/config/environments/production.rb (diff)
- rool/rails/typo/trunk/config/routes.rb (diff)
- rool/rails/typo/trunk/db/development_structure.sql (diff)
- rool/rails/typo/trunk/db/migrate/022_superclass_trackbacks.rb (diff)
- rool/rails/typo/trunk/db/migrate/023_superclass_pages.rb (diff)
- rool/rails/typo/trunk/db/schema.mysql-v3.sql (diff)
- rool/rails/typo/trunk/db/schema.mysql.sql (diff)
- rool/rails/typo/trunk/db/schema.postgresql.sql (diff)
- rool/rails/typo/trunk/db/schema.sqlite.sql (diff)
- rool/rails/typo/trunk/db/schema.sqlserver.sql (diff)
- rool/rails/typo/trunk/lib/sidebars/plugin.rb (diff)
- rool/rails/typo/trunk/lib/tasks/release.rake (diff)
- rool/rails/typo/trunk/lib/typo_version.rb (diff)
- rool/rails/typo/trunk/public/dispatch.cgi (diff)
- rool/rails/typo/trunk/public/dispatch.fcgi (diff)
- rool/rails/typo/trunk/public/dispatch.rb (diff)
- rool/rails/typo/trunk/public/images/spinner.gif
- rool/rails/typo/trunk/public/javascripts/dragdrop.js (diff)
- rool/rails/typo/trunk/public/javascripts/effects.js (diff)
- rool/rails/typo/trunk/public/javascripts/prototype.js (diff)
- rool/rails/typo/trunk/public/stylesheets/administration.css (diff)
- rool/rails/typo/trunk/script/spacecheck (diff)
- rool/rails/typo/trunk/test/fixtures/contents.yml (diff)
- rool/rails/typo/trunk/test/functional/articles_controller_test.rb (diff)
- rool/rails/typo/trunk/test/functional/xml_controller_test.rb (diff)
- rool/rails/typo/trunk/test/mocks/test/http_mock.rb (diff)
- rool/rails/typo/trunk/test/test_helper.rb (diff)
- rool/rails/typo/trunk/test/unit/article_test.rb (diff)
- rool/rails/typo/trunk/test/unit/comment_test.rb (diff)
- rool/rails/typo/trunk/test/unit/content_state/factory_test.rb (diff)
- rool/rails/typo/trunk/test/unit/ping_test.rb (diff)
- rool/rails/typo/trunk/test/unit/trackback_test.rb (diff)
- rool/rails/typo/trunk/test/unit/trigger_test.rb (diff)
- rool/rails/typo/trunk/themes/azure/stylesheets/azure.css (diff)
- rool/rails/typo/trunk/vendor/plugins/expiring_action_cache/lib/actionparamcache.rb (diff)
rool/rails/typo/trunk/public/javascripts/typo.js:
prev. | current | |
if (request.status == 200) { commentAdded() }; | ||
} | ||
71 | function popup(mylink, windowname) | |
72 | { | |
73 | if (! window.focus) return true; | |
74 | var href; | |
75 | window.open(mylink, windowname, 'width=400,height=500,scrollbars=yes'); | |
76 | return false; | |
77 | } | |
78 | ||
79 | // From http://www.shawnolson.net/scripts/public_smo_scripts.js | |
80 | function check_all(checkbox) { | |
81 | var form = checkbox.form, z = 0; | |
82 | for(z=0; z<form.length;z++){ | |
83 | if(form[z].type == 'checkbox' && form[z].name != 'checkall'){ | |
84 | form[z].checked = checkbox.checked; | |
85 | } | |
86 | } | |
87 | } | |
88 | ||
register_onload(function() { | ||
if ($('commentform')) { | ||
var _author = getCookie('author'); |
rool/rails/typo/trunk/README:
prev. | current | |
Currently you need all of those things to get typo to run: | ||
15 | | |
16 | | |
15 | * Ruby 1.8.4 or higher | |
16 | * Rails 1.1.x | |
* A database. Typo supports MySQL, PostgreSQL, and SQLite. | ||
* Ruby drivers for your database. | ||
* For best performance, you should have a web server running either | ||
... | ... | |
Installation | ||
============ | ||
27 | ||
27 | See doc/Installer.text and doc/typo-4.0-release-notes.txt. | |
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 | ||
Usage | ||
====== | ||
rool/rails/typo/trunk/app/controllers/admin/content_controller.rb:
prev. | current | |
def new_or_edit | ||
get_or_build_article | ||
params[:article] ||= {} | ||
81 | | |
82 | | |
83 | | |
81 | # params[:article].reverse_merge!('allow_comments' => this_blog.default_allow_comments, | |
82 | # 'allow_pings' => this_blog.default_allow_pings, | |
83 | # 'published' => true) | |
@article.attributes = (params[:article]) | ||
setup_categories | ||
@selected = @article.categories.collect { |c| c.id } | ||
... | ... | |
def get_or_build_article | ||
@article = case params[:action] | ||
when 'new' | ||
132 | | |
132 | art = this_blog.articles.build | |
133 | art.allow_comments = this_blog.default_allow_comments | |
134 | art.allow_pings = this_blog.default_allow_pings | |
135 | art.published = true | |
136 | art | |
when 'edit' | ||
this_blog.articles.find(params[:id]) | ||
else |
rool/rails/typo/trunk/app/controllers/articles_controller.rb:
prev. | current | |
class ArticlesController < ContentController | ||
before_filter :verify_config | ||
3 | | |
layout :theme_layout, :except => [:comment_preview, :trackback] | ||
... | ... | |
:render => { :text => 'Forbidden', :status => 403 }) | ||
def index | ||
20 | | |
21 | | |
22 | | |
23 | | |
24 | | |
25 | | |
26 | | |
19 | # On Postgresql, paginate's default count is *SLOW*, because it does a join against | |
20 | # all of the eager-loaded tables. I've seen it take up to 7 seconds on my test box. | |
21 | # | |
22 | # So, we're going to use the older Paginator class and manually provide a count. | |
23 | # This is a 100x speedup on my box. | |
24 | count = Article.count(:conditions => ['published = ? AND contents.published_at < ? AND blog_id = ?', | |
25 | true, Time.now, this_blog.id]) | |
26 | @pages = Paginator.new self, count, this_blog.limit_article_display, @params[:page] | |
27 | @articles = Article.find( :all, | |
28 | :offset => @pages.current.offset, | |
29 | :limit => @pages.items_per_page, | |
30 | :order => "contents.published_at DESC", | |
31 | :include => [:categories, :tags, :user, :blog], | |
32 | :conditions => | |
33 | ['published = ? AND contents.published_at < ? AND blog_id = ?', | |
34 | true, Time.now, this_blog.id] | |
35 | ) | |
end | ||
def search | ||
... | ... | |
@article = this_blog.published_articles.find(params[:id]) | ||
@comment = @article.comments.build(params[:comment]) | ||
@comment.user = session[:user] | ||
102 | ||
103 | spam_options = { | |
104 | :user_agent => request.env['HTTP_USER_AGENT'], | |
105 | :referrer => request.env['HTTP_REFERER'], | |
106 | :permalink => this_blog.article_url(@article, false)} | |
107 | ||
108 | if @comment.is_spam? spam_options | |
109 | STDERR.puts "Moderating comment as spam!" | |
110 | @comment.withdraw | |
111 | end | |
112 | ||
@comment.save! | ||
add_to_cookies(:author, @comment.author) | ||
add_to_cookies(:url, @comment.url) | ||
... | ... | |
render :nothing => true, :status => 404 | ||
end | ||
end | ||
168 | ||
169 | def markup_help | |
170 | render :text => TextFilter.find(params[:id]).commenthelp | |
171 | end | |
private | ||
... | ... | |
:expires => 6.weeks.from_now } | ||
end | ||
156 | | |
157 | | |
158 | | |
159 | | |
160 | | |
161 | ||
def verify_config | ||
if User.count == 0 | ||
redirect_to :controller => "accounts", :action => "signup" | ||
... | ... | |
def render_grouping(klass) | ||
return list_groupings(klass) unless params[:id] | ||
221 | @page_title = "#{this_blog.blog_name} - #{klass.to_s.underscore} #{params[:id]}" | |
@articles = klass.find_by_permalink(params[:id]).articles.find_already_published rescue [] | ||
auto_discovery_feed :type => klass.to_s.underscore, :id => params[:id] | ||
render_paginated_index("Can't find posts with #{klass.to_prefix} '#{h(params[:id])}'") |
rool/rails/typo/trunk/app/controllers/content_controller.rb:
prev. | current | |
def after(controller) | ||
future_article = | ||
Article.find(:first, | ||
12 | | |
13 | | |
12 | :conditions => ['published = ? AND published_at > ?', true, @request_time], | |
13 | :order => "published_at ASC" ) | |
if future_article | ||
15 | | |
15 | delta = future_article.published_at - Time.now | |
controller.response.lifetime = (delta <= 0) ? 0 : delta | ||
end | ||
end | ||
... | ... | |
include LoginSystem | ||
model :user | ||
23 | ||
helper :theme | ||
25 | ||
before_filter :auto_discovery_defaults | ||
def self.caches_action_with_params(*actions) |
rool/rails/typo/trunk/app/controllers/redirect_controller.rb:
prev. | current | |
path = url_root + path unless url_root.nil? or path[0,url_root.length] == url_root | ||
redirect_to path | ||
else | ||
13 | | |
14 | ||
15 | ||
16 | ||
13 | render :text => "Page not found", :status => 404 | |
end | ||
end | ||
end |
rool/rails/typo/trunk/app/controllers/xml_controller.rb:
prev. | current | |
session :off | ||
NORMALIZED_FORMAT_FOR = {'atom' => 'atom10', 'rss' => 'rss20', | ||
6 | | |
6 | 'atom10' => 'atom10', 'rss20' => 'rss20', | |
7 | 'googlesitemap' => 'googlesitemap' } | |
CONTENT_TYPE_FOR = { 'rss20' => 'application/xml', | ||
9 | | |
10 | 'atom10' => 'application/atom+xml', | |
11 | 'googlesitemap' => 'application/xml' } | |
def feed | ||
... | ... | |
association = this_blog.send(association) | ||
end | ||
limit ||= this_blog.limit_rss_display | ||
71 | | |
73 | @items += association.find_already_published(:all, :limit => limit, :order => order) | |
end | ||
def prep_feed | ||
... | ... | |
@link = url_for({:controller => "articles_controller.rb", :action => 'tag', :tag => tag.name}, | ||
{:only_path => false}) | ||
end | ||
113 | ||
114 | def prep_sitemap | |
115 | fetch_items(:articles, 'created_at DESC', 1000) | |
116 | fetch_items(:pages, 'created_at DESC', 1000) | |
117 | @items += Category.find_all_with_article_counters(1000) | |
118 | @items += Tag.find_all_with_article_counters(1000) | |
119 | end | |
120 | ||
end |
rool/rails/typo/trunk/app/helpers/application_helper.rb:
prev. | current | |
page.html(@controller,:body) | ||
end | ||
91 | | |
91 | def strip_html(text) | |
92 | text.strip_html | |
93 | end | |
94 | ||
95 | def markup_help_popup(markup, text) | |
96 | if markup and markup.commenthelp.size > 1 | |
97 | "<a href=\"#{url_for :controller => '/articles', :action => 'markup_help', :id => markup.id}\" onClick=\"return popup(this, 'Typo Markup Help')\">#{text}</a>" | |
98 | else | |
99 | '' | |
100 | end | |
101 | end | |
end |
rool/rails/typo/trunk/app/helpers/xml_helper.rb:
prev. | current | |
def blog_title | ||
this_blog.blog_name || "Unnamed blog" | ||
end | ||
21 | ||
22 | def tag_link(tag) | |
23 | url_for :controller => "articles", :action => 'tag', :id => tag.name, :only_path => false | |
24 | end | |
25 | ||
26 | def collection_lastmod(collection) | |
27 | article_updated = collection.articles.find(:first, :order => 'updated_at DESC') | |
28 | article_published = collection.articles.find(:first, :order => 'published_at DESC') | |
29 | ||
30 | times = [] | |
31 | times.push article_updated.updated_at if article_updated | |
32 | times.push article_published.updated_at if article_published | |
33 | ||
34 | if times.empty? | |
35 | Time.at(0).xmlschema | |
36 | else | |
37 | times.max.xmlschema | |
38 | end | |
39 | end | |
40 | ||
41 | def category_link(category) | |
42 | url_for :controller => "articles", :action => 'category', :id => category.permalink, :only_path => false | |
43 | end | |
end |
rool/rails/typo/trunk/app/models/article.rb:
prev. | current | |
def keywords_to_tags | ||
Article.transaction do | ||
tags.clear | ||
123 | | |
123 | keywords.to_s.scan(/((['"]).*?\2|[\.\w]+)/).collect do |x| | |
x.first.tr("\"'", '') | ||
end.uniq.each do |tagword| | ||
tags << Tag.get(tagword) | ||
... | ... | |
end | ||
end | ||
149 | def comments_closed? | |
150 | if self.allow_comments? | |
151 | if !self.blog.sp_article_auto_close.zero? and self.created_at.to_i < self.blog.sp_article_auto_close.days.ago.to_i | |
152 | return true | |
153 | else | |
154 | return false | |
155 | end | |
156 | else | |
157 | return true | |
158 | end | |
159 | end | |
160 | ||
protected | ||
before_create :set_defaults, :create_guid, :add_notifications | ||
164 | before_save :set_published_at | |
after_save :keywords_to_tags | ||
def correct_counts | ||
self.comments_count = self.comments_count | ||
self.trackbacks_count = self.trackbacks_count | ||
end | ||
171 | ||
172 | def set_published_at | |
173 | if self.published and self[:published_at].nil? | |
174 | self[:published_at] = self.created_at || Time.now | |
175 | end | |
176 | end | |
def set_defaults | ||
if self.attributes.include?("permalink") and self.permalink.blank? | ||
... | ... | |
if blog && self.allow_pings.nil? | ||
self.allow_pings = blog.default_allow_pings | ||
end | ||
190 | ||
true | ||
end | ||
... | ... | |
return [from, to] | ||
end | ||
219 | def find_published(what = :all, options = {}) | |
220 | options[:include] ||= [] | |
221 | options[:include] += [:user] | |
222 | super(what, options) | |
223 | end | |
validates_uniqueness_of :guid | ||
validates_presence_of :title |
rool/rails/typo/trunk/app/models/blog.rb:
prev. | current | |
1 | # BlogRequest is a fake Request object, created so blog.url_for will work. | |
2 | # This isn't enabled yet, but it will be soon... | |
3 | class BlogRequest | |
4 | include Reloadable | |
5 | ||
6 | attr_accessor :protocol, :host_with_port, :path, :symbolized_path_parameters, :relative_url_root | |
7 | ||
8 | def initialize(root) | |
9 | @protocol = @host_with_port = @path = '' | |
10 | @symbolized_path_parameters = {} | |
11 | @relative_url_root = root.gsub(%r{/^},'') | |
12 | end | |
13 | end | |
14 | ||
class Blog < ActiveRecord::Base | ||
include ConfigManager | ||
... | ... | |
setting :sp_article_auto_close, :integer, 0 | ||
setting :sp_allow_non_ajax_comments, :boolean, true | ||
setting :sp_url_limit, :integer, 0 | ||
48 | setting :sp_akismet_key, :string, '' | |
# Podcasting | ||
setting :itunes_explicit, :boolean, false | ||
... | ... | |
setting :show_extended_on_rss, :boolean, true | ||
setting :theme, :string, 'azure' | ||
setting :use_gravatar, :boolean, false | ||
71 | setting :global_pings_disable, :boolean, false | |
setting :ping_urls, :string, "http://rpc.technorati.com/rpc/ping\nhttp://ping.blo.gs/\nhttp://rpc.weblogs.com/RPC2" | ||
setting :send_outbound_pings, :boolean, true | ||
setting :email_from, :string, 'typo@example.com' | ||
... | ... | |
settings[:blog_id] = self.id | ||
article_id = settings[:id] | ||
settings.delete(:id) | ||
72 | | |
88 | trackback = published_articles.find(article_id).trackbacks.create!(settings) | |
89 | ||
90 | if trackback.is_spam? | |
91 | STDERR.puts "Moderating trackback as spam!" | |
92 | trackback.withdraw! | |
93 | end | |
94 | ||
95 | trackback | |
end | ||
... | ... | |
end | ||
def article_url(article, only_path = true, anchor = nil) | ||
141 | | |
142 | | |
143 | | |
164 | url_for(:year => article.published_at.year, | |
165 | :month => sprintf("%.2d", article.published_at.month), | |
166 | :day => sprintf("%.2d", article.published_at.day), | |
:title => article.permalink, :anchor => anchor, | ||
:only_path => only_path) | ||
end | ||
... | ... | |
private | ||
def request | ||
182 | #BlogRequest.new(self.canonical_server_url) | |
controller.request rescue ActionController::TestRequest.new | ||
end | ||
end |
rool/rails/typo/trunk/app/models/comment.rb:
prev. | current | |
require_dependency 'spam_protection' | ||
2 | require 'sanitize' | |
3 | require 'timeout' | |
class Comment < Content | ||
include TypoGuid | ||
... | ... | |
belongs_to :user | ||
validates_presence_of :author, :body | ||
12 | | |
validates_age_of :article_id | ||
validate_on_create :check_article_is_open_to_comments | ||
17 | ||
def self.default_order | ||
'created_at ASC' | ||
end | ||
... | ... | |
end | ||
end | ||
51 | ||
52 | ||
def body_html_postprocess(value, controller) | ||
54 | | |
54 | sanitize(controller.send(:auto_link, value),'a href, b, br, i, p, em, strong, pre, code, ol, ul, li') | |
end | ||
def default_text_filter_config_key | ||
... | ... | |
self.author = author.nofollowify | ||
self.body_html = body_html.to_s.nofollowify | ||
end | ||
76 | ||
77 | def akismet_options | |
78 | {:user_ip => ip, :comment_type => 'comment', :comment_author => author, :comment_author_email => email, | |
79 | :comment_author_url => url, :comment_content => body} | |
80 | end | |
81 | ||
82 | def spam_fields | |
83 | [:body, :url, :ip] | |
84 | end | |
end |
rool/rails/typo/trunk/app/models/content.rb:
prev. | current | |
require 'observer' | ||
require 'set' | ||
3 | ||
class Content < ActiveRecord::Base | ||
include Observable | ||
... | ... | |
belongs_to :blog | ||
validates_presence_of :blog_id | ||
11 | composed_of :state, :class_name => 'ContentState::Factory', | |
12 | :mapping => %w{ state memento } | |
13 | ||
has_and_belongs_to_many :notify_users, :class_name => 'User', | ||
:join_table => 'notifications', :foreign_key => 'notify_content_id', | ||
:association_foreign_key => 'notify_user_id', :uniq => true | ||
... | ... | |
@@content_fields = Hash.new | ||
@@html_map = Hash.new | ||
23 | | |
27 | ||
def initialize(*args) | ||
super(*args) | ||
26 | | |
27 | | |
30 | set_default_blog | |
31 | end | |
32 | ||
33 | def set_default_blog | |
if self.blog_id == nil or self.blog_id == 0 | ||
29 | | |
35 | self.blog = Blog.default | |
end | ||
end | ||
... | ... | |
options.reverse_merge!(:order => default_order) | ||
options[:conditions] = merge_conditions(['published = ?', true], | ||
options[:conditions]) | ||
86 | options[:include] ||= [] | |
87 | options[:include] += [:blog] | |
find(what, options) | ||
end | ||
... | ... | |
end | ||
end | ||
106 | | |
107 | | |
108 | | |
109 | ||
110 | | |
111 | | |
112 | | |
113 | ||
def state_before_save | ||
self.state.before_save(self) | ||
end | ||
... | ... | |
end | ||
def text_filter=(filter) | ||
171 | | |
171 | self[:text_filter_id] = filter.to_text_filter.id | |
end | ||
def blog | ||
... | ... | |
self.save! | ||
end | ||
183 | def withdraw | |
184 | self.published = false | |
185 | self.published_at = nil | |
186 | end | |
187 | ||
188 | def withdraw! | |
189 | self.withdraw | |
190 | self.save! | |
191 | end | |
192 | ||
def published=(a_boolean) | ||
self[:published] = a_boolean | ||
state.change_published_state(self, a_boolean) | ||
... | ... | |
def send_notifications(controller = nil) | ||
state.send_notifications(self, controller || blog.controller) | ||
end | ||
230 | ||
231 | # is_spam? checks to see if this is spam. This really belongs in a 'feedback' class | |
232 | # that is the parent of Comment and Trackback, but we aren't going to build one right | |
233 | # now. | |
234 | # | |
235 | # options are passed on to Akismet. Recommended options (when available) are: | |
236 | # | |
237 | # :permalink => the article's URL | |
238 | # :user_agent => the poster's UserAgent string | |
239 | # :referer => the poster's Referer string | |
240 | # | |
241 | def is_spam?(options={}) | |
242 | return false unless blog.sp_global | |
243 | ||
244 | sp = SpamProtection.new(blog) | |
245 | spam = false | |
246 | ||
247 | # Check fields against the blacklist. | |
248 | spam_fields.each do |field| | |
249 | spam ||= sp.is_spam? self[field] | |
250 | end | |
251 | ||
252 | # Attempt to use Akismet. Timeout after 5 seconds if we can't contact them. | |
253 | unless blog.sp_akismet_key.blank? | |
254 | Timeout.timeout(5) do | |
255 | akismet = Akismet.new(blog.sp_akismet_key,blog.canonical_server_url) | |
256 | spam ||= akismet.commentCheck(akismet_options.merge(options)) | |
257 | end | |
258 | end | |
259 | ||
260 | spam == true | |
261 | end | |
262 | ||
263 | def set_spam(is_spam, options ={}) | |
264 | unless blog.sp_akismet_key.blank? | |
265 | Timeout.timeout(5) do | |
266 | akismet = Akismet.new(blog.sp_akismet_key,blog.canonical_server_url) | |
267 | if is_spam | |
268 | STDERR.puts "** submitting spam for #{id}" | |
269 | akismet.submitSpam(akismet_options.merge(options)) | |
270 | else | |
271 | STDERR.puts "** submitting ham for #{id}" | |
272 | akismet.submitHam(akismet_options.merge(options)) | |
273 | end | |
274 | end | |
275 | end | |
276 | end | |
end | ||
class Object; def to_text_filter; TextFilter.find_by_name(self.to_s); end; end |
rool/rails/typo/trunk/app/models/content_observer.rb:
prev. | current | |
class ContentObserver < ActiveRecord::Observer | ||
def before_save(content) | ||
3 | | |
3 | # content.populate_html_fields | |
end | ||
end |
rool/rails/typo/trunk/app/models/content_state/base.rb:
prev. | current | |
protected :new | ||
end | ||
13 | def memento | |
14 | self.class.to_s | |
15 | end | |
16 | ||
def before_save(content) | ||
serialize_on(content) | ||
true |
rool/rails/typo/trunk/app/models/content_state/factory.rb:
prev. | current | |
module ContentState | ||
class Factory | ||
3 | | |
4 | | |
5 | | |
6 | | |
7 | | |
8 | ||
9 | | |
10 | | |
11 | | |
12 | | |
3 | def self.new(state_name) | |
4 | return ContentState::New.instance unless state_name | |
5 | state_name = state_name.to_s.underscore | |
6 | unless state_name.rindex('/') | |
7 | state_name = 'content_state/' + state_name | |
end | ||
9 | require state_name | |
10 | state_name.camelize.constantize.instance | |
end | ||
end | ||
end |
rool/rails/typo/trunk/app/models/ping.rb:
prev. | current | |
end | ||
def send_pingback_or_trackback(origin_url) | ||
90 | | |
90 | t = Thread.start do | |
91 | Pinger.new(origin_url, self).send_pingback_or_trackback | |
92 | end | |
93 | t.join if defined? $TESTING | |
end | ||
def send_trackback(trackback_url, origin_url) | ||
94 | | |
97 | t = Thread.start do | |
98 | trackback_uri = URI.parse(trackback_url) | |
96 | | |
97 | | |
98 | | |
99 | | |
100 | post = "title=#{CGI.escape(article.title)}" | |
101 | post << "&excerpt=#{CGI.escape(article.body_html.strip_html[0..254])}" | |
102 | post << "&url=#{origin_url}" | |
103 | post << "&blog_name=#{CGI.escape(article.blog.blog_name)}" | |
101 | | |
102 | | |
103 | | |
104 | | |
105 | Net::HTTP.start(trackback_uri.host, trackback_uri.port) do |http| | |
106 | path = trackback_uri.path | |
107 | path += "?#{trackback_uri.query}" if trackback_uri.query | |
108 | http.post(path, post, 'Content-type' => 'application/x-www-form-urlencoded; charset=utf-8') | |
109 | end | |
end | ||
111 | t.join if defined? $TESTING | |
end | ||
108 | ||
109 | ||
def send_weblogupdatesping(server_url, origin_url) | ||
111 | | |
115 | t = Thread.start do | |
116 | send_xml_rpc(self.url, "weblogUpdates.ping", article.blog.blog_name, server_url, origin_url) | |
117 | end | |
118 | t.join if defined? $TESTING | |
end | ||
protected | ||
def send_xml_rpc(xml_rpc_url, name, *args) | ||
117 | | |
118 | | |
124 | t = Thread.start do | |
125 | begin | |
126 | server = XMLRPC::Client.new2(URI.parse(xml_rpc_url).to_s) | |
120 | | |
121 | | |
122 | | |
128 | begin | |
129 | result = server.call(name, *args) | |
130 | rescue XMLRPC::FaultException => e | |
131 | logger.error(e) | |
132 | end | |
133 | rescue Exception => e | |
logger.error(e) | ||
end | ||
125 | | |
126 | | |
end | ||
137 | t.join if defined? $TESTING | |
end | ||
end |
rool/rails/typo/trunk/app/models/text_filter.rb:
prev. | current | |
help_text = help.collect do |f| | ||
f.help_text.blank? ? '' : "#{BlueCloth.new(f.help_text).to_html}\n" | ||
103 | | |
103 | end.join("\n") | |
return help_text | ||
end |
rool/rails/typo/trunk/app/models/trackback.rb:
prev. | current | |
content_fields :excerpt | ||
validates_age_of :article_id | ||
10 | | |
validates_presence_of :title, :excerpt, :url | ||
validate_on_create :article_is_pingable | ||
... | ... | |
def article_is_pingable | ||
return if article.nil? | ||
45 | if blog.global_pings_disable | |
46 | errors.add(:article, "Pings are disabled") | |
47 | end | |
unless article.allow_pings? | ||
errors.add(:article, "Article is not pingable") | ||
end | ||
end | ||
52 | ||
53 | def akismet_options | |
54 | {:user_ip => ip, :comment_type => 'trackback', :comment_author => blog_name, :comment_author_email => nil, | |
55 | :comment_author_url => url, :comment_content => excerpt} | |
56 | end | |
57 | ||
58 | def spam_fields | |
59 | [:title, :excerpt, :ip, :url] | |
60 | end | |
end | ||
rool/rails/typo/trunk/app/views/admin/content/_form.rhtml:
prev. | current | |
<p> | ||
<label for="article_body">Body:</label><br /> | ||
<%= text_area 'article', 'body', :rows => 25, :style => 'width: 48%;' %> | ||
15 | <br/><%= markup_help_popup @article.text_filter, "Markup Help" %> | |
</p> | ||
<p> | ||
<label for="categories">Categories:</label><br /> | ||
... | ... | |
</select> | ||
</p> | ||
<p> | ||
23 | | |
24 | <label for="article_keywords">Tags:</label><br/> | |
<%= text_field 'article', 'keywords' %> | ||
</p> | ||
<p> | ||
... | ... | |
<a href="#" onclick="Element.toggle('advanced'); return false;">Toggle Advanced Options (+/-)</a> | ||
<div id="advanced" style="display:none;"> | ||
<label for="article_allow_comments">Allow comments: </label><%= check_box 'article', 'allow_comments' %><br /> | ||
37 | ||
38 | <label for="article_allow_pings">Allow trackbacks: </label><%= check_box 'article', 'allow_pings' %><br /> | |
<label for="article_published">Published:</label><%= check_box 'article', 'published' %><br /> | ||
<label for="article_text_filter">Textfilter: </label><%= select 'article', 'text_filter', text_filter_options %><br /> | ||
<label for="article_published_at">Publish at:</label><%= datetime_select 'article', 'published_at', :include_blank => true %><br /> |
rool/rails/typo/trunk/app/views/admin/general/index.rhtml:
prev. | current | |
<hr/> | ||
81 | <p>This setting allows you to disable trackbacks for every article in | |
82 | your blog. It won't remove existing trackbacks, but it will prevent | |
83 | any further attempt to add a trackback anywhere on your blog. You can | |
84 | enable or disable trackbacks per-article using the article's extended | |
85 | settings. See also the | |
86 | <a href="#gensettings" onclick="new Effect.ScrollTo('gensettings'); return false">"Enable Trackbacks by default" setting</a> above. | |
87 | </p> | |
88 | <p> | |
89 | <input name="setting[global_pings_disable]" id="global_pings_disable" type="checkbox" value="1" <%= 'checked="checked"' if this_blog.global_pings_disable%> /> | |
90 | <input name="setting[global_pings_disable]" type="hidden" value="0"/> | |
91 | <label for="global_pings_disable">Disable trackbacks site-wide</label> | |
92 | ||
93 | </p> | |
94 | ||
95 | <hr /> | |
96 | ||
<p>Should Typo send trackbacks to websites that you link to? This should be disabled | ||
for private blogs, as it will leak non-public information to sites that you're discussing. | ||
For public blogs, there's no real point in disabling this.</p> | ||
... | ... | |
<input name="setting[sp_global]" id="sp_global" type="checkbox" value="1" <%= 'checked="checked"' if this_blog.sp_global%> /><input name="setting[sp_global]" type="hidden" value="0"/> | ||
<label for="sp_global">Enable spam protection</label> | ||
</p> | ||
160 | <p>Typo can (optionally) use the <a href="http://akismet.com">Akismet</a> spam-filtering service. You need to register with | |
161 | Akismet and receive an API key before you can use their service. If you have an Akismet key, enter it here. | |
162 | </p> | |
<p> | ||
164 | <label for="sp_akismet_key">Akismet Key</label> | |
165 | <input name="setting[sp_akismet_key]" id="sp_akismet_key" type="text" value="<%=h this_blog.sp_akismet_key %>"/> | |
166 | </p> | |
167 | <p>You can optionally disable non-Ajax comments. Typo will always use Ajax for comment submission if Javascript is enabled, | |
168 | so non-Ajax comments are either from spammers or users without Javascript. | |
169 | </p> | |
170 | <p> | |
<input name="setting[sp_allow_non_ajax_comments]" id="sp_allow_non_ajax_comments" type="checkbox" value="1" <%= 'checked="checked"' if this_blog.sp_allow_non_ajax_comments%> /> | ||
<input name="setting[sp_allow_non_ajax_comments]" type="hidden" value="0" /> | ||
<label for="sp_allow_non_ajax_comments">Allow non-ajax comments</label> | ||
... | ... | |
<p> | ||
<label for="itunes_summary">Summary:<small>(setting for channel)</small> | ||
</label> <br /> | ||
179 | | |
205 | <textarea name="setting[itunes_summary]" cols="40" rows="3"><%=h this_blog.itunes_summary %></textarea> | |
</p> | ||
<p> | ||
<label for="itunes_email">Email:</label> |
rool/rails/typo/trunk/app/views/admin/pages/_form.rhtml:
prev. | current | |
<p> | ||
<label for="page_body">Content:</label><br /> | ||
<%= text_area 'page', 'body', :rows => 25, :style => 'width: 48%;' %> | ||
14 | <br/><%= markup_help_popup @page.text_filter, "Markup Help" %> | |
</p> | ||
<label for="page_text_filter">Textfilter: </label><%= select 'page', 'text_filter', text_filter_options %><br/> |
rool/rails/typo/trunk/app/views/articles/_comment.rhtml:
prev. | current | |
<%= gravatar_tag(comment.email) if this_blog.use_gravatar and comment.email %> | ||
<cite><strong><%= link_to_unless(comment.url.blank?, h(comment.author), comment.url) %></strong> </cite> said <%= distance_of_time_in_words comment.article.published_at, comment.created_at %> later:<br /> | ||
<%= comment.full_html %> | ||
7 | <% unless comment.published -%> | |
8 | <div class="spamwarning">This comment has been flagged for moderator approval. It won't appear on this blog until the author approves it.</div> | |
9 | <% end -%> | |
</li> |
rool/rails/typo/trunk/app/views/articles/_comment_box.rhtml:
prev. | current | |
<tr> | ||
<td colspan="2" id="frm-btns"> | ||
<span id="comment_loading" style="display:none;"><%= image_tag "spinner.gif" %></span> | ||
37 | <%= markup_help_popup TextFilter.find_by_name(config[:comment_text_filter]), "Comment Markup Help" %> | |
<a href="#" onclick="new Ajax.Updater('preview', '<%= url_for :action => 'comment_preview' %>', {asynchronous:true, evalScripts:true, parameters:Form.serialize('commentform'), onComplete:function(request){Element.show('preview')}}); return false;">Preview comment</a> | ||
<input type="submit" name="submit" id="form-submit-button" value="submit" class="button" /> | ||
</td> |
rool/rails/typo/trunk/app/views/articles/read.rhtml:
prev. | current | |
<% if @article.allow_comments? or @article.comments.size > 0 -%> | ||
<a name="comments"></a><h4 class="blueblk">Comments</h4> | ||
32 | | |
32 | <% unless @article.comments_closed? -%> | |
<p class="postmetadata alt"> | ||
<small><a href="#respond">Leave a response</a></small> | ||
</p> | ||
... | ... | |
</small> | ||
</p> | ||
66 | ||
66 | <% unless @article.comments_closed? -%> | |
<%= render :partial => 'comment_box' %> | ||
<% else -%> | ||
<p>Comments are disabled</p> |
rool/rails/typo/trunk/app/views/layouts/administration.rhtml:
prev. | current | |
<ul id="tabs"> | ||
<%= tab "Articles", :controller=>"/admin/content", :action => 'index' %> | ||
<%= tab "Pages", :controller=>"/admin/pages", :action => 'index' %> | ||
33 | <%= tab "Feedback", :controller=>"/admin/feedback", :action => 'index' %> | |
<%= tab "Categories", :controller=>"/admin/categories", :action => 'index' %> | ||
<%= tab "Blacklist", :controller=>"/admin/blacklist", :action => 'index' %> | ||
<%= tab "Sidebar", :controller=>"/admin/sidebar", :action => 'index' %> |
rool/rails/typo/trunk/app/views/notification_mailer/_mail_footer.rhtml:
prev. | current | |
</div> | ||
<p><em>This is being sent to <%=h @user.name %> because you asked to be notified via email whenever | ||
4 | ||
4 | new content is posted to <%= link_to @blog_name, @controller.url_for(:controller => 'articles', :action => 'index') %> | |
To unsubscribe, go to | ||
<a href="<%= @link_url = @controller.url_for(:controller => 'admin/users', :action => 'edit', :id => @user.id) %>"><%=h @link_url%></a> | ||
and change your user settings.</p> |
rool/rails/typo/trunk/app/views/xml/itunes_feed.rxml:
prev. | current | |
xml.itunes :email,(this_blog.itunes_email) | ||
end | ||
xml.copyright(this_blog.itunes_copyright) | ||
23 | | |
25 | | |
26 | | |
27 | | |
24 | @items.each do |item| | |
25 | render :partial => "itunes_item_resource", | |
26 | :locals => {:item => item, :xm => xml} | |
27 | end | |
end | ||
end |
rool/rails/typo/trunk/components/plugins/sidebars/archives_controller.rb:
prev. | current | |
def content | ||
8 | | |
9 | | |
10 | ||
11 | | |
12 | | |
13 | | |
14 | | |
15 | | |
16 | ||
17 | | |
18 | | |
19 | | |
20 | | |
21 | | |
8 | # The original query that was here instantiated every article and every | |
9 | # tag, and then sorted through them just to do a 'group by date'. | |
10 | # Unfortunately, there's no universally-supported way to do this | |
11 | # across all three of our supported DBs. So, we resort to a bit of | |
12 | # DB-specific code. | |
13 | if Content.connection.kind_of? ActiveRecord::ConnectionAdapters::SQLiteAdapter | |
14 | date_func = "strftime('%Y', published_at) as year, strftime('%m', published_at) as month" | |
15 | else | |
16 | date_func = "extract(year from published_at) as year,extract(month from published_at) as month" | |
end | ||
18 | ||
19 | article_counts = Content.find_by_sql(["select count(*) as count, #{date_func} from contents where type='Article' and published = ? and published_at < ? group by year,month order by year desc,month desc limit ?",true,Time.now,count.to_i]) | |
20 | ||
21 | @archives = article_counts.map do |entry| | |
22 | { | |
23 | :name => "#{Date::MONTHNAMES[entry.month.to_i]} #{entry.year}", | |
24 | :month => entry.month.to_i, | |
25 | :year => entry.year.to_i, | |
26 | :article_count => entry.count | |
27 | } | |
28 | end | |
end | ||
end |
rool/rails/typo/trunk/components/plugins/sidebars/delicious/content.rhtml:
prev. | current | |
<% if @delicious -%> | ||
<div id="delicious"> | ||
3 | | |
3 | <h3><a href="http://<%=h @delicious.title %>"><%=h @delicious.title %></a></h3> | |
<% (@sb_config['groupdate'] ? @delicious.days : [{ :container => @delicious.items }]).each do |group| -%> | ||
<% if @sb_config['groupdate'] -%> | ||
6 | | |
6 | <span class="date"><%=h group[:date].to_s.to_date.strftime("%b %d") %></span> | |
<% end -%> | ||
<ul> | ||
<% for item in group[:container] %> | ||
<li> | ||
11 | | |
11 | <a href="<%=h item.link %>" title="<%=h item.description%>"><%=h item.title %></a> | |
<% if @sb_config['description'] -%> | ||
13 | | |
13 | <br /><span class="desc"><%=h @sb_config['desclink'] ? item.description_link : item.description %></span> | |
<% end -%> | ||
</li> | ||
<% end -%> |
rool/rails/typo/trunk/components/plugins/sidebars/xml_controller.rb:
prev. | current | |
setting :trackbacks, false, :input_type => :checkbox | ||
setting :format, 'rss20', :input_type => :radio, | ||
10 | | |
10 | :choices => [["rss20", "RSS 2.0"], ["atom10", "Atom 1.0"]] | |
end |
rool/rails/typo/trunk/components/plugins/textfilters/amazon_controller.rb:
prev. | current | |
turns into | ||
37 | | |
37 | <a href="http://www.amazon.com/.../097669400X/scottstuff-20">} | |
end | ||
end |
rool/rails/typo/trunk/components/plugins/textfilters/flickr_controller.rb:
prev. | current | |
imageurl = details['source'] | ||
imagelink = flickrimage.url | ||
58 | | |
58 | caption ||= sanitize(CGI.unescapeHTML(flickrimage.description)) unless flickrimage.description.blank? | |
title ||= flickrimage.title | ||
alt ||= title | ||
rool/rails/typo/trunk/components/plugins/textfilters/sparkline_controller.rb:
prev. | current | |
require 'net/http' | ||
begin | ||
4 | | |
4 | Kernel.require 'sparklines' | |
6 | Sparklines # this will throw an exception if the require failed. | |
7 | ||
class Plugins::Textfilters::SparklineController < TextFilterPlugin::MacroPost | ||
plugin_public_action :plot | ||
plugin_display_name "Sparkline" | ||
... | ... | |
render :text => '' | ||
end | ||
end | ||
84 | ||
rescue LoadError | ||
# ignore load errors by not loading any of the library | ||
end |
rool/rails/typo/trunk/components/plugins/textfilters/textile_controller.rb:
prev. | current | |
plugin_display_name "Textile" | ||
plugin_description 'Textile markup language' | ||
5 | def self.help_text | |
6 | %{ | |
7 | See [_why's Textile reference](http://hobix.com/textile/). | |
8 | } | |
9 | end | |
10 | ||
def self.filtertext(controller,content,text,params) | ||
6 | | |
12 | RedCloth.new(text).to_html(:textile) | |
end | ||
end |
rool/rails/typo/trunk/config/boot.rb:
prev. | current | |
end | ||
Rails::Initializer.run(:set_load_path) | ||
44 | ||
44 | end | |
rool/rails/typo/trunk/config/environment.rb:
prev. | current | |
require File.join(File.dirname(__FILE__), 'boot') | ||
Rails::Initializer.run do |config| | ||
11 | | |
12 | | |
13 | | |
14 | | |
15 | ||
# Skip frameworks you're not going to use | ||
# config.frameworks -= [ :action_web_service, :action_mailer ] | ||
... | ... | |
# config.load_paths += %W( #{RAILS_ROOT}/app/services ) | ||
config.load_paths += %W( | ||
vendor/rubypants | ||
18 | vendor/akismet | |
vendor/redcloth/lib | ||
vendor/bluecloth/lib | ||
vendor/flickr | ||
... | ... | |
# Force all environments to use the same logger level | ||
# (by default production uses :info, the others :debug) | ||
41 | | |
37 | # config.log_level = :debug | |
# Use the database for sessions instead of the file system | ||
# (create the session table with 'rake create_sessions_table') | ||
... | ... | |
# Include your application configuration below | ||
76 | ||
77 | ||
78 | ||
79 | ||
80 | ||
# Load included libraries. | ||
require 'redcloth' | ||
require 'bluecloth' |
rool/rails/typo/trunk/config/environments/production.rb:
prev. | current | |
# Use a different logger for distributed setups | ||
# config.logger = SyslogLogger.new | ||
8 | ||
# Full error reports are disabled and caching is turned on | ||
config.action_controller.consider_all_requests_local = false | ||
config.action_controller.perform_caching = true | ||
# Enable serving of images, stylesheets, and javascripts from an asset server | ||
13 | ||
14 | # config.action_controller.asset_host = "http://assets.example.com" | |
# Disable delivery errors if you bad email addresses should just be ignored | ||
# config.action_mailer.raise_delivery_errors = false |
rool/rails/typo/trunk/config/routes.rb:
prev. | current | |
ActionController::Routing::Routes.draw do |map| | ||
# default | ||
4 | | |
5 | | |
4 | map.index '', :controller => 'articles', :action => 'index' | |
5 | map.admin 'admin', :controller => 'admin/general', :action => 'index' | |
# admin/comments controller needs parent article id | ||
8 | | |
8 | map.connect 'admin/comments/article/:article_id/:action/:id', | |
:controller => 'admin/comments', :action => nil, :id => nil | ||
10 | | |
10 | map.connect 'admin/trackbacks/article/:article_id/:action/:id', | |
:controller => 'admin/trackbacks', :action => nil, :id => nil | ||
12 | | |
12 | map.connect 'admin/content/:action/:id', :controller => 'admin/content' | |
# make rss feed urls pretty and let them end in .xml | ||
# this improves caches_page because now apache and webrick will send out the | ||
# cached feeds with the correct xml mime type. | ||
17 | | |
18 | | |
19 | | |
20 | | |
17 | map.xml 'xml/itunes/feed.xml', :controller => 'xml', :action => 'itunes' | |
18 | map.xml 'xml/articlerss/:id/feed.xml', :controller => 'xml', :action => 'articlerss' | |
19 | map.xml 'xml/commentrss/feed.xml', :controller => 'xml', :action => 'commentrss' | |
20 | map.xml 'xml/trackbackrss/feed.xml', :controller => 'xml', :action => 'trackbackrss' | |
22 | | |
23 | | |
24 | | |
25 | | |
26 | ||
22 | map.xml 'xml/:format/feed.xml', :controller => 'xml', :action => 'feed', :type => 'feed' | |
23 | map.xml 'xml/:format/:type/feed.xml', :controller => 'xml', :action => 'feed' | |
24 | map.xml 'xml/:format/:type/:id/feed.xml', :controller => 'xml', :action => 'feed' | |
25 | map.xml 'xml/rss', :controller => 'xml', :action => 'feed', :type => 'feed', :format => 'rss' | |
26 | map.xml 'sitemap.xml', :controller => 'xml', :action => 'feed', :format => 'googlesitemap', :type => 'sitemap' | |
27 | ||
# allow neat perma urls | ||
28 | | |
29 | map.connect 'articles', | |
:controller => 'articles', :action => 'index' | ||
30 | | |
31 | map.connect 'articles/page/:page', | |
:controller => 'articles', :action => 'index', | ||
:page => /\d+/ | ||
34 | | |
35 | map.connect 'articles/:year/:month/:day', | |
:controller => 'articles', :action => 'find_by_date', | ||
:year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/ | ||
37 | | |
38 | map.connect 'articles/:year/:month', | |
:controller => 'articles', :action => 'find_by_date', | ||
:year => /\d{4}/, :month => /\d{1,2}/ | ||
40 | | |
41 | map.connect 'articles/:year', | |
:controller => 'articles', :action => 'find_by_date', | ||
:year => /\d{4}/ | ||
44 | | |
45 | map.connect 'articles/:year/:month/:day/page/:page', | |
:controller => 'articles', :action => 'find_by_date', | ||
:year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/, :page => /\d+/ | ||
47 | | |
48 | map.connect 'articles/:year/:month/page/:page', | |
:controller => 'articles', :action => 'find_by_date', | ||
:year => /\d{4}/, :month => /\d{1,2}/, :page => /\d+/ | ||
50 | | |
51 | map.connect 'articles/:year/page/:page', | |
:controller => 'articles', :action => 'find_by_date', | ||
:year => /\d{4}/, :page => /\d+/ | ||
54 | | |
55 | map.connect 'articles/:year/:month/:day/:title', | |
:controller => 'articles', :action => 'permalink', | ||
:year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/ | ||
58 | | |
59 | map.connect 'articles/category/:id', | |
:controller => 'articles', :action => 'category' | ||
60 | | |
61 | map.connect 'articles/category/:id/page/:page', | |
:controller => 'articles', :action => 'category', | ||
:page => /\d+/ | ||
64 | | |
65 | map.connect 'articles/tag/:id', | |
:controller => 'articles', :action => 'tag' | ||
66 | | |
67 | map.connect 'articles/tag/:id/page/:page', | |
:controller => 'articles', :action => 'tag', | ||
:page => /\d+/ | ||
70 | | |
71 | map.connect 'pages/*name',:controller => 'articles', :action => 'view_page' | |
72 | | |
73 | map.connect 'stylesheets/theme/:filename', | |
:controller => 'theme', :action => 'stylesheets' | ||
74 | | |
75 | map.connect 'javascript/theme/:filename', | |
:controller => 'theme', :action => 'javascript' | ||
76 | | |
77 | map.connect 'images/theme/:filename', | |
:controller => 'theme', :action => 'images' | ||
79 | | |
80 | map.connect 'plugins/filters/:filter/:public_action', | |
:controller => 'textfilter', :action => 'public_action' | ||
# Kill attempts to connect directly to the theme controller. | ||
# Ideally we'd disable these by removing the default route (below), | ||
# but that breaks too many things for Typo 2.5. | ||
85 | | |
86 | map.connect 'theme/*stuff', | |
:controller => 'theme', :action => 'error' | ||
# Allow legacy urls to still work | ||
89 | | |
90 | map.connect ':controller/:action/:id' | |
91 | | |
92 | map.connect '*from', :controller => 'redirect', :action => 'redirect' | |
end |
rool/rails/typo/trunk/db/development_structure.sql:
prev. | current | |
SET default_tablespace = ''; | ||
20 | ||
20 | SET default_with_oids = false; | |
-- | ||
23 | ||
23 | -- Name: articles_categories; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
-- | ||
26 | ||
27 | | |
28 | | |
29 | | |
30 | | |
31 | | |
32 | | |
33 | | |
34 | | |
35 | | |
36 | | |
37 | | |
38 | | |
39 | | |
40 | | |
41 | | |
42 | | |
43 | | |
44 | | |
26 | CREATE TABLE articles_categories ( | |
27 | article_id integer, | |
28 | category_id integer, | |
29 | primary_item integer | |
); | ||
48 | ||
49 | ||
-- | ||
51 | ||
34 | -- Name: articles_tags; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
-- | ||
54 | ||
37 | CREATE TABLE articles_tags ( | |
article_id integer, | ||
56 | | |
57 | | |
39 | tag_id integer | |
); | ||
61 | ||
62 | ||
-- | ||
-- Name: blacklist_patterns; Type: TABLE; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
); | ||
74 | ||
54 | -- | |
55 | -- Name: blogs; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
56 | -- | |
58 | CREATE TABLE blogs ( | |
59 | id serial NOT NULL, | |
60 | settings text | |
61 | ); | |
62 | ||
63 | ||
-- | ||
-- Name: categories; Type: TABLE; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
id serial NOT NULL, | ||
name character varying(255), | ||
"position" integer DEFAULT 0 NOT NULL, | ||
72 | is_primary integer, | |
permalink character varying(255) | ||
); | ||
88 | ||
89 | ||
-- | ||
91 | ||
78 | -- Name: contents; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
-- | ||
94 | ||
81 | CREATE TABLE contents ( | |
id serial NOT NULL, | ||
96 | | |
title character varying(255), | ||
author character varying(255), | ||
85 | body text, | |
86 | body_html text, | |
87 | extended text, | |
88 | excerpt text, | |
89 | keywords character varying(255), | |
90 | created_at timestamp without time zone, | |
91 | updated_at timestamp without time zone, | |
92 | extended_html text, | |
93 | user_id integer, | |
94 | permalink character varying(255), | |
95 | guid character varying(255), | |
96 | text_filter_id integer, | |
97 | whiteboard text, | |
98 | comments_count integer, | |
99 | trackbacks_count integer, | |
100 | "type" character varying(255), | |
101 | article_id integer, | |
email character varying(255), | ||
url character varying(255), | ||
101 | | |
102 | | |
103 | | |
104 | | |
105 | | |
104 | ip character varying(255), | |
105 | blog_name character varying(255), | |
106 | name character varying(255), | |
107 | published boolean DEFAULT true, | |
108 | allow_pings boolean, | |
109 | allow_comments boolean, | |
110 | blog_id integer | |
); | ||
109 | ||
114 | -- | |
115 | -- Name: mt_author_id; Type: SEQUENCE; Schema: public; Owner: typo | |
116 | -- | |
118 | CREATE SEQUENCE mt_author_id | |
119 | START WITH 1 | |
120 | INCREMENT BY 1 | |
121 | NO MAXVALUE | |
122 | NO MINVALUE | |
123 | CACHE 1; | |
124 | ||
125 | ||
-- | ||
112 | ||
127 | -- Name: mt_blog_id; Type: SEQUENCE; Schema: public; Owner: typo | |
-- | ||
115 | ||
116 | | |
117 | | |
118 | ||
130 | CREATE SEQUENCE mt_blog_id | |
131 | START WITH 1 | |
132 | INCREMENT BY 1 | |
133 | NO MAXVALUE | |
134 | NO MINVALUE | |
135 | CACHE 1; | |
121 | ||
138 | -- | |
139 | -- Name: mt_category_id; Type: SEQUENCE; Schema: public; Owner: typo | |
140 | -- | |
142 | CREATE SEQUENCE mt_category_id | |
143 | START WITH 1 | |
144 | INCREMENT BY 1 | |
145 | NO MAXVALUE | |
146 | NO MINVALUE | |
147 | CACHE 1; | |
148 | ||
149 | ||
-- | ||
124 | ||
151 | -- Name: mt_comment_id; Type: SEQUENCE; Schema: public; Owner: typo | |
-- | ||
127 | ||
154 | CREATE SEQUENCE mt_comment_id | |
155 | INCREMENT BY 1 | |
156 | NO MAXVALUE | |
157 | NO MINVALUE | |
158 | CACHE 1; | |
159 | ||
160 | ||
161 | -- | |
162 | -- Name: mt_entry_id; Type: SEQUENCE; Schema: public; Owner: typo | |
163 | -- | |
164 | ||
165 | CREATE SEQUENCE mt_entry_id | |
166 | INCREMENT BY 1 | |
167 | NO MAXVALUE | |
168 | NO MINVALUE | |
169 | CACHE 1; | |
170 | ||
171 | ||
172 | -- | |
173 | -- Name: mt_ext_bl_group_id; Type: SEQUENCE; Schema: public; Owner: typo | |
174 | -- | |
175 | ||
176 | CREATE SEQUENCE mt_ext_bl_group_id | |
177 | INCREMENT BY 1 | |
178 | NO MAXVALUE | |
179 | NO MINVALUE | |
180 | CACHE 1; | |
181 | ||
182 | ||
183 | -- | |
184 | -- Name: mt_ext_bl_groupmap_id; Type: SEQUENCE; Schema: public; Owner: typo | |
185 | -- | |
186 | ||
187 | CREATE SEQUENCE mt_ext_bl_groupmap_id | |
188 | INCREMENT BY 1 | |
189 | NO MAXVALUE | |
190 | NO MINVALUE | |
191 | CACHE 1; | |
192 | ||
193 | ||
194 | -- | |
195 | -- Name: mt_ext_bl_item_id; Type: SEQUENCE; Schema: public; Owner: typo | |
196 | -- | |
197 | ||
198 | CREATE SEQUENCE mt_ext_bl_item_id | |
199 | INCREMENT BY 1 | |
200 | NO MAXVALUE | |
201 | NO MINVALUE | |
202 | CACHE 1; | |
203 | ||
204 | ||
205 | -- | |
206 | -- Name: mt_ext_bl_log_id; Type: SEQUENCE; Schema: public; Owner: typo | |
207 | -- | |
208 | ||
209 | CREATE SEQUENCE mt_ext_bl_log_id | |
210 | INCREMENT BY 1 | |
211 | NO MAXVALUE | |
212 | NO MINVALUE | |
213 | CACHE 1; | |
214 | ||
215 | ||
216 | -- | |
217 | -- Name: mt_ext_bl_permission_id; Type: SEQUENCE; Schema: public; Owner: typo | |
218 | -- | |
219 | ||
220 | CREATE SEQUENCE mt_ext_bl_permission_id | |
221 | INCREMENT BY 1 | |
222 | NO MAXVALUE | |
223 | NO MINVALUE | |
224 | CACHE 1; | |
225 | ||
226 | ||
227 | -- | |
228 | -- Name: mt_ext_bl_source_id; Type: SEQUENCE; Schema: public; Owner: typo | |
229 | -- | |
230 | ||
231 | CREATE SEQUENCE mt_ext_bl_source_id | |
232 | START WITH 1 | |
233 | INCREMENT BY 1 | |
234 | NO MAXVALUE | |
235 | NO MINVALUE | |
236 | CACHE 1; | |
237 | ||
238 | ||
239 | -- | |
240 | -- Name: mt_ext_bl_update_id; Type: SEQUENCE; Schema: public; Owner: typo | |
241 | -- | |
242 | ||
243 | CREATE SEQUENCE mt_ext_bl_update_id | |
244 | START WITH 1 | |
245 | INCREMENT BY 1 | |
246 | NO MAXVALUE | |
247 | NO MINVALUE | |
248 | CACHE 1; | |
249 | ||
250 | ||
251 | -- | |
252 | -- Name: mt_fileinfo_id; Type: SEQUENCE; Schema: public; Owner: typo | |
253 | -- | |
254 | ||
255 | CREATE SEQUENCE mt_fileinfo_id | |
256 | START WITH 1 | |
257 | INCREMENT BY 1 | |
258 | NO MAXVALUE | |
259 | NO MINVALUE | |
260 | CACHE 1; | |
261 | ||
262 | ||
263 | -- | |
264 | -- Name: mt_ipbanlist_id; Type: SEQUENCE; Schema: public; Owner: typo | |
265 | -- | |
266 | ||
267 | CREATE SEQUENCE mt_ipbanlist_id | |
268 | START WITH 1 | |
269 | INCREMENT BY 1 | |
270 | NO MAXVALUE | |
271 | NO MINVALUE | |
272 | CACHE 1; | |
273 | ||
274 | ||
275 | -- | |
276 | -- Name: mt_log_id; Type: SEQUENCE; Schema: public; Owner: typo | |
277 | -- | |
278 | ||
279 | CREATE SEQUENCE mt_log_id | |
280 | INCREMENT BY 1 | |
281 | NO MAXVALUE | |
282 | NO MINVALUE | |
283 | CACHE 1; | |
284 | ||
285 | ||
286 | -- | |
287 | -- Name: mt_notification_id; Type: SEQUENCE; Schema: public; Owner: typo | |
288 | -- | |
289 | ||
290 | CREATE SEQUENCE mt_notification_id | |
291 | START WITH 1 | |
292 | INCREMENT BY 1 | |
293 | NO MAXVALUE | |
294 | NO MINVALUE | |
295 | CACHE 1; | |
296 | ||
297 | ||
298 | -- | |
299 | -- Name: mt_permission_id; Type: SEQUENCE; Schema: public; Owner: typo | |
300 | -- | |
301 | ||
302 | CREATE SEQUENCE mt_permission_id | |
303 | START WITH 1 | |
304 | INCREMENT BY 1 | |
305 | NO MAXVALUE | |
306 | NO MINVALUE | |
307 | CACHE 1; | |
308 | ||
309 | ||
310 | -- | |
311 | -- Name: mt_placement_id; Type: SEQUENCE; Schema: public; Owner: typo | |
312 | -- | |
313 | ||
314 | CREATE SEQUENCE mt_placement_id | |
315 | INCREMENT BY 1 | |
316 | NO MAXVALUE | |
317 | NO MINVALUE | |
318 | CACHE 1; | |
319 | ||
320 | ||
321 | -- | |
322 | -- Name: mt_plugindata_id; Type: SEQUENCE; Schema: public; Owner: typo | |
323 | -- | |
324 | ||
325 | CREATE SEQUENCE mt_plugindata_id | |
326 | INCREMENT BY 1 | |
327 | NO MAXVALUE | |
328 | NO MINVALUE | |
329 | CACHE 1; | |
330 | ||
331 | ||
332 | -- | |
333 | -- Name: mt_tbping_id; Type: SEQUENCE; Schema: public; Owner: typo | |
334 | -- | |
335 | ||
336 | CREATE SEQUENCE mt_tbping_id | |
337 | INCREMENT BY 1 | |
338 | NO MAXVALUE | |
339 | NO MINVALUE | |
340 | CACHE 1; | |
341 | ||
342 | ||
343 | -- | |
344 | -- Name: mt_template_id; Type: SEQUENCE; Schema: public; Owner: typo | |
345 | -- | |
346 | ||
347 | CREATE SEQUENCE mt_template_id | |
348 | INCREMENT BY 1 | |
349 | NO MAXVALUE | |
350 | NO MINVALUE | |
351 | CACHE 1; | |
352 | ||
353 | ||
354 | -- | |
355 | -- Name: mt_templatemap_id; Type: SEQUENCE; Schema: public; Owner: typo | |
356 | -- | |
357 | ||
358 | CREATE SEQUENCE mt_templatemap_id | |
359 | INCREMENT BY 1 | |
360 | NO MAXVALUE | |
361 | NO MINVALUE | |
362 | CACHE 1; | |
363 | ||
364 | ||
365 | -- | |
366 | -- Name: mt_trackback_id; Type: SEQUENCE; Schema: public; Owner: typo | |
367 | -- | |
368 | ||
369 | CREATE SEQUENCE mt_trackback_id | |
370 | INCREMENT BY 1 | |
371 | NO MAXVALUE | |
372 | NO MINVALUE | |
373 | CACHE 1; | |
374 | ||
375 | ||
376 | -- | |
377 | -- Name: notifications; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
378 | -- | |
379 | ||
380 | CREATE TABLE notifications ( | |
381 | notify_user_id integer, | |
382 | notify_content_id integer, | |
383 | created_at timestamp without time zone, | |
384 | updated_at timestamp without time zone | |
385 | ); | |
386 | ||
387 | ||
388 | -- | |
389 | -- Name: page_caches; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
390 | -- | |
391 | ||
392 | CREATE TABLE page_caches ( | |
id serial NOT NULL, | ||
129 | | |
130 | | |
131 | | |
132 | | |
133 | | |
134 | | |
135 | | |
136 | | |
394 | name character varying(255) | |
); | ||
140 | ||
141 | ||
-- | ||
-- Name: pings; Type: TABLE; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
); | ||
154 | ||
410 | -- | |
411 | -- Name: redirects; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
412 | -- | |
414 | CREATE TABLE redirects ( | |
415 | id serial NOT NULL, | |
416 | from_path character varying(255), | |
417 | to_path character varying(255) | |
418 | ); | |
419 | ||
420 | ||
-- | ||
-- Name: resources; Type: TABLE; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
filename character varying(255), | ||
mime character varying(255), | ||
created_at timestamp without time zone DEFAULT now(), | ||
166 | | |
431 | updated_at timestamp without time zone DEFAULT now(), | |
432 | article_id integer, | |
433 | itunes_metadata boolean, | |
434 | itunes_author character varying(255), | |
435 | itunes_subtitle character varying(255), | |
436 | itunes_duration integer, | |
437 | itunes_summary text, | |
438 | itunes_keywords character varying(255), | |
439 | itunes_category character varying(255), | |
440 | itunes_explicit boolean | |
); | ||
170 | ||
171 | ||
-- | ||
-- Name: schema_info; Type: TABLE; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
); | ||
181 | ||
182 | ||
-- | ||
-- Name: sessions; Type: TABLE; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
); | ||
196 | ||
197 | ||
-- | ||
199 | ||
467 | -- Name: sidebars; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
-- | ||
202 | ||
470 | CREATE TABLE sidebars ( | |
id serial NOT NULL, | ||
204 | | |
205 | | |
206 | | |
472 | active_position integer, | |
473 | controller character varying(255), | |
474 | staged_position integer, | |
475 | active_config character varying, | |
476 | staged_config character varying | |
); | ||
210 | ||
211 | ||
-- | ||
213 | ||
481 | -- Name: tags; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
-- | ||
216 | ||
484 | CREATE TABLE tags ( | |
id serial NOT NULL, | ||
218 | | |
219 | | |
220 | | |
221 | | |
222 | | |
223 | | |
224 | | |
486 | name character varying(255), | |
487 | created_at timestamp without time zone, | |
488 | updated_at timestamp without time zone, | |
489 | display_name character varying(255) | |
); | ||
228 | ||
229 | ||
-- | ||
231 | ||
494 | -- Name: text_filters; Type: TABLE; Schema: public; Owner: typo; Tablespace: | |
-- | ||
234 | ||
497 | CREATE TABLE text_filters ( | |
id serial NOT NULL, | ||
236 | | |
237 | | |
238 | | |
239 | | |
240 | | |
241 | | |
242 | | |
243 | | |
499 | name character varying(255), | |
500 | description character varying(255), | |
501 | markup character varying(255), | |
502 | filters text, | |
503 | params text | |
); | ||
247 | ||
248 | ||
-- | ||
-- Name: users; Type: TABLE; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
CREATE TABLE users ( | ||
id serial NOT NULL, | ||
255 | | |
513 | "login" character varying(40), | |
"password" character varying(40), | ||
515 | email text, | |
name text, | ||
258 | | |
517 | notify_via_email boolean, | |
518 | notify_on_new_articles boolean, | |
519 | notify_on_comments boolean, | |
520 | notify_watch_my_articles boolean, | |
521 | notify_via_jabber boolean, | |
522 | jabber character varying(255) | |
); | ||
262 | ||
263 | ||
-- | ||
265 | ||
527 | -- Name: blacklist_patterns_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
268 | ||
269 | | |
530 | ALTER TABLE ONLY blacklist_patterns | |
531 | ADD CONSTRAINT blacklist_patterns_pkey PRIMARY KEY (id); | |
272 | ||
273 | ||
-- | ||
275 | ||
535 | -- Name: blogs_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
278 | ||
279 | | |
538 | ALTER TABLE ONLY blogs | |
539 | ADD CONSTRAINT blogs_pkey PRIMARY KEY (id); | |
282 | ||
283 | ||
-- | ||
-- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
ADD CONSTRAINT categories_pkey PRIMARY KEY (id); | ||
292 | ||
293 | ||
-- | ||
295 | ||
551 | -- Name: contents_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
298 | ||
299 | | |
554 | ALTER TABLE ONLY contents | |
555 | ADD CONSTRAINT contents_pkey PRIMARY KEY (id); | |
302 | ||
303 | ||
-- | ||
-- Name: page_caches_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
ADD CONSTRAINT page_caches_pkey PRIMARY KEY (id); | ||
312 | ||
313 | ||
-- | ||
315 | ||
567 | -- Name: pings_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
318 | ||
319 | | |
570 | ALTER TABLE ONLY pings | |
571 | ADD CONSTRAINT pings_pkey PRIMARY KEY (id); | |
322 | ||
323 | ||
-- | ||
325 | ||
575 | -- Name: redirects_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
328 | ||
329 | | |
578 | ALTER TABLE ONLY redirects | |
579 | ADD CONSTRAINT redirects_pkey PRIMARY KEY (id); | |
332 | ||
333 | ||
-- | ||
-- Name: resources_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
ADD CONSTRAINT resources_pkey PRIMARY KEY (id); | ||
342 | ||
343 | ||
-- | ||
-- Name: sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
ADD CONSTRAINT sessions_pkey PRIMARY KEY (id); | ||
352 | ||
353 | ||
-- | ||
355 | ||
599 | -- Name: sidebars_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
358 | ||
359 | | |
602 | ALTER TABLE ONLY sidebars | |
603 | ADD CONSTRAINT sidebars_pkey PRIMARY KEY (id); | |
362 | ||
363 | ||
-- | ||
365 | ||
607 | -- Name: tags_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
368 | ||
369 | | |
610 | ALTER TABLE ONLY tags | |
611 | ADD CONSTRAINT tags_pkey PRIMARY KEY (id); | |
372 | ||
373 | ||
-- | ||
375 | ||
615 | -- Name: text_filters_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | |
-- | ||
378 | ||
379 | | |
618 | ALTER TABLE ONLY text_filters | |
619 | ADD CONSTRAINT text_filters_pkey PRIMARY KEY (id); | |
382 | ||
383 | ||
-- | ||
-- Name: users_login_key; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
ALTER TABLE ONLY users | ||
389 | | |
627 | ADD CONSTRAINT users_login_key UNIQUE ("login"); | |
392 | ||
393 | ||
-- | ||
-- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
ADD CONSTRAINT users_pkey PRIMARY KEY (id); | ||
402 | ||
638 | -- | |
639 | -- Name: categories_permalink_index; Type: INDEX; Schema: public; Owner: typo; Tablespace: | |
640 | -- | |
642 | CREATE INDEX categories_permalink_index ON categories USING btree (permalink); | |
643 | ||
644 | ||
-- | ||
405 | ||
646 | -- Name: contents_article_id_index; Type: INDEX; Schema: public; Owner: typo; Tablespace: | |
-- | ||
408 | ||
649 | CREATE INDEX contents_article_id_index ON contents USING btree (article_id); | |
411 | ||
412 | ||
-- | ||
414 | ||
653 | -- Name: contents_blog_id_index; Type: INDEX; Schema: public; Owner: typo; Tablespace: | |
-- | ||
417 | ||
656 | CREATE INDEX contents_blog_id_index ON contents USING btree (blog_id); | |
420 | ||
421 | ||
-- | ||
-- Name: idx_blacklist_pattern; Type: INDEX; Schema: public; Owner: typo; Tablespace: | ||
-- | ||
... | ... | |
CREATE INDEX idx_blacklist_pattern ON blacklist_patterns USING btree (pattern); | ||
429 | ||
430 | ||
-- | ||
432 | ||
667 | -- Name: idx_pings_article_id; Type: INDEX; Schema: public; Owner: typo; Tablespace: | |
-- | ||
435 | ||
670 | CREATE INDEX idx_pings_article_id ON pings USING btree (article_id); | |
438 | ||
439 | ||
-- | ||
441 | ||
674 | -- Name: page_caches_name_index; Type: INDEX; Schema: public; Owner: typo; Tablespace: | |
-- | ||
444 | ||
677 | CREATE INDEX page_caches_name_index ON page_caches USING btree (name); | |
447 | ||
448 | ||
-- | ||
450 | ||
681 | -- Name: sessions_sessid_index; Type: INDEX; Schema: public; Owner: typo; Tablespace: | |
-- | ||
453 | ||
684 | CREATE INDEX sessions_sessid_index ON sessions USING btree (sessid); | |
456 | ||
457 | ||
-- | ||
459 | ||
688 | -- PostgreSQL database dump complete | |
-- | ||
462 | ||
463 | ||
464 | ||
465 | ||
466 | ||
691 | INSERT INTO schema_info (version) VALUES (40) | |
rool/rails/typo/trunk/db/migrate/022_superclass_trackbacks.rb:
prev. | current | |
class SuperclassTrackbacks < ActiveRecord::Migration | ||
class BareContent < ActiveRecord::Base | ||
include BareMigration | ||
4 | set_inheritance_column :bogustype # see migration #20 for why | |
end | ||
class BareTrackback < ActiveRecord::Base |
rool/rails/typo/trunk/db/migrate/023_superclass_pages.rb:
prev. | current | |
class Bare23Content < ActiveRecord::Base | ||
include BareMigration | ||
3 | set_inheritance_column :bogustype # see migration #20 for why | |
end | ||
class Bare23Page < ActiveRecord::Base | ||
... | ... | |
class SuperclassPages < ActiveRecord::Migration | ||
def self.up | ||
STDERR.puts "Merging Pages into Content table" | ||
12 | | |
13 | modify_tables_and_update(:add_column, Bare23Content, :name, :string) do | |
Bare23Content.transaction do | ||
if not $schema_generator | ||
Bare23Page.find(:all).each do |p| | ||
Bare23Content.create(:type => 'Page', | ||
17 | | |
18 | :name => p.name, | |
:user_id => p.user_id, | ||
:body => p.body, | ||
:body_html => p.body_html, | ||
... | ... | |
modify_tables_and_update(:create_table, :pages, lambda {|t| init_pages(t)}) do | ||
Bare23Content.transaction do | ||
Bare23Content.find(:all, :conditions => "type = 'Page'").each do |p| | ||
49 | | |
50 | Bare23Page.create(:name => p.name, | |
:user_id => p.user_id, | ||
:body => p.body, | ||
:body_html => p.body_html, |
rool/rails/typo/trunk/db/schema.mysql-v3.sql:
prev. | current | |
-- indexes | ||
173 | ||
174 | ||
175 | ||
176 | ||
177 | ||
178 | ||
179 | ||
173 | CREATE INDEX `blacklist_patterns_pattern_index` ON blacklist_patterns (`pattern`); | |
174 | CREATE INDEX `categories_permalink_index` ON categories (`permalink`); | |
175 | CREATE INDEX `contents_blog_id_index` ON contents (`blog_id`); | |
176 | CREATE INDEX `contents_article_id_index` ON contents (`article_id`); | |
177 | CREATE INDEX `page_caches_name_index` ON page_caches (`name`); | |
178 | CREATE INDEX `pings_article_id_index` ON pings (`article_id`); | |
179 | CREATE INDEX `sessions_sessid_index` ON sessions (`sessid`); | |
-- data | ||
rool/rails/typo/trunk/db/schema.mysql.sql:
prev. | current | |
-- indexes | ||
173 | ||
174 | ||
175 | ||
176 | ||
177 | ||
178 | ||
179 | ||
173 | CREATE INDEX `blacklist_patterns_pattern_index` ON blacklist_patterns (`pattern`); | |
174 | CREATE INDEX `categories_permalink_index` ON categories (`permalink`); | |
175 | CREATE INDEX `contents_blog_id_index` ON contents (`blog_id`); | |
176 | CREATE INDEX `contents_article_id_index` ON contents (`article_id`); | |
177 | CREATE INDEX `page_caches_name_index` ON page_caches (`name`); | |
178 | CREATE INDEX `pings_article_id_index` ON pings (`article_id`); | |
179 | CREATE INDEX `sessions_sessid_index` ON sessions (`sessid`); | |
-- data | ||
rool/rails/typo/trunk/db/schema.postgresql.sql:
prev. | current | |
-- indexes | ||
173 | ||
174 | ||
175 | ||
176 | ||
177 | ||
178 | ||
179 | ||
173 | CREATE INDEX "blacklist_patterns_pattern_index" ON blacklist_patterns ("pattern"); | |
174 | CREATE INDEX "categories_permalink_index" ON categories ("permalink"); | |
175 | CREATE INDEX "contents_blog_id_index" ON contents ("blog_id"); | |
176 | CREATE INDEX "contents_article_id_index" ON contents ("article_id"); | |
177 | CREATE INDEX "page_caches_name_index" ON page_caches ("name"); | |
178 | CREATE INDEX "pings_article_id_index" ON pings ("article_id"); | |
179 | CREATE INDEX "sessions_sessid_index" ON sessions ("sessid"); | |
-- data | ||
rool/rails/typo/trunk/db/schema.sqlite.sql:
prev. | current | |
-- indexes | ||
173 | ||
174 | ||
175 | ||
176 | ||
177 | ||
178 | ||
179 | ||
173 | CREATE INDEX "blacklist_patterns_pattern_index" ON blacklist_patterns ("pattern"); | |
174 | CREATE INDEX "categories_permalink_index" ON categories ("permalink"); | |
175 | CREATE INDEX "contents_blog_id_index" ON contents ("blog_id"); | |
176 | CREATE INDEX "contents_article_id_index" ON contents ("article_id"); | |
177 | CREATE INDEX "page_caches_name_index" ON page_caches ("name"); | |
178 | CREATE INDEX "pings_article_id_index" ON pings ("article_id"); | |
179 | CREATE INDEX "sessions_sessid_index" ON sessions ("sessid"); | |
-- data | ||
rool/rails/typo/trunk/db/schema.sqlserver.sql:
prev. | current | |
-- indexes | ||
187 | ||
188 | ||
189 | ||
190 | ||
191 | ||
192 | ||
193 | ||
187 | CREATE INDEX [blacklist_patterns_pattern_index] ON blacklist_patterns ([pattern]); | |
188 | CREATE INDEX [categories_permalink_index] ON categories ([permalink]); | |
189 | CREATE INDEX [contents_blog_id_index] ON contents ([blog_id]); | |
190 | CREATE INDEX [contents_article_id_index] ON contents ([article_id]); | |
191 | CREATE INDEX [page_caches_name_index] ON page_caches ([name]); | |
192 | CREATE INDEX [pings_article_id_index] ON pings ([article_id]); | |
193 | CREATE INDEX [sessions_sessid_index] ON sessions ([sessid]); | |
-- data | ||
rool/rails/typo/trunk/lib/sidebars/plugin.rb:
prev. | current | |
class TextAreaField < self | ||
def input_html(sidebar) | ||
html_options = { "rows" => "10", "cols" => "30", "style" => "width:255px"}.update(options.stringify_keys) | ||
41 | | |
41 | text_area_tag(input_name(sidebar), h(sidebar.config[key]), html_options) | |
end | ||
end | ||
... | ... | |
class Sidebars::Plugin < ApplicationController | ||
include ApplicationHelper | ||
103 | ||
helper :theme | ||
106 | | |
107 | | |
108 | ||
@@subclasses = { } | ||
class << self | ||
... | ... | |
end | ||
end | ||
130 | ||
# The name that needs to be used when refering to the plugin's | ||
# controller in render statements | ||
def component_name | ||
... | ... | |
def default_helper_module! | ||
end | ||
end | ||
200 | ||
195 | ||
def index | ||
@sidebar=params['sidebar'] | ||
203 | | |
198 | set_config | |
199 | @sb_config = @sidebar.config | |
content | ||
render :action=>'content' unless performed? | ||
end | ||
def configure_wrapper | ||
@sidebar=params['sidebar'] | ||
210 | | |
206 | set_config | |
configure | ||
render :action=>'configure' unless performed? | ||
end | ||
... | ... | |
end | ||
private | ||
221 | def set_config | |
222 | @sidebar.config ||= {} | |
223 | @sidebar.config = self.class.default_config.dup.merge(@sidebar.config) | |
224 | @sidebar.config ||= (self.class.default_config) | |
225 | end | |
226 | ||
def sb_config(key) | ||
config = @sidebar.class.default_config | ||
config.merge!(@sidebar.config || {}) |
rool/rails/typo/trunk/lib/tasks/release.rake:
prev. | current | |
require 'rake/gempackagetask' | ||
require 'rake/contrib/rubyforgepublisher' | ||
4 | ||
4 | PKG_VERSION = "4.0.0" | |
PKG_NAME = "typo" | ||
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" | ||
RUBY_FORGE_PROJECT = 'typo' | ||
... | ... | |
s.version = PKG_VERSION | ||
s.summary = "Modern weblog engine." | ||
s.has_rdoc = false | ||
16 | | |
17 | | |
16 | ||
17 | s.files = Dir.glob('**/*', File::FNM_DOTMATCH).reject do |f| | |
18 | [ /\.$/, /config\/database.yml$/, /config\database.yml-/, | |
19 | /\.log$/, /^pkg/, /\.svn/, /^vendor\/rails/, | |
/^public\/(files|xml|articles|pages|index.html)/, | ||
/^public\/(stylesheets|javascripts|images)\/theme/, /\~$/, | ||
/\/\._/, /\/#/ ].any? {|regex| f =~ regex } | ||
... | ... | |
s.email = "tobi@leetsoft.com" | ||
s.homepage = "http://www.typosphere.org" | ||
s.rubyforge_project = "typo" | ||
29 | s.platform = Gem::Platform::RUBY | |
30 | s.executables = ['typo'] | |
31 | ||
32 | s.add_dependency("rails", "= 1.1.4") | |
33 | s.add_dependency("mongrel", ">= 0.3.13.3") | |
34 | s.add_dependency("mongrel_cluster", ">= 0.2.0") | |
35 | s.add_dependency("sqlite3-ruby", ">= 1.1.0") | |
end | ||
Rake::GemPackageTask.new(spec) do |p| |
rool/rails/typo/trunk/lib/typo_version.rb:
prev. | current | |
1 | ||
1 | TYPO_VERSION = '4.0.0' |
rool/rails/typo/trunk/public/dispatch.cgi:
prev. | current | |
1 | ||
2 | ||
3 |
| |
4 | ||
5 |
| |
6 | ||
7 | ||
8 | ||
9 |
| |
10 | ||
11 | ||
1 | #!/usr/bin/env ruby | |
2 | ||
3 | require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) | |
4 | ||
5 | # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: | |
6 | # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired | |
7 | require "dispatcher" | |
8 | ||
9 | ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) | |
10 | Dispatcher.dispatch |
rool/rails/typo/trunk/public/dispatch.fcgi:
prev. | current | |
1 | ||
1 | #!/usr/bin/env ruby | |
# | ||
# You may specify the path to the FastCGI crash log (a log of unhandled | ||
# exceptions which forced the FastCGI instance to exit, great for debugging) |
rool/rails/typo/trunk/public/dispatch.rb:
prev. | current | |
1 | ||
1 | #!/usr/bin/ruby | |
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) | ||
rool/rails/typo/trunk/public/javascripts/dragdrop.js:
prev. | current | |
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | ||
2 | // (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) | |
// | ||
// See scriptaculous.js for full license. | ||
... | ... | |
element = $(element); | ||
var options = Object.extend({ | ||
greedy: true, | ||
18 | | |
19 | hoverclass: null, | |
20 | tree: false | |
}, arguments[1] || {}); | ||
// cache containers | ||
... | ... | |
this.drops.push(options); | ||
}, | ||
42 | ||
43 | findDeepestChild: function(drops) { | |
44 | deepest = drops[0]; | |
45 | ||
46 | for (i = 1; i < drops.length; ++i) | |
47 | if (Element.isParent(drops[i].element, deepest.element)) | |
48 | deepest = drops[i]; | |
49 | ||
50 | return deepest; | |
51 | }, | |
isContained: function(element, drop) { | ||
42 | | |
43 | | |
54 | var containmentNode; | |
55 | if(drop.tree) { | |
56 | containmentNode = element.treeNode; | |
57 | } else { | |
58 | containmentNode = element.parentNode; | |
59 | } | |
60 | return drop._containers.detect(function(c) { return containmentNode == c }); | |
}, | ||
45 | ||
62 | ||
isAffected: function(point, element, drop) { | ||
return ( | ||
(drop.element!=element) && | ||
... | ... | |
show: function(point, element) { | ||
if(!this.drops.length) return; | ||
88 | var affected = []; | |
if(this.last_active) this.deactivate(this.last_active); | ||
this.drops.each( function(drop) { | ||
74 | | |
75 | | |
76 | | |
77 | | |
78 | | |
79 | | |
80 | | |
81 | | |
92 | if(Droppables.isAffected(point, element, drop)) | |
93 | affected.push(drop); | |
}); | ||
95 | ||
96 | if(affected.length>0) { | |
97 | drop = Droppables.findDeepestChild(affected); | |
98 | Position.within(drop.element, point[0], point[1]); | |
99 | if(drop.onHover) | |
100 | drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); | |
101 | ||
102 | Droppables.activate(drop); | |
103 | } | |
}, | ||
fire: function(event, element) { | ||
... | ... | |
this.element = $(element); | ||
210 | | |
211 | | |
231 | if(options.handle && (typeof options.handle == 'string')) { | |
232 | var h = Element.childrenWithClassName(this.element, options.handle, true); | |
233 | if(h.length>0) this.handle = h[0]; | |
234 | } | |
if(!this.handle) this.handle = $(options.handle); | ||
if(!this.handle) this.handle = this.element; | ||
... | ... | |
if(this.scrollInterval) { | ||
clearInterval(this.scrollInterval); | ||
this.scrollInterval = null; | ||
438 | Draggables._lastScrollPointer = null; | |
} | ||
}, | ||
... | ... | |
Position.prepare(); | ||
Droppables.show(Draggables._lastPointer, this.element); | ||
Draggables.notify('onDrag', this); | ||
443 | | |
467 | Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); | |
468 | Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; | |
469 | Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; | |
470 | if (Draggables._lastScrollPointer[0] < 0) | |
471 | Draggables._lastScrollPointer[0] = 0; | |
472 | if (Draggables._lastScrollPointer[1] < 0) | |
473 | Draggables._lastScrollPointer[1] = 0; | |
474 | this.draw(Draggables._lastScrollPointer); | |
if(this.options.change) this.options.change(this); | ||
}, | ||
... | ... | |
} | ||
var Sortable = { | ||
495 | | |
526 | sortables: {}, | |
497 | | |
498 | | |
499 | | |
528 | _findRootElement: function(element) { | |
529 | while (element.tagName != "BODY") { | |
530 | if(element.id && Sortable.sortables[element.id]) return element; | |
531 | element = element.parentNode; | |
532 | } | |
}, | ||
534 | ||
535 | options: function(element) { | |
536 | element = Sortable._findRootElement($(element)); | |
537 | if(!element) return; | |
538 | return Sortable.sortables[element.id]; | |
539 | }, | |
destroy: function(element){ | ||
503 | | |
504 | | |
542 | var s = Sortable.options(element); | |
543 | ||
544 | if(s) { | |
Draggables.removeObserver(s.element); | ||
s.droppables.each(function(d){ Droppables.remove(d) }); | ||
s.draggables.invoke('destroy'); | ||
508 | | |
509 | | |
548 | ||
549 | delete Sortable.sortables[s.element.id]; | |
550 | } | |
}, | ||
511 | | |
552 | ||
create: function(element) { | ||
element = $(element); | ||
var options = Object.extend({ | ||
element: element, | ||
tag: 'li', // assumes li children, override with tag: 'tagname' | ||
dropOnEmpty: false, | ||
518 | | |
559 | tree: false, | |
560 | treeTag: 'ul', | |
overlap: 'vertical', // one of 'vertical', 'horizontal' | ||
constraint: 'vertical', // one of 'vertical', 'horizontal', false | ||
containment: element, // also takes array of elements (or id's); or false | ||
... | ... | |
var options_for_droppable = { | ||
overlap: options.overlap, | ||
containment: options.containment, | ||
610 | tree: options.tree, | |
hoverclass: options.hoverclass, | ||
569 | | |
570 | | |
612 | onHover: Sortable.onHover | |
613 | //greedy: !options.dropOnEmpty | |
} | ||
615 | ||
616 | var options_for_tree = { | |
617 | onHover: Sortable.onEmptyHover, | |
618 | overlap: options.overlap, | |
619 | containment: options.containment, | |
620 | hoverclass: options.hoverclass | |
621 | } | |
// fix for gecko engine | ||
Element.cleanWhitespace(element); | ||
... | ... | |
options.draggables = []; | ||
options.droppables = []; | ||
579 | | |
580 | ||
// drop on empty handling | ||
582 | | |
583 | | |
584 | | |
630 | if(options.dropOnEmpty || options.tree) { | |
631 | Droppables.add(element, options_for_tree); | |
options.droppables.push(element); | ||
} | ||
... | ... | |
options.draggables.push( | ||
new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); | ||
Droppables.add(e, options_for_droppable); | ||
642 | if(options.tree) e.treeNode = element; | |
options.droppables.push(e); | ||
}); | ||
645 | ||
646 | if(options.tree) { | |
647 | (Sortable.findTreeElements(element, options) || []).each( function(e) { | |
648 | Droppables.add(e, options_for_tree); | |
649 | e.treeNode = element; | |
650 | options.droppables.push(e); | |
651 | }); | |
652 | } | |
// keep reference | ||
599 | | |
655 | this.sortables[element.id] = options; | |
// for onupdate | ||
Draggables.addObserver(new SortableObserver(element, options.onUpdate)); | ||
... | ... | |
// return all suitable-for-sortable elements in a guaranteed order | ||
findElements: function(element, options) { | ||
608 | | |
609 | | |
610 | | |
611 | | |
612 | | |
613 | | |
614 | | |
615 | | |
616 | | |
617 | | |
618 | | |
619 | | |
620 | ||
621 | | |
664 | return Element.findChildren( | |
665 | element, options.only, options.tree ? true : false, options.tag); | |
}, | ||
667 | ||
668 | findTreeElements: function(element, options) { | |
669 | return Element.findChildren( | |
670 | element, options.only, options.tree ? true : false, options.treeTag); | |
671 | }, | |
onHover: function(element, dropon, overlap) { | ||
625 | | |
674 | if(Element.isParent(dropon, element)) return; | |
675 | ||
676 | if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { | |
677 | return; | |
678 | } else if(overlap>0.5) { | |
Sortable.mark(dropon, 'before'); | ||
if(dropon.previousSibling != element) { | ||
var oldParentNode = element.parentNode; | ||
... | ... | |
} | ||
} | ||
}, | ||
648 | ||
649 | | |
650 | | |
651 | | |
652 | | |
701 | ||
702 | onEmptyHover: function(element, dropon, overlap) { | |
703 | var oldParentNode = element.parentNode; | |
704 | var droponOptions = Sortable.options(dropon); | |
705 | ||
706 | if(!Element.isParent(dropon, element)) { | |
707 | var index; | |
708 | ||
709 | var children = Sortable.findElements(dropon, {tag: droponOptions.tag}); | |
710 | var child = null; | |
711 | ||
712 | if(children) { | |
713 | var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); | |
714 | ||
715 | for (index = 0; index < children.length; index += 1) { | |
716 | if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { | |
717 | offset -= Element.offsetSize (children[index], droponOptions.overlap); | |
718 | } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { | |
719 | child = index + 1 < children.length ? children[index + 1] : null; | |
720 | break; | |
721 | } else { | |
722 | child = children[index]; | |
723 | break; | |
724 | } | |
725 | } | |
726 | } | |
727 | ||
728 | dropon.insertBefore(element, child); | |
729 | ||
Sortable.options(oldParentNode).onChange(element); | ||
654 | | |
731 | droponOptions.onChange(element); | |
} | ||
}, | ||
... | ... | |
Element.show(Sortable._marker); | ||
}, | ||
763 | ||
764 | _tree: function(element, options, parent) { | |
765 | var children = Sortable.findElements(element, options) || []; | |
766 | ||
767 | for (var i = 0; i < children.length; ++i) { | |
768 | var match = children[i].id.match(options.format); | |
770 | if (!match) continue; | |
771 | ||
772 | var child = { | |
773 | id: encodeURIComponent(match ? match[1] : null), | |
774 | element: element, | |
775 | parent: parent, | |
776 | children: new Array, | |
777 | position: parent.children.length, | |
778 | container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase()) | |
779 | } | |
780 | ||
781 | /* Get the element containing the children and recurse over it */ | |
782 | if (child.container) | |
783 | this._tree(child.container, options, child) | |
784 | ||
785 | parent.children.push (child); | |
786 | } | |
787 | ||
788 | return parent; | |
789 | }, | |
790 | ||
791 | /* Finds the first element of the given tag type within a parent element. | |
792 | Used for finding the first LI[ST] within a L[IST]I[TEM].*/ | |
793 | _findChildrenElement: function (element, containerTag) { | |
794 | if (element && element.hasChildNodes) | |
795 | for (var i = 0; i < element.childNodes.length; ++i) | |
796 | if (element.childNodes[i].tagName == containerTag) | |
797 | return element.childNodes[i]; | |
798 | ||
799 | return null; | |
800 | }, | |
801 | ||
802 | tree: function(element) { | |
803 | element = $(element); | |
804 | var sortableOptions = this.options(element); | |
805 | var options = Object.extend({ | |
806 | tag: sortableOptions.tag, | |
807 | treeTag: sortableOptions.treeTag, | |
808 | only: sortableOptions.only, | |
809 | name: element.id, | |
810 | format: sortableOptions.format | |
811 | }, arguments[1] || {}); | |
812 | ||
813 | var root = { | |
814 | id: null, | |
815 | parent: null, | |
816 | children: new Array, | |
817 | container: element, | |
818 | position: 0 | |
819 | } | |
820 | ||
821 | return Sortable._tree (element, options, root); | |
822 | }, | |
823 | ||
824 | /* Construct a [i] index for a particular node */ | |
825 | _constructIndex: function(node) { | |
826 | var index = ''; | |
827 | do { | |
828 | if (node.id) index = '[' + node.position + ']' + index; | |
829 | } while ((node = node.parent) != null); | |
830 | return index; | |
831 | }, | |
832 | ||
sequence: function(element) { | ||
element = $(element); | ||
var options = Object.extend(this.options(element), arguments[1] || {}); | ||
... | ... | |
}); | ||
new_sequence.each(function(ident) { | ||
708 | | |
709 | | |
710 | | |
711 | | |
712 | | |
854 | var n = nodeMap[ident]; | |
855 | if (n) { | |
856 | n[1].appendChild(n[0]); | |
857 | delete nodeMap[ident]; | |
858 | } | |
}); | ||
}, | ||
715 | ||
861 | ||
serialize: function(element) { | ||
element = $(element); | ||
864 | var options = Object.extend(Sortable.options(element), arguments[1] || {}); | |
var name = encodeURIComponent( | ||
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id); | ||
720 | | |
721 | | |
722 | | |
867 | ||
868 | if (options.tree) { | |
869 | return Sortable.tree(element, arguments[1]).children.map( function (item) { | |
870 | return [name + Sortable._constructIndex(item) + "=" + | |
871 | encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); | |
872 | }).flatten().join('&'); | |
873 | } else { | |
874 | return Sortable.sequence(element, arguments[1]).map( function(item) { | |
875 | return name + "[]=" + encodeURIComponent(item); | |
876 | }).join('&'); | |
877 | } | |
} | ||
} | ||
880 | ||
881 | /* Returns true if child is contained within element */ | |
882 | Element.isParent = function(child, element) { | |
883 | if (!child.parentNode || child == element) return false; | |
884 | ||
885 | if (child.parentNode == element) return true; | |
886 | ||
887 | return Element.isParent(child.parentNode, element); | |
888 | } | |
889 | ||
890 | Element.findChildren = function(element, only, recursive, tagName) { | |
891 | if(!element.hasChildNodes()) return null; | |
892 | tagName = tagName.toUpperCase(); | |
893 | if(only) only = [only].flatten(); | |
894 | var elements = []; | |
895 | $A(element.childNodes).each( function(e) { | |
896 | if(e.tagName && e.tagName.toUpperCase()==tagName && | |
897 | (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) | |
898 | elements.push(e); | |
899 | if(recursive) { | |
900 | var grandchildren = Element.findChildren(e, only, recursive, tagName); | |
901 | if(grandchildren) elements.push(grandchildren); | |
902 | } | |
903 | }); | |
904 | ||
905 | return (elements.length>0 ? elements.flatten() : []); | |
906 | } | |
907 | ||
908 | Element.offsetSize = function (element, type) { | |
909 | if (type == 'vertical' || type == 'height') | |
910 | return element.offsetHeight; | |
911 | else | |
912 | return element.offsetWidth; | |
913 | } | |
rool/rails/typo/trunk/public/javascripts/effects.js:
prev. | current | |
} | ||
Element.childrenWithClassName = function(element, className, findFirst) { | ||
80 | | |
81 | | |
82 | | |
80 | var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)"); | |
81 | var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) { | |
82 | return (c.className && c.className.match(classNameRegExp)); | |
83 | }); | |
84 | if(!results) results = []; | |
85 | return results; | |
} | ||
Element.forceRerendering = function(element) { | ||
... | ... | |
} catch(e) { } | ||
}; | ||
94 | ||
95 | | |
96 | | |
97 | ||
98 | ||
/*--------------------------------------------------------------------------*/ | ||
Array.prototype.call = function() { | ||
... | ... | |
effect.element.setStyle(oldStyle); | ||
} }); | ||
}}, arguments[1] || {})); | ||
946 | ||
944 | }; | |
946 | ['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', | |
947 | 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each( | |
948 | function(f) { Element.Methods[f] = Element[f]; } | |
949 | ); | |
950 | ||
Element.Methods.visualEffect = function(element, effect, options) { | ||
s = effect.gsub(/_/, '-').camelize(); | ||
effect_class = s.charAt(0).toUpperCase() + s.substring(1); | ||
new Effect[effect_class](element, options); | ||
return $(element); | ||
953 | ||
957 | }; | |
958 | ||
959 | Element.addMethods(); | |
rool/rails/typo/trunk/public/javascripts/prototype.js:
prev. | current | |
1 | ||
1 | /* Prototype JavaScript framework, version 1.5.0_rc0 | |
* (c) 2005 Sam Stephenson <sam@conio.net> | ||
* | ||
* Prototype is freely distributable under the terms of an MIT-style license. | ||
... | ... | |
/*--------------------------------------------------------------------------*/ | ||
var Prototype = { | ||
10 | | |
10 | Version: '1.5.0_rc0', | |
ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', | ||
emptyFunction: function() {}, | ||
... | ... | |
var Abstract = new Object(); | ||
Object.extend = function(destination, source) { | ||
28 | | |
28 | for (var property in source) { | |
destination[property] = source[property]; | ||
} | ||
return destination; | ||
... | ... | |
}, | ||
evalScripts: function() { | ||
179 | | |
179 | return this.extractScripts().map(function(script) { return eval(script) }); | |
}, | ||
escapeHTML: function() { | ||
... | ... | |
var result; | ||
this.each(function(value, index) { | ||
value = (iterator || Prototype.K)(value, index); | ||
358 | | |
358 | if (result == undefined || value >= result) | |
result = value; | ||
}); | ||
return result; | ||
... | ... | |
var result; | ||
this.each(function(value, index) { | ||
value = (iterator || Prototype.K)(value, index); | ||
368 | | |
368 | if (result == undefined || value < result) | |
result = value; | ||
}); | ||
return result; | ||
... | ... | |
Object.extend(Array.prototype, Enumerable); | ||
450 | ||
450 | if (!Array.prototype._reverse) | |
451 | Array.prototype._reverse = Array.prototype.reverse; | |
Object.extend(Array.prototype, { | ||
_each: function(iterator) { | ||
... | ... | |
flatten: function() { | ||
return this.inject([], function(array, value) { | ||
479 | | |
480 | return array.concat(value && value.constructor == Array ? | |
value.flatten() : [value]); | ||
}); | ||
}, | ||
... | ... | |
return (inline !== false ? this : this.toArray())._reverse(); | ||
}, | ||
501 | | |
502 | | |
503 | | |
504 | | |
505 | | |
506 | | |
507 | | |
508 | ||
inspect: function() { | ||
return '[' + this.map(Object.inspect).join(', ') + ']'; | ||
} | ||
}); | ||
var Hash = { | ||
_each: function(iterator) { | ||
515 | | |
508 | for (var key in this) { | |
var value = this[key]; | ||
if (typeof value == 'function') continue; | ||
... | ... | |
var Ajax = { | ||
getTransport: function() { | ||
return Try.these( | ||
586 | function() {return new XMLHttpRequest()}, | |
function() {return new ActiveXObject('Msxml2.XMLHTTP')}, | ||
594 | | |
595 | | |
588 | function() {return new ActiveXObject('Microsoft.XMLHTTP')} | |
) || false; | ||
}, | ||
... | ... | |
this.options = { | ||
method: 'post', | ||
asynchronous: true, | ||
640 | contentType: 'application/x-www-form-urlencoded', | |
parameters: '' | ||
} | ||
Object.extend(this.options, options || {}); | ||
... | ... | |
'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; | ||
if (this.options.method == 'post') { | ||
710 | | |
711 | | |
704 | requestHeaders.push('Content-type', this.options.contentType); | |
/* Force "Connection: close" for Mozilla browsers to work around | ||
* a bug where XMLHttpReqeuest sends an incorrect Content-length | ||
... | ... | |
evalJSON: function() { | ||
try { | ||
742 | | |
735 | return eval('(' + this.header('X-JSON') + ')'); | |
} catch (e) {} | ||
}, | ||
... | ... | |
Element.extend = function(element) { | ||
if (!element) return; | ||
896 | if (_nativeExtensions) return element; | |
if (!element._extended && element.tagName && element != window) { | ||
905 | | |
899 | var methods = Element.Methods, cache = Element.extend.cache; | |
for (property in methods) { | ||
var value = methods[property]; | ||
if (typeof value == 'function') | ||
909 | | |
903 | element[property] = cache.findOrStore(value); | |
} | ||
} | ||
... | ... | |
return element; | ||
} | ||
911 | Element.extend.cache = { | |
912 | findOrStore: function(value) { | |
913 | return this[value] = this[value] || function() { | |
914 | return value.apply(null, [this].concat($A(arguments))); | |
915 | } | |
916 | } | |
917 | } | |
918 | ||
Element.Methods = { | ||
visible: function(element) { | ||
return $(element).style.display != 'none'; | ||
... | ... | |
setStyle: function(element, style) { | ||
element = $(element); | ||
1038 | | |
1040 | for (var name in style) | |
element.style[name.camelize()] = style[name]; | ||
}, | ||
... | ... | |
Object.extend(Element, Element.Methods); | ||
1110 | var _nativeExtensions = false; | |
1111 | ||
1112 | if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) { | |
1113 | var HTMLElement = {} | |
1114 | HTMLElement.prototype = document.createElement('div').__proto__; | |
1115 | } | |
1116 | ||
1117 | Element.addMethods = function(methods) { | |
1118 | Object.extend(Element.Methods, methods || {}); | |
1119 | ||
1120 | if(typeof HTMLElement != 'undefined') { | |
1121 | var methods = Element.Methods, cache = Element.extend.cache; | |
1122 | for (property in methods) { | |
1123 | var value = methods[property]; | |
1124 | if (typeof value == 'function') | |
1125 | HTMLElement.prototype[property] = cache.findOrStore(value); | |
1126 | } | |
1127 | _nativeExtensions = true; | |
1128 | } | |
1129 | } | |
1130 | ||
1131 | Element.addMethods(); | |
1132 | ||
var Toggle = new Object(); | ||
Toggle.display = Element.toggle; | ||
... | ... | |
try { | ||
this.element.insertAdjacentHTML(this.adjacency, this.content); | ||
} catch (e) { | ||
1126 | | |
1151 | var tagName = this.element.tagName.toLowerCase(); | |
1152 | if (tagName == 'tbody' || tagName == 'tr') { | |
this.insertContent(this.contentFromAnonymousTable()); | ||
} else { | ||
throw e; | ||
... | ... | |
form = $(form); | ||
var elements = new Array(); | ||
1399 | | |
1425 | for (var tagName in Form.Element.Serializers) { | |
var tagElements = form.getElementsByTagName(tagName); | ||
for (var j = 0; j < tagElements.length; j++) | ||
elements.push(tagElements[j]); | ||
... | ... | |
var value = '', opt, index = element.selectedIndex; | ||
if (index >= 0) { | ||
opt = element.options[index]; | ||
1521 | | |
1522 | | |
1523 | | |
1547 | value = opt.value || opt.text; | |
} | ||
return [element.name, value]; | ||
}, | ||
selectMany: function(element) { | ||
1529 | | |
1553 | var value = []; | |
for (var i = 0; i < element.length; i++) { | ||
var opt = element.options[i]; | ||
1532 | | |
1533 | | |
1534 | | |
1535 | | |
1536 | | |
1537 | | |
1556 | if (opt.selected) | |
1557 | value.push(opt.value || opt.text); | |
} | ||
return [element.name, value]; | ||
} | ||
... | ... | |
}); | ||
/* prevent memory leaks in IE */ | ||
1754 | ||
1774 | if (navigator.appVersion.match(/\bMSIE\b/)) | |
1775 | Event.observe(window, 'unload', Event.unloadCache, false); | |
var Position = { | ||
// set to true if needed, warning: firefox performance problems | ||
// NOT neeeded for page scrolling, only if draggable contained in |
rool/rails/typo/trunk/public/stylesheets/administration.css:
prev. | current | |
body { | ||
margin: 0; | ||
7 | | |
8 | | |
7 | font: 1em/1.6em Verdana, Helvetica, Arial, sans-serif; | |
text-align: center; | ||
color: #000; | ||
} | ||
... | ... | |
#container { | ||
text-align: left; | ||
16 | | |
15 | font-size: 70%; | |
margin: 0 auto; | ||
} | ||
... | ... | |
img { border: none; } | ||
a { | ||
66 | | |
65 | color: #8D805D; | |
text-decoration: none; | ||
} | ||
... | ... | |
#tabs-container { | ||
83 | height: 20px; | |
width: 100%; | ||
85 | | |
85 | padding: 14px 0 0 100px; | |
height: 16px; | ||
87 | | |
87 | margin-top: -40px; | |
border-bottom: 1px solid #637987; | ||
89 | background: #F8F7EF; | |
} | ||
#tabs { | ||
padding: 0; | ||
93 | | |
94 | | |
95 | | |
94 | margin: 0 0 0 40px; | |
95 | font: normal 100% Georgia, Garamond, Times ; | |
line-height: normal; | ||
97 | text-transform: uppercase; | |
} | ||
#tabs li { | ||
... | ... | |
#tabs li a { | ||
padding: 3px 8px 3px 8px; | ||
margin-left: 3px; | ||
109 | | |
110 | background: #F8F7EF; | |
text-decoration: none; | ||
color: #003; | ||
112 | | |
113 | | |
line-height: normal; | ||
} | ||
#tabs li a:hover { | ||
118 | | |
119 | | |
120 | | |
117 | color: #993300; | |
118 | border-top: 12px solid #E8E4D3; | |
} | ||
#tabs li a.active { | ||
124 | | |
122 | color: #993300; | |
123 | border-top: 12px solid #E8E4D3; | |
124 | background: #F8F7EF; | |
} | ||
#tabs li a.active:hover { | ||
... | ... | |
*/ | ||
.tasks { | ||
139 | | |
140 | | |
139 | background: #F8F7EF; | |
140 | border-top: 1px dotted #C2C0BB; | |
141 | border-bottom: 1px dotted #C2C0BB; | |
padding: 5px; | ||
143 | margin-bottom: 15px; | |
} | ||
.tasks ul { | ||
... | ... | |
} | ||
.tasks li a:hover { | ||
164 | | |
166 | background: #637987; | |
color: #fff; | ||
} | ||
... | ... | |
h2 { | ||
font: normal 170% Georgia, Times, Helvetica; | ||
175 | | |
color: #930; | ||
177 | | |
178 | padding: 5px 0 0 5px; | |
} | ||
h3 { | ||
... | ... | |
} | ||
#header h1 { | ||
188 | background: #EDEBD5; | |
margin: 0; | ||
188 | | |
189 | | |
190 | padding: 14px 0 12px 100px; | |
191 | border-bottom: 1px dashed #A9A585; | |
192 | border-top: 4px solid #4A4902; | |
193 | font: normal 200% Georgia, Garamond, Times ; | |
194 | text-transform: uppercase; | |
195 | letter-spacing: 0.08em; | |
} | ||
#header h1 a { | ||
193 | | |
194 | | |
199 | color: #000; | |
200 | margin: 10px 0 10px 0; | |
text-decoration: none; | ||
border: none; | ||
} | ||
... | ... | |
} | ||
.form { | ||
256 | | |
262 | border: 1px solid #C2C0BB; | |
263 | background: #F8F7EF; | |
margin-bottom: 10px; | ||
padding: 0 0 0 10px; | ||
} | ||
... | ... | |
padding: 5px; | ||
} | ||
272 | .form input { | |
273 | font-family: Georgia; | |
274 | font-size: 1em; | |
275 | letter-spacing: 0.02em; | |
276 | } | |
277 | ||
278 | .form textarea { | |
279 | width: 350px; | |
280 | font-family: Georgia; | |
281 | line-height: 1.1em; | |
282 | font-size: 1em; | |
283 | letter-spacing: 0.02em; | |
284 | word-spacing: 0.05em; | |
285 | } | |
286 | ||
#blog_name { | ||
font-size: 130%; | ||
} | ||
... | ... | |
#preview, #preview_extended { | ||
background: #fff; | ||
287 | | |
309 | border: 1px dashed #ccc; | |
padding: 5px; | ||
z-index: 9999; | ||
290 | | |
312 | width: 50%; | |
float: right; | ||
clear: right; | ||
margin-bottom: 10px; | ||
294 | | |
316 | line-height: 1.5em; | |
317 | letter-spacing: 0.02em; | |
318 | word-spacing: 0.05em; | |
319 | font-size: 0.95em; | |
} | ||
/* | ||
... | ... | |
*/ | ||
.set { | ||
302 | | |
303 | | |
327 | background: #F8F7EF; | |
328 | border: 1px dotted #7D8692; | |
padding: 0 10px 5px 10px; | ||
margin-bottom: 10px; | ||
position: relative; | ||
... | ... | |
#sidebar-config { | ||
/* Safari Fix */ | ||
320 | | |
345 | border-top: 5px solid #fff; | |
} | ||
#sidebar-config p { | ||
... | ... | |
#cnt-active { | ||
margin-left: 320px; | ||
340 | | |
341 | | |
365 | background: #F8F7EF; | |
} | ||
344 | | |
345 | | |
368 | #available { | |
369 | background: #F8F7EF; | |
370 | padding-bottom: 10px; | |
} | ||
373 | #active { | |
374 | background: #F8F7EF; | |
375 | padding-bottom: 10px; | |
376 | } | |
377 | ||
#available h3, #active h3, #cnt-active h3 { | ||
349 | | |
379 | background: #E4E4D7; | |
color: #333; | ||
margin: 0 0 10px 0; | ||
padding: 2px 5px; | ||
... | ... | |
} | ||
.target { | ||
384 | | |
414 | background: #F8F7EF; | |
margin: 5px; | ||
padding: 5px; | ||
} | ||
... | ... | |
padding: 0 0 5px; | ||
} | ||
427 | #info { | |
428 | color: #4A4902; | |
429 | } | |
430 | ||
#info a { | ||
398 | | |
432 | color: #4A4902; | |
} | ||
#info a:hover { | ||
402 | | |
436 | border-bottom: 1px dotted #222; | |
} | ||
.form p>small { | ||
... | ... | |
*/ | ||
div#users { | ||
459 | | |
493 | background: #F8F7EF; | |
margin-top: 10px; | ||
} | ||
... | ... | |
*/ | ||
#quick-post { | ||
498 | | |
532 | background: #EDEBD5; | |
padding: 10px; | ||
border: 1px solid #9cabba; | ||
margin-left: 10px; | ||
border-top: none; | ||
} | ||
539 | #quick-post input { | |
540 | font-family: Georgia; | |
541 | font-size: 13px; | |
542 | letter-spacing: 0.02em; | |
543 | } | |
544 | ||
545 | #quick-post textarea { | |
546 | width: 350px; | |
547 | font-family: Georgia; | |
548 | line-height: 14px; | |
549 | font-size: 12px; | |
550 | letter-spacing: 0.02em; | |
551 | word-spacing: 0.05em; | |
552 | } | |
553 | ||
#quick-navigate { | ||
506 | | |
555 | background: #F8F7EF; | |
padding: 2px 5px 0px 5px; | ||
508 | | |
557 | border: 1px dotted #9cabba; | |
margin-left: 10px; | ||
border-top: none; | ||
} | ||
512 | ||
513 | | |
514 | | |
515 | | |
516 | | |
517 | | |
518 | ||
520 | ||
521 | | |
522 | | |
523 | | |
524 | | |
525 | ||
#advanced { line-height: 1.3em; } | ||
#advanced label { | ||
... | ... | |
#loginform { | ||
width: 300px; | ||
536 | | |
537 | | |
572 | margin-left: auto; | |
573 | margin-right: auto; | |
574 | padding: 100px; | |
} | ||
577 | #loginform input { | |
578 | margin-bottom: 10px; | |
579 | } | |
580 | ||
#loginform div.form { | ||
padding:10px; | ||
} | ||
... | ... | |
} | ||
#flash .notice { | ||
557 | | |
558 | | |
559 | | |
598 | font-size: 11px; | |
599 | color: #fff; | |
600 | background: #637987; | |
601 | border-top: 1px solid #336699; | |
602 | border-bottom: 1px solid #336699; | |
} | ||
#flash .error { | ||
... | ... | |
border-bottom: 1px dotted #ccc; | ||
} | ||
581 | ||
582 | | |
583 | | |
584 | | |
624 | /* | |
625 | * Feedback | |
626 | */ | |
627 | ||
628 | .feedbackbody td { | |
629 | border-bottom: 1px dotted #ccc; | |
} |
rool/rails/typo/trunk/script/spacecheck:
prev. | current | |
1 | ||
1 | #!/usr/bin/env ruby | |
require 'fileutils' | ||
rool/rails/typo/trunk/test/fixtures/contents.yml:
prev. | current | |
guid: a87c4220-18d4-11da-aadd-0002a5d5c51b | ||
type: Article | ||
published: true | ||
22 | state: ContentState::Published | |
article2: | ||
type: Article | ||
... | ... | |
author: Bob | ||
guid: bbbbb | ||
published: true | ||
43 | state: ContentState::Published | |
article3: | ||
... | ... | |
author: Tobi | ||
guid: ccccc | ||
published: true | ||
65 | state: ContentState::Published | |
article4: | ||
type: Article | ||
... | ... | |
body: I'm not "public":http://www.example.com/public! | ||
body_html: I'm not <a href="http://www.example.com/public">public</a>! | ||
published: false | ||
75 | state: ContentState::Draft | |
created_at: 2004-06-01 20:00:01 | ||
updated_at: 2004-06-01 20:00:01 | ||
published_at: 2004-06-01 20:00:01 | ||
... | ... | |
updated_at: 2005-01-01 02:00:00 | ||
published_at: 2005-01-01 02:00:00 | ||
guid: 12313123123123123 | ||
99 | state: ContentState::Published | |
comment2: | ||
type: Comment | ||
... | ... | |
updated_at: 2005-01-01 02:00:01 | ||
published_at: 2005-01-01 02:00:01 | ||
guid: 453456456456456 | ||
116 | state: ContentState::Published | |
comment3: | ||
type: Comment | ||
blog_id: 1 | ||
id: 12 | ||
published: false | ||
123 | state: ContentState::Draft | |
article_id: 1 | ||
author: Foo Bar | ||
body: Zzzzzz | ||
created_at: 2005-01-01 02:00:07 | ||
updated_at: 2005-01-01 02:00:07 | ||
129 | published_at: 2005-01-01 02:00:07 | |
guid: 4534564564564567 | ||
trackback1: | ||
... | ... | |
id: 7 | ||
article_id: 2 | ||
published: false | ||
138 | state: ContentState::Draft | |
blog_name: Trackback Blog | ||
title: Trackback Entry | ||
url: http://www.example.com | ||
excerpt: This is an excerpt | ||
created_at: 2005-01-01 03:00:00 | ||
updated_at: 2005-01-01 03:00:00 | ||
145 | published_at: 2005-01-01 03:00:00 | |
guid: dsafsadffsdsf | ||
trackback2: | ||
... | ... | |
blog_id: 1 | ||
id: 8 | ||
article_id: 1 | ||
153 | state: ContentState::Published | |
published: true | ||
blog_name: Trackback Blog | ||
title: Trackback Entry | ||
... | ... | |
id: 13 | ||
article_id: 1 | ||
published: true | ||
170 | state: ContentState::Published | |
blog_name: Trackback Blog 2 | ||
title: Trackback Entry 2 | ||
url: http://www.example.com | ||
... | ... | |
body: ho ho ho | ||
created_at: 2005-05-05 01:00:00 | ||
published_at: 2005-05-05 01:00:00 | ||
189 | updated_at: 2005-05-05 01:00:00 | |
user_id: 1 | ||
published: true | ||
192 | state: ContentState::Published | |
another_page: | ||
type: Page | ||
... | ... | |
name: page/two | ||
title: Another Page Title | ||
body: another body for yet another page | ||
201 | updated_at: 2005-05-05 01:00:00 | |
created_at: 2005-05-05 01:00:00 | ||
published_at: 2005-05-05 01:00:00 | ||
user_id: 1 | ||
published: true | ||
206 | state: ContentState::Published | |
markdown_page: | ||
type: Page | ||
... | ... | |
text_filter_id: 1 | ||
body: this is *markdown*. | ||
created_at: 2005-05-05 01:00:00 | ||
217 | updated_at: 2005-05-05 01:00:00 | |
published_at: 2005-05-05 01:00:00 | ||
user_id: 1 | ||
published: true | ||
221 | state: ContentState::Published | |
inactive_article: | ||
type: Article | ||
... | ... | |
author: Tobi | ||
guid: i1n2a3c4t5i6v7e | ||
published: true | ||
242 | state: ContentState::Published | |
old_comment: | ||
type: Comment | ||
... | ... | |
updated_at: 2004-05-02 20:00:02 | ||
published_at: 2004-05-02 20:00:02 | ||
published: true | ||
258 | state: ContentState::Published | |
second_blog_article: | ||
type: Article | ||
... | ... | |
author: Tobi | ||
guid: 2b1l0o6g4ar7 | ||
published: true | ||
279 | state: ContentState::Published | |
search_target: | ||
type: Article | ||
... | ... | |
author: Tobi | ||
guid: 2b1l0o6g4ar7 | ||
published: true | ||
300 | state: ContentState::Published | |
xmltest: | ||
type: Article | ||
... | ... | |
author: Tobi | ||
guid: urn:uuid:0d676c66-4135-4a8b-9d65-b6a3248d3032 | ||
published: true | ||
320 | state: ContentState::Published |
rool/rails/typo/trunk/test/functional/articles_controller_test.rb:
prev. | current | |
assert_response :success | ||
assert_rendered_file "index" | ||
40 | assert_tag :tag => 'title', :content => 'test blog - category software' | |
# Check it works when permalink != name. Ticket #736 | ||
get :category, :id => "weird-permalink" | ||
... | ... | |
assert_response :success | ||
assert_rendered_file "index" | ||
67 | assert_tag :tag => 'title', :content => 'test blog - tag foo' | |
assert_tag :tag => 'h2', :content => 'Article 2!' | ||
assert_tag :tag => 'h2', :content => 'Article 1!' | ||
end | ||
... | ... | |
end | ||
def test_comment_spam1 | ||
174 | | |
176 | comment_template_test "<p>Link to <a href=\"http://spammer.example.com\" rel=\"nofollow\">spammy goodness</a></p>", 'Link to <a href="http://spammer.example.com">spammy goodness</a>' | |
end | ||
def test_comment_spam2 | ||
... | ... | |
def test_comment_xss1 | ||
this_blog.comment_text_filter = "none" | ||
183 | | |
185 | comment_template_test %{Have you ever alert("foo"); been hacked?}, | |
%{Have you ever <script lang="javascript">alert("foo");</script> been hacked?} | ||
end | ||
def test_comment_xss2 | ||
this_blog.comment_text_filter = "none" | ||
189 | | |
191 | comment_template_test "Have you ever <a href=\"#\" rel=\"nofollow\">been hacked?</a>", 'Have you ever <a href="#" onclick="javascript">been hacked?</a>' | |
end | ||
def test_comment_autolink | ||
193 | | |
195 | comment_template_test "<p>What’s up with <a href=\"http://slashdot.org\" rel=\"nofollow\">http://slashdot.org</a> these days?</p>", "What's up with http://slashdot.org these days?" | |
end #" | ||
### TODO -- there's a bug in Rails with auto_links | ||
... | ... | |
:body => "The future is cool!", | ||
:keywords => "future", | ||
:published => true, | ||
481 | | |
483 | :published_at => Time.now + 12.minutes) | |
get :index | ||
assert_equal @article, assigns(:articles).first | ||
484 | | |
486 | assert @response.lifetime.to_i <= 12.minutes | |
end | ||
def test_search |
rool/rails/typo/trunk/test/functional/xml_controller_test.rb:
prev. | current | |
assert_xml @response.body | ||
assert_feedvalidator @response.body, :todo | ||
end | ||
341 | ||
342 | # TODO(laird): make this more robust | |
343 | def test_sitemap | |
344 | get :feed, :format => 'googlesitemap', :type => 'sitemap' | |
345 | ||
346 | assert_response :success | |
347 | assert_xml @response.body | |
348 | end | |
def assert_rss20(items) | ||
assert_equal 1, get_xpath(%{/rss[@version="2.0"]/channel[count(child::item)=#{items}]}).size, "RSS 2.0 feed has wrong number of channel/item nodes" |
rool/rails/typo/trunk/test/mocks/test/http_mock.rb:
prev. | current | |
end | ||
class Net::HTTP | ||
12 | def initialize(*args) | |
13 | end | |
13 | ||
def self.start(host, port) | ||
request = Request.new | ||
request.host = host |
rool/rails/typo/trunk/test/test_helper.rb:
prev. | current | |
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") | ||
require 'test_help' | ||
5 | $TESTING = true | |
6 | ||
User.salt = 'change-me' | ||
class Test::Unit::TestCase |
rool/rails/typo/trunk/test/unit/article_test.rb:
prev. | current | |
assert_kind_of Article,b | ||
assert_equal 0, b.tags.size | ||
122 | ||
123 | c = Article.new(:title => 'Foo', :keywords => 'test "tag test" web2.0') | |
124 | c.keywords_to_tags | |
125 | ||
126 | assert_equal 3, c.tags.size | |
127 | assert_equal ['test', 'tagtest', 'web2.0'].sort, c.tags.collect(&:name).sort | |
end | ||
def test_find_published_by_tag_name |
rool/rails/typo/trunk/test/unit/comment_test.rb:
prev. | current | |
c.url = "http://buy-computer.us" | ||
c.ip = "212.42.230.206" | ||
36 | | |
37 | | |
38 | | |
39 | | |
36 | assert_equal true, c.is_spam? | |
end | ||
def test_not_spam_but_rbl_lookup_succeeds | ||
... | ... | |
c.url = "http://www.bofh.org.uk" | ||
c.ip = "10.10.10.10" | ||
49 | | |
46 | assert_equal false, c.is_spam? | |
end | ||
def test_reject_spam_pattern | ||
... | ... | |
c.body = "Texas hold-em poker crap" | ||
c.url = "http://texas.hold-em.us" | ||
58 | | |
59 | | |
55 | assert_equal true, c.is_spam? | |
end | ||
def test_reject_spam_uri_limit | ||
... | ... | |
c.url = "http://www.uri-limit.com" | ||
c.ip = "123.123.123.123" | ||
69 | | |
70 | | |
65 | assert_equal true, c.is_spam? | |
end | ||
def test_reject_article_age | ||
... | ... | |
assert c.body_html !~ /<script>/ | ||
end | ||
end | ||
112 | ||
113 | def test_withdraw | |
114 | c = Comment.find(contents(:comment2).id) | |
115 | assert c.withdraw! | |
116 | assert ! c.published? | |
117 | assert c.reload | |
118 | assert ! c.published? | |
119 | end | |
end |
rool/rails/typo/trunk/test/unit/content_state/factory_test.rb:
prev. | current | |
require 'content_state/factory' | ||
class ContentState::FactoryTest < Test::Unit::TestCase | ||
5 | | |
6 | | |
7 | | |
5 | def test_correctly_builds_new_state | |
6 | [:new, 'new', 'content_state/new', 'New', | |
7 | 'ContentState::New', nil].each do |memento| | |
8 | assert_instance_of(ContentState::New, | |
9 | ContentState::Factory.new(memento)) | |
10 | end | |
end | ||
10 | | |
13 | def test_correctly_builds_draft_state | |
assert_instance_of(ContentState::Draft, | ||
12 | | |
15 | ContentState::Factory.new('draft')) | |
end | ||
15 | | |
18 | def test_correctly_builds_publication_pending_state | |
assert_instance_of(ContentState::PublicationPending, | ||
17 | | |
18 | | |
19 | | |
20 | | |
21 | ||
22 | | |
23 | | |
24 | | |
20 | ContentState::Factory.new('publication_pending')) | |
end | ||
27 | | |
23 | def test_correct_builds_published_state | |
assert_instance_of(ContentState::Published, | ||
29 | | |
30 | | |
25 | ContentState::Factory.new('published')) | |
end | ||
def test_cant_make_state_directly |
rool/rails/typo/trunk/test/unit/ping_test.rb:
prev. | current | |
assert_equal "anotherblog.org", ping.host | ||
assert_equal 80, ping.port | ||
assert_equal "/a-post/trackback", ping.query | ||
80 | | |
80 | assert_equal "title=Article+1%21&excerpt=body&url=http://myblog.net/referring-post&blog_name=test+blog", ping.post_data | |
end | ||
def test_send_weblogupdatesping |
rool/rails/typo/trunk/test/unit/trackback_test.rb:
prev. | current | |
assert tb.save | ||
assert tb.errors.empty? | ||
assert tb.guid.size > 15 | ||
21 | assert_equal false, tb.is_spam? | |
end | ||
def test_reject_spam_rbl | ||
... | ... | |
tb.url = "http://buy-computer.us" | ||
tb.ip = "212.42.230.206" | ||
31 | | |
32 | | |
33 | | |
32 | assert_equal true, tb.is_spam? | |
end | ||
def test_reject_spam_pattern | ||
... | ... | |
tb.title = "Spammy trackback" | ||
tb.excerpt = "Texas hold-em poker crap" | ||
42 | | |
43 | | |
41 | assert_equal true, tb.is_spam? | |
end | ||
end |
rool/rails/typo/trunk/test/unit/trigger_test.rb:
prev. | current | |
fixtures :contents | ||
def test_post_action | ||
14 | | |
14 | assert Trigger.post_action(Time.now + 2.seconds, | |
contents(:first_page), | ||
'tickle') | ||
assert_equal "ho ho ho", Page.find(contents(:first_page).id).body | ||
18 | | |
18 | sleep 3 | |
assert Trigger.fire | ||
assert_equal 0, Trigger.count | ||
assert_equal "I got tickled!", Page.find(contents(:first_page).id).body |
rool/rails/typo/trunk/themes/azure/stylesheets/azure.css:
prev. | current | |
float: right; | ||
padding: 0 5px; | ||
} | ||
184 | ||
185 | .spamwarning { | |
186 | margin: 0.5em; | |
187 | background: red; | |
188 | font-weight: bold; | |
189 | font-style: italic; | |
190 | } | |
/*+-------------------------------------------+ | ||
| SIDEBAR | | ||
+-------------------------------------------+*/ |
rool/rails/typo/trunk/vendor/plugins/expiring_action_cache/lib/actionparamcache.rb:
prev. | current | |
module ClassMethods #:nodoc: | ||
def caches_action_with_params(*actions) | ||
return unless perform_caching | ||
41 | | |
41 | prepend_around_filter(ActionParamCacheFilter.new(*actions)) | |
end | ||
end | ||
... | ... | |
def before(controller) | ||
return unless @actions.include?(controller.action_name.intern) | ||
meta, cache = controller.read_meta_fragment_expire(cache_key(controller)) | ||
74 | ||
if cache | ||
# 304 handling from Tom Fakes, | ||
# http://craz8.com/svn/trunk/plugins/action_cache/lib/action_cache.rb | ||
... | ... | |
cached_time = meta[:cached_at] rescue nil | ||
controller.response.headers['Cache-Control'] = 'max-age=1' | ||
controller.response.headers['Last-Modified'] = meta[:cached_at].httpdate rescue nil | ||
82 | controller.response.headers['Content-Type'] = meta[:content_type] | |
if request_time and cached_time <= (request_time + 1) | ||
controller.render(:text => "", :status => 304) | ||
... | ... | |
end | ||
def after(controller) | ||
96 | | |
98 | return true if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache | |
return true if controller.response.headers['Status'] != "200 OK" # without this, we cache errors. grr | ||
meta = Hash.new | ||
... | ... | |
meta[:expires] = Time.now + controller.response.lifetime | ||
end | ||
meta[:cached_at] = Time.now.utc | ||
106 | meta[:content_type] = controller.response.headers['Content-Type'] | |
controller.response.headers['Cache-Control'] = 'max-age=1' | ||
controller.response.headers['Last-Modified'] = meta[:cached_at].httpdate | ||
controller.write_meta_fragment(cache_key(controller), meta, controller.response.body) |