how to pass string to view in sinatra - ruby

How can I display the output in html? Here is my sample code in ruby:
m = ["a","b", "c"]
m.each do |i|
#html = "<p>"+#{i}+"</p>"
end
I have a separate view file which reads the #html string:
<%= #html.html_safe</p>
My question is, how do i invoke the view file?

First fix typo in your code
#html = "<p>"+#{i}+"</p>"
should read
#html = "<p>#{i}</p>"
Now coming to the point just pass this at the end of your action
erb :<name-of-your-template>
this assumes you are having your erb templates under views directory

Related

Middleman Frontmatter YAML list

I just want to make a simple each loop in my Middleman helper, datas are stored in my page'Frontmatter like this :
dir:
- test
- test2
So in my helper, I try to write my loop :
def translate_directory
current_page.data.dir.each do |dir|
dir
end
end
call my method in my page
<%= translate_directory %>
and this is what's display :
["test", "test2"]
But now, if I make the same loop in my page, write with ERB syntax :
<% current_page.data.dir.each do |x| %>
<%= x %>
<% end %>
the exit is the following
test test2
separated in two strings, so exactly what I want.
EDIT : when I puts the helper'method, it display the two strings in two lines, so in two separated strings. Don't understand why it appear as an array on my browser.
EDIT 2 : a little thing I forgot, I want to translate each word with I18n.translate, like this :
def path_translate
current_page.data.dir.each { |dir| t("paths.#{dir}", locale: lang) }
end
but i can't because the each method doesn't work so I18n can't translate each word.
Because your helper is returning an array not a interpolated string like the ERB template is doing. Try the following for your helper:
def translate_directory
current_page.data.dir.join(' ')
end
My bad. Using .map instead of .each fix the problem, then use .join makes the array a big string.

Scraping a webpage with Mechanize and Nokogiri and storing data in XML doc

I am trying to scrape a website and store data in XML using Mechanize and Nokogiri. I didn't set up a Rails project and I am only using Ruby and IRB.
I wrote this method:
def mechanize_club
agent = Mechanize.new
agent.get("http://www.rechercheclub.applipub-fft.fr/rechercheclub/")
form = agent.page.forms.first
form.field_with(:name => 'codeLigue').options[0].select
form.submit
page2 = agent.get('http://www.rechercheclub.applipub-fft.fr/rechercheclub/club.do?codeClub=01670001&millesime=2015')
body = page2.body
html_body = Nokogiri::HTML(body)
codeclub = html_body.search('.form').children("tr:first").children("th:first").to_i
#codeclubs << codeclub
filepath = '/davidgeismar/Documents/codeclubs.xml'
builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
xml.root {
xml.codeclubs {
#codeclubss.each do |c|
xml.codeclub {
xml.code_ c.code
}
end
}
}
end
puts builder.to_xml
end
My first problem is that I don't know how to test my code.
I call ruby webscraper.rb in my console, the file is treated I think, but it doesn't create an XML file in the specified path.
Then, more specifically I am quite sure this code is wrong as I didn't get a chance to test it.
Basically what I am trying to do is to submit a form several times:
agent = Mechanize.new
agent.get("http://www.rechercheclub.applipub-fft.fr/rechercheclub/")
form = agent.page.forms.first
form.field_with(:name => 'codeLigue').options[0].select
form.submit
I think this code is ok, but I dont want it to only select options[0], I want it to select an option, then scrape all the data I need, then go back to page, then select options[1]... until there are no more options (an iteration I guess).
the file is treated I think, but it doesnt create an xml file in the specified path.
There is nothing in your code that creates a file. You print some output, but don't do anything to open or write a file.
Perhaps you should read the IO and File documentation and review how you are using your filepath variable?
The second problem is that you don't call your method anywhere. Though it's defined and Ruby will see it and parse the method, it has no idea what you want to do with it unless you invoke the method:
def mechanize_club
...
end
mechanize_club()

Rhomobile: Read txt file and show content Ruby

i want to open, read and show a txt file in my Rhomobile app.
First, i want to show the complete content of the file. But here is my problem.
def text
fileName = File.join(Rho::RhoApplication::get_base_app_path(), '/app/test.txt')
f = File.open(fileName, 'r')
while line = f.gets
puts line
end
f.close
redirect :action => :index
end
the code read the txt file, but how can i call the method and show the results on a page.
I don´t know whats the varaible is?
Please help me :) Thanks a lot!
If you only want to read the whole file, you can use this method:
#file_content = File.read(fileName);
You can assign the file's content to a instance variable (prefixed with an #) and show it in your view (*.html.erb or *.erb):
File content: <%= #file_content %>
Additionally, if you call redirect then your view won't be rendered and the user will be redirected to the specified action (index). So the code for the controller action should be this:
def text
#file_content = File.read(fileName);
render action: 'text'
end

Ruby, better way to implement conditional iteration than this?

I have an array #cities = ["Vienna", "Barcelona", "Paris"];
and I am trying to display the individual items with a spacer in between. However it is possible that there is only 1 element in the array, in which case I do not want to display the spacer. And also the array could be empty, in which case I want to display nothing.
For the above array I want the following output:
Vienna
-----
Barcelona
-----
Paris
I use an erb template cityview to apply formatting, css, etc before actually printing the city names. Simplified, it looks like this:
<p><%= #cities[#city_id] %></p>
I have implemented it as follows...
unless #array.empty?
#city_id = 0;
erb :cityview
end
unless #array[1..-1].nil?
#array[1..-1].each_index do |i|
#city_id = i+1;
puts "<p>-------</p>";
erb :cityview
end
end
Is there a better way?
#cities.join("<p>--------</p>")
Edit to address the template
Here I'm assuming that there's an erbs method that returns the rendered template without doing a puts. Returning the string allows easier manipulation and reuse.
#cities.map { |c| #city = c; erb :cityview }.join("<p>--------</p>")
I'd prefer:
erb:
<p><%= #city %></p>
and loop
#array.each_with_index do |e, i|
#city = e
erb :cityview
puts "<p>-------</p>" if i < #array.length - 1
end
I assume you have split the erb, bit because you want to customize it.
If you want to mix HTML with your city names then you'll need to worry about HTML encoding things before you mix in your HTML. Using just the standard library:
require 'cgi'
html = #cities.map { |c| CGI.escapeHTML(c) }.join('<p>-----</p>')
If you're in Rails, then you can use html_escape from ERB::Util and mark the result as safe-for-HTML with html_safe to avoid having to worry about the encoding in your view:
include ERB::Util
html = #cities.map { |c| html_escape(c) }.join('<p>-----</p>').html_safe
The simpler solution would be to use a spacer template.
http://guides.rubyonrails.org/layouts_and_rendering.html#spacer-templates

Array of Ruby objects returning strings on each method. Why?

Useful additional info: I am using the decent_exposure gem so this might be the issue - correcting the code below:
expose(:get_filter_tags) do
if params[:filter_tag_names]
filter_tag_names = Array(params[:filter_tag_names].split(" "))
filter_tags = Array.new
filter_tag_names.each do |f|
t = Tag.find_by_name(f)
filter_tags << t
end
end
end
So, something funny happens when I call this in the view:
query string ?utf8=✓&filter_tag_names=test
<% get_filter_tags.each do |ft| %>
<%= ft.name %>
<% end %>
Error message: undefined method `name' for "test":String
Why is this trying to call name on a string not a Tag object? If I put the following in the view, and have jut one filter_tag_names item
def getfiltertag
Tag.find_by_name(params[:filter_tag_names])
end
#view
<%= getfiltertag.name %>
query string: ?utf8=✓&filter=test
like above then I can call name just fine, so obviously I am doing something wrong to get an array of strings instead of objects. I just don't know what. Any suggestions?
Your problem is that each returns self — so if you write filter_tag_names.each, it returns filter_tag_names. You could fix this by explicitly returning filter_tags, but more idiomatically, you could just rewrite it as:
expose(:get_filter_tags) do
if params[:filter_tag_names]
filter_tag_names = Array(params[:filter_tag_names].split(" "))
filter_tag_names.map {|f| Tag.find_by_name(f) }
end
end
Just as an aside, this method will return nil if there aren't any filter tag names. You may want to do that, or you might want to return an empty collection to avoid exceptions in the calling code.

Resources