radiant-grandchildren_tags-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ Radiant Grandchildren Tags Extension
2
+ ===
3
+
4
+ About
5
+ ---
6
+
7
+ An extension by [Benny Degezelle][jomz] that adds r:grandchildren tags. Think of this tag like r:aggregate, where the paths attribute would be the urls of all the children of the current page. All features of r:children are implemented, see Available Tags.
8
+
9
+ Tested on [Radiant CMS][radiant] 1.0.0.rc2, but should work for 0.9.1+ (uses Radiant's render_children_with_pagination)
10
+
11
+ Installation
12
+ ---
13
+
14
+ git clone git://github.com/jomz/radiant-grandchildren_tags-extension.git vendor/extensions/grandchildren_tags
15
+
16
+
17
+ ###Available Tags
18
+
19
+ * <r:grandchildren:count>
20
+ * <r:grandchildren:first>
21
+ * <r:grandchildren:last>
22
+ * <r:grandchildren:each>
23
+ * <r:grandchildren:each:if_first>
24
+ * <r:grandchildren:each:unless_first>
25
+ * <r:grandchildren:each:if_last>
26
+ * <r:grandchildren:each:unless_last>
27
+ * <r:grandchildren:each:header>
28
+
29
+ See the "available tags" documentation built into the Radiant page admin for more details.
30
+
31
+ [jomz]: http://github.com/jomz
32
+ [radiant]: http://radiantcms.org/
@@ -0,0 +1,109 @@
1
+ # Determine where the RSpec plugin is by loading the boot
2
+ unless defined? RADIANT_ROOT
3
+ ENV["RAILS_ENV"] = "test"
4
+ case
5
+ when ENV["RADIANT_ENV_FILE"]
6
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
7
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
8
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
9
+ else
10
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
11
+ end
12
+ end
13
+
14
+ require 'rake'
15
+ require 'rake/rdoctask'
16
+ require 'rake/testtask'
17
+
18
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
19
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
20
+ require 'spec/rake/spectask'
21
+ require 'cucumber'
22
+ require 'cucumber/rake/task'
23
+
24
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
25
+ Object.send(:remove_const, :RADIANT_ROOT)
26
+
27
+ extension_root = File.expand_path(File.dirname(__FILE__))
28
+
29
+ task :default => [:spec, :features]
30
+ task :stats => "spec:statsetup"
31
+
32
+ desc "Run all specs in spec directory"
33
+ Spec::Rake::SpecTask.new(:spec) do |t|
34
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
35
+ t.spec_files = FileList['spec/**/*_spec.rb']
36
+ end
37
+
38
+ task :features => 'spec:integration'
39
+
40
+ namespace :spec do
41
+ desc "Run all specs in spec directory with RCov"
42
+ Spec::Rake::SpecTask.new(:rcov) do |t|
43
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
44
+ t.spec_files = FileList['spec/**/*_spec.rb']
45
+ t.rcov = true
46
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
47
+ end
48
+
49
+ desc "Print Specdoc for all specs"
50
+ Spec::Rake::SpecTask.new(:doc) do |t|
51
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
52
+ t.spec_files = FileList['spec/**/*_spec.rb']
53
+ end
54
+
55
+ [:models, :controllers, :views, :helpers].each do |sub|
56
+ desc "Run the specs under spec/#{sub}"
57
+ Spec::Rake::SpecTask.new(sub) do |t|
58
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
59
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
60
+ end
61
+ end
62
+
63
+ desc "Run the Cucumber features"
64
+ Cucumber::Rake::Task.new(:integration) do |t|
65
+ t.fork = true
66
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
67
+ # t.feature_pattern = "#{extension_root}/features/**/*.feature"
68
+ t.profile = "default"
69
+ end
70
+
71
+ # Setup specs for stats
72
+ task :statsetup do
73
+ require 'code_statistics'
74
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
75
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
76
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
77
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
78
+ ::CodeStatistics::TEST_TYPES << "Model specs"
79
+ ::CodeStatistics::TEST_TYPES << "View specs"
80
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
81
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
82
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
83
+ end
84
+
85
+ namespace :db do
86
+ namespace :fixtures do
87
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
88
+ task :load => :environment do
89
+ require 'active_record/fixtures'
90
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
91
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
92
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ desc 'Generate documentation for the grandchildren_tags extension.'
100
+ Rake::RDocTask.new(:rdoc) do |rdoc|
101
+ rdoc.rdoc_dir = 'rdoc'
102
+ rdoc.title = 'GrandchildrenTagsExtension'
103
+ rdoc.options << '--line-numbers' << '--inline-source'
104
+ rdoc.rdoc_files.include('README')
105
+ rdoc.rdoc_files.include('lib/**/*.rb')
106
+ end
107
+
108
+ # Load any custom rakefiles for extension
109
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,3 @@
1
+ ---
2
+ en:
3
+ grandchildren tags: Grandchildren Tags
@@ -0,0 +1 @@
1
+ default: --format progress features --tags ~@proposed,~@in_progress
@@ -0,0 +1,10 @@
1
+ require 'radiant-grandchildren_tags-extension/version'
2
+ class GrandchildrenTagsExtension < Radiant::Extension
3
+ version RadiantGrandchildrenTagsExtension::VERSION
4
+ description "Adds grandchildren tags to Radiant."
5
+ url "http://github.com/jomz/radiant-grandchildren_tags-extension"
6
+
7
+ def activate
8
+ Page.send :include, GrandchildrenTags
9
+ end
10
+ end
@@ -0,0 +1,260 @@
1
+ module GrandchildrenTags
2
+ include Radiant::Taggable
3
+
4
+ desc %{
5
+ Renders the contained elements only if the current contextual page has one or
6
+ more grandchild pages. The @status@ attribute limits the status of found child pages
7
+ to the given status, the default is @"published"@. @status="all"@ includes all
8
+ non-virtual pages regardless of status.
9
+
10
+ *Usage:*
11
+
12
+ <pre><code><r:if_grandchildren [status="published"]>...</r:if_grandchildren></code></pre>
13
+ }
14
+ tag "if_grandchildren" do |tag|
15
+ tag.locals.parent_ids = tag.locals.page.children.map(&:id)
16
+ options = aggregate_children(tag)
17
+ tag.expand if Page.count(options) > 0
18
+ end
19
+
20
+ desc %{
21
+ Renders the contained elements only if the current contextual page has no grandchildren.
22
+ The @status@ attribute limits the status of found child pages to the given status,
23
+ the default is @"published"@. @status="all"@ includes all non-virtual pages
24
+ regardless of status.
25
+
26
+ *Usage:*
27
+
28
+ <pre><code><r:unless_grandchildren [status="published"]>...</r:unless_grandchildren></code></pre>
29
+ }
30
+ tag "unless_grandchildren" do |tag|
31
+ tag.locals.parent_ids = tag.locals.page.children.map(&:id)
32
+ options = aggregate_children(tag)
33
+ tag.expand unless Page.count(options) > 0
34
+ end
35
+
36
+ desc %{
37
+ Gives access to a page's grandchildren.
38
+
39
+ *Usage:*
40
+
41
+ <pre><code><r:grandchildren>...</r:grandchildren></code></pre>
42
+ }
43
+ tag 'grandchildren' do |tag|
44
+ tag.locals.parent_ids = tag.locals.page.children.map(&:id)
45
+ tag.expand
46
+ end
47
+
48
+ desc %{
49
+ Renders the total number of grandchildren.
50
+ }
51
+ tag 'grandchildren:count' do |tag|
52
+ options = aggregate_children(tag)
53
+ Page.count(options)
54
+ end
55
+
56
+ desc %{
57
+ Returns the first grandchild. Inside this tag all page attribute tags are mapped to
58
+ the first child. Takes the same ordering options as @<r:children:each>@.
59
+
60
+ *Usage:*
61
+
62
+ <pre><code><r:grandchildren:first>...</r:grandchildren:first></code></pre>
63
+ }
64
+ tag 'grandchildren:first' do |tag|
65
+ options = aggregate_children(tag)
66
+ grandchildren = Page.find(:all, options)
67
+ if first = grandchildren.first
68
+ tag.locals.page = first
69
+ tag.expand
70
+ end
71
+ end
72
+
73
+ desc %{
74
+ Returns the last grandchild. Inside this tag all page attribute tags are mapped to
75
+ the last grandchild. Takes the same ordering options as @<r:children:each>@.
76
+
77
+ *Usage:*
78
+
79
+ <pre><code><r:grandchildren:last>...</r:grandchildren:last></code></pre>
80
+ }
81
+ tag 'grandchildren:last' do |tag|
82
+ options = aggregate_children(tag)
83
+ grandchildren = Page.find(:all, options)
84
+ if last = grandchildren.last
85
+ tag.locals.page = last
86
+ tag.expand
87
+ end
88
+ end
89
+
90
+ desc %{
91
+ Cycles through each of the grandchildren. Inside this tag all page attribute tags
92
+ are mapped to the current grandchild page.
93
+
94
+ Supply @paginated="true"@ to paginate the displayed list. will_paginate view helper
95
+ options can also be specified, including @per_page@, @previous_label@, @next_label@,
96
+ @class@, @separator@, @inner_window@ and @outer_window@.
97
+
98
+ *Usage:*
99
+
100
+ <pre><code><r:grandchildren:each [offset="number"] [limit="number"]
101
+ [by="published_at|updated_at|created_at|slug|title|keywords|description"]
102
+ [order="asc|desc"]
103
+ [status="draft|reviewed|published|hidden|all"]
104
+ [paginated="true"]
105
+ [per_page="number"]
106
+ >
107
+ ...
108
+ </r:children:each>
109
+ </code></pre>
110
+ }
111
+ tag 'grandchildren:each' do |tag|
112
+ render_children_with_pagination(tag, :aggregate => true)
113
+ end
114
+
115
+ desc %{
116
+ The pagination tag is not usually called directly. Supply paginated="true" when you display a list and it will
117
+ be automatically display only the current page of results, with pagination controls at the bottom.
118
+
119
+ *Usage:*
120
+
121
+ <pre><code><r:grandchildren:each paginated="true" per_page="50" container="false" previous_label="foo" next_label="bar">
122
+ <r:child>...</r:child>
123
+ </r:grandchildren:each>
124
+ </code></pre>
125
+ }
126
+ tag 'pagination' do |tag|
127
+ if tag.locals.paginated_list
128
+ will_paginate(tag.locals.paginated_list, will_paginate_options(tag))
129
+ end
130
+ end
131
+
132
+ desc %{
133
+ Page attribute tags inside of this tag refer to the current grandchild. This is occasionally
134
+ useful if you are inside of another tag (like &lt;r:find&gt;) and need to refer back to the
135
+ current child.
136
+
137
+ *Usage:*
138
+
139
+ <pre><code><r:grandchildren:each>
140
+ <r:child>...</r:child>
141
+ </r:grandchildren:each>
142
+ </code></pre>
143
+ }
144
+ tag 'grandchildren:each:child' do |tag|
145
+ tag.locals.page = tag.locals.child
146
+ tag.expand
147
+ end
148
+
149
+ desc %{
150
+ Renders the tag contents only if the current page is the first child in the context of
151
+ a grandchildren:each tag
152
+
153
+ *Usage:*
154
+
155
+ <pre><code><r:grandchildren:each>
156
+ <r:if_first >
157
+ ...
158
+ </r:if_first>
159
+ </r:grandchildren:each>
160
+ </code></pre>
161
+
162
+ }
163
+ tag 'grandchildren:each:if_first' do |tag|
164
+ tag.expand if tag.locals.first_child
165
+ end
166
+
167
+
168
+ desc %{
169
+ Renders the tag contents unless the current page is the first child in the context of
170
+ a grandchildren:each tag
171
+
172
+ *Usage:*
173
+
174
+ <pre><code><r:grandchildren:each>
175
+ <r:unless_first >
176
+ ...
177
+ </r:unless_first>
178
+ </r:grandchildren:each>
179
+ </code></pre>
180
+
181
+ }
182
+ tag 'grandchildren:each:unless_first' do |tag|
183
+ tag.expand unless tag.locals.first_child
184
+ end
185
+
186
+ desc %{
187
+ Renders the tag contents only if the current page is the last child in the context of
188
+ a grandchildren:each tag
189
+
190
+ *Usage:*
191
+
192
+ <pre><code><r:grandchildren:each>
193
+ <r:if_last >
194
+ ...
195
+ </r:if_last>
196
+ </r:grandchildren:each>
197
+ </code></pre>
198
+
199
+ }
200
+ tag 'grandchildren:each:if_last' do |tag|
201
+ tag.expand if tag.locals.last_child
202
+ end
203
+
204
+
205
+ desc %{
206
+ Renders the tag contents unless the current page is the last child in the context of
207
+ a grandchildren:each tag
208
+
209
+ *Usage:*
210
+
211
+ <pre><code><r:grandchildren:each>
212
+ <r:unless_last >
213
+ ...
214
+ </r:unless_last>
215
+ </r:grandchildren:each>
216
+ </code></pre>
217
+
218
+ }
219
+ tag 'grandchildren:each:unless_last' do |tag|
220
+ tag.expand unless tag.locals.last_child
221
+ end
222
+
223
+ desc %{
224
+ Renders the tag contents only if the contents do not match the previous header. This
225
+ is extremely useful for rendering date headers for a list of child pages.
226
+
227
+ If you would like to use several header blocks you may use the @name@ attribute to
228
+ name the header. When a header is named it will not restart until another header of
229
+ the same name is different.
230
+
231
+ Using the @restart@ attribute you can cause other named headers to restart when the
232
+ present header changes. Simply specify the names of the other headers in a semicolon
233
+ separated list.
234
+
235
+ *Usage:*
236
+
237
+ <pre><code><r:grandchildren:each>
238
+ <r:header [name="header_name"] [restart="name1[;name2;...]"]>
239
+ ...
240
+ </r:header>
241
+ </r:grandchildren:each>
242
+ </code></pre>
243
+ }
244
+ tag 'grandchildren:each:header' do |tag|
245
+ previous_headers = tag.locals.previous_headers
246
+ name = tag.attr['name'] || :unnamed
247
+ restart = (tag.attr['restart'] || '').split(';')
248
+ header = tag.expand
249
+ unless header == previous_headers[name]
250
+ previous_headers[name] = header
251
+ unless restart.empty?
252
+ restart.each do |n|
253
+ previous_headers[n] = nil
254
+ end
255
+ end
256
+ header
257
+ end
258
+ end
259
+
260
+ end
@@ -0,0 +1,2 @@
1
+ module RadiantGrandchildrenTagsExtension
2
+ end
@@ -0,0 +1,3 @@
1
+ module RadiantGrandchildrenTagsExtension
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,55 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :grandchildren_tags do
4
+
5
+ desc "Runs the migration of the Grandchildren Tags extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ GrandchildrenTagsExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ Rake::Task['db:schema:dump'].invoke
11
+ else
12
+ GrandchildrenTagsExtension.migrator.migrate
13
+ Rake::Task['db:schema:dump'].invoke
14
+ end
15
+ end
16
+
17
+ desc "Copies public assets of the Grandchildren Tags to the instance public/ directory."
18
+ task :update => :environment do
19
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
20
+ puts "Copying assets from GrandchildrenTagsExtension"
21
+ Dir[GrandchildrenTagsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
22
+ path = file.sub(GrandchildrenTagsExtension.root, '')
23
+ directory = File.dirname(path)
24
+ mkdir_p RAILS_ROOT + directory, :verbose => false
25
+ cp file, RAILS_ROOT + path, :verbose => false
26
+ end
27
+ unless GrandchildrenTagsExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
28
+ puts "Copying rake tasks from GrandchildrenTagsExtension"
29
+ local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
30
+ mkdir_p local_tasks_path, :verbose => false
31
+ Dir[File.join GrandchildrenTagsExtension.root, %w(lib tasks *.rake)].each do |file|
32
+ cp file, local_tasks_path, :verbose => false
33
+ end
34
+ end
35
+ end
36
+
37
+ desc "Syncs all available translations for this ext to the English ext master"
38
+ task :sync => :environment do
39
+ # The main translation root, basically where English is kept
40
+ language_root = GrandchildrenTagsExtension.root + "/config/locales"
41
+ words = TranslationSupport.get_translation_keys(language_root)
42
+
43
+ Dir["#{language_root}/*.yml"].each do |filename|
44
+ next if filename.match('_available_tags')
45
+ basename = File.basename(filename, '.yml')
46
+ puts "Syncing #{basename}"
47
+ (comments, other) = TranslationSupport.read_file(filename, basename)
48
+ words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
49
+ other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
50
+ TranslationSupport.write_file(filename, basename, comments, other)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "radiant-grandchildren_tags-extension/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "radiant-grandchildren_tags-extension"
7
+ s.version = RadiantGrandchildrenTagsExtension::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Benny Degezelle"]
10
+ s.email = ["benny@gorilla-webdesign.be"]
11
+ s.homepage = "http://github.com/jomz/radiant-grandchildren_tags-extension"
12
+ s.summary = %q{Grandchildren Tags for Radiant CMS}
13
+ s.description = %q{Makes Radiant better by adding grandchildren_tags!}
14
+
15
+ ignores = if File.exist?('.gitignore')
16
+ File.read('.gitignore').split("\n").inject([]) {|a,p| a + Dir[p] }
17
+ else
18
+ []
19
+ end
20
+ s.files = Dir['**/*'] - ignores
21
+ s.test_files = Dir['test/**/*','spec/**/*','features/**/*'] - ignores
22
+ # s.executables = Dir['bin/*'] - ignores
23
+ s.require_paths = ["lib"]
24
+
25
+ s.post_install_message = %{
26
+ Add this to your radiant project with:
27
+ config.gem 'radiant-grandchildren_tags-extension', :version => '~>#{RadiantGrandchildrenTagsExtension::VERSION}'
28
+ }
29
+ end
@@ -0,0 +1,35 @@
1
+ class GrandchildrenDataset < Dataset::Base
2
+ uses :home_page, :pages
3
+
4
+ helpers do
5
+ describe "Archive index page", :shared => true do
6
+ it "should render <r:archive:children:first /> as unimplemented" do
7
+ @page.should render('<r:archive:children:first><r:slug /></r:archive:children:first>').as('unimplemented')
8
+ end
9
+
10
+ it "should render <r:archive:children:last /> as unimplemented" do
11
+ @page.should render('<r:archive:children:last><r:slug /></r:archive:children:last>').as('unimplemented')
12
+ end
13
+
14
+ it "should <r:archive:children:count /> as unimplemented" do
15
+ @page.should render('<r:archive:children:count><r:slug /></r:archive:children:count>').as('unimplemented')
16
+ end
17
+
18
+ it "should render the <r:archive:year /> tag" do
19
+ @page.should render("<r:archive:year />").as("2000").on("/archive/2000/")
20
+ end
21
+
22
+ it "should render the <r:archive:month /> tag" do
23
+ @page.should render("<r:archive:month />").as("June").on("/archive/2000/06/")
24
+ end
25
+
26
+ it "should render the <r:archive:day /> tag" do
27
+ @page.should render('<r:archive:day />').as("9").on('/archive/2000/06/09/')
28
+ end
29
+
30
+ it "should render the <r:archive:day_of_week /> tag" do
31
+ @page.should render('<r:archive:day_of_week />').as('Friday').on("/archive/2000/06/09/")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,253 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "Grandchildren Tags" do
4
+ dataset :home_page, :users_and_pages
5
+
6
+ it '<r:if_grandchildren> should render the contained block if the current page has child pages' do
7
+ pages(:home).should render('<r:if_grandchildren>true</r:if_grandchildren>').as('true')
8
+ pages(:childless).should render('<r:if_grandchildren>true</r:if_grandchildren>').as('')
9
+ end
10
+
11
+ it '<r:unless_grandchildren> should render the contained block if the current page has no child pages' do
12
+ pages(:home).should render('<r:unless_grandchildren>true</r:unless_grandchildren>').as('')
13
+ pages(:childless).should render('<r:unless_grandchildren>true</r:unless_grandchildren>').as('true')
14
+ end
15
+
16
+ describe "<r:grandchildren:each>" do
17
+ it "should iterate through the grandchildren of the current page" do
18
+ pages(:parent).should render('<r:grandchildren:each:title />').as('Grandchild')
19
+ pages(:parent).should render('<r:grandchildren:each><r:parent:slug />/<r:slug /></r:grandchildren:each>').as('child/grandchild')
20
+ end
21
+
22
+ it 'should not list draft pages' do
23
+ pages(:home).should render(page_grandchildren_each_tags(%{by="title"})).as('a article article-2 article-3 article-4 b c child child-2 child-3 d e f g guests h i j ')
24
+ end
25
+
26
+ it 'should include draft pages with status="all"' do
27
+ pages(:home).should render(page_grandchildren_each_tags(%{status="all" by="slug"})).as('a article article-2 article-3 article-4 b c child child-2 child-3 d draft draft-article e f g guests h i j ')
28
+ end
29
+
30
+ it "should include draft pages by default on the dev host" do
31
+ pages(:home).should render(page_grandchildren_each_tags(%{by="slug"})).as('a article article-2 article-3 article-4 b c child child-2 child-3 d draft draft-article e f g guests h i j ').on('dev.site.com')
32
+ end
33
+
34
+ it 'should not list draft pages on dev.site.com when Radiant::Config["dev.host"] is set to something else' do
35
+ Radiant::Config['dev.host'] = 'preview.site.com'
36
+ pages(:home).should render(page_grandchildren_each_tags(%{by="title"})).as('a article article-2 article-3 article-4 b c child child-2 child-3 d e f g guests h i j ').on('dev.site.com')
37
+ end
38
+
39
+ describe 'with paginated="true"' do
40
+ it 'should limit correctly the result set' do
41
+ page(:home)
42
+ page.pagination_parameters = {:page => 1, :per_page => 20}
43
+ page.should render(page_grandchildren_each_tags(%{paginated="true"})).as('article article-2 article-3 article-4 a b c d e f g h i j child child-3 child-2 guests ')
44
+ page.should render(page_grandchildren_each_tags(%{paginated="true" per_page="2"})).not_matching(/article article-2 article-3/)
45
+ end
46
+ it 'should display a pagination control block' do
47
+ page(:home)
48
+ page.pagination_parameters = {:page => 1, :per_page => 1}
49
+ page.should render(page_grandchildren_each_tags(%{ paginated="true"})).matching(/div class="pagination"/)
50
+ end
51
+ it 'should link to the correct paginated page' do
52
+ page(:home)
53
+ page.pagination_parameters = {:page => 1, :per_page => 1}
54
+ page.should render('<r:find path="/"><r:grandchildren:each paginated="true"><r:slug /> </r:grandchildren:each></r:find>').matching(%r{href="/\?page=2})
55
+ end
56
+ it 'should pass through selected will_paginate parameters' do
57
+ page(:home)
58
+ page.pagination_parameters = {:page => 5, :per_page => 1}
59
+ page.should render(page_grandchildren_each_tags(%{ paginated="true" separator="not that likely a choice"})).matching(/not that likely a choice/)
60
+ page.should render(page_grandchildren_each_tags(%{ paginated="true" previous_label="before"})).matching(/before/)
61
+ page.should render(page_grandchildren_each_tags(%{ paginated="true" next_label="after"})).matching(/after/)
62
+ page.should render(page_grandchildren_each_tags(%{ paginated="true" inner_window="1" outer_window="0"})).not_matching(/\?p=2/)
63
+ end
64
+ end
65
+
66
+ it 'should error with invalid "limit" attribute' do
67
+ message = "`limit' attribute must be a positive number"
68
+ pages(:home).should render(page_grandchildren_each_tags(%{limit="a"})).with_error(message)
69
+ pages(:home).should render(page_grandchildren_each_tags(%{limit="-10"})).with_error(message)
70
+ end
71
+
72
+ it 'should error with invalid "offset" attribute' do
73
+ message = "`offset' attribute must be a positive number"
74
+ pages(:home).should render(page_grandchildren_each_tags(%{offset="a"})).with_error(message)
75
+ pages(:home).should render(page_grandchildren_each_tags(%{offset="-10"})).with_error(message)
76
+ end
77
+
78
+ it 'should error with invalid "by" attribute' do
79
+ message = "`by' attribute of `each' tag must be set to a valid field name"
80
+ pages(:home).should render(page_grandchildren_each_tags(%{by="non-existant-field"})).with_error(message)
81
+ end
82
+
83
+ it 'should error with invalid "order" attribute' do
84
+ message = %{`order' attribute of `each' tag must be set to either "asc" or "desc"}
85
+ pages(:home).should render(page_grandchildren_each_tags(%{order="asdf"})).with_error(message)
86
+ end
87
+
88
+ it "should limit the number of children when given a 'limit' attribute" do
89
+ pages(:home).should render(page_grandchildren_each_tags(%{limit="5"})).as('article article-2 article-3 article-4 a ')
90
+ end
91
+
92
+ it "should limit and offset the children when given 'limit' and 'offset' attributes" do
93
+ pages(:home).should render(page_grandchildren_each_tags(%{offset="3" limit="5"})).as('article-4 a b c d ')
94
+ end
95
+
96
+ it "should sort by the 'by' attribute" do
97
+ pages(:home).should render(page_grandchildren_each_tags(%{by="breadcrumb"})).as('f article article-2 article-3 article-4 e d child child-2 child-3 c b a j guests i h g ')
98
+ end
99
+
100
+ it "should sort by the 'by' attribute according to the 'order' attribute" do
101
+ pages(:home).should render(page_grandchildren_each_tags(%{by="breadcrumb" order="desc"})).as('g h i guests j a b c child-3 child-2 child d e article-4 article-3 article-2 article f ')
102
+ end
103
+
104
+ describe 'with "status" attribute' do
105
+ it "set to 'draft' should list only children with 'draft' status" do
106
+ pages(:home).should render(page_grandchildren_each_tags(%{status="draft"})).as('draft draft-article ')
107
+ end
108
+
109
+ it "set to 'published' should list only children with 'draft' status" do
110
+ pages(:home).should render(page_grandchildren_each_tags(%{status="published"})).as('article article-2 article-3 article-4 a b c d e f g h i j child child-3 child-2 guests ')
111
+ end
112
+
113
+ it "set to an invalid status should render an error" do
114
+ pages(:home).should render(page_grandchildren_each_tags(%{status="askdf"})).with_error("`status' attribute of `each' tag must be set to a valid status")
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "<r:grandchildren:each:if_first>" do
120
+ it "should render for the first child" do
121
+ tags = '<r:grandchildren:each><r:if_first>FIRST:</r:if_first><r:slug /> </r:grandchildren:each>'
122
+ expected = "FIRST:article article-2 article-3 article-4 a b c d e f g h i j child child-3 child-2 guests "
123
+ page(:home).should render(tags).as(expected)
124
+ end
125
+ end
126
+
127
+ describe "<r:grandchildren:each:unless_first>" do
128
+ it "should render for all but the first child" do
129
+ tags = '<r:grandchildren:each><r:unless_first>NOT-FIRST:</r:unless_first><r:slug /> </r:grandchildren:each>'
130
+ expected = "article NOT-FIRST:article-2 NOT-FIRST:article-3 NOT-FIRST:article-4 NOT-FIRST:a NOT-FIRST:b NOT-FIRST:c NOT-FIRST:d NOT-FIRST:e NOT-FIRST:f NOT-FIRST:g NOT-FIRST:h NOT-FIRST:i NOT-FIRST:j NOT-FIRST:child NOT-FIRST:child-3 NOT-FIRST:child-2 NOT-FIRST:guests "
131
+ page(:home).should render(tags).as(expected)
132
+ end
133
+ end
134
+
135
+ describe "<r:grandchildren:each:if_last>" do
136
+ it "should render for the last child" do
137
+ tags = '<r:grandchildren:each><r:if_last>LAST:</r:if_last><r:slug /> </r:grandchildren:each>'
138
+ expected = "article article-2 article-3 article-4 a b c d e f g h i j child child-3 child-2 LAST:guests "
139
+ page(:home).should render(tags).as(expected)
140
+ end
141
+ end
142
+
143
+ describe "<r:grandchildren:each:unless_last>" do
144
+ it "should render for all but the last child" do
145
+ tags = '<r:grandchildren:each><r:unless_last>NOT-LAST:</r:unless_last><r:slug /> </r:grandchildren:each>'
146
+ expected = "NOT-LAST:article NOT-LAST:article-2 NOT-LAST:article-3 NOT-LAST:article-4 NOT-LAST:a NOT-LAST:b NOT-LAST:c NOT-LAST:d NOT-LAST:e NOT-LAST:f NOT-LAST:g NOT-LAST:h NOT-LAST:i NOT-LAST:j NOT-LAST:child NOT-LAST:child-3 NOT-LAST:child-2 guests "
147
+ page(:home).should render(tags).as(expected)
148
+ end
149
+ end
150
+
151
+ describe "<r:grandchildren:each:header>" do
152
+ it "should render the header when it changes" do
153
+ tags = '<r:grandchildren:each><r:header>[<r:date format="%b/%y" />] </r:header><r:slug /> </r:grandchildren:each>'
154
+ expected = "[Dec/00] article [Feb/01] article-2 article-3 [Mar/01] article-4 [Jun/11] a b c d e f g h i j child child-3 child-2 guests "
155
+ page(:home).should render(tags).as(expected)
156
+ end
157
+
158
+ it 'with "name" attribute should maintain a separate header' do
159
+ tags = %{<r:grandchildren:each><r:header name="year">[<r:date format='%Y' />] </r:header><r:header name="month">(<r:date format="%b" />) </r:header><r:slug /> </r:grandchildren:each>}
160
+ expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 [2011] (Jun) a b c d e f g h i j child child-3 child-2 guests "
161
+ page(:home).should render(tags).as(expected)
162
+ end
163
+
164
+ it 'with "restart" attribute set to one name should restart that header' do
165
+ tags = %{<r:grandchildren:each><r:header name="year" restart="month">[<r:date format='%Y' />] </r:header><r:header name="month">(<r:date format="%b" />) </r:header><r:slug /> </r:grandchildren:each>}
166
+ expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 [2011] (Jun) a b c d e f g h i j child child-3 child-2 guests "
167
+ page(:home).should render(tags).as(expected)
168
+ end
169
+
170
+ it 'with "restart" attribute set to two names should restart both headers' do
171
+ tags = %{<r:grandchildren:each><r:header name="year" restart="month;day">[<r:date format='%Y' />] </r:header><r:header name="month" restart="day">(<r:date format="%b" />) </r:header><r:header name="day"><<r:date format='%d' />> </r:header><r:slug /> </r:grandchildren:each>}
172
+ expected = "[2000] (Dec) <01> article [2001] (Feb) <09> article-2 <24> article-3 (Mar) <06> article-4 [2011] (Jun) <05> a b c d e f g h i j child child-3 child-2 guests "
173
+ page(:home).should render(tags).as(expected)
174
+ end
175
+ end
176
+
177
+ describe "<r:grandchildren:count>" do
178
+ it 'should render the number of grandchildren of the current page' do
179
+ page(:home).should render('<r:grandchildren:count />').as('18')
180
+ end
181
+
182
+ it "should accept the same scoping conditions as <r:children:each>" do
183
+ page(:home).should render('<r:grandchildren:count status="all" />').as('20')
184
+ page(:home).should render('<r:grandchildren:count status="draft" />').as('2')
185
+ page(:home).should render('<r:grandchildren:count status="hidden" />').as('0')
186
+ end
187
+ end
188
+
189
+ describe "<r:grandchildren:first>" do
190
+ it 'should render its contents in the context of the first grandchild page' do
191
+ page(:parent).should render('<r:grandchildren:first:title />').as('Grandchild')
192
+ end
193
+
194
+ it 'should accept the same scoping attributes as <r:children:each>' do
195
+ page(:home)
196
+ page.should render(page_grandchildren_first_tags).as('article')
197
+ page.should render(page_grandchildren_first_tags(%{limit="5"})).as('article')
198
+ page.should render(page_grandchildren_first_tags(%{offset="3" limit="5"})).as('article-4')
199
+ page.should render(page_grandchildren_first_tags(%{order="desc" by="published_at"})).as('guests')
200
+ page.should render(page_grandchildren_first_tags(%{by="breadcrumb"})).as('f')
201
+ page.should render(page_grandchildren_first_tags(%{by="breadcrumb" order="desc"})).as('g')
202
+ end
203
+
204
+ it "should render nothing when no children exist" do
205
+ page(:first).should render('<r:grandchildren:first:title />').as('')
206
+ end
207
+ end
208
+
209
+ describe "<r:grandchildren:last>" do
210
+ it 'should render its contents in the context of the last child page' do
211
+ pages(:home).should render('<r:grandchildren:last:title />').as('Guests')
212
+ end
213
+
214
+ it 'should accept the same scoping attributes as <r:children:each>' do
215
+ page(:home)
216
+ page.should render(page_grandchildren_last_tags).as('guests')
217
+ page.should render(page_grandchildren_last_tags(%{limit="5"})).as('a')
218
+ page.should render(page_grandchildren_last_tags(%{offset="3" limit="5"})).as('d')
219
+ page.should render(page_grandchildren_last_tags(%{order="desc" by="published_at"})).as('article')
220
+ page.should render(page_grandchildren_last_tags(%{by="breadcrumb"})).as('g')
221
+ page.should render(page_grandchildren_last_tags(%{by="breadcrumb" order="desc"})).as('f')
222
+ end
223
+
224
+ it "should render nothing when no grandchildren exist" do
225
+ page(:first).should render('<r:grandchildren:last:title />').as('')
226
+ end
227
+ end
228
+
229
+ private
230
+
231
+ def page(symbol = nil)
232
+ if symbol.nil?
233
+ @page ||= pages(:assorted)
234
+ else
235
+ @page = pages(symbol)
236
+ end
237
+ end
238
+
239
+ def page_grandchildren_each_tags(attr = nil)
240
+ attr = ' ' + attr unless attr.nil?
241
+ "<r:grandchildren:each#{attr}><r:slug /> </r:grandchildren:each>"
242
+ end
243
+
244
+ def page_grandchildren_first_tags(attr = nil)
245
+ attr = ' ' + attr unless attr.nil?
246
+ "<r:grandchildren:first#{attr}><r:slug /></r:grandchildren:first>"
247
+ end
248
+
249
+ def page_grandchildren_last_tags(attr = nil)
250
+ attr = ' ' + attr unless attr.nil?
251
+ "<r:grandchildren:last#{attr}><r:slug /></r:grandchildren:last>"
252
+ end
253
+ end
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,36 @@
1
+ unless defined? RADIANT_ROOT
2
+ ENV["RAILS_ENV"] = "test"
3
+ case
4
+ when ENV["RADIANT_ENV_FILE"]
5
+ require ENV["RADIANT_ENV_FILE"]
6
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
7
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
8
+ else
9
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
10
+ end
11
+ end
12
+ require "#{RADIANT_ROOT}/spec/spec_helper"
13
+
14
+ Dataset::Resolver.default << (File.dirname(__FILE__) + "/datasets")
15
+
16
+ if File.directory?(File.dirname(__FILE__) + "/matchers")
17
+ Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
18
+ end
19
+
20
+ Spec::Runner.configure do |config|
21
+ # config.use_transactional_fixtures = true
22
+ # config.use_instantiated_fixtures = false
23
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
24
+
25
+ # You can declare fixtures for each behaviour like this:
26
+ # describe "...." do
27
+ # fixtures :table_a, :table_b
28
+ #
29
+ # Alternatively, if you prefer to declare them only once, you can
30
+ # do so here, like so ...
31
+ #
32
+ # config.global_fixtures = :table_a, :table_b
33
+ #
34
+ # If you declare global fixtures, be aware that they will be declared
35
+ # for all of your examples, even those that don't use them.
36
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-grandchildren_tags-extension
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Benny Degezelle
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-06-05 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Makes Radiant better by adding grandchildren_tags!
23
+ email:
24
+ - benny@gorilla-webdesign.be
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - config/locales/en.yml
33
+ - cucumber.yml
34
+ - grandchildren_tags_extension.rb
35
+ - lib/grandchildren_tags.rb
36
+ - lib/radiant-grandchildren_tags-extension/version.rb
37
+ - lib/radiant-grandchildren_tags-extension.rb
38
+ - lib/tasks/grandchildren_tags_extension_tasks.rake
39
+ - radiant-grandchildren_tags-extension.gemspec
40
+ - Rakefile
41
+ - README.md
42
+ - spec/datasets/grandchildren_dataset.rb
43
+ - spec/models/grandchildren_tags_spec.rb
44
+ - spec/spec.opts
45
+ - spec/spec_helper.rb
46
+ has_rdoc: true
47
+ homepage: http://github.com/jomz/radiant-grandchildren_tags-extension
48
+ licenses: []
49
+
50
+ post_install_message: "\n Add this to your radiant project with:\n config.gem 'radiant-grandchildren_tags-extension', :version => '~>1.0.0'\n "
51
+ rdoc_options: []
52
+
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ requirements: []
74
+
75
+ rubyforge_project:
76
+ rubygems_version: 1.3.7
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: Grandchildren Tags for Radiant CMS
80
+ test_files:
81
+ - spec/datasets/grandchildren_dataset.rb
82
+ - spec/models/grandchildren_tags_spec.rb
83
+ - spec/spec.opts
84
+ - spec/spec_helper.rb