radiant-sibling_tags-extension 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +152 -0
- data/Rakefile +128 -0
- data/app/models/sibling_tags.rb +223 -0
- data/lib/radiant-sibling-tags-extension.rb +5 -0
- data/lib/radiant-sibling_tags-extension/version.rb +3 -0
- data/lib/tasks/sibling_tags_extension_tasks.rake +28 -0
- data/radiant-sibling_tags-extension.gemspec +23 -0
- data/sibling_tags_extension.rb +15 -0
- data/spec/models/sibling_tags_spec.rb +170 -0
- data/spec/scenarios/sibling_pages_scenario.rb +27 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +37 -0
- metadata +87 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
Sibling Tags
|
2
|
+
============
|
3
|
+
|
4
|
+
This extension for Radiant provides tags allowing you to refer to the neighbouring siblings of a page.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
If your Radiant site is running on version 0.6.9 or greater, you can install extensions very easily. If you are using an
|
10
|
+
older version of Radiant, don't worry, it is still quite straightforward. Instructions follow for both.
|
11
|
+
|
12
|
+
|
13
|
+
### Installing for Radiant 1.0
|
14
|
+
|
15
|
+
In a terminal, `cd` to the root directory of your Radiant site.
|
16
|
+
|
17
|
+
Add the following line to your Gemfile
|
18
|
+
|
19
|
+
gem 'radiant-sibling-tags-extension'
|
20
|
+
|
21
|
+
Run
|
22
|
+
|
23
|
+
bundle install
|
24
|
+
|
25
|
+
### Installing for Radiant 0.6.9+
|
26
|
+
|
27
|
+
In a terminal, `cd` to the root directory of your Radiant site. Run the following command:
|
28
|
+
|
29
|
+
script/extension install sibling_tags
|
30
|
+
|
31
|
+
That's it!
|
32
|
+
|
33
|
+
### Installing for Radiant pre-0.6.9
|
34
|
+
|
35
|
+
This extension is hosted on github. If you have git installed, then `cd` to the root of your radiant project and
|
36
|
+
issue this command:
|
37
|
+
|
38
|
+
git clone git://github.com/nelstrom/radiant-sibling-tags-extension.git vendor/extensions/sibling_tags
|
39
|
+
|
40
|
+
If you don’t have git, then you can instead download the tarball from this URL:
|
41
|
+
|
42
|
+
http://github.com/nelstrom/radiant-sibling-tags-extension/tarball/master
|
43
|
+
|
44
|
+
and expand the contents to `your-radiant-project/vendor/extensions/sibling_tags`.
|
45
|
+
|
46
|
+
This extension does not modify the database, so there is no need to run any migrations. Your done!
|
47
|
+
|
48
|
+
Usage
|
49
|
+
-----
|
50
|
+
|
51
|
+
When you restart you Radiant site, you should have access to the sibling tags in regular pages of your site.
|
52
|
+
Documentation for each individual tag is provided within Radiant. If you go to edit a page, then click the '<b>Available
|
53
|
+
tags</b>' link, you should see a list of all the available tags. You can filter the list, by typing 'sibling' into the
|
54
|
+
field at the top right of the window.
|
55
|
+
|
56
|
+
For examples of usage, we'll use the following site map:
|
57
|
+
|
58
|
+
Title Date of Publication
|
59
|
+
---------------- -------------------
|
60
|
+
Home
|
61
|
+
\_Articles
|
62
|
+
\_Apple 2008-02-29
|
63
|
+
\_Brocolli 2007-12-17
|
64
|
+
\_Carrot 2008-01-25
|
65
|
+
|
66
|
+
Using the sibling tags, you can access immediate neighbours of a page. But which pages are considered neighbours depends
|
67
|
+
upon how you shuffle the deck! You can sort pages by any field that is stored in the database. Most likely you will want
|
68
|
+
to sort by date of publication, or by page title. These could also be arranged in ascending or descending order.
|
69
|
+
|
70
|
+
By default, pages are sorted in ascending order of publication, i.e. from oldest to newest. The children of 'Articles'
|
71
|
+
in the above site map would be arranged as follows:
|
72
|
+
|
73
|
+
Default order: Brocolli, Carrot, Apple
|
74
|
+
|
75
|
+
Lets examine the following snippet of code:
|
76
|
+
|
77
|
+
<r:siblings>
|
78
|
+
<r:previous>Previous article: <r:link/></r:previous>
|
79
|
+
<r:next>Next article: <r:link/></r:next>
|
80
|
+
</r:siblings>
|
81
|
+
|
82
|
+
If this was called on the 'Carrot' page, it would output:
|
83
|
+
|
84
|
+
Previous article: <a href="/articles/brocolli">Brocolli</a>
|
85
|
+
Next article: <a href="/articles/apple">Apple</a>
|
86
|
+
|
87
|
+
Whereas, if the same snippet was called from the 'Brocolli' page, it would output:
|
88
|
+
|
89
|
+
Next article: <a href="/articles/carrot">Carrot</a>
|
90
|
+
|
91
|
+
When arranged in the default sort order, 'Brocolli' comes first, so it has no predecessor. Hence, the contents of the
|
92
|
+
`<r:siblings:previous></r:siblings:previous>` tag are not output.
|
93
|
+
|
94
|
+
You can change the sort order using the `order` and `by` attributes. `order` can either be
|
95
|
+
`asc` or `desc`, whereas `by` can be any column name associated with a page in the database.
|
96
|
+
|
97
|
+
The following lists demonstrate how the 'Articles' pages above could be sorted:
|
98
|
+
|
99
|
+
order="desc": Apple, Carrot, Brocolli
|
100
|
+
by="title": Apple, Brocolli, Carrot
|
101
|
+
by="title" order="desc": Carrot, Brocolli, Apple
|
102
|
+
|
103
|
+
Remember that the default values are `order="asc"` and `by="published_at"`, so if either of these are not
|
104
|
+
specified, they fall back to those values.
|
105
|
+
|
106
|
+
This example demonstrates how these sorting options may be applied:
|
107
|
+
|
108
|
+
<r:siblings by="title">
|
109
|
+
<r:previous>Previous in alphabet:<r:link/></r:previous>
|
110
|
+
<r:unless_previous>This is the start of the alphabet.</r:unless_previous>
|
111
|
+
<r:next>Next in alphabet: <r:link/></r:next>
|
112
|
+
<r:unless_next>This is the end of the alphabet.</r:unless_next>
|
113
|
+
</r:siblings>
|
114
|
+
|
115
|
+
Where do the conditions go?
|
116
|
+
---------------------------
|
117
|
+
|
118
|
+
You can specify `order` and `by` attributes inside of the `<r:siblings/>` tag itself, and these conditions are inherited by the child tags. The following examples are equivalent:
|
119
|
+
|
120
|
+
<r:siblings>
|
121
|
+
<r:previous by="title"><r:link/></r:previous>
|
122
|
+
<r:next by="title"><r:link/></r:next>
|
123
|
+
</r:siblings>
|
124
|
+
|
125
|
+
<r:siblings by="title">
|
126
|
+
<r:previous><r:link/></r:previous>
|
127
|
+
<r:next><r:link/></r:next>
|
128
|
+
</r:siblings>
|
129
|
+
|
130
|
+
By placing the `by` attribute in the `<r:siblings/>` tag, we can save on repetition. If you are planning on using both `<r:previous/>` and `<r:next/>` tags, then the second example is neater. However, if you just want to fetch one of the two, then you don't even have to nest the tags within a `<r:siblings/>` tag. Just make sure that you specify the full namespace at once, e.g.:
|
131
|
+
|
132
|
+
<r:siblings:previous by="title"><r:link/></r:siblings:previous>
|
133
|
+
|
134
|
+
<r:siblings:next by="title"><r:link/></r:siblings:next>
|
135
|
+
|
136
|
+
When you specify conditions in the `<r:siblings/>` tag, they are inherited by nested tags, but they may also be overridden. E.g.:
|
137
|
+
|
138
|
+
<r:siblings by="title" order="asc">
|
139
|
+
<r:next>Next alphabetically: <r:link/></r:next>
|
140
|
+
<r:previous>Previous alphabetically: <r:link/></r:previous>
|
141
|
+
|
142
|
+
<r:next by="published_at">Next chronologically</r:next>
|
143
|
+
<r:previous by="published_at">Previous chronologically</r:previous>
|
144
|
+
</r:siblings>
|
145
|
+
|
146
|
+
In this example, the first usage of `<r:next/>` and `<r:previous/>` inherit the attributes set in `<r:siblings/>`. The second time these same tags are used, they provide their own attributes, and these override the values set by the parent `<r:siblings/>` tag.
|
147
|
+
|
148
|
+
|
149
|
+
Credits
|
150
|
+
-------
|
151
|
+
|
152
|
+
Jim Gay created the `siblings:each`, `each_before` and `each_after` tags.
|
data/Rakefile
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
|
4
|
+
# I think this is the one that should be moved to the extension Rakefile template
|
5
|
+
|
6
|
+
# In rails 1.2, plugins aren't available in the path until they're loaded.
|
7
|
+
# Check to see if the rspec plugin is installed first and require
|
8
|
+
# it if it is. If not, use the gem version.
|
9
|
+
|
10
|
+
# Determine where the RSpec plugin is by loading the boot
|
11
|
+
unless defined? RADIANT_ROOT
|
12
|
+
ENV["RAILS_ENV"] = "test"
|
13
|
+
boot = if ENV["RADIANT_ENV_FILE"]
|
14
|
+
File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
|
15
|
+
elsif File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
|
16
|
+
"#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
|
17
|
+
else
|
18
|
+
"#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
|
19
|
+
end
|
20
|
+
begin
|
21
|
+
require boot
|
22
|
+
rescue LoadError => e
|
23
|
+
warn "Can’t boot radiant, #{e.message}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'rake'
|
28
|
+
require 'rake/rdoctask'
|
29
|
+
require 'rake/testtask'
|
30
|
+
|
31
|
+
if defined? RADIANT_ROOT
|
32
|
+
rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
|
33
|
+
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
|
34
|
+
# Cleanup the RADIANT_ROOT constant so specs will load the environment
|
35
|
+
Object.send(:remove_const, :RADIANT_ROOT)
|
36
|
+
end
|
37
|
+
require 'spec/rake/spectask'
|
38
|
+
# require 'spec/translator'
|
39
|
+
|
40
|
+
extension_root = File.expand_path(File.dirname(__FILE__))
|
41
|
+
|
42
|
+
task :default => :spec
|
43
|
+
task :stats => "spec:statsetup"
|
44
|
+
|
45
|
+
desc "Run all specs in spec directory"
|
46
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
47
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
48
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
49
|
+
end
|
50
|
+
|
51
|
+
namespace :spec do
|
52
|
+
desc "Run all specs in spec directory with RCov"
|
53
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
54
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
55
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
56
|
+
t.rcov = true
|
57
|
+
t.rcov_opts = ['--exclude', 'spec', '--rails']
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Print Specdoc for all specs"
|
61
|
+
Spec::Rake::SpecTask.new(:doc) do |t|
|
62
|
+
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
63
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
64
|
+
end
|
65
|
+
|
66
|
+
[:models, :controllers, :views, :helpers].each do |sub|
|
67
|
+
desc "Run the specs under spec/#{sub}"
|
68
|
+
Spec::Rake::SpecTask.new(sub) do |t|
|
69
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
70
|
+
t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Hopefully no one has written their extensions in pre-0.9 style
|
75
|
+
# desc "Translate specs from pre-0.9 to 0.9 style"
|
76
|
+
# task :translate do
|
77
|
+
# translator = ::Spec::Translator.new
|
78
|
+
# dir = RAILS_ROOT + '/spec'
|
79
|
+
# translator.translate(dir, dir)
|
80
|
+
# end
|
81
|
+
|
82
|
+
# Setup specs for stats
|
83
|
+
task :statsetup do
|
84
|
+
require 'code_statistics'
|
85
|
+
::STATS_DIRECTORIES << %w(Model\ specs spec/models)
|
86
|
+
::STATS_DIRECTORIES << %w(View\ specs spec/views)
|
87
|
+
::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
|
88
|
+
::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
|
89
|
+
::CodeStatistics::TEST_TYPES << "Model specs"
|
90
|
+
::CodeStatistics::TEST_TYPES << "View specs"
|
91
|
+
::CodeStatistics::TEST_TYPES << "Controller specs"
|
92
|
+
::CodeStatistics::TEST_TYPES << "Helper specs"
|
93
|
+
::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
|
94
|
+
end
|
95
|
+
|
96
|
+
namespace :db do
|
97
|
+
namespace :fixtures do
|
98
|
+
desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
99
|
+
task :load => :environment do
|
100
|
+
require 'active_record/fixtures'
|
101
|
+
ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
|
102
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
103
|
+
Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
desc 'Generate documentation for the sibling_tags extension.'
|
111
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
112
|
+
rdoc.rdoc_dir = 'rdoc'
|
113
|
+
rdoc.title = 'SiblingTagsExtension'
|
114
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
115
|
+
rdoc.rdoc_files.include('README')
|
116
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
117
|
+
end
|
118
|
+
|
119
|
+
# For extensions that are in transition
|
120
|
+
desc 'Test the sibling_tags extension.'
|
121
|
+
Rake::TestTask.new(:test) do |t|
|
122
|
+
t.libs << 'lib'
|
123
|
+
t.pattern = 'test/**/*_test.rb'
|
124
|
+
t.verbose = true
|
125
|
+
end
|
126
|
+
|
127
|
+
# Load any custom rakefiles for extension
|
128
|
+
Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module SiblingTags
|
2
|
+
include Radiant::Taggable
|
3
|
+
|
4
|
+
desc %{
|
5
|
+
Set's the scope for a page's siblings.
|
6
|
+
|
7
|
+
The order in which siblings are sorted can be manipulated using all the same attributes
|
8
|
+
as the @<r:children:each/>@ tag. If no attributes are supplied, the siblings will
|
9
|
+
have order = "published_at ASC". The @by@ attribute allows you to order by any page
|
10
|
+
properties stored in the database, the most likely of these to be useful are
|
11
|
+
@published_at@ and @title@.
|
12
|
+
|
13
|
+
Values set in the @<r:siblings/>@ tag will be inherited by tags nested within,
|
14
|
+
but may also be overridden in the child tags.
|
15
|
+
|
16
|
+
*Usage:*
|
17
|
+
<pre><code><r:siblings [by="published_at|title"] [order="asc|desc"] [status="published|all"]/>
|
18
|
+
<r:next><r:link/></r:next>
|
19
|
+
<r:previous><r:link/></r:previous>
|
20
|
+
</r:siblings></code></pre>
|
21
|
+
}
|
22
|
+
tag 'siblings' do |tag|
|
23
|
+
tag.locals.filter_attributes = tag.attr || {}
|
24
|
+
tag.expand
|
25
|
+
end
|
26
|
+
|
27
|
+
desc %{
|
28
|
+
Loops through each sibling and outputs the contents
|
29
|
+
}
|
30
|
+
tag 'siblings:each' do |tag|
|
31
|
+
result = []
|
32
|
+
inherit_filter_attributes(tag)
|
33
|
+
tag.locals.siblings = tag.locals.page.parent.children.find(:all, siblings_find_options(tag))
|
34
|
+
tag.locals.siblings.each do |sib|
|
35
|
+
tag.locals.page = sib
|
36
|
+
result << tag.expand
|
37
|
+
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
desc %{
|
42
|
+
Only renders the contents of this tag if the current page has any published siblings.
|
43
|
+
}
|
44
|
+
tag 'if_siblings' do |tag|
|
45
|
+
if parent = tag.locals.page.parent
|
46
|
+
if parent.children.find(:all, siblings_find_options(tag)).size > 0
|
47
|
+
tag.expand
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
desc %{
|
53
|
+
Only renders the contents of this tag if the current page has no published siblings.
|
54
|
+
}
|
55
|
+
tag 'unless_siblings' do |tag|
|
56
|
+
if !tag.locals.page.parent or tag.locals.page.parent.children.find(:all, siblings_find_options(tag)).size == 0
|
57
|
+
tag.expand
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
desc %{
|
62
|
+
Only render the contents of this tag if the current page has a sibling *after* it, when sorted according to the @order@ and @by@ options.
|
63
|
+
|
64
|
+
See @<siblings/>@ for a more detailed description of the sorting options.
|
65
|
+
}
|
66
|
+
tag 'siblings:if_next' do |tag|
|
67
|
+
inherit_filter_attributes(tag)
|
68
|
+
tag.expand if find_next_sibling(tag)
|
69
|
+
end
|
70
|
+
|
71
|
+
desc %{
|
72
|
+
Only render the contents of this tag if the current page has a sibling *before* it, when sorted according to the @order@ and @by@ options.
|
73
|
+
|
74
|
+
See @<siblings/>@ for a more detailed description of the sorting options.
|
75
|
+
}
|
76
|
+
tag 'siblings:if_previous' do |tag|
|
77
|
+
inherit_filter_attributes(tag)
|
78
|
+
tag.expand if find_previous_sibling(tag)
|
79
|
+
end
|
80
|
+
|
81
|
+
desc %{
|
82
|
+
Only render the contents of this tag if the current page is the last of its siblings, when sorted according to the @order@ and @by@ options.
|
83
|
+
|
84
|
+
See @<siblings/>@ for a more detailed description of the sorting options.
|
85
|
+
}
|
86
|
+
tag 'siblings:unless_next' do |tag|
|
87
|
+
inherit_filter_attributes(tag)
|
88
|
+
tag.expand unless find_next_sibling(tag)
|
89
|
+
end
|
90
|
+
|
91
|
+
desc %{
|
92
|
+
Only render the contents of this tag if the current page is the first of its siblings, when sorted according to the @order@ and @by@ options.
|
93
|
+
|
94
|
+
See @<siblings/>@ for a more detailed description of the sorting options.
|
95
|
+
}
|
96
|
+
tag 'siblings:unless_previous' do |tag|
|
97
|
+
inherit_filter_attributes(tag)
|
98
|
+
tag.expand unless find_previous_sibling(tag)
|
99
|
+
end
|
100
|
+
|
101
|
+
desc %{
|
102
|
+
All Radiant tags within a @<r:siblings:next/>@ block are interpreted in the context
|
103
|
+
of the next sibling page.
|
104
|
+
|
105
|
+
See @<siblings/>@ for a more detailed description of the sorting options.
|
106
|
+
|
107
|
+
*Usage:*
|
108
|
+
<pre><code><r:siblings:next [by="published_at|title"] [order="asc|desc"] [status="published|all"]/>...</r:siblings:next></code></pre>
|
109
|
+
}
|
110
|
+
tag 'siblings:next' do |tag|
|
111
|
+
inherit_filter_attributes(tag)
|
112
|
+
tag.expand if tag.locals.page = find_next_sibling(tag)
|
113
|
+
end
|
114
|
+
|
115
|
+
desc %{
|
116
|
+
Displays its contents for each of the following pages according to the given
|
117
|
+
attributes. See @<siblings>@ for details about the attributes.
|
118
|
+
}
|
119
|
+
tag 'siblings:each_before' do |tag|
|
120
|
+
inherit_filter_attributes(tag)
|
121
|
+
result = []
|
122
|
+
tag.locals.siblings = find_siblings_before(tag)
|
123
|
+
tag.locals.siblings.each do |sib|
|
124
|
+
tag.locals.page = sib
|
125
|
+
result << tag.expand
|
126
|
+
end
|
127
|
+
result
|
128
|
+
end
|
129
|
+
|
130
|
+
desc %{
|
131
|
+
All Radiant tags within a @<r:siblings:previous/>@ block are interpreted in the context
|
132
|
+
of the previous sibling page, when sorted according to the @order@ and @by@ options.
|
133
|
+
|
134
|
+
See @<siblings/>@ for a more detailed description of the sorting options.
|
135
|
+
|
136
|
+
*Usage:*
|
137
|
+
<pre><code><r:siblings:previous [by="published_at|title"] [order="asc|desc"]
|
138
|
+
[status="published|all"]/>...</r:siblings:previous></code></pre>
|
139
|
+
}
|
140
|
+
tag 'siblings:previous' do |tag|
|
141
|
+
inherit_filter_attributes(tag)
|
142
|
+
tag.expand if tag.locals.page = find_previous_sibling(tag)
|
143
|
+
end
|
144
|
+
|
145
|
+
desc %{
|
146
|
+
Displays its contents for each of the following pages according to the given
|
147
|
+
attributes. See @<siblings>@ for details about the attributes.
|
148
|
+
}
|
149
|
+
tag 'siblings:each_after' do |tag|
|
150
|
+
inherit_filter_attributes(tag)
|
151
|
+
result = []
|
152
|
+
tag.locals.siblings = find_siblings_after(tag)
|
153
|
+
tag.locals.siblings.each do |sib|
|
154
|
+
tag.locals.page = sib
|
155
|
+
result << tag.expand
|
156
|
+
end
|
157
|
+
result
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def inherit_filter_attributes(tag)
|
163
|
+
tag.attr ||= {}
|
164
|
+
tag.attr.reverse_merge!(tag.locals.filter_attributes)
|
165
|
+
end
|
166
|
+
|
167
|
+
def find_next_sibling(tag)
|
168
|
+
if tag.locals.page.parent
|
169
|
+
tag.attr['adjacent'] = 'next'
|
170
|
+
tag.locals.page.parent.children.find(:first, adjacent_siblings_find_options(tag))
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def find_siblings_before(tag)
|
175
|
+
if tag.locals.page.parent
|
176
|
+
tag.attr['adjacent'] = 'previous'
|
177
|
+
tag.locals.page.parent.children.find(:all, adjacent_siblings_find_options(tag)).reverse!
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def find_previous_sibling(tag)
|
182
|
+
if tag.locals.page.parent
|
183
|
+
tag.attr['adjacent'] = 'previous'
|
184
|
+
sorted = tag.locals.page.parent.children.find(:all, adjacent_siblings_find_options(tag))
|
185
|
+
sorted.last unless sorted.blank?
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def find_siblings_after(tag)
|
190
|
+
if tag.locals.page.parent
|
191
|
+
tag.attr['adjacent'] = 'next'
|
192
|
+
tag.locals.page.parent.children.find(:all, adjacent_siblings_find_options(tag))
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def adjacent_siblings_find_options(tag)
|
197
|
+
options = siblings_find_options(tag)
|
198
|
+
adjacent_condition = attr_or_error(tag, :attribute_name => 'adjacent', :default => 'next', :values => 'next, previous')
|
199
|
+
attribute_sort = (tag.attr[:by] || tag.attr["by"] || 'published_at').strip
|
200
|
+
attribute_order = attr_or_error(tag, :attribute_name => 'order', :default => 'asc', :values => 'desc, asc')
|
201
|
+
|
202
|
+
find_less_than = " and (#{attribute_sort} < ?)"
|
203
|
+
find_greater_than = " and (#{attribute_sort} > ?)"
|
204
|
+
|
205
|
+
if attribute_order == "asc"
|
206
|
+
adjacent_find_condition = (adjacent_condition == 'previous' ? find_less_than : find_greater_than)
|
207
|
+
else
|
208
|
+
adjacent_find_condition = (adjacent_condition == 'previous' ? find_greater_than : find_less_than)
|
209
|
+
end
|
210
|
+
|
211
|
+
options[:conditions].first << adjacent_find_condition
|
212
|
+
options[:conditions] << tag.locals.page.send(attribute_sort)
|
213
|
+
|
214
|
+
options
|
215
|
+
end
|
216
|
+
|
217
|
+
def siblings_find_options(tag)
|
218
|
+
options = children_find_options(tag)
|
219
|
+
options[:conditions].first << ' and (id != ?)'
|
220
|
+
options[:conditions] << tag.locals.page.id
|
221
|
+
options
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :sibling_tags do
|
4
|
+
|
5
|
+
desc "Runs the migration of the Sibling Tags extension"
|
6
|
+
task :migrate => :environment do
|
7
|
+
require 'radiant/extension_migrator'
|
8
|
+
if ENV["VERSION"]
|
9
|
+
SiblingTagsExtension.migrator.migrate(ENV["VERSION"].to_i)
|
10
|
+
else
|
11
|
+
SiblingTagsExtension.migrator.migrate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Copies public assets of the Sibling Tags to the instance public/ directory."
|
16
|
+
task :update => :environment do
|
17
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
18
|
+
Dir[SiblingTagsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
19
|
+
path = file.sub(SiblingTagsExtension.root, '')
|
20
|
+
directory = File.dirname(path)
|
21
|
+
puts "Copying #{path}..."
|
22
|
+
mkdir_p RAILS_ROOT + directory
|
23
|
+
cp file, RAILS_ROOT + path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require 'radiant-sibling_tags-extension/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'radiant-sibling_tags-extension'
|
7
|
+
s.version = RadiantSiblingTagsExtension::VERSION
|
8
|
+
s.authors = ['Drew Neil']
|
9
|
+
s.email = ['andrew.jr.neil@gmail.com']
|
10
|
+
s.homepage = 'http://github.com/nelstrom/radiant-sibling-tags-extension'
|
11
|
+
s.summary = 'This extension for Radiant provides tags allowing you to refer to the neighbouring siblings of a page'
|
12
|
+
s.description = 'This extension for Radiant provides tags allowing you to refer to the neighbouring siblings of a page'
|
13
|
+
|
14
|
+
s.rubyforge_project = 'radiant-sibling_tags-extension'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_development_dependency 'bundler'
|
22
|
+
s.add_development_dependency 'rspec'
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'radiant-sibling_tags-extension/version'
|
2
|
+
|
3
|
+
class SiblingTagsExtension < Radiant::Extension
|
4
|
+
version RadiantSiblingTagsExtension::VERSION
|
5
|
+
description "Allows you to refer to the current page's previous/next sibling."
|
6
|
+
url "http://github.com/nelstrom/radiant-sibling-tags-extension"
|
7
|
+
|
8
|
+
def activate
|
9
|
+
Page.send :include, SiblingTags
|
10
|
+
end
|
11
|
+
|
12
|
+
def deactivate
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "Sibling Tags" do
|
4
|
+
scenario :sibling_pages
|
5
|
+
|
6
|
+
describe "<r:siblings>" do
|
7
|
+
it "should expand its contents" do
|
8
|
+
page(:sneezy).should render('<r:siblings>true</r:siblings>').as('true')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
describe "<r:siblings:each>" do
|
12
|
+
it "should order the page siblings by published_at" do
|
13
|
+
page(:sneezy).should render('<r:siblings:each><r:title/> </r:siblings:each>').as('Happy Grumpy Dopey Doc Bashful ')
|
14
|
+
end
|
15
|
+
it "should allow siblings to be ordered by the 'by' attribute" do
|
16
|
+
page(:sneezy).should render('<r:siblings:each by="title"><r:title /> </r:siblings:each>').as('Bashful Doc Dopey Grumpy Happy ')
|
17
|
+
page(:sneezy).should render('<r:siblings by="title"><r:each><r:title /> </r:each></r:siblings>').as('Bashful Doc Dopey Grumpy Happy ')
|
18
|
+
end
|
19
|
+
it "should allow siblings to be sorted with the 'order' attribute when using 'by'" do
|
20
|
+
page(:sneezy).should render('<r:siblings:each by="slug" order="asc"><r:title /> </r:siblings:each>').as('Bashful Doc Dopey Grumpy Happy ')
|
21
|
+
page(:sneezy).should render('<r:siblings by="slug" order="asc"><r:each><r:title /> </r:each></r:siblings>').as('Bashful Doc Dopey Grumpy Happy ')
|
22
|
+
end
|
23
|
+
it "should exclude the current page" do
|
24
|
+
page(:sneezy).should render('<r:siblings:each><r:title/> </r:siblings:each>').as('Happy Grumpy Dopey Doc Bashful ')
|
25
|
+
end
|
26
|
+
it "should exclude unpublished pages" do
|
27
|
+
page(:sneezy).should render('<r:siblings:each><r:title/> </r:siblings:each>').as('Happy Grumpy Dopey Doc Bashful ')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "<r:if_siblings>" do
|
32
|
+
it 'should output its contents if the current page has siblings' do
|
33
|
+
page(:happy).should render('<r:if_siblings>true</r:if_siblings>').as('true')
|
34
|
+
end
|
35
|
+
it 'should not output its contents if the current page has no siblings' do
|
36
|
+
page(:solo).should render('<r:if_siblings>false</r:if_siblings>').as('')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "<r:unless_siblings>" do
|
41
|
+
it 'should output its contents if the current page has no siblings' do
|
42
|
+
page(:solo).should render('<r:unless_siblings>true</r:unless_siblings>').as('true')
|
43
|
+
end
|
44
|
+
it 'should not output its contents if the current page has siblings' do
|
45
|
+
page(:happy).should render('<r:unless_siblings>false</r:unless_siblings>').as('')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "<r:siblings:next>" do
|
50
|
+
it 'should output nothing if the current page has no siblings' do
|
51
|
+
page(:home).should render('<r:siblings:next>false</r:siblings:next>').as('')
|
52
|
+
end
|
53
|
+
it 'should output its contents if the current page has a sibling next in order' do
|
54
|
+
page(:doc).should render('<r:siblings:next>true</r:siblings:next>').as('true')
|
55
|
+
end
|
56
|
+
it 'should not output its contents if the current page has siblings, but not next in order' do
|
57
|
+
page(:bashful).should render('<r:siblings:next>true</r:siblings:next>').as('')
|
58
|
+
end
|
59
|
+
it "should set the scoped page to the next page in order" do
|
60
|
+
page(:doc).should render('<r:siblings:next><r:title /></r:siblings:next>').as('Bashful')
|
61
|
+
end
|
62
|
+
it "should work recursively when called more than once" do
|
63
|
+
page(:dopey).should render('<r:siblings><r:next><r:next><r:title /></r:next></r:next></r:siblings>').as('Bashful')
|
64
|
+
end
|
65
|
+
it "should order with 'by' attribute in siblings tag" do
|
66
|
+
page(:dopey).should render('<r:siblings by="title"><r:next><r:title/></r:next></r:siblings>').as('Grumpy')
|
67
|
+
end
|
68
|
+
it "should order with 'by' attribute in next tag" do
|
69
|
+
page(:dopey).should render('<r:siblings:next by="title"><r:title/></r:siblings:next>').as('Grumpy')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "<r:siblings:each_before>" do
|
74
|
+
it "should render its contents for each sibling following the current one in order" do
|
75
|
+
page(:dopey).should render('<r:siblings:each_before><r:title /> </r:siblings:each_before>').as('Grumpy Happy Sneezy ')
|
76
|
+
end
|
77
|
+
it "should use 'order' and 'by' as set in siblings tag" do
|
78
|
+
page(:dopey).should render('<r:siblings order="desc"><r:each_before><r:title /> </r:each_before></r:siblings>').as('Doc Bashful ')
|
79
|
+
page(:dopey).should render('<r:siblings order="desc" by="title"><r:each_before><r:title /> </r:each_before></r:siblings>').as('Grumpy Happy Sneezy ')
|
80
|
+
end
|
81
|
+
it "should use 'order' and 'by' as set in each_before tag" do
|
82
|
+
page(:dopey).should render('<r:siblings:each_before order="desc"><r:title /> </r:siblings:each_before>').as('Doc Bashful ')
|
83
|
+
page(:dopey).should render('<r:siblings:each_before order="desc" by="title"><r:title /> </r:siblings:each_before>').as('Grumpy Happy Sneezy ')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "<r:siblings:each_after>" do
|
88
|
+
it "should render its contents for each sibling following the current one in order" do
|
89
|
+
page(:dopey).should render('<r:siblings:each_after><r:title /> </r:siblings:each_after>').as('Doc Bashful ')
|
90
|
+
end
|
91
|
+
it "should use 'order' and 'by' as set in siblings tag" do
|
92
|
+
page(:dopey).should render('<r:siblings order="desc"><r:each_after><r:title /> </r:each_after></r:siblings>').as('Grumpy Happy Sneezy ')
|
93
|
+
page(:dopey).should render('<r:siblings order="desc" by="title"><r:each_after><r:title /> </r:each_after></r:siblings>').as('Doc Bashful ')
|
94
|
+
end
|
95
|
+
it "should use 'order' and 'by' as set in each_after tag" do
|
96
|
+
page(:dopey).should render('<r:siblings:each_after order="desc" by="title"><r:title /> </r:siblings:each_after>').as('Doc Bashful ')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "<r:siblings:previous>" do
|
101
|
+
it 'should output nothing if the current page has no siblings' do
|
102
|
+
page(:home).should render('<r:siblings:previous>false</r:siblings:previous>').as('')
|
103
|
+
end
|
104
|
+
it 'should output its contents if the current page has a sibling previous in order' do
|
105
|
+
page(:doc).should render('<r:siblings:previous>true</r:siblings:previous>').as('true')
|
106
|
+
end
|
107
|
+
it 'should not output its contents if the current page has siblings, but not previous in order' do
|
108
|
+
page(:sneezy).should render('<r:siblings:previous>true</r:siblings:previous>').as('')
|
109
|
+
end
|
110
|
+
it "should set the scoped page to the previous page in order" do
|
111
|
+
page(:doc).should render('<r:siblings:previous><r:title /></r:siblings:previous>').as('Dopey')
|
112
|
+
end
|
113
|
+
it "should set the scoped page to the previous page in order" do
|
114
|
+
page(:doc).should render('<r:siblings:previous><r:previous><r:title /></r:previous></r:siblings:previous>').as('Grumpy')
|
115
|
+
end
|
116
|
+
it "should order with 'by' attribute in siblings tag" do
|
117
|
+
page(:dopey).should render('<r:siblings by="title"><r:previous><r:title/></r:previous></r:siblings>').as('Doc')
|
118
|
+
end
|
119
|
+
it "should order with 'by' attribute in previous tag" do
|
120
|
+
page(:dopey).should render('<r:siblings:previous by="title"><r:title/></r:siblings:previous>').as('Doc')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "<r:sibling:if_next>" do
|
125
|
+
it "should output its contents if the current page has a sibling next in order" do
|
126
|
+
page(:doc).should render('<r:siblings:if_next>true</r:siblings:if_next>').as('true')
|
127
|
+
end
|
128
|
+
it "should not output its contents if the current page has no sibling next in order" do
|
129
|
+
page(:bashful).should render('<r:siblings:if_next>true</r:siblings:if_next>').as('')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "<r:siblings:unless_next>" do
|
134
|
+
it "should output its contents if the current page has no sibling next in order" do
|
135
|
+
page(:bashful).should render('<r:siblings:unless_next>true</r:siblings:unless_next>').as('true')
|
136
|
+
end
|
137
|
+
it "should not output its contents if the current page has a sibling next in order" do
|
138
|
+
page(:doc).should render('<r:siblings:unless_next>true</r:siblings:unless_next>').as('')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "<r:siblings:if_previous>" do
|
143
|
+
it "should output its contents if the current page has a sibling previous in order" do
|
144
|
+
page(:doc).should render('<r:siblings:if_previous>true</r:siblings:if_previous>').as('true')
|
145
|
+
end
|
146
|
+
it "should not output its contents if the current page has no sibling previous in order" do
|
147
|
+
page(:sneezy).should render('<r:siblings:if_previous>true</r:siblings:if_previous>').as('')
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "<r:siblings:unless_previous>" do
|
152
|
+
it "should output its contents if the current page has no sibling previous in order" do
|
153
|
+
page(:sneezy).should render('<r:siblings:unless_previous>true</r:siblings:unless_previous>').as('true')
|
154
|
+
end
|
155
|
+
it "should not output its contents if the current page has a sibling previous in order" do
|
156
|
+
page(:doc).should render('<r:siblings:unless_previous>true</r:siblings:unless_previous>').as('')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def page(symbol = nil)
|
163
|
+
if symbol.nil?
|
164
|
+
@page ||= pages(:assorted)
|
165
|
+
else
|
166
|
+
@page = pages(symbol)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class SiblingPagesScenario < Scenario::Base
|
2
|
+
uses :home_page
|
3
|
+
|
4
|
+
def load
|
5
|
+
create_page "Single mum" do
|
6
|
+
create_page "Solo", :published_at => DateTime.parse('2003-08-01 08:12:01')
|
7
|
+
end
|
8
|
+
|
9
|
+
create_page "Mother of two" do
|
10
|
+
create_page "Amy", :published_at => DateTime.parse('2003-01-01 08:12:01')
|
11
|
+
create_page "Kate", :published_at => DateTime.parse('2002-10-01 04:02:10')
|
12
|
+
end
|
13
|
+
|
14
|
+
create_page "Mother of dwarves" do
|
15
|
+
create_page "Bashful", :published_at => DateTime.parse('2005-10-07 12:12:12')
|
16
|
+
create_page "Doc", :published_at => DateTime.parse('2004-09-08 12:12:12')
|
17
|
+
create_page "Dopey", :published_at => DateTime.parse('2003-08-09 12:12:12')
|
18
|
+
create_page "Grumpy", :published_at => DateTime.parse('2002-07-10 12:12:12')
|
19
|
+
create_page "Happy", :published_at => DateTime.parse('2001-06-11 12:12:12')
|
20
|
+
create_page "Sleepy", :status_id => Status[:draft].id
|
21
|
+
create_page "Sneezy", :published_at => DateTime.parse('2000-05-12 12:12:12')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
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
|
+
if File.directory?(File.dirname(__FILE__) + "/scenarios")
|
15
|
+
Scenario.load_paths.unshift File.dirname(__FILE__) + "/scenarios"
|
16
|
+
end
|
17
|
+
if File.directory?(File.dirname(__FILE__) + "/matchers")
|
18
|
+
Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
|
19
|
+
end
|
20
|
+
|
21
|
+
Spec::Runner.configure do |config|
|
22
|
+
# config.use_transactional_fixtures = true
|
23
|
+
# config.use_instantiated_fixtures = false
|
24
|
+
# config.fixture_path = RAILS_ROOT + '/spec/fixtures'
|
25
|
+
|
26
|
+
# You can declare fixtures for each behaviour like this:
|
27
|
+
# describe "...." do
|
28
|
+
# fixtures :table_a, :table_b
|
29
|
+
#
|
30
|
+
# Alternatively, if you prefer to declare them only once, you can
|
31
|
+
# do so here, like so ...
|
32
|
+
#
|
33
|
+
# config.global_fixtures = :table_a, :table_b
|
34
|
+
#
|
35
|
+
# If you declare global fixtures, be aware that they will be declared
|
36
|
+
# for all of your examples, even those that don't use them.
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: radiant-sibling_tags-extension
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Drew Neil
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: &70267021546480 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70267021546480
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70267021545860 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70267021545860
|
36
|
+
description: This extension for Radiant provides tags allowing you to refer to the
|
37
|
+
neighbouring siblings of a page
|
38
|
+
email:
|
39
|
+
- andrew.jr.neil@gmail.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- README.md
|
47
|
+
- Rakefile
|
48
|
+
- app/models/sibling_tags.rb
|
49
|
+
- lib/radiant-sibling-tags-extension.rb
|
50
|
+
- lib/radiant-sibling_tags-extension/version.rb
|
51
|
+
- lib/tasks/sibling_tags_extension_tasks.rake
|
52
|
+
- radiant-sibling_tags-extension.gemspec
|
53
|
+
- sibling_tags_extension.rb
|
54
|
+
- spec/models/sibling_tags_spec.rb
|
55
|
+
- spec/scenarios/sibling_pages_scenario.rb
|
56
|
+
- spec/spec.opts
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
homepage: http://github.com/nelstrom/radiant-sibling-tags-extension
|
59
|
+
licenses: []
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project: radiant-sibling_tags-extension
|
78
|
+
rubygems_version: 1.8.11
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: This extension for Radiant provides tags allowing you to refer to the neighbouring
|
82
|
+
siblings of a page
|
83
|
+
test_files:
|
84
|
+
- spec/models/sibling_tags_spec.rb
|
85
|
+
- spec/scenarios/sibling_pages_scenario.rb
|
86
|
+
- spec/spec.opts
|
87
|
+
- spec/spec_helper.rb
|