bumble 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/.gitignore +16 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +1 -0
  5. data/Readme.mdown +8 -0
  6. data/app/controllers/bumble_controller.rb +45 -0
  7. data/app/controllers/comments_controller.rb +99 -0
  8. data/app/controllers/password_resets_controller.rb +34 -0
  9. data/app/controllers/posts_controller.rb +103 -0
  10. data/app/controllers/user_sessions_controller.rb +22 -0
  11. data/app/controllers/users_controller.rb +60 -0
  12. data/app/helpers/bumble_helper.rb +50 -0
  13. data/app/models/asset.rb +57 -0
  14. data/app/models/comment.rb +78 -0
  15. data/app/models/notifier.rb +35 -0
  16. data/app/models/post.rb +57 -0
  17. data/app/models/posts/blog.rb +3 -0
  18. data/app/models/posts/code.rb +3 -0
  19. data/app/models/posts/image.rb +3 -0
  20. data/app/models/posts/link.rb +7 -0
  21. data/app/models/posts/quote.rb +3 -0
  22. data/app/models/posts/video.rb +4 -0
  23. data/app/models/user.rb +35 -0
  24. data/app/models/user_session.rb +2 -0
  25. data/app/views/comments/_comment.html.haml +14 -0
  26. data/app/views/comments/_form.html.haml +9 -0
  27. data/app/views/comments/edit.html.haml +7 -0
  28. data/app/views/comments/index.atom.builder +15 -0
  29. data/app/views/comments/new.html.haml +7 -0
  30. data/app/views/layouts/_sidebar.html.haml +20 -0
  31. data/app/views/layouts/bumble.html.haml +35 -0
  32. data/app/views/notifier/activation_confirmation.erb +5 -0
  33. data/app/views/notifier/activation_instructions.erb +5 -0
  34. data/app/views/notifier/new_comment_alert.erb +8 -0
  35. data/app/views/notifier/password_reset_instructions.erb +8 -0
  36. data/app/views/password_resets/edit.html.haml +10 -0
  37. data/app/views/password_resets/new.html.haml +7 -0
  38. data/app/views/posts/_form.html.haml +10 -0
  39. data/app/views/posts/_post.html.haml +16 -0
  40. data/app/views/posts/_preview.html.haml +8 -0
  41. data/app/views/posts/edit.html.haml +10 -0
  42. data/app/views/posts/forms/_blog.html.haml +4 -0
  43. data/app/views/posts/forms/_code.html.haml +6 -0
  44. data/app/views/posts/forms/_image.html.haml +9 -0
  45. data/app/views/posts/forms/_link.html.haml +6 -0
  46. data/app/views/posts/forms/_quote.html.haml +4 -0
  47. data/app/views/posts/forms/_video.html.haml +6 -0
  48. data/app/views/posts/index.atom.builder +15 -0
  49. data/app/views/posts/index.html.haml +21 -0
  50. data/app/views/posts/new.html.haml +8 -0
  51. data/app/views/posts/search.html.haml +27 -0
  52. data/app/views/posts/show.html.haml +22 -0
  53. data/app/views/posts/types/_blog.html.haml +4 -0
  54. data/app/views/posts/types/_code.html.haml +7 -0
  55. data/app/views/posts/types/_image.html.haml +3 -0
  56. data/app/views/posts/types/_link.html.haml +3 -0
  57. data/app/views/posts/types/_quote.html.haml +2 -0
  58. data/app/views/posts/types/_video.html.haml +5 -0
  59. data/app/views/user_sessions/new.html.haml +10 -0
  60. data/app/views/users/_form.html.haml +12 -0
  61. data/app/views/users/_user.html.haml +3 -0
  62. data/app/views/users/delete.html.haml +5 -0
  63. data/app/views/users/edit.html.haml +8 -0
  64. data/app/views/users/index.html.haml +3 -0
  65. data/app/views/users/new.html.haml +7 -0
  66. data/app/views/users/show.html.haml +6 -0
  67. data/bumble.gemspec +31 -0
  68. data/config/initializers/bumble.rb +9 -0
  69. data/config/initializers/haml.rb +2 -0
  70. data/config/initializers/html5_forms.rb +163 -0
  71. data/config/initializers/inflections.rb +10 -0
  72. data/config/initializers/mime_types.rb +5 -0
  73. data/config/initializers/will_paginate.rb +3 -0
  74. data/config/routes.rb +29 -0
  75. data/lib/bumble.rb +18 -0
  76. data/lib/bumble/version.rb +3 -0
  77. data/lib/generators/bumble/assets_generator.rb +10 -0
  78. data/lib/generators/bumble/migrations_generator.rb +40 -0
  79. data/lib/generators/bumble/templates/assets/images/.gitignore +0 -0
  80. data/lib/generators/bumble/templates/assets/images/close.png +0 -0
  81. data/lib/generators/bumble/templates/assets/images/email.png +0 -0
  82. data/lib/generators/bumble/templates/assets/images/feed.png +0 -0
  83. data/lib/generators/bumble/templates/assets/images/image.png +0 -0
  84. data/lib/generators/bumble/templates/assets/images/loading.gif +0 -0
  85. data/lib/generators/bumble/templates/assets/images/preview.png +0 -0
  86. data/lib/generators/bumble/templates/assets/images/shortcut.png +0 -0
  87. data/lib/generators/bumble/templates/assets/images/youtube.png +0 -0
  88. data/lib/generators/bumble/templates/assets/javascripts/admin.js +95 -0
  89. data/lib/generators/bumble/templates/assets/javascripts/bumble.js +76 -0
  90. data/lib/generators/bumble/templates/assets/javascripts/iphone.js +7 -0
  91. data/lib/generators/bumble/templates/assets/javascripts/jquery.autogrow.js +37 -0
  92. data/lib/generators/bumble/templates/assets/javascripts/jquery.cookie.js +96 -0
  93. data/lib/generators/bumble/templates/assets/javascripts/jquery.form.js +665 -0
  94. data/lib/generators/bumble/templates/assets/javascripts/jquery.hint.js +44 -0
  95. data/lib/generators/bumble/templates/assets/javascripts/jquery.jgrow.js +85 -0
  96. data/lib/generators/bumble/templates/assets/javascripts/jquery.js +154 -0
  97. data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.core.js +18 -0
  98. data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.tabs.js +13 -0
  99. data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.widget.js +18 -0
  100. data/lib/generators/bumble/templates/assets/javascripts/jquery.validate.js +16 -0
  101. data/lib/generators/bumble/templates/assets/javascripts/modernizr.js +13 -0
  102. data/lib/generators/bumble/templates/assets/javascripts/ui.core.js +289 -0
  103. data/lib/generators/bumble/templates/assets/javascripts/ui.tabs.js +593 -0
  104. data/lib/generators/bumble/templates/migrations/add_approved_to_comments.rb +15 -0
  105. data/lib/generators/bumble/templates/migrations/add_delta_to_posts.rb +9 -0
  106. data/lib/generators/bumble/templates/migrations/add_missing_indexes.rb +24 -0
  107. data/lib/generators/bumble/templates/migrations/add_url_to_users.rb +9 -0
  108. data/lib/generators/bumble/templates/migrations/create_assets.rb +18 -0
  109. data/lib/generators/bumble/templates/migrations/create_comments.rb +19 -0
  110. data/lib/generators/bumble/templates/migrations/create_posts.rb +25 -0
  111. data/lib/generators/bumble/templates/migrations/create_users.rb +28 -0
  112. data/lib/generators/bumble/templates/migrations/full_text_search.rb +13 -0
  113. data/public/stylesheets/sass/bumble.sass +423 -0
  114. data/public/stylesheets/sass/iphone.sass +79 -0
  115. data/public/stylesheets/sass/print.sass +2 -0
  116. data/public/stylesheets/sass/reset.sass +49 -0
  117. data/test/factories.rb +28 -0
  118. data/test/functional/comments_controller_test.rb +177 -0
  119. data/test/functional/password_resets_controller_test.rb +61 -0
  120. data/test/functional/posts_controller_test.rb +181 -0
  121. data/test/test_helper.rb +113 -0
  122. data/test/unit/comment_test.rb +18 -0
  123. data/test/unit/post_test.rb +18 -0
  124. data/test/unit/user_test.rb +37 -0
  125. metadata +403 -0
@@ -0,0 +1,8 @@
1
+ A request to reset your password has been made.
2
+ If you did not make this request, simply ignore this email.
3
+ If you did make this request just click the link below:
4
+
5
+ <%= @edit_password_reset_url %>
6
+
7
+ If the above URL does not work try copying and pasting it into your browser.
8
+ If you continue to have problem please feel free to contact us.
@@ -0,0 +1,10 @@
1
+ %h2 Change My Password
2
+
3
+ - form_for @user, :url => password_reset_path, :method => :put do |f|
4
+ = f.error_messages
5
+ = f.label :password
6
+ .field= f.password_field :password, :placeholder => 'Password..'
7
+ = f.label :password_confirmation
8
+ .field= f.password_field :password_confirmation, :placeholder => 'Password Confirmation..'
9
+
10
+ = f.submit "Update my password and log me in"
@@ -0,0 +1,7 @@
1
+ %h2 Forgot Password
2
+ %p Fill out the form below and instructions to reset your password will be emailed to you:
3
+
4
+ - form_tag password_resets_path do
5
+ = label_tag 'email'
6
+ .field= email_field_tag "email", '', :placeholder => 'Email..', :class => 'email'
7
+ = submit_tag "Reset my password"
@@ -0,0 +1,10 @@
1
+ .field
2
+ = form.check_box :publicly_viewable
3
+ = form.label :publicly_viewable, 'Public?'
4
+ .field
5
+ = label_tag 'blog_published_at_1i', 'Publish Date:'
6
+ = form.datetime_select :published_at, :start_year => Time.now.year
7
+ = form.label :published_at
8
+ .field= form.text_field :permalink, :placeholder => 'Custom Permalink..'
9
+ = form.label :via
10
+ .field= form.text_field :via, :placeholder => 'via..'
@@ -0,0 +1,16 @@
1
+ .post.hentry{:class => post.class.to_s.downcase, :id => "post_#{post.id}"}
2
+ = render_post post
3
+ %p.meta
4
+ = link_to format_datetime_ago(post.published_at), post_path(post), :rel => :bookmark
5
+ - if (current_user ? post.comments.any? : post.comments.ham.any?)
6
+ with
7
+ = link_to pluralize((current_user ? post.comments.count : post.comments.ham.count), 'comment'), post_path(post, :anchor => 'comments')
8
+ - if current_user
9
+ \-
10
+ = link_to "Edit", edit_post_path(post)
11
+ |
12
+ = link_to "Delete", post_path(post), :class => :delete
13
+ - unless post.via.blank?
14
+ %span.via
15
+ Via
16
+ = link_to truncate(post.via, :length => 24), post.via
@@ -0,0 +1,8 @@
1
+ .preview.post.hentry{:class => post.class.to_s.downcase}
2
+ = render_post post
3
+ %p.meta
4
+ = link_to format_datetime_ago(post.published_at), '#', :rel => :bookmark
5
+ - unless post.via.blank?
6
+ %span.via
7
+ Via
8
+ = link_to truncate(post.via, :length => 24), post.via
@@ -0,0 +1,10 @@
1
+ %h2
2
+ Editing
3
+ = @post.class.to_s.downcase
4
+
5
+ - form_for @post, :url => post_path(@post), :html => {:method => :put} do |form|
6
+ = render :partial => "posts/forms/#{@post.class.to_s.downcase}", :locals => {:form => form}
7
+ = render form
8
+ = form.submit "Update"
9
+ or
10
+ = link_to 'Cancel', post_path(@post)
@@ -0,0 +1,4 @@
1
+ = form.label :title
2
+ .field= form.text_field :title, :placeholder => 'Title..'
3
+ = form.label :description
4
+ .field= form.text_area :description, :rows => 16, :class => "required", :placeholder => 'Content..'
@@ -0,0 +1,6 @@
1
+ = form.label :title
2
+ .field= form.text_field :title, :placeholder => 'Title..'
3
+ = form.label :description
4
+ .field= form.text_area :description, :rows => 14, :class => "required", :placeholder => 'Code..'
5
+ = form.label :url
6
+ .field= form.url_field :link_url, :class => 'url', :placeholder => 'Link..'
@@ -0,0 +1,9 @@
1
+ - form.object.assets.build if form.object.new_record?
2
+ - form.fields_for :assets do |asset_form|
3
+ = asset_form.label :attachment_url
4
+ .field= asset_form.url_field :attachment_url, :class => "required url image", :placeholder => 'Image url..', :value => asset_form.object.attachment_remote_url
5
+
6
+ = form.label :link_url
7
+ .field= form.url_field :link_url, :class => 'url', :placeholder => 'Link..'
8
+ = form.label :descriptions
9
+ .field= form.text_area :description, :rows => 6, :placeholder => 'Description..'
@@ -0,0 +1,6 @@
1
+ = form.label :title
2
+ .field= form.text_field :title, :placeholder => 'Title..'
3
+ = form.label :label
4
+ .field= form.url_field :link_url, :class => "required url", :placeholder => 'Link..'
5
+ = form.label :description
6
+ .field= form.text_area :description, :rows => 6, :placeholder => 'Description..'
@@ -0,0 +1,4 @@
1
+ = form.label :quote
2
+ .field= form.text_area :quote, :rows => 8, :class => "required", :placeholder => 'Quote..'
3
+ = form.label :description
4
+ .field= form.text_area :description, :rows => 4, :placeholder => 'Context..'
@@ -0,0 +1,6 @@
1
+ = form.label :link_url
2
+ .field= form.url_field :link_url, :placeholder => 'Youtube Url..', :class => 'url youtube'
3
+ = form.label :video_embed
4
+ .field= form.text_area :video_embed, :rows => 6, :class => "", :placeholder => 'Video Embed..'
5
+ = form.label :description
6
+ .field= form.text_area :description, :rows => 6, :placeholder => 'Description..'
@@ -0,0 +1,15 @@
1
+ atom_feed(:schema_date => 2009, :root_url => root_url, :url => posts_url(:format => :atom)) do |feed|
2
+ feed.title "Posts Feed"
3
+ feed.updated @posts.first.updated_at
4
+
5
+ for post in @posts
6
+ feed.entry(post, :url => (post.link_url.present? ? post.link_url : post_url(post))) do |entry|
7
+ entry.title post.title
8
+ entry.author do |author|
9
+ author.name post.user.name
10
+ author.url post.user.url
11
+ end
12
+ entry.content render_post(post, false), :type => 'html'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ - @page_title = "Page #{@posts.current_page}" unless @posts.current_page == 1
2
+ - if current_user
3
+ = link_to "New Post", '#', :class => 'open'
4
+ #new_post
5
+ = link_to "close", '#', :class => 'close'
6
+ %ul
7
+ - Post.types.each do |t|
8
+ %li= link_to t, "#new_#{t.downcase}"
9
+ - Post.types.each do |t|
10
+ - form_for Object.const_get(t).new, :url => posts_path, :html => {:id => "new_#{t.downcase}", :class => 'new_post ui-tabs-hide'} do |form|
11
+ = render :partial => "posts/forms/#{t.downcase}", :locals => {:form => form}
12
+ = link_to "Add details", '#', :class => 'more'
13
+ .more= render form
14
+ = form.submit "Preview", :id => "#{form.object_name}_preview"
15
+ = form.submit "Post", :class => 'submit'
16
+
17
+ - if @posts.blank?
18
+ .blank No posts :'(
19
+ - else
20
+ #posts.hfeed= render :partial => 'post', :collection => @posts
21
+ = will_paginate @posts
@@ -0,0 +1,8 @@
1
+ %h2 New post
2
+
3
+ - form_for @post, :url => posts_path do |form|
4
+ = render :partial => "posts/forms/#{@post.type.downcase}", :locals => {:form => form}
5
+ = render :partial => form
6
+ = form.submit "Create"
7
+ or
8
+ = link_to 'Cancel', posts_path
@@ -0,0 +1,27 @@
1
+ - content_for :header do
2
+ = auto_discovery_link_tag :atom, search_posts_url(:query => h(params[:query]), :format => :atom), :title => "Search for '#{h(params[:query])}' feed"
3
+ #search.clearfix
4
+ %h2 Search Results
5
+
6
+ - if params[:query].present?
7
+ %p.meta
8
+ = page_entries_info @posts, :entry_name => 'post'
9
+ for
10
+ = "'#{h(params[:query])}'"
11
+
12
+ - if params[:query].present? && @posts.any?
13
+ #posts= render :partial => 'post', :collection => @posts
14
+ = will_paginate @posts
15
+ - elsif params[:query].present?
16
+ %p
17
+ Nothing could be found for your search
18
+ - if params[:query].present?
19
+ %strong= "'#{h(params[:query])}'"
20
+ - else
21
+ %p You didn't enter anything to search for?!
22
+ %p
23
+ You could try a different search, return to the
24
+ = link_to "homepage", root_path
25
+ - if params[:query].present?
26
+ or maybe
27
+ = link_to "google it?", "http://www.google.co.uk/search?q=#{params[:query]}"
@@ -0,0 +1,22 @@
1
+ - @page_title = @post.title
2
+ - @page_description = @post.description
3
+ = render :partial => 'post', :object => @post
4
+
5
+ #comments= render(current_user ? @post.comments : @post.comments.ham)
6
+
7
+ - form_for :comment, :url => post_comments_path(@post), :html =>{:class => 'new_comment'} do |form|
8
+ = render :partial => 'comments/form', :object => form
9
+ #formatting
10
+ %span.bold
11
+ %strong *bold*
12
+ %span.link
13
+ = link_to "&lt;http://link.com&gt;", 'http://link.com'
14
+ %span.italic
15
+ %em _italic_
16
+ %span.code
17
+ %pre code (indent 4 spaces)
18
+ .more
19
+ Read more:
20
+ = link_to "http://en.wikipedia.org/wiki/Markdown", "http://en.wikipedia.org/wiki/Markdown", :rel => :external
21
+ = form.submit "Post Comment"
22
+ = link_to "Formatting", '#formatting', :class => 'help'
@@ -0,0 +1,4 @@
1
+ - if title
2
+ - unless blog.read_attribute(:title).blank?
3
+ %h2.entry-title= blog.title
4
+ .entry-content= markdown blog.description
@@ -0,0 +1,7 @@
1
+ - if title
2
+ %h2.entry-title
3
+ - if !code.read_attribute(:title).blank?
4
+ = link_to_unless code.link_url.blank?, code.title, code.link_url
5
+ - elsif code.link_url
6
+ = link_to code.link_url, code.link_url, :rel => 'external'
7
+ %pre.entry-content= escape_once code.description
@@ -0,0 +1,3 @@
1
+ .entry-content.hmedia
2
+ = link_to_unless image.link_url.blank?, image_tag((image.asset.present? ? image.asset.try(:attachment).try(:url, :thumb) : image.image_url), :class => :photo), image.link_url, :class => :enclosure
3
+ .description= markdown image.description
@@ -0,0 +1,3 @@
1
+ - if title
2
+ %h2= link_to link.title, link.link_url
3
+ = markdown link.description
@@ -0,0 +1,2 @@
1
+ %blockquote= quote.quote
2
+ = markdown quote.description
@@ -0,0 +1,5 @@
1
+ - unless video.link_url.blank?
2
+ = youtube_embed(video.link_url)
3
+ - else
4
+ = video.video_embed
5
+ .description= markdown video.description
@@ -0,0 +1,10 @@
1
+ - form_for :user_session, :url => user_session_path do |f|
2
+ = f.label :email
3
+ .field= f.email_field :email, :class => 'required email', :placeholder => 'Email..', :autocorrect => 'off'
4
+ = f.label :password
5
+ .field= f.password_field :password, :class => 'required', :placeholder => 'Password..'
6
+ .field
7
+ = f.check_box :remember_me
8
+ = f.label :remember_me
9
+ = f.submit "Login"
10
+ = link_to "Forgot your password?", new_password_reset_path, :class => 'more'
@@ -0,0 +1,12 @@
1
+ = form.label :email
2
+ .field= form.email_field :email, :placeholder => 'Email..'
3
+ = form.label :password
4
+ .field= form.password_field :password, :placeholder => 'Password..'
5
+ = form.label :password_confirmation
6
+ .field= form.password_field :password_confirmation, :placeholder => 'Password confirmation..'
7
+ = form.label :first_name
8
+ .field= form.text_field :first_name, :placeholder => 'First name..'
9
+ = form.label :last_name
10
+ .field= form.text_field :last_name, :placeholder => 'Last name..'
11
+ = form.label :url
12
+ .field= form.url_field :url, :placeholder => 'Url..'
@@ -0,0 +1,3 @@
1
+ %li.user
2
+ = link_to image_tag(user.gravatar_url), user
3
+ = link_to user, user
@@ -0,0 +1,5 @@
1
+ %h2 Delete User
2
+ %p
3
+ Are you sure you want to delete this user:
4
+ = @user
5
+ = button_to 'Confirm Deletion', user_path, :method => :delete
@@ -0,0 +1,8 @@
1
+ %h2
2
+ Editing
3
+ = @user
4
+
5
+ - form_for @user do |form|
6
+ = form.error_messages
7
+ = render form
8
+ = form.submit
@@ -0,0 +1,3 @@
1
+ %h2 Users
2
+ %ul= render @users
3
+ = will_paginate @users
@@ -0,0 +1,7 @@
1
+ %h2
2
+ New User
3
+
4
+ - form_for @user do |form|
5
+ = form.error_messages
6
+ = render form
7
+ = form.submit
@@ -0,0 +1,6 @@
1
+ %h2= @user
2
+
3
+ %p
4
+ = link_to "Edit User", edit_user_path
5
+ |
6
+ = link_to "Delete User", delete_user_path
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bumble/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bumble"
7
+ s.version = Bumble::VERSION
8
+ s.authors = ["Andrew Nesbitt"]
9
+ s.email = ["andrewnez@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Rails 3 Tumblog Engine}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_dependency(%q<rails>, ["3.0.7"])
19
+ s.add_dependency(%q<will_paginate>, ["~>3.0.pre2"])
20
+ s.add_dependency(%q<gravtastic>, ["~>2.1.3"])
21
+ s.add_dependency(%q<authlogic>, ["~>2.1.1"])
22
+ s.add_dependency(%q<rdiscount>, ["1.6.8"])
23
+ s.add_dependency(%q<haml>, ["~>3.1.1"])
24
+ s.add_dependency(%q<texticle>, ["~>1.0.4"])
25
+ s.add_dependency(%q<paperclip>, ["2.3.4"])
26
+ s.add_dependency(%q<pg>, ["~>0.10.1"])
27
+ s.add_dependency(%q<aws-s3>, ["~>0.6.2"])
28
+ s.add_dependency(%q<dynamic_form>, ["1.1.4"])
29
+ s.add_dependency(%q<sass>, ["~>3.1.2"])
30
+ s.add_dependency(%q<akismetor>)
31
+ end
@@ -0,0 +1,9 @@
1
+ # Configure the options for you site here
2
+ DOMAIN = 'example.com'
3
+ CONTACT_EMAIL = 'you@example.com'
4
+
5
+ Rails.application.config.action_mailer.default_url_options = { :host => DOMAIN }
6
+
7
+ SASS_PATH = File.join(File.dirname(__FILE__), *%w[.. .. public stylesheets sass])
8
+ CSS_PATH = File.expand_path(File.join(Rails.root, %w[public stylesheets]))
9
+ ::Sass::Plugin.add_template_location(SASS_PATH, CSS_PATH)
@@ -0,0 +1,2 @@
1
+ Haml::Template.options[:format] = :html5
2
+ Sass::Plugin.options[:style] = :compressed
@@ -0,0 +1,163 @@
1
+ module ActionView #:nodoc:
2
+ module Helpers #:nodoc:
3
+ module FormTagHelper
4
+ # Creates a search field.
5
+ #
6
+ # ==== Options
7
+ # * <tt>:autosave</tt> - If set to true, will generate a domain-based
8
+ # namespace (e.g., for blog.rubyonrails.com, "com.rubyonrails.blog").
9
+ # Also accepts string values.
10
+ # * <tt>:results</tt> - The number of previous searches displayed in the
11
+ # drop-down. Default: 10, with <tt>:autosave</tt>.
12
+ # * Otherwise accepts the same options as text_field_tag.
13
+ #
14
+ # ==== Examples
15
+ # search_field_tag 'query'
16
+ # # => <input id="query" name="query" type="search" />
17
+ #
18
+ # search_field_tag 'query', nil, :autosave => true
19
+ # # => <input id="query" name="query" type="search" autosave="tld.yourdomain" results="10">
20
+ #
21
+ # search_field_tag 'site_search', nil, :autosave => 'com.rubyonrails', :results => 5
22
+ # # => <input id="site_search" name="site_search" type="search" autosave="com.rubyonrails" results="5">
23
+ def search_field_tag(name, value = nil, options = {})
24
+ options = options.stringify_keys
25
+
26
+ if options["autosave"]
27
+ if options["autosave"] == true
28
+ options["autosave"] = request.host.split(".").reverse.join(".")
29
+ end
30
+ options["results"] ||= 10
31
+ end
32
+
33
+ if options["onsearch"]
34
+ options["incremental"] = true unless options.has_key?("incremental")
35
+ end
36
+
37
+ text_field_tag(name, value, options.update("type" => "search"))
38
+ end
39
+
40
+ # Creates a text field of type "tel".
41
+ #
42
+ # ==== Options
43
+ # * Accepts the same options as text_field_tag.
44
+ def telephone_field_tag(name, value = nil, options = {})
45
+ text_field_tag(name, value, options.stringify_keys.update("type" => "tel"))
46
+ end
47
+ alias phone_field_tag telephone_field_tag
48
+
49
+ # Creates a text field of type "url".
50
+ #
51
+ # ==== Options
52
+ # * Accepts the same options as text_field_tag.
53
+ def url_field_tag(name, value = nil, options = {})
54
+ text_field_tag(name, value, options.stringify_keys.update("type" => "url"))
55
+ end
56
+
57
+ # Creates a text field of type "email".
58
+ #
59
+ # ==== Options
60
+ # * Accepts the same options as text_field_tag.
61
+ def email_field_tag(name, value = nil, options = {})
62
+ text_field_tag(name, value, options.stringify_keys.update("type" => "email"))
63
+ end
64
+
65
+ # Creates a number field.
66
+ #
67
+ # ==== Options
68
+ # * <tt>:min</tt> - The minimum acceptable value.
69
+ # * <tt>:max</tt> - The maximum acceptable value.
70
+ # * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
71
+ # <tt>:max</tt> values.
72
+ # * <tt>:step</tt> - The acceptable value granularity.
73
+ # * Otherwise accepts the same options as text_field_tag.
74
+ #
75
+ # ==== Examples
76
+ # number_field_tag 'quantity', nil, :in => 1...10
77
+ # => <input id="quantity" name="quantity" min="1" max="9" />
78
+ def number_field_tag(name, value = nil, options = {})
79
+ options = options.stringify_keys
80
+ options["type"] ||= "number"
81
+ if range = options.delete("in") || options.delete("within")
82
+ options.update("min" => range.min, "max" => range.max)
83
+ end
84
+ text_field_tag(name, value, options)
85
+ end
86
+
87
+ # Creates a range form element.
88
+ #
89
+ # ==== Options
90
+ # * Accepts the same options as number_field_tag.
91
+ def range_field_tag(name, value = nil, options = {})
92
+ number_field_tag(name, value, options.stringify_keys.update("type" => "range"))
93
+ end
94
+ end
95
+
96
+ module FormHelper #:nodoc:
97
+ def search_field(object_name, method, options = {})
98
+ options = options.stringify_keys
99
+
100
+ if options["autosave"]
101
+ if options["autosave"] == true
102
+ options["autosave"] = request.host.split(".").reverse.join(".")
103
+ end
104
+ options["results"] ||= 10
105
+ end
106
+
107
+ if options["onsearch"]
108
+ options["incremental"] = true unless options.has_key?("incremental")
109
+ end
110
+
111
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("search", options)
112
+ end
113
+
114
+ def telephone_field(object_name, method, options = {})
115
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("tel", options)
116
+ end
117
+ alias phone_field telephone_field
118
+
119
+ def url_field(object_name, method, options = {})
120
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("url", options)
121
+ end
122
+
123
+ def email_field(object_name, method, options = {})
124
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("email", options)
125
+ end
126
+
127
+ def number_field(object_name, method, options = {})
128
+ options = options.stringify_keys
129
+ options["type"] ||= "number"
130
+ if range = options.delete("in") || options.delete("within")
131
+ options.update("min" => range.min, "max" => range.max)
132
+ end
133
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("number", options)
134
+ end
135
+
136
+ def range_field(object_name, method, options = {})
137
+ options = options.stringify_keys
138
+ options["type"] ||= "number"
139
+ if range = options.delete("in") || options.delete("within")
140
+ options.update("min" => range.min, "max" => range.max)
141
+ end
142
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("range", options)
143
+ end
144
+ end
145
+
146
+ class FormBuilder #:nodoc:
147
+ %w(search_field telephone_field url_field email_field number_field range_field).each do |selector|
148
+ src = <<-end_src
149
+ def #{selector}(method, options = {})
150
+ @template.send(
151
+ #{selector.inspect},
152
+ @object_name,
153
+ method,
154
+ objectify_options(options))
155
+ end
156
+ end_src
157
+ class_eval src, __FILE__, __LINE__
158
+ end
159
+
160
+ alias phone_field telephone_field
161
+ end
162
+ end
163
+ end