HAML - how do I create this line of HTML - haml

This is kind of a complicated line of HTML to create in HAML:
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
I am not sure how to do that. Any idea? I am only able to do this:
%a.btn
%span.icon-bar Hello
but not sure how to do the complex stuff.
Thanks!

%a.btn.btn-navbar{"data-target" => ".nav-collapse", "data-toggle" => "collapse"}
OR Else
%a.btn.btn-navbar{:data => {:toggle => 'collapse', :target => '.nav-collapse'}}

Multiple classes can just be chained together:
%a.btn.btn-navbar
gives:
<a class='btn btn-navbar'></a>
Custom data attributes can be specified with a single :data hash:
%a.btn.btn-navbar{:data => {:toggle => 'collapse', :target => '.nav-collapse'}}
gives:
<a class='btn btn-navbar' data-target='.nav-collapse' data-toggle='collapse'></a>

/ 80 characters (Chandrakant's anser):
%a.btn.btn-navbar{"data-target" => ".nav-collapse", "data-toggle" => "collapse"}
/ 79 characters (Matt's answer):
%a.btn.btn-navbar{:data => {:toggle => 'collapse', :target => '.nav-collapse'}}
/ 69 characters (My fave method):
%a.btn.btn-navbar(data-toggle="collapse" data-target=".nav-collapse")
/ 68 characters (Ruby >= 1.9):
%a.btn.btn-navbar{data: {toggle:"collapse", target:".nav-collapse"}}

%a{:class => "btn btn-navbar", :data-toggle => "collapge", :data-target => ".nav-collapse"} Hello
Just from reading the HAML website...
http://haml-lang.com/tutorial.html
** I did not test this, I just read it on the website

Related

How do I escape a colon in HAML

Can any one tell me how to write this in HAML?
<td mc:edit = "headline">
The colon between the "mc" and the "edit" is what's screwing me up.
I tried:
%td{:mc\:edit => "headline"}
%td{:mc:\edit => "headline"}
%td{:mc:plain:edit => "headline"}
%td{:mc:escape:edit => "headline"}
%td(mc:edit = "headline")
They all return errors.
Both, %td{"mc:edit": "headline"} or %td(mc:edit="headline") should work.
Using:
haml (4.0.7)
haml-rails (0.9.0)
ruby-2.3.0
rails (4.2.6)

Using tr as label-input wrapper in simple-form

I may be old school,and I've been through many div/span attempts and swore off tables at one time, but there are just some good uses for tables, one of them, imho, is a form. I prefer to shade my label fields with a different background color. I've tried may ways, but if the input (actually either) side overflows the width, it will mess up the label background. I'd look at another attempt, but I really prefer a table approach.
In 2.x I set my configuration to:
config.wrappers :tag => :tr, :class => :input,
:hint_class => :field_with_hint, :error_class => :field_with_errors do |b|
b.use :label, :wrap_with => {:tag => :td, :class => :label}
b.use :input, :wrap_with => {:tag => :td, :class => :input}
b.use :hint, :wrap_with => { :tag => :span, :class => :hint }
b.use :error, :wrap_with => { :tag => :caption, :class => :error }
Works great!, except for errors. I first had it as a span and it went to the top of the table. I then set it to caption and, at least in Safari, it ends tbody and puts in the caption and starts another tbody - but it screws up the table flow.
Is there a way I can force the error to be in the input wrapper? Or any other approach? I'd even accept (and maybe this is what I should do) putting the error in the main message like the scaffold approach. Didn't think about that until I started to write this, but I guess I could not use simple forms error stuff and go back to the scaffold approach.
At least I think you can do that. For instance, I didn't know (and could not find in documentation - but I didn't look real hard!) that you could use regular form_for input (e.g., f.text_field) mixed with f.input. Great for things like putting City, St, Zip on one row.
I guess I should answer my own question. I ended up not using Simple Forms error notification and went back to the scaffold method.
I configured my wrappers as follows:
config.wrappers :tag => :tr, :class => :input,
:hint_class => :field_with_hint, :error_class => :field_with_errors do |b|
b.use :label, :wrap_with => {:tag => :td, :class => :label}
b.use :input, :wrap_with => {:tag => :td, :class => :input}
Wrote a helper method for errors:
def show_form_errors(instance)
if instance.errors.any?
errors = content_tag(:h2, pluralize(instance.errors.count, "error") +"prohibited this project from being saved:")
list = content_tag :ul do
e = ""
instance.errors.full_messages.each do |msg|
e <<"<li>#{msg}</li>"
end
e.html_safe
end
return content_tag(:div, (errors + list),:id => "error_explanation").html_safe
end
end
# instead of
# = f.error_notification
# I used
# = show_form_errors(#event)
Had to tweak the CSS for error_explanation because of how I had borders defined on my table rows (just border-bottom) and add !important to wrap the tr with a red border:
.field_with_errors {
padding: 2px;
border:solid 3px red!important;
background-color:pink;
}
Works fine and I am content with this method.

Allowing User to Download File from S3 Storage

Right now I am using Amazon S3 and Paperclip which is allowing my users to upload an image that is associated with the event they are creating. My ultimate goal is since others can view this event, to be able to click on the image and have it prompt a SAVE TO their computer. As of now, clicking the link will open the image in a browser window. I rather have it ask for them to download instead. All images only saved on S3, not local. Need to hide exposed s3 url as well if possible or camouflage it
Here is my current setup
Index.html
<%= link_to 'Download Creative', event.creative.url, class: "btn btn-info" %>
Event.rb
has_attached_file :creative,
:styles => { :thumb => "150x150", :custcreative => "250x75" },
:path => ":attachment/:id/:style.:extension",
:s3_domain_url => "******.s3.amazonaws.com",
:storage => :s3,
:s3_credentials => Rails.root.join("config/s3.yml"),
:bucket => '*****',
:s3_permissions => :public_read,
:s3_protocol => "http",
:convert_options => { :all => "-auto-orient" },
:encode => 'utf8'
Hoping someone can help me out.
To avoid extra load to your app (saving dyno's time in Heroku), I would rather do something like this: add this method to your model with the attachment:
def download_url(style_name=:original)
creative.s3_bucket.objects[creative.s3_object(style_name).key].url_for(:read,
:secure => true,
     :expires => 24*3600,  # 24 hours
     :response_content_disposition => "attachment; filename='#{creative_file_name}'").to_s
end
And then use it in your views/controllers like this:
<%= link_to 'Download Creative', event.download_url, class: "btn btn-info" %>
To make this work, I've just added a new action in the controller, so in your case it could be:
#routes
resources :events do
member { get :download }
end
#index
<%= link_to 'Download Creative', download_event_path(event), class: "btn btn-info" %>
#events_controller
def download
data = open(event.creative_url)
send_data data.read, :type => data.content_type, :x_sendfile => true
end
EDIT:
the correct solution for download controller action can be found here (I've updated the code above): Force a link to download an MP3 rather than play it?
Now in aws-sdk v2, there is a method :presigned_url defined in Aws::S3::Object, you can use this method to construct the direct download url for a s3 object:
s3 = Aws::S3::Resource.new
# YOUR-OBJECT-KEY should be the relative path of the object like 'uploads/user/logo/123/pic.png'
obj = s3.bucket('YOUR-BUCKET-NAME').object('YOUR-OBJECT-KEY')
url = obj.presigned_url(:get, expires_in: 3600, response_content_disposition: "attachment; filename='FILENAME'")
then in your views, just use:
= link_to 'download', url
event = Event.find(params[:id])
data = open(event.creative.url)
send_data data.read, :type => data.content_type, :x_sendfile => true, :url_based_filename => true
end
You need to set the "Content-Disposition" to "attachment" in your HTTP response header. I'm not a Rails developer - so just Google it and you'll see plenty of examples - but it probably looks something like this:
:content_disposition => "attachment"
or
...
:disposition => "attachment"

HAML - syntax error, unexpected keyword_ensure

In the part of code below I am still getting this error:
syntax error, unexpected keyword_ensure, expecting $end):
17: %input.btn.btn-primary{:name => "commit", :type => "submit", :value => "Set As Profile Picture"}/
Code:
#settings_photos_window.wide_width.modal.fade
= form_tag '/photos/set_avatar', :method => 'post' do
.modal-header
%a.close{"data-dismiss" => "modal"} ×
%h3 Choose Your Profile Picture
#choose_profile_pic.modal-body
= hidden_field_tag 'photo[avatar]', ((#cur_avatar) ? #cur_avatar.id : '')
- #settings_photos.each_slice(2) do |slice|
.row{:style => "text-align: left;"}
- slice.each do |photo|
- (photo.avatar == 1) ? (bg_color = 'background: #28AD4B;') : (bg_color = 'background: #fff;')
.span5.choose_picture{:style => "cursor: pointer; margin-right: 40px;"}
%div
= image_tag(photo.photo.url(:thumb), :class => 'thumbnail', :id => photo.id, :style => bg_color)
%br/
.modal-footer
%input.btn.btn-primary{:name => "commit", :type => "submit", :value => "Set As Profile Picture"}/
What could be wrong, or... doesn't exist any debugger for HAML?
Thanks
I think its probably the parentheses around the tenary statements. Its just a guess, but the rest of it seems perfectly acceptable to me.

haml display address

album/show.html.haml
#comment_list= render :partial => 'shared/comments', :locals => { :commentable => #album }
shared/_comments.html.haml
#comments
= commentable.comments.each do |comment|
= comment.content
display
Hello #<Comment:0x7f668f037710>
why is address displaying? How to remove it?
What happens if you remove the = before commentable?
I think the parser understand that you are mixIng erb and haml. Try removing = and inserting - instead.