Ruby on Rails 3 : Playing with views - ruby

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.

Related

Using Nokogiri to generate static header list in Slate/Middleman

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 %>

Heroku will not render 'paginate.render' correctly

I'm using kaminari, everything works fine locally. On heroku, any code written inside the standard kaminari paginator.render block is not getting rendered.
consider
<%= paginator.render do %>
<h1> this is the paginator</h1>
<nav class="text-center">
<ul class="pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| %>
<% if page.left_outer? || page.right_outer? || page.inside_window? %>
<%= page_tag page %>
<% elsif !page.was_truncated? %>
<%= gap_tag %>
<% end %>
<% end %>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
</ul>
</nav>
<% end %>
I added the <h1>this is the paginator</h1> to tinker with what is happening. My logs look clean, there is not issue. am I missing something really obvious here? I've looked at the kaminari docs and given things are working locally, I'm not entirely sure what to look at on heroku, any pointers would be much appreciated.
snap, this hurted, my collection didn't have enough objects in it, therefore, kaminari had nothing to paginate. #usererror

DocPad: Empty or Missing YAML Elements

I have the following in one of my Layout files...
<% for link in #document.nextlink[0..0]: %>
<% if (link.name): %>
<ul class="actions">
<li><%- "#{link.helptext}" %></li>
</ul>
<% end %>
<% end %>
This works great. Unless, nextlink is not in my YAML at all. But that's what I want. Sometimes I want to have that button called Next and sometimes I do not.
if nextlink is not in my YAML, the DocPad compiler throws an error.
Any help would be much appreciated.

Understanding Ajax in Rails 3

I thought I understood Ajax in Rails 3 to a point but think I am confusing myself somewhere or misinterpreted something. My understanding is that if I want to call different content on the same page then i create a js.erb file for that particular action. For example if i have an action of tynewyddnews, I will have an tynewyddnews view and a tynewyddnews.js.erb file.
I then create a partial to render on that page and call that partial in my .js.erb file.
Example
View
<% #tynewyddpost.each do |t| %>
<li>
<% single = t.photos.first %>
<a class="photo" href="#"><%= image_tag(single.avatar.url(:thumbnail_news_images)) %></a>
<p><%= link_to t.title, tynewyddnews_path(:type => 'tynewyddnews'), :post_id => t.id, :remote => true %></p>
<p class="date"><%= date_output(t.published_on) %></p>
</li>
<% end %>
<div class="post-item">
<h2><%= #tynewyddpostlatest.title %></h2>
<div id="work-samples">
<% for photo in #tynewyddpostlatest.photos %>
<%= image_tag(photo.avatar.url(:news_images), :class => 'work-sample') %>
<% end %>
</div>
<p class="post-description"><%= #tynewyddpostlatest.comments.html_safe %></p><a class="post-more" href="#">Continue Reading ยป</a>
<div class="post-item-panel">
<ul>
<li class="date">
<p><%= date_output(#tynewyddpostlatest.published_on) %></p>
</li>
</ul>
</div>
</div>
So the historical posts go down the left hand side and the latest post goes in the center
.js.erb
<% if params[:type] == 'tynewyddnews' %>
jQuery('.post-item').html('<%= escape_javascript(render partial: 'tynewyddnewspost') %>');
<% end %>
Partial
<div class="post-item">
<h2><%= #tynewyddpost.title %></h2>
<div id="work-samples">
<% for photo in #tynewyddpost.photos %>
<%= image_tag(photo.avatar.url(:news_images), :class => 'work-sample') %>
<% end %>
</div>
<p class="post-description"><%= #tynewyddpost.comments.html_safe %></p>
<div class="post-item-panel">
<ul>
<li class="date">
<p><%= date_output(#tynewyddpost.published_on) %></p>
</li>
</ul>
</div>
</div>
Controller
def tynewyddnews
tynewyddpost = Post.tynewydd_posts.find(params[:post_id])
tynewyddpost.shift
#tynewyddpost = tynewyddpost
#tynewyddpostlatest = Post.tynewydd_posts.first
end
tynewydd_posts is a scope
scope :tynewydd_posts, :include => :department, :conditions => {"departments.name" => "Ty Newydd"}, :order => "posts.published_on DESC"
So my issue at the moment is when i try and render the page i get the error
Couldn't find Post without an ID
Apologies for the long post but if someone could point me in the right direction that would be great
Thanks
It looks to me like you're doing it way wrong, sorry. It doesn't need to be that complicated. I would start over from scratch with a much simpler example, and then build up from there.
I would do something like rails g scaffold post title:string and then do this, just in a browser console:
$.ajax({
url: "/posts/index"
}).done(function() {
console.log("done");
});
You should be able to see the data coming back through your browser's console. On the Rails side, that data is coming from here:
class PostsController < ApplicationController
def index
#posts = Post.all
# there might be more stuff here
end
end
Hopefully you understand what I'm talking about. If you don't, I'd recommend separately learning a little more about Rails and a little more about jQuery/ajax before trying to combine the two.
OK so it seems my issue was the way i was calling the id of a post and I also moved my ajax call into a separate action, setup all be it complicated is correct.
What i changed
<%= link_to t.title, tynewyddnews_path(:type => 'tynewyddnews'), :post_id => t.id, :remote => true %>
was changed to
<%= link_to t.title, my_path_path(:type => 'tynewyddnews', :id => t.id), :remote => true %>
Controller
I added a new action to handle the ajax call, finding a post by id
def my_path
#tynewyddpost = Post.find(params[:id])
end
Then in my partial I could use the #tynewyddpost instance variable
Hope this helps someone else

Conditional navigation bar

Hello Guys I've a request for you.I've Drinks, Menus and Users routes.
I've this code in views/layout/application.html.erb:
<div>
<%= render "shared/navigation_bar"
</div>
How to make the navigation_bar to render in all the pages except in users pages?
I finally work around many methods, but I finally come up with a solution(not really stunnin', I must confess) , that works for me.
<div>
<% if controller.controller_name == "drinks" %>
<%= render "shared/navigation_bar" %>
<% elsif controller.controller_name == "menus" %>
<%= render "shared/navigation_bar" %>
<% end %>
</div>
The flow control doesn't include Users's controller, so the navigation_bar layout won't appear on User's pages.
That's it.If you guys have a better alternative just let me know.

Resources