I have:
#layout = [:maincol => ['a'], :sidecol => []]
then I want to loop and get:
<div class="maincol"><div class="a"></a></div>
<div class="sidecol"></div>
How do I do it?
First of all, this is a ruby question not ruby-on-rails. Secondly there are a few naming conventions in Rails and #layout would certainly confuse other programmers as well as :maincol and :sidecol is a rather bad naming and they should be what ever the model behind is.
<div class="maincol"><% #layout[:maincol].each do |element| %>
<%= "<div class="%s"></div>" % element %>
<% end %></div>
<div class="sidecol"></div>
<% #layout.each |column| %>
<%= column.each |outer,inner| %>
<%= content_tag(:div, inner.empty? ? {} : content_tag(:div, {}, :class=>inner), class => outer) %>
<% end %>
<% end %>
Assuming that you actually wanted a div tag in the inner loop, and the </a> in the question is a typo.
Here's a quick way:
#layout = [{:maincol => ['a']}, {:sidecol => []}] # I'm assuming this was the explicit data structure you meant
html = #layout.map do |s|
s.map do |k,v|
contents = (v.map{|ss| content_tag('div', '', :class => ss)} unless v.empty?) || ''
content_tag('div', contents, :class => k)
end
end.join('')
I think you should try a different arrangement for your #layout variable, if you want a tag inside another tag, what you really want to use is a recursive data structure.
http://ruby-doc.org/core/classes/Array.html
Check "each" method...
Related
I've got an easy one for you guys.
I want to have a featured content section where the current article link is hidden or removed
So already this works using Middleman Blog with delete_if:
<% blog(content).articles.delete_if{|item| item == current_article}.each do |article| %>
<%= article.href %>
<% end %>
However I'm using Middleman proxies so I don't have access to the current_article method...
I've got an YAML structure that holds the following mock data (amongst others) with the folder setup like: data > site > caseStudy > RANDOM-ID423536.yaml (Generated by a CMS)
Inside each yaml file you'll find stuff like:
:id: 2k1YccJrQsKE2siSO6o6ac
:title: Heyplace
My config.rb looks like this
data.site.caseStudy.each do | id, this |
proxy "/cases/#{this.slug}/index.html", "/cases/cases-template.html", :locals => { this: this }, :ignore => true
end
My template file holds the following
<%= partial(:'partials/footer', :locals => {:content => data.site.caseStudy, :title => 'See more projects'}) %>
My loop that gets content
<% content.each do |id, this| %>
<%= partial "partials/tile" %>
<% end %>
So I guess my question is, how can I use delete_if in this instance so that the current article isnt being displayed?
I have tried stuff like, but to no avail:
<% content.delete_if{|e| e.title == content.title}.each do |id, article| %>
<%= article.href %>
<% end %>
As well as:
<% content.reject{|key, value| key >= this.id }.sort_by{ |index| rand }.each do |id, this| %>
<%= partial "partials/tile" %>
<% end %>
(This deletes the data all together forever until you reload the page, strange!)
Any help is appreciated! Thank you!
I've got an easy one for you guys.
I want to have a featured content section where the current article is EXCLUDED
So this works using Middleman Blog with delete_if:
<% blog(content).articles.delete_if{|item| item == current_article}.each do |article| %>
<%= article_content %>
<% end %>
However I'm using Middleman proxies so I don't have access to the current_article method...
I've got an YAML structure that holds the following mock data (amongst others) with the folder setup like: data > site > caseStudy > RANDOM-ID423536.yaml (Generated by a CMS)
Inside each yaml file you'll find stuff like:
:id: 2k1YccJrQsKE2siSO6o6ac
:title: Heyplace
My config.rb looks like this
data.site.caseStudy.each do | id, this |
proxy "/cases/#{this.slug}/index.html", "/cases/cases-template.html", :locals => { this: this }, :ignore => true
end
My template file holds the following
<%= partial(:'partials/footer', :locals => {:content => data.site.caseStudy, :title => 'See more projects'}) %>
My loop that gets content
<% content.each do |id, this| %>
<%= partial "partials/tile" %>
<% end %>
So I guess my question is, how can I use delete_if in this instance so that the current article isnt being displayed?
I have tried stuff like, but to no avail:
<% content.delete_if{|e| e.title == content.title}.each do |id, this| %>
<%= partial "partials/tile" %>
<% end %>
Any help is appreciated! Thank you!
Solved, ended up doing
<% content.reject{ | id, item| item == this }.each do |id, this| %>
<%= partial "partials/tile", :locals => { :this => this, :dir => "/#{this.content_type_id.downcase}/", :secondary => 'View' } %>
<% end %>
Courtesy of #David Litvak
I'm the maintainer of contentful_middleman. Looks like you could just send the this to the partial as local, then iterate through your content and make sure that you exclude the one that matches the id of this.
There's a good number of related questions but their answers haven't helped me. I have a method fetch_all_sections which populates an array with this line:
all_sections << {:id => section.id, :sortlabel => section.sortlabel, :title => section.title, :depth => depth}
In a loop in a view, I would like to easily access the values by their key, like this:
<% fetch_all_sections(#standard).each do |section| %>
<%= section.id %>
<% end %>
This says no method id on section. section[:id] and #{section['id']} have similarly themed errors. I used a hash for ease of retrieval - should I use a different structure?
I'm hoping I don't need .map like section.map { |id| id[:id] } for every value.
EDIT: Here's the context. It's a little loopy (pun intended) but it does what's intended.
# Calls itself for each section recursively to fetch all possible children
def fetch_all_sections(standard, section = nil, depth = 0)
all_sections = []
if section.nil?
rootsections = standard.sections.sorted
if ! rootsections.nil?
rootsections.each_with_index do |section, i|
depth = section.sortlabel.split('.').length - 1
all_sections.push(fetch_all_sections(standard, section, depth))
end
end
else
all_sections << {:id => section.id, :sortlabel => section.sortlabel, :title => section.title, :depth => depth}
section.children.sorted.each do |section|
all_sections | fetch_all_sections(standard, section)
end
end
return all_sections
end
Try with the following:
<% fetch_all_sections(#standard).each do |section| %>
<%= section['id'] %>
<% end %>
If not working, try debugging using these methods:
<% fetch_all_sections(#standard).each do |section| %>
<%= section.inspect %>
<%= section.class %>
<% end %>
As the Question author said, this fixed:
all_sections << fetch_all_sections(standard, section, depth).first
And tell us the output of the inspect
I've setup a flash helper:
def flash_message
flash.each do |key, msg|
content_tag :div, msg, :id => key, :class => 'flash'
end
end
And I've put this in my application.html.erb:
<%= flash_message %>
And it's returning content like this:
{:notice=>"Testing"}
I'm fairly new to rails so this could be an amateur mistake.
You're right, it is an amateur mistake. ;)
Using .each here just iterates over the the messages and creates a div for each one. What you want is to make an array out of the divs and then concatenate them together at the end. Something like this:
def flash_message
flash.map do |key, msg|
content_tag :div, msg, :id => key, :class => 'flash'
end.join
end
You haven't made any mistakes and by creating a helper, you're reducing the amount of code required to do common things which is great for testing and organization.
One suggestion that I have is that you change your setup and make a shared partial to display the code so it's easier to manage. Then have your helper method just proxy the arguments to the partial function call.
First setup your partial (save it as shared/_flash_messages.html.erb):
<div class="flash-messages">
<% if messages && messages.length > 0 %>
<% messages.each do |key, message| %>
<div id="<%= key %>" class="flash"><%= message %></div>
<% end %>
<% else %>
No Messages to display
<% end %>
</div>
Then setup your helper methods:
def register_flash_message(key,message)
flash[key]=message
end
def display_flash_messages()
render 'shared/flash_messages', :messages => flash
end
This will make things much easier to maintain and customize. You also won't have to deal with having to build your HTML inside of Ruby since everything's stored inside of a partial.
The problem is the return of your helper. You must return the html code in a variable.
With this little change worked for me:
def flash_message
html = ""
flash.each do |key, msg|
html << (content_tag :div, msg, :id => key, :class => 'flash')
end
html
end
Remember that the last line in ruby it's a return.
To get the closing button on the flash message span, you could do something like this: (it can probably be written nicer):
def flash_helper
content_tag :div, class: "flash-messages" do
flash.map do |key, value|
content_tag :div, class: "alert alert-dismissable alert-#{key}" do
content_tag(:span, '×'.html_safe, class: :close, 'data-dismiss' => 'alert') + value
end
end.join().html_safe
end
end
In my rails application I wanted to use pagination for names. I'm fetching the names from a postgresql table.
def index
#users = User.order("name").paginate(:page=>params[:page],:per_page=>50)
end
Is there a way of alphabetic pagination that has page numbers as a,b,c..........z
Thanks for your help,
Ramya.
Im doing this too in one of my projects. I didnt use a gem for this. Its really easy using Ranges... For example:
<% ('A'..'Z').each do |char| %>
<% if char==params[:char] %>
<%= link_to :action => 'your_action', :char => char, :class => 'selected_char' %>
<% else %>
<%= link_to :action => 'your_action', :char => char %>
<% end %>
<% end %>
Then in the controller Action you select the Objects by the params[:char] given. For example:
#instance_var = ModelName.where("field LIKE ?", "#{params[:char]}%")
this did it for me. You can easy build a partial out of this and use it for many different Models.