grandstand 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. data/.gitignore +2 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +7 -0
  4. data/Rakefile +44 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/admin/galleries_controller.rb +52 -0
  7. data/app/controllers/admin/images_controller.rb +68 -0
  8. data/app/controllers/admin/main_controller.rb +36 -0
  9. data/app/controllers/admin/pages_controller.rb +51 -0
  10. data/app/controllers/admin/posts_controller.rb +48 -0
  11. data/app/controllers/admin/sessions_controller.rb +41 -0
  12. data/app/controllers/admin/templates_controller.rb +6 -0
  13. data/app/controllers/admin/users_controller.rb +48 -0
  14. data/app/controllers/galleries_controller.rb +5 -0
  15. data/app/controllers/pages_controller.rb +5 -0
  16. data/app/controllers/posts_controller.rb +5 -0
  17. data/app/helpers/admin/main_helper.rb +31 -0
  18. data/app/helpers/admin/pages_helper.rb +2 -0
  19. data/app/helpers/admin/posts_helper.rb +2 -0
  20. data/app/helpers/admin/sessions_helper.rb +2 -0
  21. data/app/helpers/admin/templates_helper.rb +2 -0
  22. data/app/helpers/admin/users_helper.rb +2 -0
  23. data/app/helpers/pages_helper.rb +2 -0
  24. data/app/helpers/posts_helper.rb +2 -0
  25. data/app/helpers/site_helper.rb +2 -0
  26. data/app/models/gallery.rb +22 -0
  27. data/app/models/image.rb +61 -0
  28. data/app/models/page.rb +45 -0
  29. data/app/models/page_section.rb +6 -0
  30. data/app/models/post.rb +27 -0
  31. data/app/models/template.rb +33 -0
  32. data/app/models/user.rb +68 -0
  33. data/app/stylesheets/_buttons.less +76 -0
  34. data/app/stylesheets/_dialogs.less +85 -0
  35. data/app/stylesheets/application.less +238 -0
  36. data/app/stylesheets/global.less +435 -0
  37. data/app/stylesheets/login.less +30 -0
  38. data/app/stylesheets/wysiwyg.less +96 -0
  39. data/app/views/admin/galleries/_form.html.erb +11 -0
  40. data/app/views/admin/galleries/_gallery.html.erb +16 -0
  41. data/app/views/admin/galleries/_list.html.erb +17 -0
  42. data/app/views/admin/galleries/delete.html.erb +8 -0
  43. data/app/views/admin/galleries/edit.html.erb +8 -0
  44. data/app/views/admin/galleries/editor.html.erb +13 -0
  45. data/app/views/admin/galleries/editor_with_images.html.erb +19 -0
  46. data/app/views/admin/galleries/index.html.erb +13 -0
  47. data/app/views/admin/galleries/new.html.erb +8 -0
  48. data/app/views/admin/galleries/show.html.erb +15 -0
  49. data/app/views/admin/images/_form.html.erb +11 -0
  50. data/app/views/admin/images/delete.html.erb +8 -0
  51. data/app/views/admin/images/edit.html.erb +8 -0
  52. data/app/views/admin/images/new.html.erb +8 -0
  53. data/app/views/admin/images/upload.html.erb +11 -0
  54. data/app/views/admin/main/index.html.erb +10 -0
  55. data/app/views/admin/pages/_form.html.erb +33 -0
  56. data/app/views/admin/pages/_left.html.erb +3 -0
  57. data/app/views/admin/pages/_row.html.erb +9 -0
  58. data/app/views/admin/pages/delete.html.erb +8 -0
  59. data/app/views/admin/pages/edit.html.erb +8 -0
  60. data/app/views/admin/pages/index.html.erb +20 -0
  61. data/app/views/admin/pages/new.html.erb +8 -0
  62. data/app/views/admin/pages/show.html.erb +3 -0
  63. data/app/views/admin/posts/_form.html.erb +29 -0
  64. data/app/views/admin/posts/_left.html.erb +3 -0
  65. data/app/views/admin/posts/_list.html.erb +22 -0
  66. data/app/views/admin/posts/delete.html.erb +9 -0
  67. data/app/views/admin/posts/edit.html.erb +10 -0
  68. data/app/views/admin/posts/index.html.erb +10 -0
  69. data/app/views/admin/posts/new.html.erb +10 -0
  70. data/app/views/admin/posts/show.html.erb +4 -0
  71. data/app/views/admin/sessions/forgot.html.erb +8 -0
  72. data/app/views/admin/sessions/show.html.erb +12 -0
  73. data/app/views/admin/shared/_flash.html.erb +3 -0
  74. data/app/views/admin/users/_form.html.erb +16 -0
  75. data/app/views/admin/users/_left.html.erb +3 -0
  76. data/app/views/admin/users/delete.html.erb +10 -0
  77. data/app/views/admin/users/edit.html.erb +8 -0
  78. data/app/views/admin/users/index.html.erb +22 -0
  79. data/app/views/admin/users/new.html.erb +8 -0
  80. data/app/views/admin/users/show.html.erb +12 -0
  81. data/app/views/galleries/index.html.erb +0 -0
  82. data/app/views/galleries/show.html.erb +12 -0
  83. data/app/views/layouts/admin.html.erb +80 -0
  84. data/app/views/layouts/admin_login.html.erb +17 -0
  85. data/app/views/layouts/admin_xhr.html.erb +3 -0
  86. data/app/views/pages/show.html.erb +8 -0
  87. data/app/views/posts/show.html.erb +3 -0
  88. data/app/views/shared/404.html.erb +5 -0
  89. data/app/views/shared/gallery.html +14 -0
  90. data/app/views/shared/image.html +1 -0
  91. data/app/views/shared/page.html +0 -0
  92. data/app/views/shared/post.html +3 -0
  93. data/grandstand.gemspec +189 -0
  94. data/lib/grandstand/application.rb +50 -0
  95. data/lib/grandstand/controller/development.rb +15 -0
  96. data/lib/grandstand/controller.rb +104 -0
  97. data/lib/grandstand/helper.rb +117 -0
  98. data/lib/grandstand/routes.rb +59 -0
  99. data/lib/grandstand/session.rb +25 -0
  100. data/lib/grandstand.rb +27 -0
  101. data/public/.DS_Store +0 -0
  102. data/public/admin/.DS_Store +0 -0
  103. data/public/admin/images/.DS_Store +0 -0
  104. data/public/admin/images/background-input.gif +0 -0
  105. data/public/admin/images/background-progress-bar.png +0 -0
  106. data/public/admin/images/background-progress-complete.gif +0 -0
  107. data/public/admin/images/background-progress.gif +0 -0
  108. data/public/admin/images/icons/.DS_Store +0 -0
  109. data/public/admin/images/icons/add.png +0 -0
  110. data/public/admin/images/icons/collapse.png +0 -0
  111. data/public/admin/images/icons/delete.png +0 -0
  112. data/public/admin/images/icons/edit.png +0 -0
  113. data/public/admin/images/icons/editor/bold.png +0 -0
  114. data/public/admin/images/icons/editor/gallery.png +0 -0
  115. data/public/admin/images/icons/editor/image-center.png +0 -0
  116. data/public/admin/images/icons/editor/image-left.png +0 -0
  117. data/public/admin/images/icons/editor/image-right.png +0 -0
  118. data/public/admin/images/icons/editor/image.png +0 -0
  119. data/public/admin/images/icons/editor/italic.png +0 -0
  120. data/public/admin/images/icons/editor/ordered-list.png +0 -0
  121. data/public/admin/images/icons/editor/quote.png +0 -0
  122. data/public/admin/images/icons/editor/source.png +0 -0
  123. data/public/admin/images/icons/editor/strikethrough.png +0 -0
  124. data/public/admin/images/icons/editor/underline.png +0 -0
  125. data/public/admin/images/icons/editor/unordered-list.png +0 -0
  126. data/public/admin/images/icons/error.png +0 -0
  127. data/public/admin/images/icons/expand.png +0 -0
  128. data/public/admin/images/icons/galleries.png +0 -0
  129. data/public/admin/images/icons/gallery.png +0 -0
  130. data/public/admin/images/icons/image.png +0 -0
  131. data/public/admin/images/icons/okay.png +0 -0
  132. data/public/admin/images/icons/pages.png +0 -0
  133. data/public/admin/images/icons/posts.png +0 -0
  134. data/public/admin/images/icons/upload.png +0 -0
  135. data/public/admin/images/icons/users.png +0 -0
  136. data/public/admin/images/logo.png +0 -0
  137. data/public/admin/images/spinner-dark.gif +0 -0
  138. data/public/admin/images/uploader.swf +0 -0
  139. data/public/admin/javascripts/application.js +231 -0
  140. data/public/admin/javascripts/jquery.js +404 -0
  141. data/public/admin/javascripts/mustache.js +324 -0
  142. data/public/admin/javascripts/selection.js +280 -0
  143. data/public/admin/javascripts/string.js +264 -0
  144. data/public/admin/javascripts/wysiwyg.js +335 -0
  145. data/public/admin/stylesheets/application.css +1 -0
  146. data/public/admin/stylesheets/global.css +1 -0
  147. data/public/admin/stylesheets/login.css +1 -0
  148. data/public/admin/stylesheets/wysiwyg-content.css +20 -0
  149. data/public/admin/stylesheets/wysiwyg.css +1 -0
  150. data/vendor/cache/more-0.1.1.gem +0 -0
  151. metadata +216 -0
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg/
2
+ .DS_Store
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 [name of plugin creator]
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 ADDED
@@ -0,0 +1,7 @@
1
+ Grandstand
2
+ ==========
3
+
4
+ Grandstand is a Rails 3 (only!) Gem that allows you to build totally simple blogs and portfolios using a gallery and blog post
5
+ editor. It's under active development, so don't get all excited just yet!
6
+
7
+ Copyright (c) 2010 Flip Sasser, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,44 @@
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 grandstand plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the grandstand plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'Grandstand'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ begin
26
+ require "jeweler"
27
+ Jeweler::Tasks.new do |gemspec|
28
+ gemspec.name = "grandstand"
29
+ gemspec.summary = "A blog / gallery gem for Rails 3 that's dead-simple to configure, override, and rebuild"
30
+ # gem.files = Dir["{lib}/**/*", "{app}/**/*", "{config}/**/*", "{public}/**/*", "{rails}/**/*", "README"]
31
+ # other fields that would normally go in your gemspec
32
+ # like authors, email and has_rdoc can also be included here
33
+ gemspec.description = %{
34
+ Grandstand is a simple blog and photo gallery application. It takes a minimal amount of configuration and can
35
+ be built installed as a gem and used like any other thingymagig. It's totally cool.
36
+ }
37
+ gemspec.email = "flip@x451.com"
38
+ gemspec.homepage = "http://github.com/flipsasser/grandstand"
39
+ gemspec.authors = ["Flip Sasser"]
40
+ gemspec.test_files = []
41
+ end
42
+ rescue
43
+ puts "Jeweler or one of its dependencies is not installed."
44
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,52 @@
1
+ class Admin::GalleriesController < Admin::MainController
2
+ before_filter :find_gallery, :except => [:create, :index, :new, :reorder]
3
+
4
+ def create
5
+ @gallery = Gallery.new(params[:gallery].merge(:user => current_user))
6
+ if @gallery.save
7
+ flash[:success] = "#{@gallery.name} was successfully added"
8
+ redirect_to admin_gallery_path(@gallery)
9
+ else
10
+ flash[:error] = 'There was a problem creating this gallery'
11
+ render :new
12
+ end
13
+ end
14
+
15
+ def destroy
16
+ @gallery.destroy
17
+ flash[:delete] = 'Your gallery has been deleted'
18
+ redirect_to admin_galleries_path
19
+ end
20
+
21
+ def index
22
+ @galleries = Gallery.all
23
+ if request.xhr?
24
+ if params.has_key?(:image)
25
+ render :editor_with_images
26
+ else
27
+ render :editor
28
+ end
29
+ end
30
+ end
31
+
32
+ def new
33
+ @gallery = Gallery.new
34
+ end
35
+
36
+ def reorder
37
+ params[:galleries].each_with_index do |gallery_id, index|
38
+ Gallery.update(gallery_id, :position => index + 1)
39
+ end if params[:galleries]
40
+ render :json => {:status => :ok}
41
+ end
42
+
43
+ def update
44
+ if @gallery.update_attributes(params[:gallery])
45
+ flash[:success] = "#{@gallery.name} was successfully saved"
46
+ request.xhr? ? render(:json => {:status => :ok}) : redirect_to(admin_gallery_path(@gallery))
47
+ else
48
+ flash[:error] = 'There was a problem saving this gallery'
49
+ render :edit
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,68 @@
1
+ class Admin::ImagesController < Admin::MainController
2
+ before_filter :find_gallery
3
+ before_filter :find_image, :only => [:delete, :destroy, :edit, :show, :update]
4
+ prepend_before_filter :relax_session, :only => :create
5
+ # session :cookies_only => false, :only => :create
6
+
7
+ def create
8
+ @image = @gallery.images.new(params[:image])
9
+ if @image.save
10
+ flash[:success] = 'Your image was successfully uploaded'
11
+ params.has_key?('Filename') || request.xhr? ? render(:json => {:status => :ok}) : redirect_to(admin_gallery_path(@gallery))
12
+ else
13
+ render :new
14
+ end
15
+ end
16
+
17
+ def delete
18
+ end
19
+
20
+ def destroy
21
+ @image.destroy
22
+ flash[:delete] = 'Your image has been deleted'
23
+ redirect_to admin_gallery_path(@gallery)
24
+ end
25
+
26
+ def edit
27
+ @image = @gallery.images.find(params[:id])
28
+ end
29
+
30
+ def editor
31
+ end
32
+
33
+ def index
34
+ redirect_to admin_gallery_path(@gallery)
35
+ end
36
+
37
+ def new
38
+ @image = Image.new
39
+ end
40
+
41
+ def reorder
42
+ params[:images].each_with_index do |image_id, index|
43
+ @gallery.images.update(image_id, :position => index + 1)
44
+ end if params[:images]
45
+ render :json => {:status => :ok}
46
+ end
47
+
48
+ def update
49
+ if @image.update_attributes(params[:image])
50
+ flash[:success] = 'Your image was successfully saved'
51
+ request.xhr? ? render(:json => {:status => :ok}) : redirect_to(admin_gallery_path(@gallery))
52
+ else
53
+ render :new
54
+ end
55
+ end
56
+
57
+ def upload
58
+ end
59
+
60
+ protected
61
+ def find_image
62
+ @image = @gallery.images.find(params[:id])
63
+ end
64
+
65
+ def relax_session
66
+ request.session_options[:cookies_only] = false
67
+ end
68
+ end
@@ -0,0 +1,36 @@
1
+ class Admin::MainController < ApplicationController
2
+ skip_before_filter :find_page
3
+ before_filter :require_user, :except => [:login]
4
+ before_filter :set_return_path, :only => [:index, :show]
5
+
6
+ layout :admin_layout
7
+
8
+ def expand
9
+ session[:expand] ||= []
10
+ if params[:add] == 'yup' && !session[:expand].include?(params[:section])
11
+ session[:expand].push(params[:section])
12
+ elsif params[:add] == 'nope'
13
+ session[:expand].delete(params[:section])
14
+ end
15
+ render :text => ''
16
+ end
17
+
18
+ protected
19
+ def admin_layout
20
+ request.xhr? ? 'admin_xhr' : 'admin'
21
+ end
22
+
23
+ def admin_not_found
24
+ options = {:layout => 'minimal', :status => 404, :template => 'shared/404'}.merge(options)
25
+ render options
26
+ false
27
+ end
28
+
29
+ def find_gallery
30
+ return admin_not_found unless @gallery = Gallery.where(:id => params[:gallery_id] || params[:id]).first
31
+ end
32
+
33
+ def require_no_user
34
+ redirect_to return_path || admin_root_path if current_user
35
+ end
36
+ end
@@ -0,0 +1,51 @@
1
+ class Admin::PagesController < Admin::MainController
2
+ before_filter :find_page, :except => [:create, :index, :new]
3
+ before_filter :build_page_sections, :only => [:edit]
4
+
5
+ def create
6
+ @page = Page.new(params[:page])
7
+ if @page.save
8
+ flash[:success] = "#{@page.name} was successfully added"
9
+ redirect_to admin_page_path(@page)
10
+ else
11
+ flash[:error] = 'There was a problem creating this page'
12
+ render :new
13
+ end
14
+ end
15
+
16
+ def destroy
17
+ @page.destroy
18
+ flash[:delete] = 'Your page has been deleted'
19
+ redirect_to admin_pages_path
20
+ end
21
+
22
+ def index
23
+ @pages = Page.where(:parent_id => nil).all
24
+ end
25
+
26
+ def new
27
+ @page = Page.new
28
+ build_page_sections
29
+ end
30
+
31
+ def update
32
+ if @page.update_attributes(params[:page])
33
+ flash[:success] = "#{@page.name} was successfully saved"
34
+ request.xhr? ? render(:json => {:status => :ok}) : redirect_to(admin_page_path(@page))
35
+ else
36
+ flash[:error] = 'There was a problem saving this page'
37
+ render :edit
38
+ end
39
+ end
40
+
41
+ protected
42
+ def build_page_sections
43
+ Grandstand::Application.page_sections.each do |page_section|
44
+ @page.page_sections.where(:section => page_section).first || @page.page_sections.build(:section => page_section)
45
+ end
46
+ end
47
+
48
+ def find_page
49
+ return admin_not_found unless @page = Page.where(:id => params[:id]).first
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+ class Admin::PostsController < Admin::MainController
2
+ before_filter :find_post, :except => [:create, :index, :new]
3
+ layout :check_form_layout
4
+
5
+ def create
6
+ @post = Post.new(params[:post].merge(:user => current_user))
7
+ if @post.save
8
+ flash[:success] = "#{@post.name} was successfully added"
9
+ redirect_to admin_post_path(@post)
10
+ else
11
+ flash[:error] = 'There was a problem creating this post'
12
+ render :new
13
+ end
14
+ end
15
+
16
+ def destroy
17
+ @post.destroy
18
+ flash[:delete] = 'Your post has been deleted'
19
+ redirect_to admin_posts_path
20
+ end
21
+
22
+ def index
23
+ @posts = Post.all
24
+ end
25
+
26
+ def new
27
+ @post = Post.new
28
+ end
29
+
30
+ def update
31
+ if @post.update_attributes(params[:post])
32
+ flash[:success] = "#{@post.name} was successfully saved"
33
+ request.xhr? ? render(:json => {:status => :ok}) : redirect_to(admin_post_path(@post))
34
+ else
35
+ flash[:error] = 'There was a problem saving this post'
36
+ render :edit
37
+ end
38
+ end
39
+
40
+ protected
41
+ def check_form_layout
42
+ %w(create edit new update).include?(params[:action]) && params[:preview] == 'yup' ? 'application' : admin_layout
43
+ end
44
+
45
+ def find_post
46
+ return admin_not_found unless @post = Post.where(:id => params[:id]).first
47
+ end
48
+ end
@@ -0,0 +1,41 @@
1
+ class Admin::SessionsController < Admin::MainController
2
+ before_filter :require_no_user, :except => [:destroy]
3
+ skip_before_filter :require_user, :except => [:destroy]
4
+ skip_before_filter :set_return_path
5
+ layout 'admin_login'
6
+
7
+ def create
8
+ login_attempts = (session[:login_attempts] || 0).next
9
+ if !params[:email].blank? && user = User.authenticates_with(:email => params[:email])
10
+ if user.authenticates_with?(params[:password])
11
+ saved_return_path = return_path
12
+ reset_session
13
+ session[:user_id] = user.id
14
+ redirect_to saved_return_path || admin_root_path
15
+ return
16
+ else
17
+ flash.now[:error] = 'The password you entered is incorrect. Please try again.'
18
+ end
19
+ else
20
+ flash.now[:error] = 'An account with that e-mail could not be found. Please try again.'
21
+ end
22
+ session[:login_attempts] = login_attempts
23
+ render :show
24
+ end
25
+
26
+ def destroy
27
+ reset_session
28
+ redirect_to admin_session_path
29
+ end
30
+
31
+ def reset
32
+ if user = User.where(:email => params[:email]).first
33
+ user.reset_password
34
+ flash[:notice] = "A link containing password reset instructions has been sent to #{user.email}"
35
+ redirect_to admin_session_path
36
+ else
37
+ flash[:error] = "There is no user account with that e-mail address!"
38
+ redirect_to forgot_admin_session_path
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ class Admin::TemplatesController < Admin::MainController
2
+ def show
3
+ return admin_not_found unless @template = Template[params[:id]]
4
+ render :text => @template.render
5
+ end
6
+ end
@@ -0,0 +1,48 @@
1
+ class Admin::UsersController < Admin::MainController
2
+ before_filter :find_user, :except => [:create, :index, :new]
3
+
4
+ def create
5
+ @user = User.new(params[:user])
6
+ if @user.save
7
+ flash[:success] = "#{@user.name} was successfully added"
8
+ redirect_to admin_user_path(@user)
9
+ else
10
+ flash[:error] = 'There was a problem creating this user'
11
+ render :new
12
+ end
13
+ end
14
+
15
+ def delete
16
+ return admin_not_found if @user.id == current_user.id
17
+ end
18
+
19
+ def destroy
20
+ return admin_not_found if @user.id == current_user.id
21
+ @user.destroy
22
+ flash[:delete] = 'Your user has been deleted'
23
+ redirect_to admin_users_path
24
+ end
25
+
26
+ def index
27
+ @users = User.all
28
+ end
29
+
30
+ def new
31
+ @user = User.new
32
+ end
33
+
34
+ def update
35
+ if @user.update_attributes(params[:user])
36
+ flash[:success] = "#{@user.name} was successfully saved"
37
+ request.xhr? ? render(:json => {:status => :ok}) : redirect_to(admin_user_path(@user))
38
+ else
39
+ flash[:error] = 'There was a problem saving this user'
40
+ render :edit
41
+ end
42
+ end
43
+
44
+ protected
45
+ def find_user
46
+ return admin_not_found unless @user = User.where(:id => params[:id]).first
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ class GalleriesController < SiteController
2
+ def show
3
+ @gallery = Gallery.where(:id => params[:id]).first
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class PagesController < ApplicationController
2
+ def show
3
+ return not_found unless current_page
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class PostsController < ApplicationController
2
+ def show
3
+ return not_found unless @post = Post.where("#{Post.extract_year('created_at')} = ? AND #{Post.extract_month('created_at')} = ? AND url = ?", params[:year], params[:month].rjust(2, '0'), params[:id]).first
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ module Admin::MainHelper
2
+ def expand(*controllers)
3
+ options = controllers.extract_options!
4
+ options[:class] = Array(options[:class]).compact
5
+ options[:class].push(:expandable)
6
+ section = controllers.first
7
+ controllers.map!(&:to_s)
8
+ if controllers.include?(controller_name) || !((session[:expand] ||= []) & controllers).empty?
9
+ options[:class].push(:expanded)
10
+ end
11
+ raw %( class="#{options[:class].join(' ')}")
12
+ end
13
+
14
+ def expand_link(section)
15
+ link_to(raw('<span></span>'), '#', :class => 'expand', :rel => section)
16
+ end
17
+
18
+ def hide(condition)
19
+ raw ' style="display:none;"' if condition
20
+ end
21
+
22
+ # A form wrapper that's used to override the default field_error_proc in a thread-safeish way.
23
+ # The new field_error_proc returns a <div> with class "errors" on it, instead of an irritating
24
+ # "fieldWithErrors" classname that nobody likes or wants to use. Only used in admin at the moment.
25
+ def wrap_admin_form(&block)
26
+ field_error_proc = ActionView::Base.field_error_proc
27
+ ActionView::Base.field_error_proc = Proc.new {|html_tag, instance| raw("<div class=\"errors\">#{html_tag}</div>") }
28
+ concat(capture(&block))
29
+ ActionView::Base.field_error_proc = field_error_proc
30
+ end
31
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::PagesHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::PostsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::SessionsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::TemplatesHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::UsersHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module PagesHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module PostsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module SiteHelper
2
+ end
@@ -0,0 +1,22 @@
1
+ class Gallery < ActiveRecord::Base
2
+ before_save :set_url
3
+ belongs_to :user
4
+ default_scope order('position, id')
5
+ has_many :images, :dependent => :destroy
6
+
7
+ validates_presence_of :name, :message => 'Your gallery needs a name'
8
+ validates_uniqueness_of :name, :message => 'A gallery with that name already exists'
9
+
10
+ def cover_image
11
+ images.first || Image.new
12
+ end
13
+
14
+ # def to_param
15
+ # url
16
+ # end
17
+
18
+ protected
19
+ def set_url
20
+ self.url ||= name.parameterize
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ class Image < ActiveRecord::Base
2
+ belongs_to :gallery
3
+ belongs_to :user
4
+ default_scope order('position, id')
5
+
6
+ has_attached_file :file,
7
+ :default_url => "http://dummyimage.com/:dimensions",
8
+ :path => '/images/:padded_id-:style.:extension',
9
+ :styles => {
10
+ :admin_icon => '16x16#',
11
+ :admin_medium => '200x200#'
12
+ }.merge(Grandstand::Application.image_sizes),
13
+ :storage => :s3,
14
+ :s3_credentials => Grandstand::Application.s3[:credentials],
15
+ :bucket => Grandstand::Application.s3[:bucket]
16
+
17
+ delegate :url, :to => :file
18
+
19
+ validates_presence_of :gallery
20
+ validate :file_attached
21
+
22
+ class << self
23
+ # Returns the image sizes available for embedding in the public-facing pages. Sorts by potential pixel dimensions,
24
+ # so icon sizes (75x75) return as smaller than page-width sizes (500x500 or whatever). Also adds a fun description
25
+ # for the WYSIWYG editor, so '1024x768#' becomes '1024 x 768 (cropped)' in the event that the user is unhappy with
26
+ # whatever goddamn sizes they're intended to accept.
27
+ def sizes
28
+ return @sizes if defined? @sizes
29
+ sorted_sizes = ActiveSupport::OrderedHash.new
30
+ Image.attachment_definitions[:file][:styles].reject {|style, dimensions| style.to_s =~ /^admin_/ }.inject({}) do |sizes, style_definition|
31
+ style, dimensions = style_definition
32
+ width, height = dimensions.gsub(/[^0-9x]/, '').split('x').map(&:to_i)
33
+ width ||= 0
34
+ height ||= 0
35
+ if width.zero?
36
+ description = "#{height} pixel#{'s' unless height == 1} tall; width to scale"
37
+ elsif height.zero?
38
+ description = "#{width} pixel#{'s' unless width == 1} wide; height to scale"
39
+ else
40
+ description = "#{width} x #{height}"
41
+ end
42
+ additional = []
43
+ clean_dimensions = dimensions.gsub(/[0-9x]/, '')
44
+ if clean_dimensions =~ /\#$/
45
+ additional.push('cropped')
46
+ end
47
+ description << " (#{additional.join(', ')})" unless additional.empty?
48
+ sizes[style.to_sym] = {:description => description, :dimensions => dimensions, :size => (width.zero? ? height : width) * (height.zero? ? width : height)}
49
+ sizes
50
+ end.sort {|a, b| a[1][:size] <=> b[1][:size] }.each do |key, value|
51
+ sorted_sizes[key] = value
52
+ end
53
+ sorted_sizes
54
+ end
55
+ end
56
+
57
+ protected
58
+ def file_attached
59
+ errors.add(:file, 'You must upload a file!') if file_file_name.blank?
60
+ end
61
+ end
@@ -0,0 +1,45 @@
1
+ class Page < ActiveRecord::Base
2
+ attr_writer :new_parent_slug
3
+
4
+ after_update :update_children
5
+ before_validation :set_slug_and_url
6
+
7
+ belongs_to :parent, :class_name => 'Page'
8
+ belongs_to :user
9
+
10
+ has_many :children, :class_name => 'Page', :foreign_key => :parent_id
11
+ has_many :page_sections, :dependent => :destroy
12
+ accepts_nested_attributes_for :page_sections, :reject_if => lambda {|page_section| page_section['content'].try(:strip).blank? }
13
+
14
+ scope :roots, where(:parent_id => nil)
15
+
16
+ validates_presence_of :name, :slug, :url
17
+
18
+ class << self
19
+ def per_page
20
+ 10
21
+ end
22
+ end
23
+
24
+ def class_name
25
+ @class_name ||= class_names.join(' ')
26
+ end
27
+
28
+ def class_names
29
+ @class_names ||= page_sections.group_by(&:section).map{|section, page_sections| "has-#{section}"}
30
+ end
31
+
32
+ protected
33
+ def set_slug_and_url
34
+ self.slug ||= name.parameterize
35
+ if new_record? || slug_changed? || parent_id_changed? || @new_parent_slug
36
+ self.url = [parent.try(:url), slug].compact.join('/')
37
+ end
38
+ end
39
+
40
+ def update_children
41
+ if slug_changed? || parent_id_changed?
42
+ children.each{|child| child.update_attributes(:new_parent_slug => true, :updated_at => Time.now) }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,6 @@
1
+ class PageSection < ActiveRecord::Base
2
+ belongs_to :page
3
+ Grandstand::Application.page_sections.each do |section|
4
+ scope section.to_sym, where(:section => section)
5
+ end
6
+ end