radiant-search-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,36 @@
1
+ # Radiant Search Extension
2
+
3
+ [![Build Status](https://secure.travis-ci.org/radiant/radiant-search-extension.png)](http://travis-ci.org/radiant/radiant-search-extension)
4
+
5
+ Version: 1.0
6
+ Description: A simple search extension for Radiant CMS
7
+
8
+ ## Installation
9
+
10
+ Add `gem "radiant-search-extension", "~> 1.0"` to your Gemfile and run `bundle install`
11
+
12
+ ## Example
13
+
14
+ ```
15
+ <r:search:form submit="Search"/>
16
+
17
+ <r:search:initial>
18
+ <strong>Enter a phrase above to search this website.</strong>
19
+ </r:search:initial>
20
+
21
+ <r:search:empty>
22
+ <strong>I couldn't find anything named "<r:search:query/>".</strong>
23
+ </r:search:empty>
24
+
25
+ <r:search:results>
26
+ Found the following pages that contain "<r:search:query/>".
27
+ <ul>
28
+ <r:search:results:each>
29
+ <li>
30
+ <r:link/><br/>
31
+ <r:search:highlight><r:content/></r:search:highlight>
32
+ </li>
33
+ </r:search:results:each>
34
+ </ul>
35
+ </r:search:results>
36
+ ```
@@ -0,0 +1,120 @@
1
+ # I think this is the one that should be moved to the extension Rakefile template
2
+
3
+ # In rails 1.2, plugins aren't available in the path until they're loaded.
4
+ # Check to see if the rspec plugin is installed first and require
5
+ # it if it is. If not, use the gem version.
6
+
7
+ # Determine where the RSpec plugin is by loading the boot
8
+ unless defined? RADIANT_ROOT
9
+ ENV["RAILS_ENV"] = "test"
10
+ case
11
+ when ENV["RADIANT_ENV_FILE"]
12
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
13
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
14
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
15
+ else
16
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
17
+ end
18
+ end
19
+
20
+ require 'rake'
21
+ require 'rake/rdoctask'
22
+ require 'rake/testtask'
23
+
24
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
25
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
26
+ require 'spec/rake/spectask'
27
+ # require 'spec/translator'
28
+
29
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
30
+ Object.send(:remove_const, :RADIANT_ROOT)
31
+
32
+ extension_root = File.expand_path(File.dirname(__FILE__))
33
+
34
+ task :default => :spec
35
+ task :stats => "spec:statsetup"
36
+
37
+ desc "Run all specs in spec directory"
38
+ Spec::Rake::SpecTask.new(:spec) do |t|
39
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
40
+ t.spec_files = FileList['spec/**/*_spec.rb']
41
+ end
42
+
43
+ namespace :spec do
44
+ desc "Run all specs in spec directory with RCov"
45
+ Spec::Rake::SpecTask.new(:rcov) do |t|
46
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
47
+ t.spec_files = FileList['spec/**/*_spec.rb']
48
+ t.rcov = true
49
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
50
+ end
51
+
52
+ desc "Print Specdoc for all specs"
53
+ Spec::Rake::SpecTask.new(:doc) do |t|
54
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
55
+ t.spec_files = FileList['spec/**/*_spec.rb']
56
+ end
57
+
58
+ [:models, :controllers, :views, :helpers].each do |sub|
59
+ desc "Run the specs under spec/#{sub}"
60
+ Spec::Rake::SpecTask.new(sub) do |t|
61
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
62
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
63
+ end
64
+ end
65
+
66
+ # Hopefully no one has written their extensions in pre-0.9 style
67
+ # desc "Translate specs from pre-0.9 to 0.9 style"
68
+ # task :translate do
69
+ # translator = ::Spec::Translator.new
70
+ # dir = RAILS_ROOT + '/spec'
71
+ # translator.translate(dir, dir)
72
+ # end
73
+
74
+ # Setup specs for stats
75
+ task :statsetup do
76
+ require 'code_statistics'
77
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
78
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
79
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
80
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
81
+ ::CodeStatistics::TEST_TYPES << "Model specs"
82
+ ::CodeStatistics::TEST_TYPES << "View specs"
83
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
84
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
85
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
86
+ end
87
+
88
+ namespace :db do
89
+ namespace :fixtures do
90
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
91
+ task :load => :environment do
92
+ require 'active_record/fixtures'
93
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
94
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
95
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ desc 'Generate documentation for the search extension.'
103
+ Rake::RDocTask.new(:rdoc) do |rdoc|
104
+ rdoc.rdoc_dir = 'rdoc'
105
+ rdoc.title = 'SearchExtension'
106
+ rdoc.options << '--line-numbers' << '--inline-source'
107
+ rdoc.rdoc_files.include('README')
108
+ rdoc.rdoc_files.include('lib/**/*.rb')
109
+ end
110
+
111
+ # For extensions that are in transition
112
+ desc 'Test the search extension.'
113
+ Rake::TestTask.new(:test) do |t|
114
+ t.libs << 'lib'
115
+ t.pattern = 'test/**/*_test.rb'
116
+ t.verbose = true
117
+ end
118
+
119
+ # Load any custom rakefiles for extension
120
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,157 @@
1
+ class SearchPage < Page
2
+ description "Provides tags and behavior to support searching Radiant. Based on Oliver Baltzer's search_behavior."
3
+ attr_accessor :query_result, :query
4
+ #### Tags ####
5
+
6
+ desc %{ Renders the passed query.}
7
+ tag 'search:query' do |tag|
8
+ CGI.escapeHTML(query)
9
+ end
10
+
11
+ desc %{ Renders the contained block when query is blank.}
12
+ tag 'search:initial' do |tag|
13
+ if query.empty?
14
+ tag.expand
15
+ end
16
+ end
17
+
18
+ desc %{ Renders the contained block if no results were returned.}
19
+ tag 'search:empty' do |tag|
20
+ if query_result.blank? && !query.empty?
21
+ tag.expand
22
+ end
23
+ end
24
+
25
+ desc %{ Renders the contained block if results were returned.}
26
+ tag 'search:results' do |tag|
27
+ unless query_result.blank?
28
+ if tag.double?
29
+ tag.expand
30
+ else
31
+ content = ''
32
+ query_result.each do |page|
33
+ content << "<p><a href='#{page.url}'>#{page.title}</a><br />"
34
+ content << helper.truncate(helper.strip_tags(page.parts.first.content).gsub(/\s+/," "), 100)
35
+ content << "</p>"
36
+ end
37
+ content
38
+ end
39
+ end
40
+ end
41
+
42
+ desc %{ Renders the contained block for each result page. The context
43
+ inside the tag refers to the found page.}
44
+ tag 'search:results:each' do |tag|
45
+ returning String.new do |content|
46
+ query_result.each do |page|
47
+ tag.locals.page = page
48
+ content << tag.expand unless page == tag.globals.page
49
+ end
50
+ end
51
+ end
52
+
53
+ desc %{ Quantity of search results fetched.}
54
+ tag 'search:results:quantity' do |tag|
55
+ query_result.blank? ? 0 : query_result.size
56
+ end
57
+
58
+ desc %{ <r:truncate_and_strip [length="100"] />
59
+ Truncates and strips all HTML tags from the content of the contained block.
60
+ Useful for displaying a snippet of a found page. The optional `length' attribute
61
+ specifies how many characters to truncate to.}
62
+ tag 'truncate_and_strip' do |tag|
63
+ tag.attr['length'] ||= 100
64
+ length = tag.attr['length'].to_i
65
+ helper.truncate(helper.strip_tags(tag.expand).gsub(/\s+/," "), :length => length)
66
+ end
67
+
68
+ desc %{ <r:search:highlight [length="100"] />
69
+ Highlights the search keywords from the content of the contained block.
70
+ Strips all HTML tags and truncates the relevant part.
71
+ Useful for displaying a snippet of a found page. The optional `length' attribute
72
+ specifies how many characters to truncate to.}
73
+ tag 'highlight' do |tag|
74
+ length = (tag.attr['length'] ||= 100).to_i
75
+ content = helper.strip_tags(tag.expand).gsub(/\s+/," ")
76
+ match = content.match(query.split(' ').first)
77
+ if match
78
+ start = match.begin(0)
79
+ begining = (start - length/2)
80
+ begining = 0 if begining < 0
81
+ chars = content.mb_chars
82
+ relevant_content = chars.length > length ? (chars[(begining)...(begining + length)]).to_s + "..." : content
83
+ helper.highlight(relevant_content, query.split)
84
+ else
85
+ helper.truncate(content, length)
86
+ end
87
+ end
88
+
89
+ #### "Behavior" methods ####
90
+ def cache?
91
+ false
92
+ end
93
+
94
+ def render
95
+ @query_result = []
96
+ @query = ""
97
+ q = @request.parameters[:q]
98
+ exclude_pages = (@request.parameters[:exclude_pages] || '').split(',')
99
+ case Page.connection.adapter_name.downcase
100
+ when 'postgresql'
101
+ sql_content_check = "((lower(page_parts.content) ILIKE ?) OR (lower(title) ILIKE ?))"
102
+ else
103
+ sql_content_check = "((LOWER(page_parts.content) LIKE ?) OR (LOWER(title) LIKE ?))"
104
+ end
105
+ unless (@query = q.to_s.strip).blank?
106
+ tokens = query.split.collect { |c| "%#{c.downcase}%"}
107
+ pages = Page.find(:all, :order => 'published_at DESC', :include => [ :parts ],
108
+ :conditions => [(["#{sql_content_check}"] * tokens.size).join(" AND "),
109
+ *tokens.collect { |token| [token] * 2 }.flatten])
110
+ @query_result = pages.delete_if { |p| !p.published? ||
111
+ exclude_pages.include?(p.url)}
112
+ end
113
+ lazy_initialize_parser_and_context
114
+ if layout
115
+ parse_object(layout)
116
+ else
117
+ render_part(:body)
118
+ end
119
+ end
120
+
121
+ def helper
122
+ @helper ||= ActionView::Base.new
123
+ end
124
+
125
+ end
126
+
127
+ class Page
128
+ #### Tags ####
129
+ desc %{ The namespace for all search tags.}
130
+ tag 'search' do |tag|
131
+ tag.expand
132
+ end
133
+
134
+ desc %{
135
+ Renders a search form, with the optional label, submit text and url.
136
+
137
+ If you need to exclude some pages from the search results you can specify their URLs in exclude_pages attribute separated by comma. Don't forget trailing slash
138
+
139
+ Optionally allows setting the CSS class of the button and text inputs for formatting.
140
+
141
+ <pre><code><r:search:form [label=""] [url="/search"]
142
+ [submit="Search"] [exclude_pages=""]
143
+ [box_class="CSS class name"]
144
+ [button_class="CSS class name"] /></code></pre>}
145
+ tag 'search:form' do |tag|
146
+ label = tag.attr['label'].nil? ? "" : "<label for=\"q\">#{tag.attr['label']}</label> "
147
+ button_class = tag.attr['button_class'].nil? ? "" : " class=\"#{tag.attr['button_class']}\""
148
+ box_class = tag.attr['box_class'].nil? ? "" : " class=\"#{tag.attr['box_class']}\""
149
+ submit = "<input#{button_class} value=\"#{tag.attr['submit'] || "Search"}\" type=\"submit\" />"
150
+ url = tag.attr['url'].nil? ? self.url.chop : tag.attr['url']
151
+ exclude_pages_input = %{<input type="hidden" name="exclude_pages" value="#{CGI.escapeHTML(tag.attr['exclude_pages'])}" />}
152
+ @query ||= ""
153
+ content = %{<form action="#{url}" method="get" id="search_form">#{exclude_pages_input}<p>#{label}<input type="text"#{box_class} id="q" name="q" value="#{CGI.escapeHTML(@query)}" size="15" alt="search"/> #{submit}</p></form>}
154
+ content << "\n"
155
+ end
156
+
157
+ end
@@ -0,0 +1,2 @@
1
+ module RadiantSearchExtension
2
+ end
@@ -0,0 +1,3 @@
1
+ module RadiantSearchExtension
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,13 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :search do
4
+
5
+ desc "Runs the migration of the Search extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ SearchExtension.migrator.migrate
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "radiant-search-extension/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "radiant-search-extension"
7
+ s.version = RadiantSearchExtension::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Radiant CMS Dev Team"]
10
+ s.email = ["radiant@radiantcms.org"]
11
+ s.homepage = "http://radiantcms.org/"
12
+ s.summary = %q{Simple search for Radiant CMS}
13
+ s.description = %q{An extension for Radiant CMS to support searching pages}
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.require_paths = ["lib"]
23
+ end
@@ -0,0 +1,14 @@
1
+ class SearchExtension < Radiant::Extension
2
+ version "1.0.0"
3
+ description %{Provides a page type that allows you to search for pages in
4
+ Radiant. Based on Oliver Baltzer's search_behavior.}
5
+ url "http://github.com/radiant/radiant-search-extension"
6
+
7
+ def activate
8
+ SearchPage
9
+ end
10
+
11
+ def deactivate
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ class SearchedPagesDataset < Dataset::Base
2
+ uses :home_page
3
+
4
+ def load
5
+ create_page "Ruby Home Page" do
6
+ create_page_part :ruby_home_page_body, :content => 'This is the body portion of the Ruby home page.'
7
+ create_page_part :ruby_home_page_extended, :content => 'This is an extended portion of the Ruby home page.'
8
+ create_page_part :ruby_home_page_summary, :content => 'This is a summary.'
9
+ create_page_part :ruby_home_page_sidebar, :content => '<r:title /> sidebar.'
10
+ end
11
+ create_page "Documentation", :body => 'This is the documentation section.'
12
+ create_page "Search", :body => "This is the search section.", :class_name => 'SearchPage'
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe SearchPage do
4
+ dataset :searched_pages
5
+ describe "<r:truncate_and_strip>" do
6
+ it "should truncate the contents to the given length" do
7
+ pages(:search).should render('<r:truncate_and_strip length="10">abcde fghij klmno</r:truncate_and_strip>').as('abcde f...')
8
+ end
9
+ end
10
+
11
+ describe "<r:search:form />" do
12
+ it "should add exclude_pages parameter in hidden input" do
13
+ pages(:search).should render('<r:search:form exclude_pages="/page/" />').matching(%r{<input type="hidden" name="exclude_pages" value="/page/"})
14
+ end
15
+
16
+ it "should escape value of exclude_pages field" do
17
+ pages(:search).should render('<r:search:form exclude_pages=">" />').matching(%r{name="exclude_pages" value="&gt;"})
18
+ end
19
+ end
20
+
21
+ describe "render" do
22
+ before :each do
23
+ @page = SearchPage.new
24
+ @page.request = ActionController::TestRequest.new
25
+ @page.response = ActionController::TestResponse.new
26
+ end
27
+
28
+ it "should return pages containing search term" do
29
+ @page.request.query_parameters = {:q => 'documentation'}
30
+ @page.render
31
+ @page.query_result.should include pages(:documentation)
32
+ end
33
+ it "should not return pages not containing search term" do
34
+ @page.request.query_parameters = {:q => "documentation"}
35
+ @page.render
36
+ @page.query_result.should_not include pages(:ruby_home_page)
37
+ end
38
+ it "should not include pages with URL specified in exclude_page" do
39
+ exclude_page = pages(:documentation)
40
+ @page.request.query_parameters = {
41
+ :q => "documentation",
42
+ :exclude_pages => exclude_page.url
43
+ }
44
+ Rails::logger.info "Query_parameters set to #{@page.request.query_parameters}"
45
+
46
+ @page.render
47
+ @page.query_result.should_not include pages(:documentation)
48
+ end
49
+
50
+ it "accepts multiple pages in exclude_page separated by comma" do
51
+ exclude_pages = "#{pages(:documentation).url},#{pages(:ruby_home_page).url}"
52
+ @page.request.query_parameters = {
53
+ :q => ".",
54
+ :exclude_pages => exclude_pages
55
+ }
56
+ Rails::logger.info "Query_parameters set to #{@page.request.query_parameters}"
57
+
58
+ @page.render
59
+ @page.query_result.should_not include pages(:documentation)
60
+ @page.query_result.should_not include pages(:ruby_home_page)
61
+ end
62
+ end
63
+ 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
@@ -0,0 +1,31 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+ body:
3
+ id: 1
4
+ name: body
5
+ content: This is the body portion of the Ruby home page.
6
+ page_id: 1
7
+ extended:
8
+ id: 2
9
+ name: extended
10
+ content: This is an extended portion of the Ruby home page.
11
+ page_id: 1
12
+ summary:
13
+ id: 3
14
+ name: summary
15
+ content: This is a summary.
16
+ page_id: 1
17
+ sidebar:
18
+ id: 4
19
+ name: sidebar
20
+ content: <r:title /> sidebar.
21
+ page_id: 1
22
+ documentation_body:
23
+ id: 5
24
+ name: body
25
+ content: This is the documentation section.
26
+ page_id: 2
27
+ search_body:
28
+ id: 6
29
+ name: body
30
+ content: This is the search section.
31
+ page_id: 3
@@ -0,0 +1,26 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+ homepage:
3
+ id: 1
4
+ title: Ruby Home Page
5
+ breadcrumb: Home
6
+ slug: /
7
+ status_id: 100
8
+ parent_id:
9
+ published_at: 2006-01-30 08:41:07
10
+ documentation:
11
+ id: 2
12
+ title: Documentation
13
+ breadcrumb: Documentation
14
+ slug: documentation
15
+ status_id: 100
16
+ parent_id: 1
17
+ published_at: 2006-01-30 08:41:07
18
+ search:
19
+ id: 3
20
+ class_name: SearchPage
21
+ title: Search
22
+ breadcrumb: search
23
+ slug: search
24
+ status_id: 100
25
+ parent_id: 1
26
+ published_at: 2006-01-30 08:41:07
@@ -0,0 +1,89 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class SearchExtensionTest < ActiveSupport::TestCase
4
+ fixtures :pages
5
+
6
+ def setup
7
+ @controller = SiteController.new
8
+ @request = ActionController::TestRequest.new
9
+ @response = ActionController::TestResponse.new
10
+ end
11
+
12
+ def test_initialization
13
+ assert_equal RAILS_ROOT + '/vendor/extensions/search', SearchExtension.root
14
+ assert_equal 'Search', SearchExtension.extension_name
15
+ end
16
+
17
+ end
18
+
19
+ class SearchTagsTest < ActiveSupport::TestCase
20
+ test_helper :pages, :render
21
+ fixtures :pages
22
+
23
+ def test_search_form_works_for_regular_page
24
+ @page = pages(:documentation)
25
+ form = "<form action=\"/documentation\" method=\"get\" id=\"search_form\"><p><input type=\"text\" id=\"q\" name=\"q\" value=\"\" size=\"15\" alt=\"search\"/> <input value=\"Search\" type=\"submit\" /></p></form>\n"
26
+ assert_renders form,'<r:search:form />'
27
+ end
28
+
29
+ def test_search_form_with_query
30
+ @page = pages(:search)
31
+ @page.query = 'test'
32
+ form = "<form action=\"/search\" method=\"get\" id=\"search_form\"><p><input type=\"text\" id=\"q\" name=\"q\" value=\"test\" size=\"15\" alt=\"search\"/> <input value=\"Search\" type=\"submit\" /></p></form>\n"
33
+ assert_renders form, '<r:search:form />'
34
+ end
35
+
36
+ def test_search_form_with_url
37
+ @page = pages(:search)
38
+ form = "<form action=\"/other_url\" method=\"get\" id=\"search_form\"><p><input type=\"text\" id=\"q\" name=\"q\" value=\"\" size=\"15\" alt=\"search\"/> <input value=\"Search\" type=\"submit\" /></p></form>\n"
39
+ assert_renders form, '<r:search:form url="/other_url" />'
40
+ end
41
+
42
+ def test_search_form_with_label
43
+ @page = pages(:search)
44
+ form = "<form action=\"/search\" method=\"get\" id=\"search_form\"><p><label for=\"q\">Search:</label> <input type=\"text\" id=\"q\" name=\"q\" value=\"\" size=\"15\" alt=\"search\"/> <input value=\"Search\" type=\"submit\" /></p></form>\n"
45
+ assert_renders form, '<r:search:form label="Search:" />'
46
+ end
47
+
48
+ def test_search_form_with_submit
49
+ @page = pages(:search)
50
+ form = "<form action=\"/search\" method=\"get\" id=\"search_form\"><p><input type=\"text\" id=\"q\" name=\"q\" value=\"\" size=\"15\" alt=\"search\"/> <input value=\"Go!\" type=\"submit\" /></p></form>\n"
51
+ assert_renders form, '<r:search:form submit="Go!" />'
52
+ end
53
+
54
+ def test_truncate_and_strip
55
+ @page = pages(:search)
56
+ assert_renders 'abcde f...', '<r:truncate_and_strip length="10">abcde fghij klmno</r:truncate_and_strip>'
57
+ end
58
+
59
+ def test_highlight
60
+ @page = pages(:search)
61
+ @page.query = 'abc'
62
+ assert_renders '<strong class="highlight">abc</strong>de fghij klmno', '<r:search:highlight>abcde fghij klmno</r:search:highlight>'
63
+ end
64
+
65
+ def test_highlight_only_highlights_first_word
66
+ @page = pages(:search)
67
+ @page.query = 'cde fgh'
68
+ assert_renders 'ab<strong class="highlight">cde</strong> <strong class="highlight">fgh</strong>ij klmno', '<r:search:highlight>abcde fghij klmno</r:search:highlight>'
69
+ end
70
+
71
+ def test_highlight_renders_truncated_content_if_content_does_not_match_query
72
+ @page = pages(:search)
73
+ @page.query = 'X'
74
+ assert_renders 'abcde f...', '<r:search:highlight length="10">abcde fghij klmno</r:search:highlight>'
75
+ end
76
+
77
+ def test_highlight_with_uneven_length
78
+ @page = pages(:search)
79
+ @page.query = 'X'
80
+ assert_renders 'abcde ...', '<r:search:highlight length="9">abcde fghij klmno</r:search:highlight>'
81
+ end
82
+
83
+ def test_highlight_with_small_length
84
+ @page = pages(:search)
85
+ @page.query = 'abc'
86
+ assert_renders '<strong class="highlight">abc</strong>de fgh...', '<r:search:highlight length="9">abcde fghij klmno</r:search:highlight>'
87
+ end
88
+ end
89
+
@@ -0,0 +1,18 @@
1
+ # Load the environment
2
+ unless defined? RADIANT_ROOT
3
+ ENV["RAILS_ENV"] = "test"
4
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
5
+ end
6
+ require "#{RADIANT_ROOT}/test/test_helper"
7
+
8
+ class ActiveSupport::TestCase
9
+
10
+ # Include a helper to make testing Radius tags easier
11
+ #test_helper :extension_tags
12
+
13
+ # Add the fixture directory to the fixture path
14
+ self.fixture_path = File.dirname(__FILE__) + "/fixtures"
15
+
16
+ # Add more helper methods to be used by all extension tests here...
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-search-extension
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Radiant CMS Dev Team
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-01-08 00:00:00 -06:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: An extension for Radiant CMS to support searching pages
23
+ email:
24
+ - radiant@radiantcms.org
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - app/models/search_page.rb
33
+ - lib/radiant-search-extension/version.rb
34
+ - lib/radiant-search-extension.rb
35
+ - lib/tasks/search_extension_tasks.rake
36
+ - radiant-search-extension-1.0.0.gem
37
+ - radiant-search-extension.gemspec
38
+ - Rakefile
39
+ - README.md
40
+ - search_extension.rb
41
+ - spec/datasets/searched_pages_dataset.rb
42
+ - spec/models/search_page_spec.rb
43
+ - spec/spec.opts
44
+ - spec/spec_helper.rb
45
+ - test/fixtures/page_parts.yml
46
+ - test/fixtures/pages.yml
47
+ - test/functional/search_extension_test.rb
48
+ - test/test_helper.rb
49
+ has_rdoc: true
50
+ homepage: http://radiantcms.org/
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ requirements: []
77
+
78
+ rubyforge_project:
79
+ rubygems_version: 1.3.9.3
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Simple search for Radiant CMS
83
+ test_files:
84
+ - test/fixtures/page_parts.yml
85
+ - test/fixtures/pages.yml
86
+ - test/functional/search_extension_test.rb
87
+ - test/test_helper.rb
88
+ - spec/datasets/searched_pages_dataset.rb
89
+ - spec/models/search_page_spec.rb
90
+ - spec/spec.opts
91
+ - spec/spec_helper.rb