radiant-find_replace-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.
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # Find Replace
2
+
3
+ This extension adds find and replace functionality to the backend of your Radiant CMS based website.
4
+
5
+ Supports regular expressions and case (in)sensitivity.
6
+ When showing results, you can check which matches you want to update with the replace string.
7
+ If you are using regular expressions, you can render matches in the replace string. For example, find:
8
+
9
+ <p class="title">([^</p>]*)</p>
10
+
11
+ Replace:
12
+
13
+ <h2>\1</h2>
14
+
15
+ The results page does not show the actual results, but the pages, snippets and layouts that had at least one match.
16
+ All the more reason to be very careful when you use the replace functionality, especially when you are using regular expressions.
17
+
18
+ Created by Benny Degezelle.
data/Rakefile ADDED
@@ -0,0 +1,109 @@
1
+ # Determine where the RSpec plugin is by loading the boot
2
+ unless defined? RADIANT_ROOT
3
+ ENV["RAILS_ENV"] = "test"
4
+ case
5
+ when ENV["RADIANT_ENV_FILE"]
6
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
7
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
8
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
9
+ else
10
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
11
+ end
12
+ end
13
+
14
+ require 'rake'
15
+ require 'rdoc/task'
16
+ require 'rake/testtask'
17
+
18
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
19
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
20
+ require 'spec/rake/spectask'
21
+ require 'cucumber'
22
+ require 'cucumber/rake/task'
23
+
24
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
25
+ Object.send(:remove_const, :RADIANT_ROOT)
26
+
27
+ extension_root = File.expand_path(File.dirname(__FILE__))
28
+
29
+ task :default => [:spec, :features]
30
+ task :stats => "spec:statsetup"
31
+
32
+ desc "Run all specs in spec directory"
33
+ Spec::Rake::SpecTask.new(:spec) do |t|
34
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
35
+ t.spec_files = FileList['spec/**/*_spec.rb']
36
+ end
37
+
38
+ task :features => 'spec:integration'
39
+
40
+ namespace :spec do
41
+ desc "Run all specs in spec directory with RCov"
42
+ Spec::Rake::SpecTask.new(:rcov) do |t|
43
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
44
+ t.spec_files = FileList['spec/**/*_spec.rb']
45
+ t.rcov = true
46
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
47
+ end
48
+
49
+ desc "Print Specdoc for all specs"
50
+ Spec::Rake::SpecTask.new(:doc) do |t|
51
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
52
+ t.spec_files = FileList['spec/**/*_spec.rb']
53
+ end
54
+
55
+ [:models, :controllers, :views, :helpers].each do |sub|
56
+ desc "Run the specs under spec/#{sub}"
57
+ Spec::Rake::SpecTask.new(sub) do |t|
58
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
59
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
60
+ end
61
+ end
62
+
63
+ desc "Run the Cucumber features"
64
+ Cucumber::Rake::Task.new(:integration) do |t|
65
+ t.fork = true
66
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
67
+ # t.feature_pattern = "#{extension_root}/features/**/*.feature"
68
+ t.profile = "default"
69
+ end
70
+
71
+ # Setup specs for stats
72
+ task :statsetup do
73
+ require 'code_statistics'
74
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
75
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
76
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
77
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
78
+ ::CodeStatistics::TEST_TYPES << "Model specs"
79
+ ::CodeStatistics::TEST_TYPES << "View specs"
80
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
81
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
82
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
83
+ end
84
+
85
+ namespace :db do
86
+ namespace :fixtures do
87
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
88
+ task :load => :environment do
89
+ require 'active_record/fixtures'
90
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
91
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
92
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ desc 'Generate documentation for the find_replace extension.'
100
+ RDoc::Task.new(:rdoc) do |rdoc|
101
+ rdoc.rdoc_dir = 'rdoc'
102
+ rdoc.title = 'FindReplaceExtension'
103
+ rdoc.options << '--line-numbers' << '--inline-source'
104
+ rdoc.rdoc_files.include('README')
105
+ rdoc.rdoc_files.include('lib/**/*.rb')
106
+ end
107
+
108
+ # Load any custom rakefiles for extension
109
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,53 @@
1
+ class Admin::SearchController < ApplicationController
2
+ only_allow_access_to :results,
3
+ :when => [:designer, :admin],
4
+ :denied_url => { :controller => 'admin/pages', :action => 'index' },
5
+ :denied_message => 'You must have designer privileges to perform this action.'
6
+
7
+ def results
8
+ if params[:doReplace]
9
+ params.select{|k, v| k =~ /(page|snippet|layout)_(\d)/ }.map do |k,v|
10
+ class_name, id = k.to_s.split('_')
11
+ to_replace = class_name.titlecase.constantize.find(id)
12
+ srch = Regexp.new(params[:query], params[:case_insensitive])
13
+
14
+ if class_name == 'page'
15
+ Page.find(id).parts.each do |page_part|
16
+ page_part.update_attribute :content, page_part.content.gsub(srch, params[:replace])
17
+ end
18
+ else
19
+ to_replace.update_attribute :content, to_replace.content.gsub(srch, params[:replace])
20
+ end
21
+ end
22
+ end
23
+
24
+ if query = params[:query]
25
+ like = case Page.connection.adapter_name.downcase
26
+ when 'postgresql'
27
+ if params[:regex_mode]
28
+ sqlike = params[:case_insensitive] ? '~*' : '~'
29
+ else
30
+ sqlike = params[:case_insensitive] ? "ILIKE" : "LIKE"
31
+ end
32
+ else
33
+ if params[:regex_mode]
34
+ sqlike = params[:case_insensitive] ? "REGEXP" : "REGEXP BINARY"
35
+ else
36
+ sqlike = params[:case_insensitive] ? "LIKE" : "LIKE BINARY"
37
+ end
38
+ end
39
+
40
+ @page_results = Page.find(:all, :include => [ :parts ], :conditions => ["page_parts.content #{like} ? ", match])
41
+ @snippet_results = Snippet.find(:all, :conditions => ["content #{like} ?", match])
42
+ @layout_results = Layout.find(:all, :conditions => ["content #{like} ?", match])
43
+ end
44
+
45
+ end
46
+
47
+ private
48
+
49
+ def match
50
+ qry = params[:regex_mode] ? params[:query] : "%#{params[:query]}%"
51
+ params[:case_insensitive] ? qry.downcase : qry
52
+ end
53
+ end
@@ -0,0 +1,71 @@
1
+ - @page_title = 'Search'
2
+
3
+ .outset
4
+ %form
5
+ - if params[:query]
6
+ %table.index#results{:summary=>"Results", :style => "margin-bottom: 60px"}
7
+ %thead
8
+ %tr
9
+ %th{:style => "width: 2em"}
10
+ %input{:type => 'checkbox', :id => 'toggler', :onclick => "toggle_cbs()"}
11
+ %th.identifier Search result
12
+ %tbody
13
+ - @page_results.each do |page|
14
+ %tr
15
+ %td
16
+ %input{:type => 'checkbox', :name => "page_#{page.id}"}
17
+ %td
18
+ = image_tag 'admin/page.png', :class => "icon", :title => 'Page'
19
+ = link_to page.path, edit_admin_page_path(page)
20
+ - @snippet_results.each do |snippet|
21
+ %tr
22
+ %td
23
+ %input{:type => 'checkbox', :name => "snippet_#{snippet.id}"}
24
+ %td
25
+ = image_tag 'admin/snippet.png', :class => "icon", :title => 'Snippet'
26
+ = link_to snippet.name, edit_admin_snippet_path(snippet)
27
+ - @layout_results.each do |layout|
28
+ %tr
29
+ %td
30
+ %input{:type => 'checkbox', :name => "layout_#{layout.id}"}
31
+ %td
32
+ = image_tag 'admin/layout.png', :class => "icon", :title => 'Layout'
33
+ = link_to layout.name, edit_admin_layout_path(layout)
34
+ - if @page_results.empty? && @snippet_results.empty? && @layout_results.empty?
35
+ %tr
36
+ %td.empty{:colspan => 3}
37
+ No results for
38
+ %em
39
+ = params[:query]
40
+ \.
41
+
42
+ #actions{:style => "color: #eee"}
43
+ %ul
44
+ %li
45
+ Find:
46
+ %input{:type => 'text', :name => 'query', :value => params[:query]}
47
+ %li
48
+ Replace:
49
+ %input{:type => 'text', :name => 'replace', :value => params[:replace]}
50
+ %li
51
+ %input{:type => 'checkbox', :name => 'regex_mode', :checked => params[:regex_mode] }
52
+ Use regular expressions
53
+ %li
54
+ %input{:type => 'checkbox', :name => 'case_insensitive', :checked => params[:case_insensitive] }
55
+ Ignore case
56
+ %li
57
+ %input{:type => :submit, :class => 'action_button', :value => 'Find all'}
58
+ - if params[:query]
59
+ %li
60
+ = submit_tag 'Replace selected', {:class => 'action_button', :name => 'doReplace', :confirm => "Are you sure you want to replace all instances of '#{params[:query]}' with '#{params[:replace]}' in all of the selected Pages, Snippets and Layouts? This can not be reverted!"}
61
+ / %input{:type => :submit}
62
+
63
+ :javascript
64
+ function toggle_cbs() {
65
+ if($("toggler").checked){
66
+ $$('input[type="checkbox"]').slice(1,-1).each(function(e){ e.checked = 1 });
67
+ }
68
+ else{
69
+ $$('input[type="checkbox"]').slice(1,-1).each(function(e){ e.checked = 0 });
70
+ }
71
+ }
@@ -0,0 +1,3 @@
1
+ Radiant.config do |config|
2
+ # config.define "setting.name", :default => 'value', :select_from => ['foo', 'bar']
3
+ end
@@ -0,0 +1,3 @@
1
+ ---
2
+ en:
3
+ find replace: Find Replace
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.namespace :admin do |admin|
3
+ admin.search 'search', :controller => :search, :action => :results
4
+ end
5
+ # map.namespace :admin, :member => { :remove => :get } do |admin|
6
+ # admin.resources :find_replace
7
+ # end
8
+ end
data/cucumber.yml ADDED
@@ -0,0 +1 @@
1
+ default: --format progress features --tags ~@proposed,~@in_progress
@@ -0,0 +1,11 @@
1
+ # Sets up the Rails environment for Cucumber
2
+ ENV["RAILS_ENV"] = "test"
3
+ # Extension root
4
+ extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
5
+ require extension_env+'.rb'
6
+
7
+ Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step unless step =~ /datasets_loader\.rb$/}
8
+
9
+ Cucumber::Rails::World.class_eval do
10
+ dataset :find_replace
11
+ end
@@ -0,0 +1,22 @@
1
+ module NavigationHelpers
2
+
3
+ # Extend the standard PathMatchers with your own paths
4
+ # to be used in your features.
5
+ #
6
+ # The keys and values here may be used in your standard web steps
7
+ # Using:
8
+ #
9
+ # When I go to the "find_replace" admin page
10
+ #
11
+ # would direct the request to the path you provide in the value:
12
+ #
13
+ # admin_find_replace_path
14
+ #
15
+ PathMatchers = {} unless defined?(PathMatchers)
16
+ PathMatchers.merge!({
17
+ # /find_replace/i => 'admin_find_replace_path'
18
+ })
19
+
20
+ end
21
+
22
+ World(NavigationHelpers)
@@ -0,0 +1,21 @@
1
+ # Uncomment this if you reference any of your controllers in activate
2
+ # require_dependency "application_controller"
3
+ require "radiant-find_replace-extension"
4
+
5
+ class FindReplaceExtension < Radiant::Extension
6
+ version RadiantFindReplaceExtension::VERSION
7
+ description RadiantFindReplaceExtension::DESCRIPTION
8
+ url RadiantFindReplaceExtension::URL
9
+
10
+ # See your config/routes.rb file in this extension to define custom routes
11
+
12
+ extension_config do |config|
13
+ # config is the Radiant.configuration object
14
+ end
15
+
16
+ def activate
17
+ tab 'Content' do
18
+ add_item "Find/Replace", "/admin/search", :after => "Pages"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ module RadiantFindReplaceExtension
2
+ VERSION = "1.0.0"
3
+ SUMMARY = "Find Replace for Radiant CMS"
4
+ DESCRIPTION = "Adds backend search and replace functionality to Radiant CMS!"
5
+ URL = "https://github.com/jomz/radiant-find_replace-extension"
6
+ AUTHORS = ["Benny Degezelle"]
7
+ EMAIL = ["hi@monkeypatch.be"]
8
+ end
@@ -0,0 +1,47 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :find_replace do
4
+
5
+ desc "Runs the migration of the Find Replace extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ FindReplaceExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ Rake::Task['db:schema:dump'].invoke
11
+ else
12
+ FindReplaceExtension.migrator.migrate
13
+ Rake::Task['db:schema:dump'].invoke
14
+ end
15
+ end
16
+
17
+ desc "Copies public assets of the Find Replace to the instance public/ directory."
18
+ task :update => :environment do
19
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
20
+ puts "Copying assets from FindReplaceExtension"
21
+ Dir[FindReplaceExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
22
+ path = file.sub(FindReplaceExtension.root, '')
23
+ directory = File.dirname(path)
24
+ mkdir_p RAILS_ROOT + directory, :verbose => false
25
+ cp file, RAILS_ROOT + path, :verbose => false
26
+ end
27
+ end
28
+
29
+ desc "Syncs all available translations for this ext to the English ext master"
30
+ task :sync => :environment do
31
+ # The main translation root, basically where English is kept
32
+ language_root = FindReplaceExtension.root + "/config/locales"
33
+ words = TranslationSupport.get_translation_keys(language_root)
34
+
35
+ Dir["#{language_root}/*.yml"].each do |filename|
36
+ next if filename.match('_available_tags')
37
+ basename = File.basename(filename, '.yml')
38
+ puts "Syncing #{basename}"
39
+ (comments, other) = TranslationSupport.read_file(filename, basename)
40
+ words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
41
+ other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
42
+ TranslationSupport.write_file(filename, basename, comments, other)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "radiant-find_replace-extension"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "radiant-find_replace-extension"
7
+ s.version = RadiantFindReplaceExtension::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = RadiantFindReplaceExtension::AUTHORS
10
+ s.email = RadiantFindReplaceExtension::EMAIL
11
+ s.homepage = RadiantFindReplaceExtension::URL
12
+ s.summary = RadiantFindReplaceExtension::SUMMARY
13
+ s.description = RadiantFindReplaceExtension::DESCRIPTION
14
+
15
+ # Define gem dependencies here.
16
+ # Don't include a dependency on radiant itself: it causes problems when radiant is in vendor/radiant.
17
+ # s.add_dependency "something", "~> 1.0.0"
18
+ # s.add_dependency "radiant-some-extension", "~> 1.0.0"
19
+
20
+ ignores = if File.exist?('.gitignore')
21
+ File.read('.gitignore').split("\n").inject([]) {|a,p| a + Dir[p] }
22
+ else
23
+ []
24
+ end
25
+ s.files = Dir['**/*'] - ignores
26
+ s.test_files = Dir['test/**/*','spec/**/*','features/**/*'] - ignores
27
+ # s.executables = Dir['bin/*'] - ignores
28
+ s.require_paths = ["lib"]
29
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,42 @@
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
+ # Include any datasets from loaded extensions
16
+ Radiant::Extension.descendants.each do |extension|
17
+ if File.directory?(extension.root + "/spec/datasets")
18
+ Dataset::Resolver.default << (extension.root + "/spec/datasets")
19
+ end
20
+ end
21
+
22
+ if File.directory?(File.dirname(__FILE__) + "/matchers")
23
+ Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
24
+ end
25
+
26
+ Spec::Runner.configure do |config|
27
+ # config.use_transactional_fixtures = true
28
+ # config.use_instantiated_fixtures = false
29
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
30
+
31
+ # You can declare fixtures for each behaviour like this:
32
+ # describe "...." do
33
+ # fixtures :table_a, :table_b
34
+ #
35
+ # Alternatively, if you prefer to declare them only once, you can
36
+ # do so here, like so ...
37
+ #
38
+ # config.global_fixtures = :table_a, :table_b
39
+ #
40
+ # If you declare global fixtures, be aware that they will be declared
41
+ # for all of your examples, even those that don't use them.
42
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-find_replace-extension
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Benny Degezelle
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-05-11 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Adds backend search and replace functionality to Radiant CMS!
15
+ email:
16
+ - hi@monkeypatch.be
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - app/controllers/admin/search_controller.rb
22
+ - app/views/admin/search/results.html.haml
23
+ - config/initializers/radiant_config.rb
24
+ - config/locales/en.yml
25
+ - config/routes.rb
26
+ - cucumber.yml
27
+ - features/support/env.rb
28
+ - features/support/paths.rb
29
+ - find_replace_extension.rb
30
+ - lib/radiant-find_replace-extension.rb
31
+ - lib/tasks/find_replace_extension_tasks.rake
32
+ - radiant-find_replace-extension.gemspec
33
+ - Rakefile
34
+ - README.md
35
+ - spec/spec.opts
36
+ - spec/spec_helper.rb
37
+ homepage: https://github.com/jomz/radiant-find_replace-extension
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.23.2
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Find Replace for Radiant CMS
61
+ test_files:
62
+ - spec/spec.opts
63
+ - spec/spec_helper.rb
64
+ - features/support/env.rb
65
+ - features/support/paths.rb