typo 5.4 → 5.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/CHANGELOG +23 -30
  2. data/Typo users guide.pdf +0 -0
  3. data/app/controllers/admin/content_controller.rb +28 -36
  4. data/app/controllers/admin/tags_controller.rb +4 -4
  5. data/app/controllers/articles_controller.rb +119 -1
  6. data/app/controllers/comments_controller.rb +0 -7
  7. data/app/controllers/content_controller.rb +1 -0
  8. data/app/helpers/admin/content_helper.rb +9 -28
  9. data/app/helpers/admin/themes_helper.rb +4 -6
  10. data/app/helpers/articles_helper.rb +4 -0
  11. data/app/models/article.rb +21 -12
  12. data/app/models/blog.rb +0 -1
  13. data/app/models/category.rb +1 -6
  14. data/app/models/content.rb +10 -6
  15. data/app/models/feedback/states.rb +6 -6
  16. data/app/models/tag.rb +8 -8
  17. data/app/views/admin/content/_drafts.html.erb +1 -1
  18. data/app/views/admin/content/_form.html.erb +7 -4
  19. data/app/views/admin/content/index.html.erb +3 -3
  20. data/app/views/admin/feedback/index.html.erb +4 -4
  21. data/app/views/admin/settings/feedback.html.erb +8 -7
  22. data/app/views/admin/settings/write.html.erb +71 -72
  23. data/app/views/admin/tags/index.html.erb +4 -4
  24. data/app/views/admin/themes/editor.html.erb +13 -10
  25. data/app/views/articles/_article.html.erb +6 -4
  26. data/bin/typo +25 -0
  27. data/config/initializers/access_rules.rb +4 -0
  28. data/config/routes.rb +2 -2
  29. data/db/schema.rb +32 -26
  30. data/db/schema.sqlite3.sql +3 -0
  31. data/lang/fr_FR.rb +46 -44
  32. data/lib/tasks/release.rake +1 -1
  33. data/lib/typo_version.rb +1 -1
  34. data/public/images/admin/loading.gif +0 -0
  35. data/public/images/closelabel.gif +0 -0
  36. data/public/stylesheets/administration.css +28 -8
  37. data/spec/controllers/admin/content_controller_spec.rb +91 -7
  38. data/spec/controllers/articles_controller_spec.rb +209 -0
  39. data/spec/controllers/comments_controller_spec.rb +0 -17
  40. data/spec/controllers/xml_controller_spec.rb +0 -5
  41. data/spec/factories.rb +8 -3
  42. data/spec/models/article_spec.rb +31 -4
  43. data/spec/models/configuration_spec.rb +0 -4
  44. data/spec/models/user_spec.rb +13 -0
  45. data/spec/spec_helper.rb +13 -0
  46. data/spec/views/articles/index_spec.rb +9 -11
  47. data/spec/views/articles/read_spec.rb +3 -5
  48. data/test/fixtures/blogs.yml +0 -1
  49. data/themes/dirtylicious/views/articles/_article.html.erb +6 -4
  50. data/themes/scribbish/views/articles/_article.html.erb +6 -4
  51. data/themes/standard_issue/views/articles/_article.html.erb +6 -4
  52. data/themes/true-blue-3/views/articles/_article.html.erb +8 -6
  53. data/themes/true-blue-3/views/categories/_article.html.erb +1 -1
  54. data/themes/typographic/views/articles/_article.html.erb +7 -5
  55. metadata +6 -8
  56. data/app/controllers/admin/previews_controller.rb +0 -10
  57. data/app/controllers/previews_controller.rb +0 -10
  58. data/app/controllers/redirect_controller.rb +0 -143
  59. data/app/helpers/redirect_helper.rb +0 -13
  60. data/spec/controllers/previews_controller_spec.rb +0 -28
  61. data/spec/controllers/redirect_controller_spec.rb +0 -165
data/CHANGELOG CHANGED
@@ -1,44 +1,37 @@
1
- After 9 months of hard work, we're proud to announce the official release of Typo 5.4 Willy Ronis, the most advanced and user friendly blogging platform on Rails. Despite having a minor version number, Typo 5.4 is a major release, coming with a lot of new features and some bugfixes as Willy Ronis was a great photographer who died this year at the age of 99. Since Typo 5.4 fixes some major security issues, you should really think about upgrading.
1
+ Only 1 week after releasing Typo 5.4, we're back with another cool Typo release. Since it was fixing a major security breach, Typo 5.4 was released a bit too quickly, and we left some bugs here and there we promptly fixed. So don't expect any new feature here, it's only about bug fixing and refactoring. Apparently, Matijs and Cyril had great fun doing this. I started to work on the first Typo user's guide as in our documentation effort. The 0.1 version is provided in Typo 5.4.1. We've also upgraded every theme at Typogarden to make them 5.4.1 compliant.
2
2
 
3
- Typo 5.4 is also a major release because we had many contributors from all over the world sending new features and fixes along this year. After contributing for a while, Matijs van Zuijlen (http://www.matijs.net/) finally joined the core team in late February and did a great job on this release. We would also like to thank, in alphabetical order: Diego Elio 'Flameeyes' Pettenò, Edward Middleton, Erik Ostrom, Hans de Graaff, Jakob Skov-Pedersen, Kurt Werle, Michael Reinsch, Mike Mondragon, Wei Jen Lu, Yuka Ouka, jzellman, and mpagalan.
3
+ Since we're still working on what we want to see in the next Typo, don't mind opening a ticket to ask for something you want.
4
4
 
5
- So, what's new in Typo 5.4? A lot of things
5
+ [#68] Atom feed has duplicated content
6
+ There was a duplicate content in atom feed because of the use of atom:summary with extended content. Since summary is not mandatory, and it should not duplicate content, we've decided to remove it one from the feed.
6
7
 
7
- = A brand new theme
8
- As we announced on our blog, Typo has now a default new theme. True Blue 3 is a port of the theme used at http://t37.net. Typographic is a great theme, but we needed something that would fit everyone's blog. Typographic is still proposed as a standard theme in Typo, but it's not the default theme anymore.
8
+ [#75] <typo:code> textfilter need change all < by &lt; in atom feed
9
9
 
10
- = A brand new admin
11
- Once again, we've deeply changed the admin. It now comes in the same blue flavor we've been using on True Blue 3. Some things have moved, some others have disappeared.
10
+ [#86] Migrations out of necessary sequence
12
11
 
13
- = Performances improvement
14
- Performances improvement has been a huge part of the work on Typo 5.4. We followed 3 axes to give Typo better performances:
15
- * Switching to Rails 2.3.4 divided the memory footprint by 2 since a major bug was fixed in this release.
16
- * Removing lots of dead, legacy code made Typo slightly faster. It may break your theme though, but the changed are easy.
17
- * Switching from Ruby Bluecloth to C Bluecloth 2 has surprising effects on page generation speed. Generating a page with 4500 comments switched from more than 2 minutes to about 2 seconds on our testing machines.
12
+ [#124] &gt; and &lt; entities are decoded in the atom feed
18
13
 
19
- = Autosave for all
20
- Previsouly reserved to new posts only with the simple editor, autosave is now avaliable when you create and edit posts, on both simple and visual editor.
14
+ [#126] Previews give an application error
21
15
 
22
- = New visual editor
23
- Speaking of the visual editor, we've upgraded to the new CKEditor, aka FCKEditor 3. Lighter, producing better code, CKEditor is the new generation of visual web editors. CKEditor is now plugged to Typo resources engine, providing better backward compatibility with older blogs. Switch between simple and visual editor without losing content has also been fixed.
16
+ [#127] Changing post's title changes the permalink slug
24
17
 
25
- = Articles preview
26
- A long awaited feature was the article preview during edition. It is now avaliable, so you can be sure of what you're going to publish.
18
+ [#128] Fix typogarden themes
19
+ Seems obvious isn't it?
27
20
 
28
- = User creation simplified
29
- Users creation from the front end has been simplified. You now just need to provide a login and an email, and you're done!
21
+ [#130] Theme editor textbox is too small
22
+ There was actually wet paint in our new admin. We fixed that quickly.
30
23
 
31
- = Users public profiles
32
- Users public pages are back, coming with an improved profile, allowing you to display your msn, aim, or twitter id. You can also chose the name you'll display on screen, chosing from your login, real name, or anything else. Authors also have their RSS and Atom feed back. An author sidebar is now also avaliable.
24
+ [#131] New Tags are created two times
25
+ The way autosave on new / saved articles worked was quite complicated and ended with strange behavior.
33
26
 
34
- = Chinese support
35
- Simple Chinese joins the number of languages supported by Typo. Cool.
27
+ [#132] Categories are brocken
28
+ A typo in the category views.
29
+
30
+ [#133] Installer parameter database=sqlite3 doesn't work
31
+ Awated parameter was database=sqlite, but since this could be confusing, we've made sqlite3 avaliable as well.
32
+
33
+ [#134] "Continue reading ..." link appears for posts that do not have additional content.
34
+ This one was actually the tree hiding the forest of all our themes being brocken because it constant renaming of the read controller and action name.
36
35
 
37
- = Better Wordpress converter
38
- Wordpress converter has been greatly improved, fixing lots of points that made the import incomplete: pages imported as article, spam comments considered as ham, blog name and subtitle not imported... Switching to Typo has never been easier.
39
36
 
40
- = Secondary layout for pages
41
- Lost of users have been asking for the possibility to define a secondary layout for pages. It's now done. Just add a pages.html.erb in your theme layout directory, mix some HTML and Ruby and you're done!
42
37
 
43
- = Cache unification
44
- Since we've fixed the static cache, we've decided to drop the cached model support along with the memcache support for cache model. It results in a lighter, simpler code, and less errors possible.
Binary file
@@ -10,13 +10,11 @@ class Admin::ContentController < Admin::BaseController
10
10
  @items = Tag.find_with_char params[:article][:keywords].strip
11
11
  render :inline => "<%= auto_complete_result @items, 'name' %>"
12
12
  end
13
-
13
+
14
14
  def index
15
- @drafts = Article.draft.all
16
- setup_categories
17
15
  @search = params[:search] ? params[:search] : {}
18
16
  @articles = Article.search_no_draft_paginate(@search, :page => params[:page], :per_page => this_blog.admin_display_elements)
19
-
17
+
20
18
  if request.xhr?
21
19
  render :partial => 'article_list', :object => @articles
22
20
  else
@@ -24,31 +22,30 @@ class Admin::ContentController < Admin::BaseController
24
22
  end
25
23
  end
26
24
 
27
- def new
25
+ def new
28
26
  new_or_edit
29
27
  end
30
-
28
+
31
29
  def edit
32
- @drafts = Article.draft.all
33
30
  @article = Article.find(params[:id])
34
-
35
- unless @article.access_by? current_user
31
+
32
+ unless @article.access_by? current_user
36
33
  redirect_to :action => 'index'
37
34
  flash[:error] = _("Error, you are not allowed to perform this action")
38
35
  return
39
36
  end
40
- new_or_edit
37
+ new_or_edit
41
38
  end
42
39
 
43
40
  def destroy
44
41
  @article = Article.find(params[:id])
45
-
42
+
46
43
  unless @article.access_by?(current_user)
47
44
  redirect_to :action => 'index'
48
45
  flash[:error] = _("Error, you are not allowed to perform this action")
49
46
  return
50
47
  end
51
-
48
+
52
49
  if request.post?
53
50
  @article.destroy
54
51
  redirect_to :action => 'index'
@@ -60,7 +57,7 @@ class Admin::ContentController < Admin::BaseController
60
57
  return unless params[:editor].to_s =~ /simple|visual/
61
58
  current_user.editor = params[:editor].to_s
62
59
  current_user.save!
63
-
60
+
64
61
  render :partial => "#{params[:editor].to_s}_editor"
65
62
  end
66
63
 
@@ -91,23 +88,21 @@ class Admin::ContentController < Admin::BaseController
91
88
  def autosave
92
89
  get_or_build_article
93
90
 
94
- # This is ugly, but I have to check whether or not the article is
91
+ # This is ugly, but I have to check whether or not the article is
95
92
  # published to create the dummy draft I'll replace later so that the
96
93
  # published article doesn't get overriden on the front
97
94
  if @article.published
98
95
  parent_id = @article.id
99
- @article = Article.new
96
+ @article = Article.drafts.child_of(parent_id).first || Article.new
100
97
  @article.allow_comments = this_blog.default_allow_comments
101
98
  @article.allow_pings = this_blog.default_allow_pings
102
99
  @article.text_filter = (current_user.editor == 'simple') ? current_user.text_filter : 1
103
100
  @article.parent_id = parent_id
104
101
  end
105
-
102
+
106
103
  params[:article] ||= {}
107
104
  @article.attributes = params[:article]
108
105
  @article.published = false
109
- setup_categories
110
- @selected = @article.categories.collect { |c| c.id }
111
106
  set_article_author
112
107
  save_attachments
113
108
 
@@ -144,24 +139,22 @@ class Admin::ContentController < Admin::BaseController
144
139
 
145
140
  def new_or_edit
146
141
  get_or_build_article
147
-
142
+
148
143
  @macros = TextFilter.available_filters.select { |filter| TextFilterPlugin::Macro > filter }
149
144
  @article.published = true
150
-
145
+
151
146
  # TODO Test if we can delete the next line. It's delete on nice_permalinks branch
152
147
  params[:article] ||= {}
153
148
 
154
149
  @resources = Resource.find(:all, :order => 'filename')
155
150
  @article.attributes = params[:article]
156
-
157
- setup_categories
158
- @selected = @article.categories.collect { |c| c.id }
159
- @drafts = Article.drafts
151
+
152
+
160
153
  if request.post?
161
154
  set_article_author
162
155
  save_attachments
163
156
  @article.state = "draft" if @article.draft
164
-
157
+
165
158
  if @article.save
166
159
  destroy_the_draft unless @article.draft
167
160
  set_article_categories
@@ -185,8 +178,7 @@ class Admin::ContentController < Admin::BaseController
185
178
  end
186
179
 
187
180
  def destroy_the_draft
188
- draft = Article.find(:first, :conditions => { :parent_id => @article.id })
189
- draft.destroy if draft
181
+ Article.all(:conditions => { :parent_id => @article.id }).map(&:destroy)
190
182
  end
191
183
 
192
184
  def set_article_author
@@ -196,10 +188,15 @@ class Admin::ContentController < Admin::BaseController
196
188
  end
197
189
 
198
190
  def set_article_title_for_autosave
199
- lastid = Article.find(:first, :order => 'id DESC').id
200
- @article.title = @article.title.blank? ? "Draft article " + lastid.to_s : @article.permalink = @article.stripped_title
191
+ if @article.title.blank?
192
+ lastid = Article.find(:first, :order => 'id DESC').id
193
+ @article.title = "Draft article " + lastid.to_s
194
+ end
195
+ unless @article.parent_id and Article.find(@article.parent_id).published
196
+ @article.permalink = @article.stripped_title
197
+ end
201
198
  end
202
-
199
+
203
200
  def save_attachments
204
201
  return if params[:attachments].nil?
205
202
  params[:attachments].each do |k,v|
@@ -215,7 +212,6 @@ class Admin::ContentController < Admin::BaseController
215
212
  @article.categories << cat
216
213
  end
217
214
  end
218
- @selected = params[:categories] || []
219
215
  end
220
216
 
221
217
  def def_build_body
@@ -224,7 +220,7 @@ class Admin::ContentController < Admin::BaseController
224
220
  @article.body = body[0]
225
221
  @article.extended = body[1]
226
222
  end
227
-
223
+
228
224
  end
229
225
 
230
226
  def get_or_build_article
@@ -240,10 +236,6 @@ class Admin::ContentController < Admin::BaseController
240
236
  end
241
237
  end
242
238
 
243
- def setup_categories
244
- @categories = Category.find(:all, :order => 'UPPER(name)')
245
- end
246
-
247
239
  def setup_resources
248
240
  @resources = Resource.find(:all, :order => 'created_at DESC')
249
241
  end
@@ -1,5 +1,5 @@
1
1
  class Admin::TagsController < Admin::BaseController
2
-
2
+
3
3
  cache_sweeper :blog_sweeper
4
4
 
5
5
  def index
@@ -15,7 +15,7 @@ class Admin::TagsController < Admin::BaseController
15
15
 
16
16
  @tags = Tag.paginate(:page => params[:page], :order => :display_name, :per_page => this_blog.admin_display_elements)
17
17
  end
18
-
18
+
19
19
  def edit
20
20
  @tag = Tag.find(params[:id])
21
21
  @tag.attributes = params[:tag]
@@ -25,7 +25,7 @@ class Admin::TagsController < Admin::BaseController
25
25
  redirect_to :action => 'index'
26
26
  end
27
27
  end
28
-
28
+
29
29
  def destroy
30
30
  @tag = Tag.find(params[:id])
31
31
  if request.post?
@@ -33,5 +33,5 @@ class Admin::TagsController < Admin::BaseController
33
33
  redirect_to :action => 'index'
34
34
  end
35
35
  end
36
-
36
+
37
37
  end
@@ -1,11 +1,12 @@
1
1
  class ArticlesController < ContentController
2
2
  before_filter :verify_config
3
+ before_filter :login_required, :only => [:preview]
3
4
  before_filter :auto_discovery_feed, :only => [:show, :index]
4
5
 
5
6
  layout :theme_layout, :except => [:comment_preview, :trackback]
6
7
 
7
8
  cache_sweeper :blog_sweeper
8
- caches_page :index, :read, :archives, :view_page, :if => Proc.new {|c|
9
+ caches_page :index, :read, :archives, :view_page, :redirect, :if => Proc.new {|c|
9
10
  c.request.query_string == ''
10
11
  }
11
12
 
@@ -58,6 +59,91 @@ class ArticlesController < ContentController
58
59
  render :layout => false, :action => :live_search
59
60
  end
60
61
 
62
+ def preview
63
+ @article = Article.last_draft(params[:id])
64
+ render :action => 'read'
65
+ end
66
+
67
+ def redirect
68
+ part = this_blog.permalink_format.split('/')
69
+ part.delete('') # delete all par of / where no data. Avoid all // or / started
70
+ params[:from].delete('')
71
+ if params[:from].last =~ /\.atom$/
72
+ params[:format] = 'atom'
73
+ params[:from].last.gsub!(/\.atom$/, '')
74
+ elsif params[:from].last =~ /\.rss$/
75
+ params[:format] = 'rss'
76
+ params[:from].last.gsub!(/\.rss$/, '')
77
+ end
78
+ zip_part = part.zip(params[:from])
79
+ article_params = {}
80
+ zip_part.each do |asso|
81
+ ['%year%', '%month%', '%day%', '%title%'].each do |format_string|
82
+ if asso[0] =~ /(.*)#{format_string}(.*)/
83
+ before_format = $1
84
+ after_format = $2
85
+ next if asso[1].nil?
86
+ result = asso[1].gsub(before_format, '')
87
+ result.gsub!(after_format, '')
88
+ article_params[format_string.gsub('%', '').to_sym] = result
89
+ end
90
+ end
91
+ end
92
+ begin
93
+ @article = this_blog.requested_article(article_params)
94
+ rescue
95
+ #Not really good.
96
+ # TODO :Check in request_article type of DATA made in next step
97
+ end
98
+ return show_article if @article
99
+
100
+ # Redirect old version with /:year/:month/:day/:title to new format.
101
+ # because it's change
102
+ ["%year%/%month%/%day%/%title%".split('/'), "articles/%year%/%month%/%day%/%title%".split('/')].each do |part|
103
+ part.delete('') # delete all par of / where no data. Avoid all // or / started
104
+ params[:from].delete('')
105
+ zip_part = part.zip(params[:from])
106
+ article_params = {}
107
+ zip_part.each do |asso|
108
+ ['%year%', '%month%', '%day%', '%title%'].each do |format_string|
109
+ if asso[0] =~ /(.*)#{format_string}(.*)/
110
+ before_format = $1
111
+ after_format = $2
112
+ next if asso[1].nil?
113
+ result = asso[1].gsub(before_format, '')
114
+ result.gsub!(after_format, '')
115
+ article_params[format_string.gsub('%', '').to_sym] = result
116
+ end
117
+ end
118
+ end
119
+ begin
120
+ @article = this_blog.requested_article(article_params)
121
+ rescue
122
+ #Not really good.
123
+ # TODO :Check in request_article type of DATA made in next step
124
+ end
125
+ if @article
126
+ redirect_to @article.permalink_url, :status => 301
127
+ return
128
+ end
129
+ end
130
+
131
+
132
+ # see how manage all by this redirect to redirect in different possible
133
+ # way maybe define in a controller in admin part in insert in this table
134
+ r = Redirect.find_by_from_path(params[:from].join("/"))
135
+
136
+ if(r)
137
+ path = r.to_path
138
+ url_root = self.class.relative_url_root
139
+ path = url_root + path unless url_root.nil? or path[0,url_root.length] == url_root
140
+ redirect_to path, :status => 301
141
+ else
142
+ render :text => "Page not found", :status => 404
143
+ end
144
+ end
145
+
146
+
61
147
  ### Deprecated Actions ###
62
148
 
63
149
  def archives
@@ -110,6 +196,33 @@ class ArticlesController < ContentController
110
196
  end
111
197
  end
112
198
 
199
+ # See an article We need define @article before
200
+ def show_article
201
+ @comment = Comment.new
202
+ @page_title = @article.title
203
+ article_meta
204
+
205
+ auto_discovery_feed
206
+ respond_to do |format|
207
+ format.html { render :template => '/articles/read' }
208
+ format.atom { render_feed('atom') }
209
+ format.rss { render_feed('rss20') }
210
+ format.xml { render_feed('atom') }
211
+ end
212
+ rescue ActiveRecord::RecordNotFound
213
+ error("Post not found...")
214
+ end
215
+
216
+ def article_meta
217
+ @keywords = ""
218
+ @keywords << @article.categories.map { |c| c.name }.join(", ") << ", " unless @article.categories.empty?
219
+ @keywords << @article.tags.map { |t| t.name }.join(", ") unless @article.tags.empty?
220
+ @description = "#{@article.title}, "
221
+ @description << @article.categories.map { |c| c.name }.join(", ") << ", " unless @article.categories.empty?
222
+ @description << @article.tags.map { |t| t.name }.join(", ") unless @article.tags.empty?
223
+ @description << " #{this_blog.blog_name}"
224
+ end
225
+
113
226
  def send_feed(format)
114
227
  if this_blog.feedburner_url.empty? or request.env["HTTP_USER_AGENT"] =~ /FeedBurner/i
115
228
  render :partial => "articles/#{format}_feed", :object => @articles
@@ -118,6 +231,11 @@ class ArticlesController < ContentController
118
231
  end
119
232
  end
120
233
 
234
+ # TODO: Merge with send_feed?
235
+ def render_feed(type)
236
+ render :partial => "/articles/#{type}_feed", :object => @article.published_feedback
237
+ end
238
+
121
239
  def set_headers
122
240
  headers["Content-Type"] = "text/html; charset=utf-8"
123
241
  end
@@ -1,5 +1,4 @@
1
1
  class CommentsController < FeedbackController
2
- before_filter :check_request_type, :only => [:create]
3
2
  before_filter :get_article, :only => [:create, :preview]
4
3
 
5
4
  def create
@@ -76,12 +75,6 @@ class CommentsController < FeedbackController
76
75
  headers["Content-Type"] = "text/html; charset=utf-8"
77
76
  end
78
77
 
79
- def check_request_type
80
- return true if this_blog.sp_allow_non_ajax_comments || request.xhr?
81
- render :nothing => true, :status => :bad_request
82
- return false
83
- end
84
-
85
78
  def set_comment_cookies
86
79
  add_to_cookies(:author, @comment.author)
87
80
  if ! @comment.email.blank?
@@ -24,6 +24,7 @@ class ContentController < ApplicationController
24
24
 
25
25
  protected
26
26
 
27
+ # TODO: Make this work for all content.
27
28
  def auto_discovery_feed(options = { })
28
29
  with_options(options.reverse_merge(:only_path => true)) do |opts|
29
30
  @auto_discovery_url_rss = opts.url_for(:format => 'rss')