Im building a simple practice Sinatra app which allows users to enter urls via a form, and once submitted the app will open each of these urls in a new table (similar to urlopener.com)
My app.rb file
require 'sinatra'
get '/' do
erb :'index.html'
end
post '/' do
urls = params[:urls]
end
My View file
<h1>Enter URLs Below </h1>
<form action="/" method="post">
<textarea rows="40" cols="50" id="urls" name="urls" ></textarea>
<br/>
<input type= "submit" value="Open 'em up!">
</form>
I am able to print the urls to the console in the post action, but am unsure how to redirect back to the index, and display each of the urls before opening them in new tabs (which I plan on using JS to do).
You don't have to redirect back to the original page (in fact, the URL hasn't changed, so redirecting doesn't make sense). Instead, you render the same template. Simply insert erb :'index.html' in the second block (post '/') as well, and put the URLs in a class variable, so that they will be available to the template:
#urls=params[:urls].split
(The split is there so you get an array of strings, rather than one long string with linebreaks.)
Finally, you add some logic to the template to check whether there are any URLs to display, and if so render them as a list:
<% if #urls && !#urls.empty? %>
<h1>URLs</h1>
<ul>
<% for #url in #urls %>
<li>
<%= #url %>
</li>
<% end %>
</ul>
<% end %>
<h1>Enter URLs Below </h1>
...etc...
Related
I'm inexperienced with middleman and ruby, but I've been trying to get Slate working so it generates a side navigation/list of header during build time instead of client side using javascript. The problem I am running into is getting the code to include the headers from partials.
An example of the directory structure:
Source
+--config.rb
+--includes
+--file.md
+--otherfile.md
+--index.html
+--layouts
+--layout.erb
Gist of layout and config.rb
Config.rb snippet for this:
require 'nokogiri'
helpers do
def toc_data(page_content)
html_doc = Nokogiri::HTML::DocumentFragment.parse(page_content)
# get a flat list of headers
headers = []
html_doc.css('h1, h2, h3').each do |header|
headers.push({
id: header.attribute('id').to_s,
content: header.content,
level: header.name[1].to_i,
children: []
})
end
[3,2].each do |header_level|
header_to_nest = nil
headers = headers.reject do |header|
if header[:level] == header_level
header_to_nest[:children].push header if header_to_nest
true
else
header_to_nest = header if header[:level] == (header_level - 1)
false
end
end
end
headers
end
end
Layout snippet for this:
<ul id="toc" class="toc">
<% toc_data(page_content).each do |h1| %>
<li>
<%= h1[:content] %>
<ul class="toc-section">
<% h1[:children].each do |h2| %>
<li>
<%= h2[:content] %>
<ul class="toc-submenu">
<% h2[:children].each do |h3| %>
<li>
<%= h3[:content] %>
</li>
<% end %>
</ul>
</li>
<% end %>
</ul>
</li>
<% end %>
</ul>
...
<div class="page-wrapper">
<div class="content">
<%= page_content %>
<% current_page.data.includes && current_page.data.includes.each do |include| %>
<%= partial "includes/#{include}" %>
<% end %>
</div>
</div>
Currently, only headers from the index.html file are getting populated and nothing from the included partials. I believe I may need the existing helper to occur post build similar to what is described in the Middleman docs for sitemaps using a ready helper. I believe I have to make another change to the config code so that it captures additional content outside of the page_content, but I'm not sure what that is due to lack of familiarity. Any pointers would be appreciated.
Edit: After looking into the middleman basics docs, there appear to be two helpers from the Padrino framework that I could make use of: capture_html and concat_content. I'm trying to find where the helper page_content is defined to get extra context for the specific changes I'm making.
Not familiar with that framework but looks like toc_data(page_content) only looks at the main content but not at the current_page.data.includes partials.
So guess you need to pass the partial to your toc_data function as well.
Maybe this works?
<%
full_content = page_content
current_page.data.includes && current_page.data.includes.each do |include|
full_content += partial("includes/#{include}")
end
toc_data(full_content).each do |h1|
%>
...
<% end %>
Hope that helps.
In order to concatenate the current page data with partials with the page_content, use the code below. This also changes what all is needed to yield a complete page.
<%
if current_page.data.includes
current_page.data.includes.each do |include|
page_content += partial("includes/#{include}")
end
end
%>
...
<%= page_content %>
I am attempting to make a quiz in my rails application and I have looked around and the only gem out there that looked like it did what I want was Survey, but that is not ready for rails 4. Anyway I borrowed the structure that Survey gem creates. So I have Attempts, Surveys, Questions, and Answers
My problem is when I try to pass back which answers were picked to the attempt controller and I am not sure. I am still new to rails so it could be something I am doing / not doing.
The View looks like this
<% provide(:title, 'Quiz') %>
<h1>Quiz</h1>
<%= form_for(Attempt.new) do |f| %>
<% #survey = Survey.find(1) %>
<h3><%= #survey.description %></h3>
<br/>
<% #survey.questions.each do |question| %>
<h4><%= question.text %></h4>
<br/>
<% question.answers.each do |answer| %>
<h5><%= f.radio_button question, answer.correct?, :checked => false %> <%=answer.text%></h5>
<br/>
<% end %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The Params currently being returned are
{"utf8"=>"✓", "authenticity_token"=>"yCp4rsZfgZDTYK32FYgXTyZSQRQ4DcTWfokbrhImI1Q=", "attempt"=>{}, "commit"=>"Create Attempt", "action"=>"create", "controller"=>"attempts"}
This is my model structure (Grouped together to make it easier to read)
Attempt has many Surveys
Survey belongs to Attempts
Survey has many Questions
Question belongs to Surveys
Question has many Answers
Answer belongs to Questions
Edited: Added in form html
<form accept-charset="UTF-8" action="/attempts" class="new_attempt" id="new_attempt" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"><input name="authenticity_token" type="hidden" value="jOQCSERK6LKWwKwIprv0fhn62W+9T13WSXss8oswyFo="></div>
<h3>Tests if I can register individuals</h3>
<br>
<h4>Paul's Favorite Color</h4>
<br>
<h5><input id="attempt_#<Question:0x007f41704d11e8>_false" name="attempt[#<Question:0x007f41704d11e8>]" type="radio" value="false"> Green</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d11e8>_false" name="attempt[#<Question:0x007f41704d11e8>]" type="radio" value="false"> Blue</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d11e8>_true" name="attempt[#<Question:0x007f41704d11e8>]" type="radio" value="true"> Teal</h5>
<br>
<h4>Paul's Age</h4>
<br>
<h5><input id="attempt_#<Question:0x007f41704d0b80>_false" name="attempt[#<Question:0x007f41704d0b80>]" type="radio" value="false"> 20</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d0b80>_true" name="attempt[#<Question:0x007f41704d0b80>]" type="radio" value="true"> 21</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d0b80>_false" name="attempt[#<Question:0x007f41704d0b80>]" type="radio" value="false"> 22</h5>
<br>
<div class="actions">
<input name="commit" type="submit" value="Create Attempt">
</div>
</form>
Create an Attempt instance variable in AttemptsConroller on creation:
def new
#attempt = Attempt.new
end
In your view use the instance just created:
<%= form_for(#attempt) do |f| %>
That should do the trick if I did not completely miss the problem at hand.
The HTML you posted really makes it clear that something "un-railsish" is going on here. If you call the form_for-helper method in the way you did it it will create a FormBuilder object which will build the actual form, so we have to check the parameters of the radio_button in the FormBuilder class (in Rubyspeak that might also be FormBuilder#radio_button). There we find
radio_button(method, tag_value, options = {})
so the three parameters of the method rails expects are the name of the method of the object the form should operate on (which in your case would be your Attempt.new object). The most usual thing to pass at this point is a symbol with the method name, but as you provided a Question-object rails is trying to be forgiving and converts whatever it is passed into a String (probably using the to_s method). As you do not seem to have implemented to_s in your Question class the default implementation of Object will kick in to provide a "description" of your object with a class name and an address in angular brackets. As the angular brackets would confuse the HTML-parser these are gently escaped for you and you end up with messed up id and name attributes of your input elements. This will most certainly confuse the rails params parser when the HTTP POST-request is passed back and you end up with what you posted.
It is not really obvious how to fix this without knowing more about your Model classes, but most probably you want to use a nested form to solve this in the right way. This is not something I can do from the top of my head, but you can check out this RailsCast for more info.
I tried to display the images in Backbone.js view page.
My show_view.js.coffee is
Myapp.Views.Checklists ||= {}
class Myapp.Views.Checklists.ShowView extends Backbone.View
template: JST["backbone/templates/checklists/show"]
render: ->
#$el.html(#template(#model.toJSON() ))
return this
My show.jst.ejs file is
<p>
<b>Title:</b>
<%= title %>
</p>
<p>
<img src="<%= how_to_show_photo_url %>" alt="No image">
</p>
Back
I am using paperclip gem. I tried using <%= photo.url %> in image tag but it is not working. How do I show the photo in image tag?
I altered the response in rails before sending it to backbone.js. I updated the photo_file_name attribute with original path of the file. I updated the code as
#checklists = Checklist.find(:all)
#checklists.map{|k,v| k.photo_file_name = k.photo.url }
Now my Json response is
{"comments":"Backbone attachment","created_at":"2013-03-12T23:41:40Z","id":16,"photo_content_type":"image/jpeg",
"photo_file_name":"/system/checklists/photos/000/000/016/original/IMG_0011.JPG?1363131700",
"photo_file_size":2714495,"photo_updated_at":"2013-03-12T23:41:40Z","title":"Test Attaachment using backbone","updated_at":"2013-03-12T23:41:40Z"}
I used photo_file_name attribute in image src tag
Any better solutions are most welcome
I am sorry for my bad english. I just try to description my question. :)
I have an application layout that have a yield for display post in body. I have another yield :footerpost3 for display title of recent post on the footer.
When I in localhost:3000, the yield :footerpost3 display a recent of title correctly. but when i am click a post link, which is the url is localhost:3000/posts/3, the yield :footerpost3 display nothing.
Here is my code:
app/views/layout/application.html.erb
<!-- begin footer comment widget -->
<div class="footer_list widget_recent_comments">
<div class="title"><h5>Artikel Terkini</h5></div>
<%= yield :footerpost3 %>
</div>
<!-- end footer comment widget -->
app/views/store/index.html.erb
<% content_for :footerpost3 do %>
<% #postsMain.each do |dopostAll| %>
<div class="entry">
<ul>
<li class="recentcomments"><%= link_to dopostAll.title, dopostAll %></li>
</ul>
</div>
<% end %>
<% end %>
i hope my question is easy to understand.. :)
Looks like your root url is stores#index .
You must be initializing #postsMain in the stores#index action and generating the content_for footerpost3 in stores/index.html.erb.
When you click on a post, you will be taken to posts#show page. So you have to initialize #postsMain even in posts#show action and generate the content for footerpost3 even in posts/show.html.erb
The answer is there in your question. You are defining the "content for" footerpost3 in that block, which exists in index.html.erb. When you're on /posts/3, index.html.erb is not rendered, but rather show.html.erb is.
To solve this, you'd need to add the content in the show.html.erb template as well.
You could solve this in multiple ways. Using nested layouts would be one. For example, you might create a posts layout at app/views/layout/posts.html.erb, like so:
<% content_for :footerpost3 do %>
<% #postsMain.each do |dopostAll| %>
<div class="entry">
<ul>
<li class="recentcomments"><%= link_to dopostAll.title, dopostAll %></li>
</ul>
</div>
<% end %>
<% end %>
<%= render :file => 'layouts/application' %>
In this way, all the views of your PostsController would use this layout, which simply adds your footer content, then renders the application_layout.
Something's wrong with the PUT action here, the form gets processed but the updated field is not being saved.
I've did what Sinatra users are doing, by adding in "_method" for Sinatra to recognise that's its a HTTP PUT action. Could anyone spot any mistake here?
# edit
get '/entries/*/:id/edit' do
#entry = Entries.get(params[:id])
#title = "edit"
erb :edit, :layout => :edit_layout
end
# update
put '/entries/:id' do
#entry = Entries.get(params[:id])
if #entry.save
redirect "/entries/id=#{#entry.id}"
else
redirect "/enewsletters"
end
end
<!-- Edit form -->
<form action="/enewsletters/edit/<%= #entry.id %>" method="post">
<input name="_method" value="put" type="hidden"/>
<p>
<label>Content</label><br/>
<input type="text" name="entry[title]" value="<%= #enew.title %>">
</p>
<p>
<input type="submit" name="commit" value="update">
</p>
</form>
You don't seem to be doing any update to the #entry, you're just fetching the specific entry with the id from params. Are you using ActiveRecord? If so, instead of #entry.save, try #entry.update_attributes(params[:entry]).
Edit: I'm guessing you're not using AR since I just noticed the .get call. Whatever ORM you are using must have an easy way to update the attributes and then save the record.