public
Fork of halorgium/mephisto
Description: A refactored Mephisto that has multiple spam detection engines.
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/francois/mephisto.git
Extract template rendering code to separate handler class, add support for 
alternate template handlers. [Pascal Belloncle]  Add {{ article.next }} 
and {{ article | next: section }} for paginating articles [Pascal 
Belloncle]

git-svn-id: http://svn.techno-weenie.net/projects/mephisto/trunk@2737 
567b1171-46fb-0310-a4c9-b4bef9110e78
technoweenie (author)
Mon Feb 12 05:38:49 -0800 2007
commit  a5750df30446856991edbe3eab59daeb018d6290
tree    747a0547b37475e70ee98d8898d4ebbc9a0f8279
parent  04b98f73086119779661e9b5a34da458297c7843
...
1
2
 
 
 
 
3
4
5
...
1
2
3
4
5
6
7
8
9
0
@@ -1,5 +1,9 @@
0
 * SVN *
0
 
0
+* Extract template rendering code to separate handler class, add support for alternate template handlers. [Pascal Belloncle]
0
+
0
+* Add {{ article.next }} and {{ article | next: section }} for paginating articles [Pascal Belloncle]
0
+
0
 * [converters] initial movable type support [sd]
0
 
0
 * [converters] use no filter for wordpress articles
...
29
30
31
32
 
33
34
35
...
29
30
31
 
32
33
34
35
0
@@ -29,7 +29,7 @@ class Admin::ArticlesController < Admin::BaseController
0
     Mephisto::Liquid::CommentForm.article = @article
0
     @article = @article.to_liquid(:mode => :single)
0
     
0
- render :text => site.render_liquid_for(site.sections.home, :single, 'articles' => [@article], 'article' => @article, 'comments' => @comments, 'site' => site.to_liquid)
0
+ render :text => site.call_render(site.sections.home, :single, 'articles' => [@article], 'article' => @article, 'comments' => @comments, 'site' => site.to_liquid)
0
   end
0
 
0
   def new
...
28
29
30
31
 
32
33
34
...
28
29
30
 
31
32
33
34
0
@@ -28,7 +28,7 @@ class Admin::TemplatesController < Admin::DesignController
0
       if !@tmpl.file?
0
         page.flash.errors "File does not exist"
0
         page.visual_effect :fade, params[:context], :duration => 0.3
0
- elsif @theme.templates.custom.include?(@tmpl.basename.to_s)
0
+ elsif @theme.templates.custom(@theme.extension).include?(@tmpl.basename.to_s)
0
         @tmpl.unlink
0
         page.visual_effect :fade, params[:context], :duration => 0.3
0
       else
...
49
50
51
52
 
53
54
55
...
49
50
51
 
52
53
54
55
0
@@ -49,7 +49,7 @@ class ApplicationController < ActionController::Base
0
       end
0
       status = (assigns.delete(:status) || :ok)
0
       @liquid_assigns = assigns
0
- render :text => site.render_liquid_for(@section, template_type, assigns, self), :status => status
0
+ render :text => site.call_render(@section, template_type, assigns, self), :status => status
0
     end
0
 
0
     def show_error(message = 'An error occurred.', status = :internal_server_error)
...
58
59
60
 
 
 
 
 
 
 
 
 
 
 
 
61
62
63
...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
0
@@ -58,6 +58,18 @@ class ArticleDrop < BaseDrop
0
     @assets ||= liquify(*@source.assets)
0
   end
0
 
0
+ def next(section=nil)
0
+ if nxt = @source.next(section ? section.source : nil)
0
+ nxt.to_liquid.tap { |n| n.context = @context if n }
0
+ end
0
+ end
0
+
0
+ def previous(section=nil)
0
+ if prev = @source.previous(section ? section.source : nil)
0
+ prev.to_liquid.tap { |p| p.context = @context if p }
0
+ end
0
+ end
0
+
0
   protected
0
     def body_for_mode(mode)
0
       contents = [before_method(:excerpt), before_method(:body)]
...
118
119
120
 
 
 
 
 
 
 
 
121
122
123
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
0
@@ -118,6 +118,14 @@ module UrlFilters
0
     atom_feed '/feed/' + section.source.to_feed_url.join('/'), (title.blank? ? "Articles for #{section['name']}" : title)
0
   end
0
 
0
+ def next(article, section = nil)
0
+ article.next(section)
0
+ end
0
+
0
+ def previous(article, section = nil)
0
+ article.previous(section)
0
+ end
0
+
0
   private
0
     # marks a page as class=selected
0
     def page_anchor_options(page, section = nil)
...
158
159
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
162
163
...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
0
@@ -158,6 +158,31 @@ class Article < Content
0
     add_podcast_xml(builder)
0
   end
0
 
0
+ def next(section=nil)
0
+ self.class.with_published do
0
+ if section
0
+ site.articles.find :first, :conditions => ['published_at > ? and assigned_sections.section_id = ?', published_at, section.id],
0
+ :joins => 'inner join assigned_sections on contents.id = assigned_sections.article_id',
0
+ :order => 'published_at'
0
+ else
0
+ site.articles.find :first, :conditions => ['published_at > ?', published_at], :order => 'published_at'
0
+ end
0
+ end
0
+ end
0
+
0
+ def previous(section=nil)
0
+ self.class.with_published do
0
+ if section
0
+ site.articles.find :first, :conditions => ['published_at < ? and assigned_sections.section_id = ?', published_at, section.id],
0
+ :joins => 'inner join assigned_sections on contents.id = assigned_sections.article_id',
0
+ :order => 'published_at desc'
0
+ else
0
+ site.articles.find :first, :conditions => ['published_at < ?', published_at], :order => 'published_at desc'
0
+ end
0
+ end
0
+ end
0
+
0
+
0
   protected
0
     def convert_to_utc
0
       self.published_at = published_at.utc if published_at
...
4
5
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
8
9
...
162
163
164
165
 
166
167
168
169
 
 
 
 
170
171
 
172
173
174
...
196
197
198
 
 
 
 
 
 
 
199
200
201
...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
...
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
181
182
183
 
184
185
186
 
 
187
188
189
190
191
 
192
193
194
195
...
217
218
219
220
221
222
223
224
225
226
227
228
229
...
295
296
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
0
@@ -4,6 +4,25 @@ class Site < ActiveRecord::Base
0
   cattr_reader :theme_path, :default_assigns
0
 
0
   cattr_accessor :multi_sites_enabled, :cache_sweeper_tracing
0
+
0
+ # @@template_handlers = HashWithIndifferentAccess.new if @@template_handlers.nil?
0
+ @@template_handlers = {}
0
+
0
+ # Register a class that knows how to handle template files with the given
0
+ # extension. This can be used to implement new template types.
0
+ # The constructor for the class must take a Site instance
0
+ # as a parameter, and the class must implement a #render method that
0
+ # has the following signature
0
+ # def render(section, layout, template, assigns ={}, controller = nil)
0
+ # and return the rendered template as a string.
0
+ def self.register_template_handler(extension, klass)
0
+ @@template_handlers[extension] = klass
0
+ end
0
+ register_template_handler(".liquid", Mephisto::Liquid::LiquidTemplate)
0
+
0
+ def self.extensions
0
+ @@template_handlers.keys
0
+ end
0
 
0
   has_many :sections, :order => "position" do
0
     def home
0
@@ -162,13 +181,15 @@ class Site < ActiveRecord::Base
0
     comment_age.to_i > -1
0
   end
0
 
0
- def render_liquid_for(section, template_type, assigns = {}, controller = nil)
0
+ def call_render(section, template_type, assigns = {}, controller = nil)
0
     assigns.update('site' => to_liquid(section), 'mode' => template_type)
0
     assigns.update(default_assigns) unless default_assigns.empty?
0
- parse_inner_template(set_content_template(section, template_type), assigns, controller)
0
- parse_template(set_layout_template(section, template_type), assigns, controller)
0
+ template = set_content_template(section, template_type)
0
+ layout = set_layout_template(section, template_type)
0
+ handler = @@template_handlers[theme.extension] || @@template_handlers[".liquid"]
0
+ handler.new(self).render(section, layout, template, assigns, controller)
0
   end
0
-
0
+
0
   def to_liquid(current_section = nil)
0
     SiteDrop.new self, current_section
0
   end
0
@@ -196,6 +217,13 @@ class Site < ActiveRecord::Base
0
     end
0
   end
0
 
0
+#need non protected method for ErbTemplate - psq
0
+ def find_preferred_template(template_type, custom_template)
0
+ preferred = templates.find_preferred(template_type, custom_template)
0
+ return preferred if preferred && preferred.file?
0
+ raise MissingTemplateError.new(template_type, templates.collect_templates(template_type, custom_template).collect(&:basename))
0
+ end
0
+
0
   protected
0
     def cached_log_message_for(log_message, pages)
0
       pages.inject([log_message, "Expiring #{pages.size} page(s)"]) { |msg, p| msg << " - #{p.url}" }.join("\n")
0
@@ -267,27 +295,4 @@ class Site < ActiveRecord::Base
0
       find_preferred_template(:layout, layout_template)
0
     end
0
 
0
- def find_preferred_template(template_type, custom_template)
0
- preferred = templates.find_preferred(template_type, custom_template)
0
- return preferred if preferred && preferred.file?
0
- raise MissingTemplateError.new(template_type, templates.collect_templates(template_type, custom_template).collect(&:basename))
0
- end
0
-
0
- def parse_template(template, assigns, controller)
0
- # give the include tag access to files in the site's fragments directory
0
- Liquid::Template.file_system = Liquid::LocalFileSystem.new(File.join(theme.path, 'templates'))
0
- tmpl = Liquid::Template.parse(template.read.to_s)
0
- returning tmpl.render(assigns, :registers => {:controller => controller}) do |result|
0
- yield tmpl, result if block_given?
0
- end
0
- end
0
-
0
- def parse_inner_template(template, assigns, controller)
0
- parse_template(template, assigns, controller) do |tmpl, result|
0
- # Liquid::Template takes a copy of the assigns.
0
- # merge any new values in to the assigns and pass them to the layout
0
- tmpl.assigns.each { |k, v| assigns[k] = v } if tmpl.respond_to?(:assigns)
0
- assigns['content_for_layout'] = result
0
- end
0
- end
0
 end
...
1
2
 
3
4
5
 
 
 
 
6
7
8
 
 
9
10
11
12
 
13
14
15
...
17
18
19
20
21
 
 
22
23
24
...
1
 
2
3
 
4
5
6
7
8
9
 
 
10
11
12
13
14
 
15
16
17
18
...
20
21
22
 
 
23
24
25
26
27
0
@@ -1,15 +1,18 @@
0
 class Templates < Attachments
0
- @@template_types = [:section, :single, :archive, :search, :error, :tag, :layout].collect! { |f| "#{f}.liquid" }
0
+ @@template_types = ["section", "single", "archive", "search", "error", "tag", "layout"]
0
   @@template_types.sort!
0
- cattr_reader :template_types
0
 
0
+ def template_types(extension = ".liquid")
0
+ @@template_types.collect { |f| "#{f}"+extension }
0
+ end
0
+
0
   def [](template_name)
0
- template_name = File.basename(template_name.to_s).sub /\.liquid$/, ''
0
- theme.path + "#{template_name =~ /layout$/ ? 'layouts' : 'templates'}/#{template_name}.liquid"
0
+ template_name = File.basename(template_name.to_s).sub /#{theme.extension}$/, ''
0
+ theme.path + "#{template_name =~ /layout$/ ? 'layouts' : 'templates'}/#{template_name}#{theme.extension}"
0
   end
0
 
0
   def collect_templates(template_type, *custom_templates)
0
- custom_templates.push(template_type).collect! { |t| self[t] }
0
+ custom_templates.push(template_type.to_s+theme.extension).collect! { |t| self[t] }
0
   end
0
 
0
   # adds the custom_template to the top of the hierarchy if given
0
@@ -17,7 +20,7 @@ class Templates < Attachments
0
     collect_templates(template_type, custom_template).detect(&:file?)
0
   end
0
   
0
- def custom
0
- @custom ||= collect { |p| p.basename.to_s } - template_types
0
+ def custom(extension = ".liquid")
0
+ @custom ||= (collect { |p| p.basename.to_s } - template_types(extension)).sort
0
   end
0
 end
0
\ No newline at end of file
...
1
2
3
4
 
5
6
 
7
8
9
...
47
48
49
 
 
50
51
52
...
98
99
100
101
 
102
103
104
...
1
2
3
 
4
5
 
6
7
8
9
...
47
48
49
50
51
52
53
54
...
100
101
102
 
103
104
105
106
0
@@ -1,9 +1,9 @@
0
 class Theme
0
   @@root_theme_files = %w(about.yml preview.png)
0
   @@theme_directories = %w(templates layouts javascripts stylesheets images)
0
- @@allowed_extensions = %w(.js .css .liquid .png .gif .jpg .swf .ico)
0
+ @@allowed_extensions = %w(.js .css .png .gif .jpg .swf .ico) | Site.extensions
0
   cattr_reader :root_theme_files, :theme_directories, :allowed_extensions
0
- attr_reader :path, :base_path
0
+ attr_reader :path, :base_path, :extension
0
 
0
   def self.import(zip_file, options = {})
0
     dest = options[:to].is_a?(Pathname) ? options[:to] : Pathname.new(options[:to] || '.')
0
@@ -47,6 +47,8 @@ class Theme
0
       @base_path = base
0
       @path = Pathname.new(@base_path)
0
     end
0
+ layout = (@path + "layouts").children(false).select {|v| v.to_s =~ /^layout/}[0] if (@path + "layouts").directory?
0
+ @extension = layout.extname if layout
0
   end
0
 
0
   def current?
0
@@ -98,7 +100,7 @@ class Theme
0
     Pathname.glob(File.join(base_path, '*/*')).each do |path|
0
       next unless path.file?
0
       @attachments << path
0
- (path.extname == '.liquid' ? @templates : @resources) << path
0
+ ((path.extname == @extension) ? @templates : @resources) << path
0
     end
0
     @attachments
0
   end
...
3
4
5
6
 
7
8
9
 
10
11
12
...
3
4
5
 
6
7
8
 
9
10
11
12
0
@@ -3,10 +3,10 @@
0
 <p>Modify a template by selecting it from the list below. Add a new layout by creating a Liquid template with an
0
   *_layout suffix (e.g custom_layout).</p>
0
 <ul id="attachments">
0
- <% @theme.templates.template_types.each do |template| -%>
0
+ <% @theme.templates.template_types(@theme.extension).each do |template| -%>
0
     <li><%= link_to template, url_for_theme(:controller => 'templates', :action => 'edit', :filename => template) %></li>
0
   <% end -%>
0
- <% @theme.templates.custom.each_with_index do |template, i| -%>
0
+ <% @theme.templates.custom(@theme.extension).each_with_index do |template, i| -%>
0
     <li id="templates-<%= i %>">
0
       <%= delete_link :templates, template, "templates-#{i}" %>
0
       <%= link_to template, url_for_theme(:controller => 'templates', :action => 'edit', :filename => template) %>
...
3
4
5
6
 
7
8
9
...
3
4
5
 
6
7
8
9
0
@@ -3,7 +3,7 @@
0
     <ul id="act-nav" class="clear">
0
       <li><%= link_to "New template", url_for_theme(:controller => 'design') %></li>
0
       <li><%= link_to "Manage themes", :controller => 'themes' %></li>
0
- <% if @theme.templates.custom.include?(@tmpl.basename.to_s) -%>
0
+ <% if @theme.templates.custom(@theme.extension).include?(@tmpl.basename.to_s) -%>
0
       <li><%= link_to 'Delete this file', url_for_theme(:action => 'remove', :filename => @tmpl.basename),
0
                 :confirm => "Are you sure you want to delete #{@tmpl.basename}?\nThis action can't be undone!" %></li>
0
     <% end -%>
...
101
102
103
 
 
 
 
 
 
104
105
...
101
102
103
104
105
106
107
108
109
110
111
0
@@ -101,4 +101,10 @@ class Time
0
       else self.class.delta(year, month, day)
0
     end
0
   end
0
+end
0
+
0
+class Object
0
+ def tap
0
+ yield self; self;
0
+ end
0
 end
0
\ No newline at end of file
...
4
5
6
7
 
8
9
 
10
11
12
...
17
18
19
20
 
21
22
23
24
 
25
...
4
5
6
 
7
8
 
9
10
11
12
...
17
18
19
 
20
21
22
 
23
24
25
0
@@ -4,9 +4,9 @@ class Site
0
   @@theme_path = Pathname.new(RAILS_ROOT) + 'tmp/themes'
0
   attr_reader :recent_template_type, :recent_preferred_template, :recent_layout_template
0
   
0
- def render_liquid_for_with_testing(section, template_type, assigns = {}, controller = nil)
0
+ def call_render_with_testing(section, template_type, assigns = {}, controller = nil)
0
     @recent_template_type = template_type
0
- render_liquid_for_without_testing(section, template_type, assigns, controller)
0
+ call_render_without_testing(section, template_type, assigns, controller)
0
   end
0
   
0
   def set_content_template_with_testing(section, template_type)
0
@@ -17,7 +17,7 @@ class Site
0
     @recent_layout_template = set_layout_template_without_testing(section, template_type)
0
   end
0
   
0
- [:render_liquid_for, :set_content_template, :set_layout_template].each do |m|
0
+ [:call_render, :set_content_template, :set_layout_template].each do |m|
0
     alias_method_chain m, :testing
0
   end
0
-end unless Site.instance_methods.include?('render_liquid_for_with_testing')
0
\ No newline at end of file
0
+end unless Site.instance_methods.include?('call_render_with_testing')
0
\ No newline at end of file
...
4
5
6
 
7
8
 
9
10
11
...
69
70
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
73
74
...
4
5
6
7
8
 
9
10
11
12
...
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
0
@@ -4,8 +4,9 @@ class ArticleDropTest < Test::Unit::TestCase
0
   fixtures :sites, :sections, :contents, :assigned_sections, :users, :tags, :taggings, :assigned_assets, :assets
0
   
0
   def setup
0
+ @context = mock_context('site' => sites(:first).to_liquid)
0
     @article = contents(:welcome).to_liquid(:mode => :single)
0
- @article.context = mock_context('site' => sites(:first).to_liquid)
0
+ @article.context = @context
0
   end
0
 
0
   def test_equality
0
@@ -69,6 +70,26 @@ class ArticleDropTest < Test::Unit::TestCase
0
     assert_equal "<p>body</p>", a.send(:body_for_mode, :single)
0
     assert_equal '<p>body</p>', a.send(:body_for_mode, :list)
0
   end
0
+
0
+ def test_find_next
0
+ another = contents(:another).to_liquid
0
+ another.context = @context
0
+ cupcake_welcome = contents(:cupcake_welcome).to_liquid
0
+ cupcake_welcome.context = @context
0
+
0
+ assert_equal another.next, contents(:site_map).to_liquid
0
+ assert_equal another.next(sections(:home).to_liquid), contents(:welcome).to_liquid
0
+ assert_equal cupcake_welcome.next(sections(:cupcake_home).to_liquid), nil
0
+ end
0
+
0
+ def test_should_find_previous
0
+ another = contents(:another).to_liquid
0
+ another.context = @context
0
+
0
+ assert_equal another.previous, contents(:at_beginning_of_next_month).to_liquid
0
+ assert_equal another.previous(sections(:home).to_liquid), nil
0
+ assert_not_equal another.previous(sections(:cupcake_home).to_liquid), contents(:at_beginning_of_next_month).to_liquid
0
+ end
0
   
0
   specify "should show article url" do
0
     t = Time.now.utc - 3.days
...
1
2
3
4
 
 
 
 
 
 
 
5
 
 
 
 
 
 
6
7
8
...
1
2
3
 
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0
@@ -1,8 +1,20 @@
0
 require File.dirname(__FILE__) + '/../test_helper'
0
 
0
 class ArticleTest < Test::Unit::TestCase
0
- fixtures :contents, :users, :sections, :sites
0
+ fixtures :contents, :users, :sections, :sites, :assigned_sections
0
+
0
+ def test_find_next
0
+ assert_equal contents(:another).next, contents(:site_map)
0
+ assert_equal contents(:another).next(sections(:home)), contents(:welcome)
0
+ assert_equal contents(:cupcake_welcome).next(sections(:cupcake_home)), nil
0
+ end
0
 
0
+ def test_should_find_previous
0
+ assert_equal contents(:another).previous, contents(:at_beginning_of_next_month)
0
+ assert_equal contents(:another).previous(sections(:home)), nil
0
+ assert_not_equal contents(:another).previous(sections(:cupcake_home)), contents(:at_beginning_of_next_month)
0
+ end
0
+
0
   def test_should_create_permalink
0
     a = create_article :title => 'This IS a Tripped out title!!.!1 (well/ not really)', :body => 'foo'
0
     assert_equal 'this-is-a-tripped-out-title-1-well-not-really', a.permalink
...
60
61
62
 
 
 
 
 
63
64
65
...
60
61
62
63
64
65
66
67
68
69
70
0
@@ -60,6 +60,11 @@ context "Site" do
0
                             [sections(:home), sections(:earth), sections(:europe), sections(:africa), sections(:bucharest), sections(:links), sections(:about)]
0
   end
0
 
0
+ specify "should find at least one extension (.liquid)" do
0
+ assert !Site.extensions.empty?
0
+ assert Site.extensions.include?(".liquid")
0
+ end
0
+
0
   protected
0
     def assert_reorder_sections(old_order, expected)
0
       assert_models_equal old_order, sites(:first).sections
...
34
35
36
 
37
 
 
 
 
 
 
 
 
 
 
 
38
...
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
0
@@ -34,5 +34,17 @@ context "Template" do
0
 
0
   def test_should_find_custom
0
     assert_equal ['alt_layout.liquid', 'author.liquid', 'home.liquid', 'index.liquid', 'page.liquid'], sites(:first).templates.custom.sort
0
+ assert_equal ['alt_layout.liquid', 'author.liquid', 'home.liquid', 'index.liquid', 'page.liquid'], sites(:first).templates.custom(".liquid").sort
0
   end
0
+
0
+ def test_template_types_should_use_extension
0
+ assert_equal ["archive.liquid", "error.liquid", "layout.liquid", "search.liquid", "section.liquid", "single.liquid", "tag.liquid"], sites(:first).templates.template_types
0
+ assert_equal ["archive.test", "error.test", "layout.test", "search.test", "section.test", "single.test", "tag.test"], sites(:first).templates.template_types(".test")
0
+ end
0
+
0
+ def test_collect_templates_find_correct_template
0
+ assert sites(:first).templates.collect_templates(:section, nil).include?(sites(:first).theme.path+"templates/section.liquid")
0
+ assert sites(:first).templates.collect_templates(:section, "home.liquid").include?(sites(:first).theme.path+"templates/home.liquid")
0
+ end
0
+
0
 end
...
59
60
61
 
 
 
 
 
 
 
 
 
 
62
...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
0
@@ -59,4 +59,14 @@ context "Theme" do
0
     site.stubs(:current_theme_path).returns(0)
0
     assert_raises(MissingThemesError) { site.theme }
0
   end
0
+
0
+ specify "should retrieve extension" do
0
+ assert_equal ".liquid", @theme.extension
0
+ end
0
+
0
+ specify "should find templates" do
0
+ assert_equal 15, @theme.attachments.size
0
+ assert_equal 12, @theme.templates.size
0
+ assert_equal 3, @theme.resources.size
0
+ end
0
 end

Comments

    No one has commented yet.