How to render partials from unrelated controllers in one view....almost Amazon style - ruby-on-rails-3.1

How can we render many partials from different controllers into one view?
The local variables of each partial are calculated separately in different and independent controllers.
What I really have to make things more specific, is a home layout, and in that layout that has dynamic content, there's a partial that only handles site wide news announcements, and these are independently updated.
I know a quick hack such like:
render :partial => '/news', :locals=> {#news = News.last}
but I want something more "correct". Like I've been reading about :templates rendering but i'm not sure how it works exactly in Rails 3.1.
Any help would be highly appreciated!

2.2.3 Rendering an Action’s Template from Another Controller
What if you want to render a template from an entirely different controller from the one that contains the action code? You can also do that with render, which accepts the full path (relative to app/views) of the template to render. For example, if you’re running code in an AdminProductsController that lives in app/controllers/admin, you can render the results of an action to a template in app/views/products this way:
render 'products/show'
Rails knows that this view belongs to a different controller because of the embedded slash character in the string. If you want to be explicit, you can use the :template option (which was required on Rails 2.2 and earlier):
render :template => 'products/show'
Sources: http://guides.rubyonrails.org/layouts_and_rendering.html#using-content_for
Should have read in more details.

Related

Making partial from crud view

I am making a Wikipedia clone to learn ruby on rails. In my app I have collaboration and wiki models with their own controllers and views. I would like to make a partial of the collaboration/new.html.erb view and put it into the wiki/new.html.erb. Is this possible? If so how would it be as simple as labeling the collaboration view _new.html.erb?
To refactor part of a view into a partial, extract the code you want to use and put it into a new partial under collaboration/_new.html.erb. Then to display this partial in a different view (such as the 'wiki' view), you would use the render function - making sure to specify the correct file path.
So in app/views/wiki/new.html.erb, add:
<%= render "collaboration/_new.html.erb %>

a rails partial but used by multiple views

I have a piece of code that I would like to have show up on several areas... from two different views. Which is to say handled by two different controllers (all the data comes from a helper though) what is the best way to break this up, should these partials be rendered then as lay outs? Though they use the twitter bootstrap modal and I have had huge issues getting those to show correctly when called from a layout (most the reason why I have to break up this code into a partial, one that comes from one index.erb.html and another that comes from a partial of its own _document_header.erb.html good time to ask, can you stuff one partial within another...
so just trying to get some pointers. This code is really common to two views.
(and is not always needing to be rendered or displayed)...so want to do this the best way.
You can reference a partial that is anywhere in your views folder.
It's common to make a "shared" folder in your views and reference the partial like: <%= render 'shared/my_partial' %>

Yii difference between rendering functions

I sometimes get messed up by the three rendering methods:
Controller::render()
Controller::renderPartial()
Controller::renderFile()
Please could you explain. Thank you!
render() is commonly used to render a view that corresponds to what a user sees as a "page" in your application. It first renders the view you have specified and then renders the layout for the current controller action (if applicable), placing the result of the first render into the layout. It then performs output processing (which at this time means automatically inserting any necessary <script> tags and updating dynamic content) and finally outputs the result.
renderPartial() is commonly used to render a "piece" of a page. The main difference from render() is that this method does not place the results of the render in a layout. By default it also does not perform output processing, but you can override this behavior using the $processOutput parameter.
renderFile() is a low-level method that does the grunt work of rendering: it extracts the data variables in the current scope and then runs the view code. The other two methods internally call this one, but you should practically never need to call it yourself. If you do, keep in mind that you need to pass in a file path (not a view path).
Render File:
Will run the rendering methods on a given file with the set rendering engine. This is fairly low level within Yii and only really used internally or in console commands.
Render Partial:
This takes the alias given and converts it into a file path using all the local variables such as current running controllers and modules and alias definitions. It then pretty much just uses render file.
Render:
This is combination of render partials to make our lives easier. It will render the layout on the currently active contoller, or the defined one, render all the content within it, handle caching of renders, and process the output for client scripts.
Hope that clears it up.
renderPartial() is really useful for displaying ssi components in a page - ie, headers, footers, widgets etc.

How does Orchard get away with no call to RenderBody?

I’ve been dissecting the Orchard CMS rendering and view engine in an effort to understand how it’s put together. I have discovered that neither RenderBody nor RenderSection are ever called. It is my understanding that the Razor view engine requires a call to one or the other.
What is it that gets around the requirement that RenderBody or RenderSection have to be called or an exception is thrown by Razor?
Is it the fact that there’s a custom view engine (ThemeAwareViewEngine)? If so, how does it handle parsing Razor syntax to generate the content?
Thank you.
It's actually the other way around. Razor itself doesn't require that RenderBody be called it's the RazorViewEngine that has this requirement. There can definitely be another view engine that uses Razor that has a completely different way of working. Take a look at https://github.com/Antaris/RazorEngine or https://github.com/Buildstarted/RazorSharp I've also written a markdown view engine that uses razor for some simple layouts.
From reading the source it looks as if they've created a few custom view engines. Their RazorViewEngine replaces the base class for razor generated files with their own custom WebViewPage which has a method Display of which Zone is an alias for. This is what allows them to render child views in addition it seems as if there are several types of Zones within the LayoutAwareViewEngine such as DocumentZone, ContentZone and so forth.
So in the end they've done a lot of custom code.

Use cases for the different Padrino haml helpers

I read http://www.padrinorb.com/guides/application-helpers but I'm unclear as to what are the use cases for each of the view helpers. Specifically, how do content_for/yield_content, render/partial, capture_html, and concat_content all fit together?
Right now I've been using render 'my/view' in my controllers and throwing in some =partial 'my/partial' within 'my/view' just to break apart the main template file into smaller chunks.
Is the right way to go about it? And when/where would I want to use the other helper functions?
Let's go through the use cases.
content_for/yield_content
This is for injecting content into a layout file that might be useful. Example is adding additional css/scripts into a layout from another template. The example on the guide is the same, showing how to add CSS files to your layout from any template that requires them. You can also use it for adding content onto sidebars, additional links, etc. It is for things that do not require their own template but need to pass information back to a layout based on the view being shown.
render/partial
render is for showing a given template associated with a route. render should be used for the main actions after a route is processed. partial is like a 'method' in a view. It can be reused and variables can be passed to change the output. You use partials in main templates to break up code and reuse pieces of views that otherwise might seem redundant.
capture_html/concat_content
This is usually used to create your own helpers that take blocks of content. For instance let's create a helper that takes a haml block and wraps it in a div. Usage is as follows:
# template.haml
# NOTE the equals so the content is returned
# and added to the view directly
= div_wrapper do
%h1 Some heading
%p This is now wrapped in a div
To implement this and use it in a template, you need to be able to 'capture' the haml passed into the block in order to process and then wrap a div around it. This is where capture_html comes in:
def div_wrapper(&block)
nested_content = capture_html(&block)
content_tag(:div, nested_content)
end
This will take the content and spit it out into the view wrapped in a div. Now, lets presume we want this helper to be more complex and so you want the use to be more like this:
# template.haml
# NOTE the dash so the content is not outputted directly
- div_wrapper do
%h1 Some heading
%p This is now wrapped in a div
but it also works in other helpers:
# some_helper.rb
def example(name)
div_wrapper { "<h1>Test</h1>" }
end
In order to properly print out the wrapped content from the helper in both a template AND straight ruby, we can use concat_content and check to see if we need to 'concat' the result to the template or simply return it.
def div_wrapper(&block)
nested_content = capture_html(&block)
tag_result = content_tag(:div, nested_content)
block_is_template?(block) ? concat_content(tag_result) : tag_result
end
I hope this works as a basic overview. The functions can overlap but generally it becomes clear when to use which based on specific context.

Resources