radiant-search-extension 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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