fesplugas-typus 0.9.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/.gitignore +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +80 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/app/controllers/admin/master_controller.rb +324 -0
- data/app/controllers/typus_controller.rb +127 -0
- data/app/helpers/admin/form_helper.rb +351 -0
- data/app/helpers/admin/master_helper.rb +99 -0
- data/app/helpers/admin/public_helper.rb +24 -0
- data/app/helpers/admin/sidebar_helper.rb +259 -0
- data/app/helpers/admin/table_helper.rb +227 -0
- data/app/helpers/typus_helper.rb +169 -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 +29 -0
- data/app/views/admin/resources/index.html.erb +28 -0
- data/app/views/admin/resources/new.html.erb +27 -0
- data/app/views/admin/resources/show.html.erb +21 -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 +72 -0
- data/app/views/layouts/typus.html.erb +29 -0
- data/app/views/typus/dashboard.html.erb +13 -0
- data/app/views/typus/recover_password.html.erb +7 -0
- data/app/views/typus/reset_password.html.erb +13 -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/es.yml +106 -0
- data/config/locales/pt-BR.yml +108 -0
- data/config/locales/typus_hacks.yml +14 -0
- data/config/routes.rb +14 -0
- data/generators/typus/templates/config/initializers/typus.rb +27 -0
- data/generators/typus/templates/config/typus/application.yml +45 -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 +709 -0
- data/generators/typus/typus_generator.rb +141 -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/init.rb +19 -0
- data/lib/typus/active_record.rb +298 -0
- data/lib/typus/authentication.rb +155 -0
- data/lib/typus/configuration.rb +92 -0
- data/lib/typus/format.rb +56 -0
- data/lib/typus/generator.rb +173 -0
- data/lib/typus/hash.rb +10 -0
- data/lib/typus/locale.rb +17 -0
- data/lib/typus/object.rb +22 -0
- data/lib/typus/quick_edit.rb +33 -0
- data/lib/typus/reloader.rb +17 -0
- data/lib/typus/string.rb +11 -0
- data/lib/typus/user.rb +137 -0
- data/lib/typus.rb +133 -0
- data/lib/vendor/active_record.rb +15 -0
- data/lib/vendor/paginator.rb +143 -0
- data/tasks/typus_tasks.rake +26 -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 +67 -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_bottom.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_edit_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_edit_top.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_index_bottom.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_index_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_index_top.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_new_bottom.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_new_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_new_top.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_show_bottom.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_show_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_show_top.html.erb +1 -0
- data/test/fixtures/app/views/admin/dashboard/_bottom.html.erb +1 -0
- data/test/fixtures/app/views/admin/dashboard/_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/dashboard/_top.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 +121 -0
- data/test/functional/admin/master_controller_test.rb +5 -0
- data/test/functional/admin/posts_controller_test.rb +278 -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 +315 -0
- data/test/helper.rb +51 -0
- data/test/helpers/admin/form_helper_test.rb +316 -0
- data/test/helpers/admin/master_helper_test.rb +65 -0
- data/test/helpers/admin/public_helper_test.rb +22 -0
- data/test/helpers/admin/sidebar_helper_test.rb +351 -0
- data/test/helpers/admin/table_helper_test.rb +255 -0
- data/test/helpers/typus_helper_test.rb +106 -0
- data/test/lib/active_record_test.rb +372 -0
- data/test/lib/configuration_test.rb +91 -0
- data/test/lib/hash_test.rb +11 -0
- data/test/lib/routes_test.rb +82 -0
- data/test/lib/string_test.rb +25 -0
- data/test/lib/typus_test.rb +105 -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 +138 -0
- data/typus.gemspec +225 -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,80 @@
|
|
|
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
|
+
- Screenshoots http://intraducibles.com/projects/typus/screenshots
|
|
12
|
+
- Plugin source http://github.com/fesplugas/typus/tree
|
|
13
|
+
- Google Group http://groups.google.es/group/typus
|
|
14
|
+
|
|
15
|
+
== For the impatients: Demo in 3 steps
|
|
16
|
+
|
|
17
|
+
Step 1. Create a Rails application using a template.
|
|
18
|
+
|
|
19
|
+
$ rails example.com -m http://intraducibles.com/projects/typus/demo.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
|
|
32
|
+
Rails 2.3.2.
|
|
33
|
+
|
|
34
|
+
$ script/plugin install git://github.com/fesplugas/typus.git
|
|
35
|
+
|
|
36
|
+
Once plugin is installed generate *Typus* files and migrate your
|
|
37
|
+
database (<tt>typus_users</tt> table is created)
|
|
38
|
+
|
|
39
|
+
$ script/generate typus
|
|
40
|
+
$ rake db:migrate
|
|
41
|
+
|
|
42
|
+
To create the first user, start the application server, go to
|
|
43
|
+
http://0.0.0.0:3000/admin and follow the instructions.
|
|
44
|
+
|
|
45
|
+
== Support Typus
|
|
46
|
+
|
|
47
|
+
*Typus* is licensed under the MIT license. As an experiment we
|
|
48
|
+
encourage you to support this project by donating[http://intraducibles.com/projects/typus/donate]
|
|
49
|
+
90 euros if you are a developer or studio. Donations do allow us to spend more
|
|
50
|
+
time working and supporting the project. All contributions are much appreciated!
|
|
51
|
+
|
|
52
|
+
Hire us to work on your next project. We build large and small websites.
|
|
53
|
+
|
|
54
|
+
Contribute your patches to the community & support people on the
|
|
55
|
+
mailing list.
|
|
56
|
+
|
|
57
|
+
Tell everybody about Typus, tell your friends and colleagues about
|
|
58
|
+
Typus and blog about Typus.
|
|
59
|
+
|
|
60
|
+
== Contributors
|
|
61
|
+
|
|
62
|
+
- Laia Gargallo (Lover and tea provider) http://azotacalles.net
|
|
63
|
+
- Isaac Feliu (Codereview on first public release) http://www.vesne.com
|
|
64
|
+
- Lluis Folch (Icons, feedback & crazy ideas) http://wet-floor.com
|
|
65
|
+
- Sergio Espeja (Code) http://github.com/spejman
|
|
66
|
+
- Eadz (Code) http://github.com/eadz
|
|
67
|
+
- Anthony Underwood (Code) http://github.com/aunderwo
|
|
68
|
+
- Felipe Talavera (Code) http://github.com/flype
|
|
69
|
+
- Erik Tigerholm (Code) http://github.com/eriktigerholm
|
|
70
|
+
- George Guimarães (Translation pt-br and code) http://github.com/georgeguimaraes
|
|
71
|
+
- José Valim (Code) http://github.com/josevalim
|
|
72
|
+
- Luqman Amjad (Code) http://github.com/snake
|
|
73
|
+
|
|
74
|
+
== Acknowledgments
|
|
75
|
+
|
|
76
|
+
- *Typus* uses "Paginator" by Bruce Williams http://codefluency.com.
|
|
77
|
+
- *Typus* has been inspired by "Django Admin" http://www.djangoproject.com.
|
|
78
|
+
|
|
79
|
+
Copyright (c) 2007-2009 Francesc Esplugas Marti, released under the
|
|
80
|
+
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.0
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
class Admin::MasterController < ApplicationController
|
|
2
|
+
|
|
3
|
+
layout 'admin'
|
|
4
|
+
|
|
5
|
+
include Typus::Authentication
|
|
6
|
+
include Typus::Format
|
|
7
|
+
include Typus::Locale
|
|
8
|
+
include Typus::Reloader
|
|
9
|
+
|
|
10
|
+
if Typus::Configuration.options[:ssl]
|
|
11
|
+
include SslRequirement
|
|
12
|
+
ssl_required :index, :new, :create, :edit, :show, :update, :destroy, :toggle, :position, :relate, :unrelate
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
filter_parameter_logging :password
|
|
16
|
+
|
|
17
|
+
before_filter :reload_config_et_roles
|
|
18
|
+
|
|
19
|
+
before_filter :require_login
|
|
20
|
+
|
|
21
|
+
before_filter :set_locale
|
|
22
|
+
|
|
23
|
+
before_filter :set_resource
|
|
24
|
+
before_filter :find_item,
|
|
25
|
+
:only => [ :show, :edit, :update, :destroy, :toggle, :position, :relate, :unrelate ]
|
|
26
|
+
|
|
27
|
+
before_filter :check_ownership_of_item,
|
|
28
|
+
:only => [ :edit, :update, :destroy, :toggle, :position, :relate, :unrelate ]
|
|
29
|
+
|
|
30
|
+
before_filter :check_if_user_can_perform_action_on_user,
|
|
31
|
+
:only => [ :edit, :update, :toggle, :destroy ]
|
|
32
|
+
before_filter :check_if_user_can_perform_action_on_resource
|
|
33
|
+
|
|
34
|
+
before_filter :set_order,
|
|
35
|
+
:only => [ :index ]
|
|
36
|
+
before_filter :set_fields,
|
|
37
|
+
:only => [ :index, :new, :edit, :create, :update, :show ]
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# This is the main index of the model. With filters, conditions
|
|
41
|
+
# and more.
|
|
42
|
+
#
|
|
43
|
+
# By default application can respond_to html, csv and xml, but you
|
|
44
|
+
# can add your formats.
|
|
45
|
+
#
|
|
46
|
+
def index
|
|
47
|
+
|
|
48
|
+
@conditions, @joins = @resource[:class].build_conditions(params)
|
|
49
|
+
|
|
50
|
+
respond_to do |format|
|
|
51
|
+
format.html { generate_html }
|
|
52
|
+
@resource[:class].typus_export_formats.each do |f|
|
|
53
|
+
format.send(f) { send("generate_#{f}") }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
rescue Exception => error
|
|
58
|
+
error_handler(error)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def new
|
|
62
|
+
|
|
63
|
+
item_params = params.dup
|
|
64
|
+
%w( controller action resource resource_id back_to selected ).each do |param|
|
|
65
|
+
item_params.delete(param)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
@item = @resource[:class].new(item_params.symbolize_keys)
|
|
69
|
+
|
|
70
|
+
select_template :new
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
##
|
|
75
|
+
# Create new items. There's an special case when we create an
|
|
76
|
+
# item from another item. In this case, after the item is
|
|
77
|
+
# created we also create the relationship between these items.
|
|
78
|
+
#
|
|
79
|
+
def create
|
|
80
|
+
|
|
81
|
+
@item = @resource[:class].new(params[:item])
|
|
82
|
+
|
|
83
|
+
if @item.attributes.include?(Typus.user_fk)
|
|
84
|
+
@item.attributes = { Typus.user_fk => session[:typus_user_id] }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if @item.valid?
|
|
88
|
+
create_with_back_to and return if params[:back_to]
|
|
89
|
+
@item.save
|
|
90
|
+
flash[:success] = _("{{model}} successfully created.", :model => @resource[:class].human_name)
|
|
91
|
+
if @resource[:class].typus_options_for(:index_after_save)
|
|
92
|
+
redirect_to :action => 'index'
|
|
93
|
+
else
|
|
94
|
+
redirect_to :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id
|
|
95
|
+
end
|
|
96
|
+
else
|
|
97
|
+
select_template :new
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def edit
|
|
103
|
+
item_params = params.dup
|
|
104
|
+
%w( action controller model model_id back_to id resource resource_id ).each { |p| item_params.delete(p) }
|
|
105
|
+
# We assign the params passed trough the url
|
|
106
|
+
@item.attributes = item_params
|
|
107
|
+
@previous, @next = @item.previous_and_next(item_params)
|
|
108
|
+
select_template :edit
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def show
|
|
112
|
+
|
|
113
|
+
@previous, @next = @item.previous_and_next
|
|
114
|
+
|
|
115
|
+
respond_to do |format|
|
|
116
|
+
format.html { select_template :show }
|
|
117
|
+
format.xml { render :xml => @item }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def update
|
|
123
|
+
if @item.update_attributes(params[:item])
|
|
124
|
+
flash[:success] = _("{{model}} successfully updated.", :model => @resource[:class].human_name)
|
|
125
|
+
path = if @resource[:class].typus_options_for(:index_after_save)
|
|
126
|
+
params[:back_to] ? "#{params[:back_to]}##{@resource[:self]}" : { :action => 'index' }
|
|
127
|
+
else
|
|
128
|
+
{ :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id }
|
|
129
|
+
end
|
|
130
|
+
redirect_to path
|
|
131
|
+
else
|
|
132
|
+
@previous, @next = @item.previous_and_next
|
|
133
|
+
select_template :edit
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def destroy
|
|
138
|
+
@item.destroy
|
|
139
|
+
flash[:success] = _("{{model}} successfully removed.", :model => @resource[:class].human_name)
|
|
140
|
+
redirect_to :back
|
|
141
|
+
rescue Exception => error
|
|
142
|
+
error_handler(error, params.merge(:action => 'index', :id => nil))
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def toggle
|
|
146
|
+
if @resource[:class].typus_options_for(:toggle)
|
|
147
|
+
@item.toggle!(params[:field])
|
|
148
|
+
flash[:success] = _("{{model}} {{attribute}} changed.",
|
|
149
|
+
:model => @resource[:class].human_name,
|
|
150
|
+
:attribute => params[:field].humanize.downcase)
|
|
151
|
+
else
|
|
152
|
+
flash[:notice] = _("Toggle is disabled.")
|
|
153
|
+
end
|
|
154
|
+
redirect_to :back
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
# Change item position. This only works if acts_as_list is
|
|
159
|
+
# installed. We can then move items:
|
|
160
|
+
#
|
|
161
|
+
# params[:go] = 'move_to_top'
|
|
162
|
+
#
|
|
163
|
+
# Available positions are move_to_top, move_higher, move_lower,
|
|
164
|
+
# move_to_bottom.
|
|
165
|
+
#
|
|
166
|
+
def position
|
|
167
|
+
@item.send(params[:go])
|
|
168
|
+
flash[:success] = _("Record moved {{to}}.", :to => params[:go].gsub(/move_/, '').humanize.downcase)
|
|
169
|
+
redirect_to :back
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
##
|
|
173
|
+
# Relate a model object to another, this action is used only by the
|
|
174
|
+
# has_and_belongs_to_many relationships.
|
|
175
|
+
#
|
|
176
|
+
def relate
|
|
177
|
+
|
|
178
|
+
resource_class = params[:related][:model].constantize
|
|
179
|
+
resource_tableized = params[:related][:model].tableize
|
|
180
|
+
|
|
181
|
+
@item.send(resource_tableized) << resource_class.find(params[:related][:id])
|
|
182
|
+
|
|
183
|
+
flash[:success] = _("{{model_a}} related to {{model_b}}.",
|
|
184
|
+
:model_a => resource_class.human_name,
|
|
185
|
+
:model_b => @resource[:class].human_name)
|
|
186
|
+
|
|
187
|
+
redirect_to :action => @resource[:class].typus_options_for(:default_action_on_item),
|
|
188
|
+
:id => @item.id,
|
|
189
|
+
:anchor => resource_tableized
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
##
|
|
194
|
+
# Remove relationship between models.
|
|
195
|
+
#
|
|
196
|
+
def unrelate
|
|
197
|
+
|
|
198
|
+
resource_class = params[:resource].classify.constantize
|
|
199
|
+
resource = resource_class.find(params[:resource_id])
|
|
200
|
+
|
|
201
|
+
case params[:association]
|
|
202
|
+
when 'has_and_belongs_to_many'
|
|
203
|
+
@item.send(resource_class.table_name).delete(resource)
|
|
204
|
+
message = "{{model_a}} unrelated from {{model_b}}."
|
|
205
|
+
when 'has_many', 'has_one'
|
|
206
|
+
resource.destroy
|
|
207
|
+
message = "{{model_a}} removed from {{model_b}}."
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
flash[:success] = _(message, :model_a => resource_class.human_name, :model_b => @resource[:class].human_name)
|
|
211
|
+
|
|
212
|
+
redirect_to :controller => @resource[:self],
|
|
213
|
+
:action => @resource[:class].typus_options_for(:default_action_on_item),
|
|
214
|
+
:id => @item.id,
|
|
215
|
+
:anchor => resource_class.table_name
|
|
216
|
+
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
private
|
|
220
|
+
|
|
221
|
+
def set_resource
|
|
222
|
+
resource = params[:controller].split('/').last
|
|
223
|
+
@resource = { :self => resource, :class => resource.classify.constantize }
|
|
224
|
+
rescue Exception => error
|
|
225
|
+
error_handler(error)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
##
|
|
229
|
+
# Find model when performing an edit, update, destroy, relate,
|
|
230
|
+
# unrelate ...
|
|
231
|
+
#
|
|
232
|
+
def find_item
|
|
233
|
+
@item = @resource[:class].find(params[:id])
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
##
|
|
237
|
+
# If item is owned by another user, we only can perform a
|
|
238
|
+
# show action on the item. Updated item is also blocked.
|
|
239
|
+
#
|
|
240
|
+
# before_filter :check_ownership_of_item, :only => [ :edit, :update, :destroy ]
|
|
241
|
+
#
|
|
242
|
+
def check_ownership_of_item
|
|
243
|
+
|
|
244
|
+
# If current_user is a root user, by-pass.
|
|
245
|
+
return if @current_user.is_root?
|
|
246
|
+
|
|
247
|
+
# If the current model doesn't include a key which relates it with the
|
|
248
|
+
# current_user, by-pass.
|
|
249
|
+
return unless @item.respond_to?(Typus.user_fk)
|
|
250
|
+
|
|
251
|
+
# If item is owned by the user ...
|
|
252
|
+
unless @item.send(Typus.user_fk) == session[:typus_user_id]
|
|
253
|
+
flash[:notice] = _("Record owned by another user.")
|
|
254
|
+
redirect_to :action => 'show', :id => @item.id
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def set_fields
|
|
260
|
+
@fields = case params[:action]
|
|
261
|
+
when 'index'
|
|
262
|
+
@resource[:class].typus_fields_for(:list)
|
|
263
|
+
when 'new', 'edit', 'create', 'update'
|
|
264
|
+
@resource[:class].typus_fields_for(:form)
|
|
265
|
+
else
|
|
266
|
+
@resource[:class].typus_fields_for(params[:action])
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def set_order
|
|
271
|
+
params[:sort_order] ||= 'desc'
|
|
272
|
+
@order = params[:order_by] ? "#{@resource[:class].table_name}.#{params[:order_by]} #{params[:sort_order]}" : @resource[:class].typus_order_by
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def select_template(template, resource = @resource[:self])
|
|
276
|
+
folder = (File.exists?("app/views/admin/#{resource}/#{template}.html.erb")) ? resource : 'resources'
|
|
277
|
+
render :template => "admin/#{folder}/#{template}"
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
##
|
|
281
|
+
# When <tt>params[:back_to]</tt> is defined this action is used.
|
|
282
|
+
#
|
|
283
|
+
# - <tt>has_and_belongs_to_many</tt> relationships.
|
|
284
|
+
# - <tt>has_many</tt> relationships (polymorphic ones).
|
|
285
|
+
#
|
|
286
|
+
def create_with_back_to
|
|
287
|
+
|
|
288
|
+
if params[:resource] && params[:resource_id]
|
|
289
|
+
resource_class = params[:resource].classify.constantize
|
|
290
|
+
resource_id = params[:resource_id]
|
|
291
|
+
resource = resource_class.find(resource_id)
|
|
292
|
+
association = @resource[:class].reflect_on_association(params[:resource].to_sym).macro rescue :polymorphic
|
|
293
|
+
else
|
|
294
|
+
association = :has_many
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
case association
|
|
298
|
+
when :belongs_to
|
|
299
|
+
@item.save
|
|
300
|
+
when :has_and_belongs_to_many
|
|
301
|
+
@item.save
|
|
302
|
+
@item.send(params[:resource]) << resource
|
|
303
|
+
when :has_many
|
|
304
|
+
@item.save
|
|
305
|
+
message = _("{{model}} successfully created.", :model => @resource[:class].human_name)
|
|
306
|
+
path = "#{params[:back_to]}?#{params[:selected]}=#{@item.id}"
|
|
307
|
+
when :polymorphic
|
|
308
|
+
resource.send(@item.class.name.tableize).create(params[:item])
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
flash[:success] = message || _("{{model_a}} successfully assigned to {{model_b}}.",
|
|
312
|
+
:model_a => @item.class,
|
|
313
|
+
:model_b => resource_class.name)
|
|
314
|
+
redirect_to path || "#{params[:back_to]}##{@resource[:self]}"
|
|
315
|
+
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def error_handler(error, path = admin_dashboard_path)
|
|
319
|
+
raise error unless Rails.env.production?
|
|
320
|
+
flash[:error] = "#{error.message} (#{@resource[:class]})"
|
|
321
|
+
redirect_to path
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
class TypusController < ApplicationController
|
|
2
|
+
|
|
3
|
+
layout :select_layout
|
|
4
|
+
|
|
5
|
+
include Typus::Authentication
|
|
6
|
+
include Typus::Locale
|
|
7
|
+
include Typus::QuickEdit
|
|
8
|
+
include Typus::Reloader
|
|
9
|
+
|
|
10
|
+
if Typus::Configuration.options[:ssl]
|
|
11
|
+
include SslRequirement
|
|
12
|
+
ssl_required :sign_in, :sign_out,
|
|
13
|
+
:dashboard,
|
|
14
|
+
:recover_password, :reset_password
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
filter_parameter_logging :password
|
|
18
|
+
|
|
19
|
+
before_filter :set_locale
|
|
20
|
+
|
|
21
|
+
before_filter :reload_config_et_roles
|
|
22
|
+
before_filter :require_login,
|
|
23
|
+
:except => [ :sign_up, :sign_in, :sign_out,
|
|
24
|
+
:recover_password, :reset_password,
|
|
25
|
+
:quick_edit ]
|
|
26
|
+
|
|
27
|
+
before_filter :check_if_user_can_perform_action_on_resource_without_model,
|
|
28
|
+
:except => [ :sign_up, :sign_in, :sign_out,
|
|
29
|
+
:dashboard,
|
|
30
|
+
:recover_password, :reset_password,
|
|
31
|
+
:quick_edit, :set_locale ]
|
|
32
|
+
|
|
33
|
+
before_filter :recover_password_disabled?,
|
|
34
|
+
:only => [ :recover_password, :reset_password ]
|
|
35
|
+
|
|
36
|
+
def dashboard
|
|
37
|
+
flash[:notice] = _("There are not defined applications in config/typus/*.yml.") if Typus.applications.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def sign_in
|
|
41
|
+
|
|
42
|
+
redirect_to admin_sign_up_path and return if Typus.user_class.count.zero?
|
|
43
|
+
|
|
44
|
+
if request.post?
|
|
45
|
+
if user = Typus.user_class.authenticate(params[:user][:email], params[:user][:password])
|
|
46
|
+
session[:typus_user_id] = user.id
|
|
47
|
+
redirect_to params[:back_to] || admin_dashboard_path
|
|
48
|
+
else
|
|
49
|
+
flash[:error] = _("The email and/or password you entered is invalid.")
|
|
50
|
+
redirect_to admin_sign_in_path
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def sign_out
|
|
57
|
+
session[:typus_user_id] = nil
|
|
58
|
+
redirect_to admin_sign_in_path
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def recover_password
|
|
62
|
+
if request.post?
|
|
63
|
+
if user = Typus.user_class.find_by_email(params[:user][:email])
|
|
64
|
+
ActionMailer::Base.default_url_options[:host] = request.host_with_port
|
|
65
|
+
TypusMailer.deliver_reset_password_link(user)
|
|
66
|
+
flash[:success] = _("Password recovery link sent to your email.")
|
|
67
|
+
redirect_to admin_sign_in_path
|
|
68
|
+
else
|
|
69
|
+
redirect_to admin_recover_password_path
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
##
|
|
75
|
+
# Available if Typus::Configuration.options[:recover_password] is enabled.
|
|
76
|
+
#
|
|
77
|
+
def reset_password
|
|
78
|
+
@user = Typus.user_class.find_by_token!(params[:token])
|
|
79
|
+
if request.post?
|
|
80
|
+
@user.password = params[:user][:password]
|
|
81
|
+
@user.password_confirmation = params[:user][:password_confirmation]
|
|
82
|
+
if @user.save
|
|
83
|
+
flash[:success] = _("You can login with your new password.")
|
|
84
|
+
redirect_to admin_sign_in_path
|
|
85
|
+
else
|
|
86
|
+
flash[:error] = _("Passwords don't match.")
|
|
87
|
+
redirect_to admin_reset_password_path(:token => params[:token])
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def sign_up
|
|
93
|
+
|
|
94
|
+
redirect_to admin_sign_in_path and return unless Typus.user_class.count.zero?
|
|
95
|
+
|
|
96
|
+
if request.post?
|
|
97
|
+
|
|
98
|
+
email, password = params[:user][:email], 'columbia'
|
|
99
|
+
user = Typus.user_class.generate(email, password)
|
|
100
|
+
|
|
101
|
+
if user.save
|
|
102
|
+
session[:typus_user_id] = user.id
|
|
103
|
+
flash[:notice] = _("Password set to \"{{password}}\".", :password => password)
|
|
104
|
+
redirect_to admin_dashboard_path
|
|
105
|
+
else
|
|
106
|
+
flash[:error] = _("That doesn't seem like a valid email address.")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
else
|
|
110
|
+
|
|
111
|
+
flash[:notice] = _("Enter your email below to create the first user.")
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def recover_password_disabled?
|
|
120
|
+
redirect_to admin_sign_in_path unless Typus::Configuration.options[:recover_password]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def select_layout
|
|
124
|
+
[ 'sign_up', 'sign_in', 'sign_out', 'recover_password', 'reset_password' ].include?(action_name) ? 'typus' : 'admin'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|