typus 0.9.17
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/.gitignore +8 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +86 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/app/controllers/admin/master_controller.rb +354 -0
- data/app/controllers/typus_controller.rb +128 -0
- data/app/helpers/admin/form_helper.rb +386 -0
- data/app/helpers/admin/master_helper.rb +104 -0
- data/app/helpers/admin/public_helper.rb +27 -0
- data/app/helpers/admin/sidebar_helper.rb +236 -0
- data/app/helpers/admin/table_helper.rb +227 -0
- data/app/helpers/typus_helper.rb +194 -0
- data/app/models/typus_mailer.rb +14 -0
- data/app/models/typus_user.rb +5 -0
- data/app/views/admin/dashboard/_sidebar.html.erb +9 -0
- data/app/views/admin/resources/edit.html.erb +24 -0
- data/app/views/admin/resources/index.html.erb +23 -0
- data/app/views/admin/resources/new.html.erb +22 -0
- data/app/views/admin/resources/show.html.erb +18 -0
- data/app/views/admin/shared/_footer.html.erb +1 -0
- data/app/views/admin/shared/_pagination.html.erb +28 -0
- data/app/views/layouts/admin.html.erb +73 -0
- data/app/views/layouts/typus.html.erb +29 -0
- data/app/views/typus/dashboard.html.erb +9 -0
- data/app/views/typus/recover_password.html.erb +7 -0
- data/app/views/typus/reset_password.html.erb +15 -0
- data/app/views/typus/sign_in.html.erb +9 -0
- data/app/views/typus/sign_up.html.erb +7 -0
- data/app/views/typus_mailer/reset_password_link.erb +11 -0
- data/config/locales/typus/de.yml +109 -0
- data/config/locales/typus/es.yml +109 -0
- data/config/locales/typus/language.yml.template +113 -0
- data/config/locales/typus/pt-BR.yml +111 -0
- data/config/locales/typus/ru.yml +111 -0
- data/generators/typus/templates/config/initializers/typus.rb +33 -0
- data/generators/typus/templates/config/typus/README +51 -0
- data/generators/typus/templates/config/typus/application.yml +6 -0
- data/generators/typus/templates/config/typus/application_roles.yml +23 -0
- data/generators/typus/templates/config/typus/typus.yml +14 -0
- data/generators/typus/templates/config/typus/typus_roles.yml +2 -0
- data/generators/typus/templates/db/create_typus_users.rb +21 -0
- data/generators/typus/templates/public/images/admin/arrow_down.gif +0 -0
- data/generators/typus/templates/public/images/admin/arrow_up.gif +0 -0
- data/generators/typus/templates/public/images/admin/spinner.gif +0 -0
- data/generators/typus/templates/public/images/admin/status_false.gif +0 -0
- data/generators/typus/templates/public/images/admin/status_true.gif +0 -0
- data/generators/typus/templates/public/images/admin/trash.gif +0 -0
- data/generators/typus/templates/public/javascripts/admin/application.js +14 -0
- data/generators/typus/templates/public/stylesheets/admin/reset.css +68 -0
- data/generators/typus/templates/public/stylesheets/admin/screen.css +729 -0
- data/generators/typus/typus_generator.rb +122 -0
- data/generators/typus_update_schema_to_01/templates/config/typus.yml +14 -0
- data/generators/typus_update_schema_to_01/templates/migration.rb +11 -0
- data/generators/typus_update_schema_to_01/typus_update_schema_to_01_generator.rb +19 -0
- data/lib/typus.rb +122 -0
- data/lib/typus/active_record.rb +307 -0
- data/lib/typus/authentication.rb +142 -0
- data/lib/typus/configuration.rb +85 -0
- data/lib/typus/extensions/routes.rb +15 -0
- data/lib/typus/format.rb +55 -0
- data/lib/typus/generator.rb +81 -0
- data/lib/typus/hash.rb +8 -0
- data/lib/typus/locale.rb +17 -0
- data/lib/typus/object.rb +21 -0
- data/lib/typus/quick_edit.rb +40 -0
- data/lib/typus/reloader.rb +15 -0
- data/lib/typus/string.rb +11 -0
- data/lib/typus/templates/index.html.erb +11 -0
- data/lib/typus/templates/resource_controller.rb.erb +15 -0
- data/lib/typus/templates/resource_controller_test.rb.erb +10 -0
- data/lib/typus/templates/resources_controller.rb.erb +37 -0
- data/lib/typus/user.rb +134 -0
- data/lib/vendor/active_record.rb +15 -0
- data/lib/vendor/paginator.rb +143 -0
- data/rails/init.rb +3 -0
- data/tasks/typus_tasks.rake +32 -0
- data/test/config/broken/application.yml +68 -0
- data/test/config/broken/application_roles.yml +20 -0
- data/test/config/broken/empty.yml +0 -0
- data/test/config/broken/empty_roles.yml +0 -0
- data/test/config/broken/undefined.yml +3 -0
- data/test/config/broken/undefined_roles.yml +6 -0
- data/test/config/default/typus.yml +14 -0
- data/test/config/default/typus_roles.yml +2 -0
- data/test/config/empty/empty_01.yml +0 -0
- data/test/config/empty/empty_01_roles.yml +0 -0
- data/test/config/empty/empty_02.yml +0 -0
- data/test/config/empty/empty_02_roles.yml +0 -0
- data/test/config/locales/es.yml +10 -0
- data/test/config/ordered/001_roles.yml +2 -0
- data/test/config/ordered/002_roles.yml +2 -0
- data/test/config/unordered/app_one_roles.yml +2 -0
- data/test/config/unordered/app_two_roles.yml +2 -0
- data/test/config/working/application.yml +68 -0
- data/test/config/working/application_roles.yml +22 -0
- data/test/config/working/typus.yml +14 -0
- data/test/config/working/typus_roles.yml +2 -0
- data/test/fixtures/app/controllers/admin/assets_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/categories_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/comments_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/pages_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/posts_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/status_controller.rb +6 -0
- data/test/fixtures/app/controllers/admin/typus_users_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/watch_dog_controller.rb +6 -0
- data/test/fixtures/app/views/admin/comments/_edit.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_index.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_new.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_show.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/dashboard/_content.html.erb +1 -0
- data/test/fixtures/app/views/admin/dashboard/_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/resources/_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/shared/_footer.html.erb +1 -0
- data/test/fixtures/app/views/admin/status/index.html.erb +1 -0
- data/test/fixtures/app/views/admin/templates/_datepicker.html.erb +1 -0
- data/test/fixtures/assets.yml +11 -0
- data/test/fixtures/categories.yml +14 -0
- data/test/fixtures/comments.yml +27 -0
- data/test/fixtures/pages.yml +41 -0
- data/test/fixtures/posts.yml +37 -0
- data/test/fixtures/typus_users.yml +54 -0
- data/test/functional/admin/assets_controller_test.rb +57 -0
- data/test/functional/admin/categories_controller_test.rb +106 -0
- data/test/functional/admin/comments_controller_test.rb +120 -0
- data/test/functional/admin/master_controller_test.rb +5 -0
- data/test/functional/admin/posts_controller_test.rb +261 -0
- data/test/functional/admin/status_controller_test.rb +43 -0
- data/test/functional/admin/typus_users_controller_test.rb +239 -0
- data/test/functional/typus_controller_test.rb +321 -0
- data/test/helper.rb +51 -0
- data/test/helpers/admin/form_helper_test.rb +337 -0
- data/test/helpers/admin/master_helper_test.rb +69 -0
- data/test/helpers/admin/public_helper_test.rb +26 -0
- data/test/helpers/admin/sidebar_helper_test.rb +335 -0
- data/test/helpers/admin/table_helper_test.rb +239 -0
- data/test/helpers/typus_helper_test.rb +117 -0
- data/test/lib/active_record_test.rb +382 -0
- data/test/lib/configuration_test.rb +94 -0
- data/test/lib/hash_test.rb +11 -0
- data/test/lib/routes_test.rb +71 -0
- data/test/lib/string_test.rb +25 -0
- data/test/lib/typus_test.rb +85 -0
- data/test/models.rb +51 -0
- data/test/schema.rb +64 -0
- data/test/unit/typus_mailer_test.rb +33 -0
- data/test/unit/typus_test.rb +17 -0
- data/test/unit/typus_user_roles_test.rb +90 -0
- data/test/unit/typus_user_test.rb +177 -0
- data/test/vendor/active_record_test.rb +18 -0
- data/test/vendor/paginator_test.rb +136 -0
- data/typus.gemspec +228 -0
- metadata +241 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2007-2009 Francesc Esplugas Marti
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
= Typus: Effortless admin interface for your Rails application
|
|
2
|
+
|
|
3
|
+
*Typus* is designed for a single activity:
|
|
4
|
+
|
|
5
|
+
Trusted users editing structured content.
|
|
6
|
+
|
|
7
|
+
*Typus* doesn't try to be all the things to all the people but it's
|
|
8
|
+
extensible enough to match lots of use cases.
|
|
9
|
+
|
|
10
|
+
- Project site and documentation http://intraducibles.com/projects/typus
|
|
11
|
+
- Plugin source http://github.com/fesplugas/typus/tree
|
|
12
|
+
- Google Group http://groups.google.es/group/typus
|
|
13
|
+
- Bugs http://typus.lighthouseapp.com/dashboard
|
|
14
|
+
|
|
15
|
+
== Impatients to see it working?
|
|
16
|
+
|
|
17
|
+
Step 1: Create a Rails application using a template.
|
|
18
|
+
|
|
19
|
+
$ rails example.com -m http://gist.github.com/86613.txt
|
|
20
|
+
|
|
21
|
+
Step 2: Start the server:
|
|
22
|
+
|
|
23
|
+
$ cd example.com && script/server
|
|
24
|
+
|
|
25
|
+
Step 3: Go to the admin area and enjoy it!
|
|
26
|
+
|
|
27
|
+
http://0.0.0.0:3000/admin
|
|
28
|
+
|
|
29
|
+
== Installing
|
|
30
|
+
|
|
31
|
+
Install from GitHub the latest version which it's compatible with Rails 2.3.2.
|
|
32
|
+
|
|
33
|
+
$ script/plugin install git://github.com/fesplugas/typus.git
|
|
34
|
+
|
|
35
|
+
Once *Typus* is installed, run the generator to create required files and migrate your
|
|
36
|
+
database. (<tt>typus_users</tt> table is created)
|
|
37
|
+
|
|
38
|
+
$ script/generate typus
|
|
39
|
+
$ rake db:migrate
|
|
40
|
+
|
|
41
|
+
To create the first user, start the application server, go to
|
|
42
|
+
http://0.0.0.0:3000/admin and follow the instructions.
|
|
43
|
+
|
|
44
|
+
== Support Typus
|
|
45
|
+
|
|
46
|
+
*Typus* is licensed under the MIT license. As an experiment we
|
|
47
|
+
encourage you to support this project by donating[http://intraducibles.com/projects/typus/donate]
|
|
48
|
+
90 euros if you are a developer or studio. Donations do allow us to spend more
|
|
49
|
+
time working and supporting the project. All contributions are much appreciated!
|
|
50
|
+
|
|
51
|
+
Hire us to work on your next project. We build large and small websites.
|
|
52
|
+
|
|
53
|
+
Contribute your patches to the community & support people on the
|
|
54
|
+
mailing list.
|
|
55
|
+
|
|
56
|
+
Tell everybody about Typus, tell your friends and colleagues about
|
|
57
|
+
Typus and blog about Typus.
|
|
58
|
+
|
|
59
|
+
== Contributors
|
|
60
|
+
|
|
61
|
+
- Laia Gargallo (Lover and tea provider) http://azotacalles.net
|
|
62
|
+
- Isaac Feliu (Codereview on first public release) http://www.vesne.com
|
|
63
|
+
- Lluis Folch (Icons, feedback & crazy ideas) http://wet-floor.com
|
|
64
|
+
- Sergio Espeja (Code) http://github.com/spejman
|
|
65
|
+
- Eadz (Code) http://github.com/eadz
|
|
66
|
+
- Anthony Underwood (Code) http://github.com/aunderwo
|
|
67
|
+
- Felipe Talavera (Code) http://github.com/flype
|
|
68
|
+
- Erik Tigerholm (Code) http://github.com/eriktigerholm
|
|
69
|
+
- George Guimarães (Portuguese translation and code) http://github.com/georgeguimaraes
|
|
70
|
+
- José Valim (Code) http://github.com/josevalim
|
|
71
|
+
- Luqman Amjad (Code) http://github.com/snake
|
|
72
|
+
- Alexey Noskov (Russian translation and code) http://github.com/alno
|
|
73
|
+
- Andres Gutierres (Bugfixes & feedback) http://github.com/andresgutgon
|
|
74
|
+
- Komzák Nándor (Code, bugfixes & feedback) http://github.com/rubymood
|
|
75
|
+
- Michael Grunewalder (German translation) http://michael.grunewalder.com
|
|
76
|
+
- Tim Harvey (Code) http://www.timharvey.net/
|
|
77
|
+
- Ned Baldessin (Code) http://github.com/nedbaldessin
|
|
78
|
+
- Robert Rouse (Code) - Ruby 1.9 compatibility fixes.
|
|
79
|
+
|
|
80
|
+
== Acknowledgments
|
|
81
|
+
|
|
82
|
+
- *Typus* uses "Paginator" by Bruce Williams http://codefluency.com.
|
|
83
|
+
- *Typus* has been inspired by "Django Admin" http://www.djangoproject.com.
|
|
84
|
+
|
|
85
|
+
Copyright (c) 2007-2009 Francesc Esplugas Marti, released under the
|
|
86
|
+
MIT license
|
data/Rakefile
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
require 'rake/rdoctask'
|
|
4
|
+
|
|
5
|
+
desc 'Default: run unit tests.'
|
|
6
|
+
task :default => :test
|
|
7
|
+
|
|
8
|
+
desc 'Test the typus plugin.'
|
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
|
10
|
+
t.libs << 'lib'
|
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
|
12
|
+
t.verbose = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'Generate documentation for the typus plugin.'
|
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
17
|
+
rdoc.rdoc_files.add ['README.rdoc', 'MIT-LICENSE', 'lib/**/*.rb']
|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
19
|
+
rdoc.title = 'Typus documentation'
|
|
20
|
+
rdoc.main = 'README.rdoc'
|
|
21
|
+
rdoc.options << '--charset=UTF-8'
|
|
22
|
+
rdoc.options << '--inline-source'
|
|
23
|
+
rdoc.options << '--line-numbers'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
desc 'Generate specdoc-style documentation from tests'
|
|
27
|
+
task :specs do
|
|
28
|
+
|
|
29
|
+
puts 'Started'
|
|
30
|
+
timer, count = Time.now, 0
|
|
31
|
+
|
|
32
|
+
File.open('SPECDOC', 'w') do |file|
|
|
33
|
+
Dir.glob('test/**/*_test.rb').each do |test|
|
|
34
|
+
test =~ /.*\/([^\/].*)_test.rb$/
|
|
35
|
+
file.puts "#{$1.gsub('_', ' ').capitalize} should:" if $1
|
|
36
|
+
File.read(test).map { |line| /test_(.*)$/.match line }.compact.each do |spec|
|
|
37
|
+
file.puts "- #{spec[1].gsub('_', ' ')}"
|
|
38
|
+
sleep 0.001; print '.'; $stdout.flush; count += 1
|
|
39
|
+
end
|
|
40
|
+
file.puts
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
puts "\nFinished in #{Time.now - timer} seconds.\n"
|
|
45
|
+
puts "#{count} specifications documented"
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
require 'jeweler'
|
|
51
|
+
Jeweler::Tasks.new do |gemspec|
|
|
52
|
+
gemspec.name = "typus"
|
|
53
|
+
gemspec.summary = "Effortless backend interface for Ruby on Rails applications. (Admin scaffold generator.)"
|
|
54
|
+
gemspec.email = "francesc@intraducibles.com"
|
|
55
|
+
gemspec.homepage = "http://intraducibles.com/projects/typus"
|
|
56
|
+
gemspec.description = "Effortless backend interface for Ruby on Rails applications. (Admin scaffold generator.)"
|
|
57
|
+
gemspec.authors = ["Francesc Esplugas"]
|
|
58
|
+
end
|
|
59
|
+
rescue LoadError
|
|
60
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
|
61
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.9.17
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
class Admin::MasterController < ApplicationController
|
|
2
|
+
|
|
3
|
+
unloadable
|
|
4
|
+
|
|
5
|
+
layout 'admin'
|
|
6
|
+
|
|
7
|
+
include Typus::Authentication
|
|
8
|
+
include Typus::Format
|
|
9
|
+
include Typus::Locale
|
|
10
|
+
include Typus::Reloader
|
|
11
|
+
|
|
12
|
+
if Typus::Configuration.options[:ssl]
|
|
13
|
+
include SslRequirement
|
|
14
|
+
ssl_required :index, :new, :create, :edit, :show, :update, :destroy, :toggle, :position, :relate, :unrelate
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
filter_parameter_logging :password
|
|
18
|
+
|
|
19
|
+
before_filter :reload_config_et_roles
|
|
20
|
+
|
|
21
|
+
before_filter :require_login
|
|
22
|
+
|
|
23
|
+
before_filter :set_locale
|
|
24
|
+
|
|
25
|
+
before_filter :set_resource
|
|
26
|
+
before_filter :find_item,
|
|
27
|
+
:only => [ :show, :edit, :update, :destroy, :toggle, :position, :relate, :unrelate ]
|
|
28
|
+
|
|
29
|
+
before_filter :check_ownership_of_item,
|
|
30
|
+
:only => [ :edit, :update, :destroy, :toggle, :position, :relate, :unrelate ]
|
|
31
|
+
|
|
32
|
+
before_filter :check_if_user_can_perform_action_on_user,
|
|
33
|
+
:only => [ :edit, :update, :toggle, :destroy ]
|
|
34
|
+
before_filter :check_if_user_can_perform_action_on_resource
|
|
35
|
+
|
|
36
|
+
before_filter :set_order,
|
|
37
|
+
:only => [ :index ]
|
|
38
|
+
before_filter :set_fields,
|
|
39
|
+
:only => [ :index, :new, :edit, :create, :update, :show ]
|
|
40
|
+
|
|
41
|
+
before_filter :set_tiny_mce,
|
|
42
|
+
:only => [ :new, :edit, :create, :update ]
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# This is the main index of the model. With filters, conditions
|
|
46
|
+
# and more.
|
|
47
|
+
#
|
|
48
|
+
# By default application can respond_to html, csv and xml, but you
|
|
49
|
+
# can add your formats.
|
|
50
|
+
#
|
|
51
|
+
def index
|
|
52
|
+
|
|
53
|
+
@conditions, @joins = @resource[:class].build_conditions(params)
|
|
54
|
+
|
|
55
|
+
check_ownership_of_items if @resource[:class].typus_options_for(:only_user_items)
|
|
56
|
+
|
|
57
|
+
respond_to do |format|
|
|
58
|
+
format.html { generate_html }
|
|
59
|
+
@resource[:class].typus_export_formats.each do |f|
|
|
60
|
+
format.send(f) { send("generate_#{f}") }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
rescue Exception => error
|
|
65
|
+
error_handler(error)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def new
|
|
69
|
+
|
|
70
|
+
item_params = params.dup
|
|
71
|
+
%w( controller action resource resource_id back_to selected ).each do |param|
|
|
72
|
+
item_params.delete(param)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
@item = @resource[:class].new(item_params.symbolize_keys)
|
|
76
|
+
|
|
77
|
+
select_template :new
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# Create new items. There's an special case when we create an
|
|
83
|
+
# item from another item. In this case, after the item is
|
|
84
|
+
# created we also create the relationship between these items.
|
|
85
|
+
#
|
|
86
|
+
def create
|
|
87
|
+
|
|
88
|
+
@item = @resource[:class].new(params[:item])
|
|
89
|
+
|
|
90
|
+
if @item.attributes.include?(Typus.user_fk)
|
|
91
|
+
@item.attributes = { Typus.user_fk => session[:typus_user_id] }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if @item.valid?
|
|
95
|
+
create_with_back_to and return if params[:back_to]
|
|
96
|
+
@item.save
|
|
97
|
+
flash[:success] = _("{{model}} successfully created.", :model => @resource[:class].typus_human_name)
|
|
98
|
+
if @resource[:class].typus_options_for(:index_after_save)
|
|
99
|
+
redirect_to :action => 'index'
|
|
100
|
+
else
|
|
101
|
+
redirect_to :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id
|
|
102
|
+
end
|
|
103
|
+
else
|
|
104
|
+
select_template :new
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def edit
|
|
110
|
+
item_params = params.dup
|
|
111
|
+
%w( action controller model model_id back_to id resource resource_id page ).each { |p| item_params.delete(p) }
|
|
112
|
+
# We assign the params passed trough the url
|
|
113
|
+
@item.attributes = item_params
|
|
114
|
+
@previous, @next = @item.previous_and_next(item_params)
|
|
115
|
+
select_template :edit
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def show
|
|
119
|
+
|
|
120
|
+
@previous, @next = @item.previous_and_next
|
|
121
|
+
|
|
122
|
+
respond_to do |format|
|
|
123
|
+
format.html { select_template :show }
|
|
124
|
+
format.xml do
|
|
125
|
+
fields = @resource[:class].typus_fields_for(:xml).collect { |i| i.first }
|
|
126
|
+
render :xml => @item.to_xml(:only => fields)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def update
|
|
133
|
+
if @item.update_attributes(params[:item])
|
|
134
|
+
flash[:success] = _("{{model}} successfully updated.", :model => @resource[:class].typus_human_name)
|
|
135
|
+
path = if @resource[:class].typus_options_for(:index_after_save)
|
|
136
|
+
params[:back_to] ? "#{params[:back_to]}##{@resource[:self]}" : { :action => 'index' }
|
|
137
|
+
else
|
|
138
|
+
{ :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id, :back_to => params[:back_to] }
|
|
139
|
+
end
|
|
140
|
+
redirect_to path
|
|
141
|
+
else
|
|
142
|
+
@previous, @next = @item.previous_and_next
|
|
143
|
+
select_template :edit
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def destroy
|
|
148
|
+
@item.destroy
|
|
149
|
+
flash[:success] = _("{{model}} successfully removed.", :model => @resource[:class].typus_human_name)
|
|
150
|
+
redirect_to :back
|
|
151
|
+
rescue Exception => error
|
|
152
|
+
error_handler(error, params.merge(:action => 'index', :id => nil))
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def toggle
|
|
156
|
+
if @resource[:class].typus_options_for(:toggle)
|
|
157
|
+
@item.toggle!(params[:field])
|
|
158
|
+
flash[:success] = _("{{model}} {{attribute}} changed.",
|
|
159
|
+
:model => @resource[:class].typus_human_name,
|
|
160
|
+
:attribute => params[:field].humanize.downcase)
|
|
161
|
+
else
|
|
162
|
+
flash[:notice] = _("Toggle is disabled.")
|
|
163
|
+
end
|
|
164
|
+
redirect_to :back
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
##
|
|
168
|
+
# Change item position. This only works if acts_as_list is
|
|
169
|
+
# installed. We can then move items:
|
|
170
|
+
#
|
|
171
|
+
# params[:go] = 'move_to_top'
|
|
172
|
+
#
|
|
173
|
+
# Available positions are move_to_top, move_higher, move_lower,
|
|
174
|
+
# move_to_bottom.
|
|
175
|
+
#
|
|
176
|
+
def position
|
|
177
|
+
@item.send(params[:go])
|
|
178
|
+
flash[:success] = _("Record moved {{to}}.", :to => params[:go].gsub(/move_/, '').humanize.downcase)
|
|
179
|
+
redirect_to :back
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
##
|
|
183
|
+
# Relate a model object to another, this action is used only by the
|
|
184
|
+
# has_and_belongs_to_many relationships.
|
|
185
|
+
#
|
|
186
|
+
def relate
|
|
187
|
+
|
|
188
|
+
resource_class = params[:related][:model].constantize
|
|
189
|
+
resource_tableized = params[:related][:model].tableize
|
|
190
|
+
|
|
191
|
+
@item.send(resource_tableized) << resource_class.find(params[:related][:id])
|
|
192
|
+
|
|
193
|
+
flash[:success] = _("{{model_a}} related to {{model_b}}.",
|
|
194
|
+
:model_a => resource_class.typus_human_name,
|
|
195
|
+
:model_b => @resource[:class].typus_human_name)
|
|
196
|
+
|
|
197
|
+
redirect_to :action => @resource[:class].typus_options_for(:default_action_on_item),
|
|
198
|
+
:id => @item.id,
|
|
199
|
+
:anchor => resource_tableized
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
##
|
|
204
|
+
# Remove relationship between models.
|
|
205
|
+
#
|
|
206
|
+
def unrelate
|
|
207
|
+
|
|
208
|
+
resource_class = params[:resource].classify.constantize
|
|
209
|
+
resource = resource_class.find(params[:resource_id])
|
|
210
|
+
|
|
211
|
+
case params[:association]
|
|
212
|
+
when 'has_and_belongs_to_many'
|
|
213
|
+
@item.send(resource_class.table_name).delete(resource)
|
|
214
|
+
message = "{{model_a}} unrelated from {{model_b}}."
|
|
215
|
+
when 'has_many', 'has_one'
|
|
216
|
+
resource.destroy
|
|
217
|
+
message = "{{model_a}} removed from {{model_b}}."
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
flash[:success] = _(message, :model_a => resource_class.typus_human_name, :model_b => @resource[:class].typus_human_name)
|
|
221
|
+
|
|
222
|
+
redirect_to :controller => @resource[:self],
|
|
223
|
+
:action => @resource[:class].typus_options_for(:default_action_on_item),
|
|
224
|
+
:id => @item.id,
|
|
225
|
+
:anchor => resource_class.table_name
|
|
226
|
+
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
private
|
|
230
|
+
|
|
231
|
+
def set_resource
|
|
232
|
+
resource = params[:controller].split('/').last
|
|
233
|
+
@resource = { :self => resource, :class => resource.classify.constantize }
|
|
234
|
+
rescue Exception => error
|
|
235
|
+
error_handler(error)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
##
|
|
239
|
+
# Find model when performing an edit, update, destroy, relate,
|
|
240
|
+
# unrelate ...
|
|
241
|
+
#
|
|
242
|
+
def find_item
|
|
243
|
+
@item = @resource[:class].find(params[:id])
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
##
|
|
247
|
+
# If item is owned by another user, we only can perform a
|
|
248
|
+
# show action on the item. Updated item is also blocked.
|
|
249
|
+
#
|
|
250
|
+
# before_filter :check_ownership_of_item, :only => [ :edit, :update, :destroy ]
|
|
251
|
+
#
|
|
252
|
+
def check_ownership_of_item
|
|
253
|
+
|
|
254
|
+
# If current_user is a root user, by-pass.
|
|
255
|
+
return if @current_user.is_root?
|
|
256
|
+
|
|
257
|
+
# OPTIMIZE: `typus_users` is currently hard-coded. We should find a good name for this option.
|
|
258
|
+
if @item.respond_to?('typus_users') && !@item.send('typus_users').include?(@current_user) ||
|
|
259
|
+
@item.respond_to?(Typus.user_fk) && !(@item.send(Typus.user_fk) == session[:typus_user_id])
|
|
260
|
+
flash[:notice] = _("You don't have permission to access this item.")
|
|
261
|
+
redirect_to :back
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def check_ownership_of_items
|
|
267
|
+
|
|
268
|
+
# By-pass if current_user is root.
|
|
269
|
+
return if @current_user.is_root?
|
|
270
|
+
|
|
271
|
+
# If current user is not root and @resource has a foreign_key which
|
|
272
|
+
# is related to the logged user (Typus.user_fk) we only show the user
|
|
273
|
+
# related items.
|
|
274
|
+
if @resource[:class].columns.map { |u| u.name }.include?(Typus.user_fk)
|
|
275
|
+
condition = { Typus.user_fk => @current_user }
|
|
276
|
+
@conditions = @resource[:class].merge_conditions(@conditions, condition)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def set_fields
|
|
282
|
+
@fields = case params[:action]
|
|
283
|
+
when 'index'
|
|
284
|
+
@resource[:class].typus_fields_for(:list)
|
|
285
|
+
when 'new', 'edit', 'create', 'update'
|
|
286
|
+
@resource[:class].typus_fields_for(:form)
|
|
287
|
+
else
|
|
288
|
+
@resource[:class].typus_fields_for(params[:action])
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def set_order
|
|
293
|
+
params[:sort_order] ||= 'desc'
|
|
294
|
+
@order = params[:order_by] ? "#{@resource[:class].table_name}.#{params[:order_by]} #{params[:sort_order]}" : @resource[:class].typus_order_by
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def set_tiny_mce
|
|
298
|
+
if !@resource[:class].typus_tiny_mce_fields.empty? && defined?(TinyMCE)
|
|
299
|
+
options = @resource[:class].typus_tiny_mce_options
|
|
300
|
+
self.class.class_eval { uses_tiny_mce :options => options }
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def select_template(template, resource = @resource[:self])
|
|
305
|
+
folder = (File.exist?("app/views/admin/#{resource}/#{template}.html.erb")) ? resource : 'resources'
|
|
306
|
+
render "admin/#{folder}/#{template}"
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
##
|
|
310
|
+
# When <tt>params[:back_to]</tt> is defined this action is used.
|
|
311
|
+
#
|
|
312
|
+
# - <tt>has_and_belongs_to_many</tt> relationships.
|
|
313
|
+
# - <tt>has_many</tt> relationships (polymorphic ones).
|
|
314
|
+
#
|
|
315
|
+
def create_with_back_to
|
|
316
|
+
|
|
317
|
+
if params[:resource] && params[:resource_id]
|
|
318
|
+
resource_class = params[:resource].classify.constantize
|
|
319
|
+
resource_id = params[:resource_id]
|
|
320
|
+
resource = resource_class.find(resource_id)
|
|
321
|
+
association = @resource[:class].reflect_on_association(params[:resource].to_sym).macro rescue :polymorphic
|
|
322
|
+
else
|
|
323
|
+
association = :has_many
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
case association
|
|
327
|
+
when :belongs_to
|
|
328
|
+
@item.save
|
|
329
|
+
when :has_and_belongs_to_many
|
|
330
|
+
@item.save
|
|
331
|
+
@item.send(params[:resource]) << resource
|
|
332
|
+
when :has_many
|
|
333
|
+
@item.save
|
|
334
|
+
message = _("{{model}} successfully created.", :model => @resource[:class].typus_human_name)
|
|
335
|
+
path = "#{params[:back_to]}?#{params[:selected]}=#{@item.id}"
|
|
336
|
+
when :polymorphic
|
|
337
|
+
resource.send(@item.class.name.tableize).create(params[:item])
|
|
338
|
+
path = "#{params[:back_to]}##{@resource[:self]}"
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
flash[:success] = message || _("{{model_a}} successfully assigned to {{model_b}}.",
|
|
342
|
+
:model_a => @item.class.typus_human_name,
|
|
343
|
+
:model_b => resource_class.name)
|
|
344
|
+
redirect_to path || params[:back_to]
|
|
345
|
+
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def error_handler(error, path = admin_dashboard_path)
|
|
349
|
+
raise error unless Rails.env.production?
|
|
350
|
+
flash[:error] = "#{error.message} (#{@resource[:class]})"
|
|
351
|
+
redirect_to path
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
end
|