Within a sinatra framework, I'm trying to yield a template, dashboard.haml, within a layout template: layout.haml. But when the page loads, a stringified version of the html appears, instead of the HTML itself. So it's clearly fetching the correct template, but I wonder why the html is being rendered as a string??
Here are the relevant code:
server.rb
get '/:developer' do
#workflow_audits = Auditor.new(params['developer']).workflow_audits
haml :dashboard, :layout => :layout
end
views/layout.haml
%html
%head
%title Workflow Stuff
%link{ :rel => :stylesheet, :type => "text/scss", :href => "/stylesheets/dashboard.scss"}
%script{ :src => "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js" }
%body
%form{action: '/', method: 'post'}
%label{for: 'developer'}Select a developer:
%input{type: 'text', name: 'developer'}
%input{type: 'submit', value: 'submit'}
= yield
views/dashboard.haml
%ul.issue-list
- #workflow_audits.each do |audit|
%li.issue
.issue-container.row
You have an indentation issue in dashboard.haml. I removed the 3 spaces and tabs in your post and put two spaces everywhere, all errors went away and was able to get it working.
%ul.issue-list
- #workflow_audits.each do |audit|
%li.issue
.issue-container.row
Related
I am using CoffeeScript and HAML. I have objects list:
{
title: "Title"
url: "http://example.com"
image_url: "img.png"
attributes: {
target: '_blank'
}
}
{
// ...
}
And I have a template:
- for item in #model.data
%a.menu-item{"href": item.url}
Can I somehow parse "attributes" if it is exists and add to %a.menu-item element to get <a href="[item.ur]" target="_blank">
If you want to merge all attributes from your hash, this should work:
%a.menu-item{item['attributes'], "href" => item['url']}
To conditionally include a tag element, use defined? The trick is in the ternery - setting the attribute value to nil will remove it. (https://gist.github.com/orioltf/3145400)
As an example (trying to mock up your situation with some quick ruby code)
- _h1 = {'title' => 'Title', 'url' => "http://example.com", 'image_url'=> "img.png", 'attributes'=> {'target'=> '_blank'}}
- _h2 = {'title' => 'Title2', 'url' => "http://example2.com", 'image_url'=> "img2.png"}
- $data_list = [_h1, _h2]
- class Model; def data() $data_list end end
- #model = Model.new
- for item in #model.data
%a.menu-item{:href => item['url'],
:target => (defined? item['attributes']['target']) ? item['attributes']['target'] : nil}
Note here that I am using hash accessors. Depending on your your objects are set up, what framework you are using, you may use what i did, item.url, item.get('url'), etc.
You can test it out with haml test.haml test.html
Hope that gets you started.
Here's the code in my haml file:
= render :partial => _paragraph,
:locals => {:content => "It is hot. But something's definitely up."}
How can I make the last sentence bold?
You can add the tags in your string, then insert them as raw text in your paragraph partial
= render :partial => _paragraph, :locals => {:content => "It's one thing to notice an uptick in appetite if you've been training hard at the gym, or if you're pregnant or PMS-ing. <b>But when you always feel like a bottomless pit for no obvious reason, then something's definitely up.</b>"}
And in _paragraph
= raw content
On each text_area on my site, I have a select_box for selecting the language. It often uses certain default languages, but sometimes checks for custom options. I initially had the array setup in the controller:
#language_array = [ ["english", 1], ["french", 2], ["spanish", 3] ]
#language_array = get_custom_array if custom_language?
And it would then be accessed by the view:
<%= select_tag(:language, options_for_select(language_array, default_language) )%>
This worked fine, and the text_area would display the language and pass on the number. However, I would now like to add multiple text_areas to each page, so I moved the code into a helper, and access the helper from every text_area in the view:
language_array = get_language_array(thing.id)
<%= select_tag(:language, options_for_select(language_array, default_language) )%>
However, now the text_area comes out messed up, and displays the array instead of just the language:
["english", 1]
How can I fix it (without changing the currently stored arrays)? I also want variables from the helper to be available to javascript on the page. Is there a better way to deal with multiple "things" than to move everything from the controller to the helpers?
You could have them inside the model as a hash like this
user.rb
def User
def self.language
{
'English' => '1',
'French' => '2',
....
}
end
end
and in the controller obtain the hash into a variable and it will be accessible in both the html.erb and the js.erb
users_controller.rb
#language = User.language
Then while building the form you can do it as
<%= talent_field.select(:language, #language, {}, {:class => 'language-select'} %>
i'm having a bit of trouble with adding a certain feature. i'm working on a buy/sell site and i want to be able to compare posts. here's what i have so far:
in the posts view:
<%= button_to "Add to Compare", :action => "addCompare" %>
in the corresponding controller:
##a = Array.new()
def addCompare
##a << Post.id
end
so, all i want to do is add the post's id to the array ##a. when i test this, i click on the "Add to Compare" button and I'm welcomed with this:
Template is missing
Missing template posts/addCompare with {:locale=>[:en, :en], :formats=>[:html], :handlers=>[:rxml, :rjs, :builder, :rhtml, :erb]} in view paths "/home/mja32/470repo/traders/app/views", "/var/lib/gems/1.8/gems/devise-1.4.2/app/views"
So I guess it's trying to redirect to a view. How do I prevent it from doing this? All I want this button to do is to add the post's id to the array and nothing more.
Thanks in advance,
Matt
First of all, storing persistent data in a controller's class variable isn't going to work the way you want it to. There's no guarantee that ##a will be the same array on your next addCompare call; for example, your next addCompare call could be handled by a different process. Also, what happens if two different clients call addCompare? Do you really want to mix their data together in one pile? Probably not. Your first task is to replace ##a with a real per-user persistent store.
If you want to return nothing at all from your controller, just do this at the end of your controller method:
render :nothing => true, :status => :ok
That will tell Rails that something has already been rendered so it doesn't need to try the default rendering action (which is to render the posts/addCompare view) and returns nothing more than a 200 status code to the client.
Once that's in place, you'll probably want to AJAXify your button with :remote => true:
:remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the submit behaviour. By default this behaviour is an ajax submit.
So this:
<%= button_to "Add to Compare", { :action => "addCompare" }, { :remote => true } %>
Note that button_to looks like this:
button_to(name, options = {}, html_options = {})
and that :action is for options but :remote is for html_options so you have to explicitly set up the hashes with {}; you could just wrap the options in braces:
<%= button_to "Add to Compare", { :action => "addCompare" }, :remote => true %>
but I prefer the consistency of wrapping them both by hand.
It's obvious from the documentation (and google) how to generate a link with a segment e.g. podcast/5#comments. You just pass a value for :anchor to link_to.
My concern is about the much simpler task of generating the <a name="comments">Comments</a> tag i.e. the destination of the first link.
I've tried the following, and although they seemed to work, the markup was not what I expected:
link_to "Comments", :name => "comments"
link_to "Comments", :anchor => "comments"
I think I'm missing something obvious. Thanks.
You are getting confused by Ruby's syntactic sugar (which Rails uses profusely). Let me explain this briefly before answering your question.
When a ruby function takes a single parameter that is a hash:
def foo(options)
#options is a hash with parameters inside
end
You can 'forget' to put the parenthesis/brackets, and call it like this:
foo :param => value, :param2 => value
Ruby will fill out the blanks and understand that what you are trying to accomplish is this:
foo({:param => value, :param2 => value})
Now, to your question: link_to takes two optional hashes - one is called options and the other html_options. You can imagine it defined like this (this is an approximation, it is much more complex)
def link_to(name, options, html_options)
...
end
Now, if you invoke it this way:
link_to 'Comments', :name => 'Comments'
Ruby will get a little confused. It will try to "fill out the blanks" for you, but incorrectly:
link_to('Comments', {:name => 'Comments'}, {}) # incorrect
It will think that name => 'Comments' part belongs to options, not to html_options!
You have to help ruby by filling up the blanks yourself. Put all the parenthesis in place and it will behave as expected:
link_to('Comments', {}, {:name => 'Comments'}) # correct
You can actually remove the last set of brackets if you want:
link_to("Comments", {}, :name => "comments") # also correct
In order to use html_options, you must leave the first set of brackets, though. For example, you will need to do this for a link with confirmation message and name:
link_to("Comments", {:confirm => 'Sure?'}, :name => "comments")
Other rails helpers have a similar construction (i.e. form_for, collection_select) so you should learn this technique. In doubt, just add all the parenthesis.
If you want to go through rails, I suggest content_tag (docs).
Example:
content_tag(:a, 'Comments', :name => 'comments')
<%= link_to('new button', action: 'login' , class: "text-center") %>
created an anchor tag for login.html i.g
new button
and for
new button
use
<%= link_to('new button', controller: 'admin',
action: 'login' , class: "text-center") %>