I have to solve an issue.
I'm trying to manage an advertising skin on my website using this gem:
Google_DFP
Now I'm using the standard invocation call on the homepage:
<%= dfp_tag :skin %>
I want to add the skin to the whole website, so in the application layout, using the targeting options to select the pages where the skin appear
<%= dfp_tag :leaderboard, { :page => 'Home' } %>
I need to set a target for some pages, for example the content type and the the section of my contents. It the right way to use a variable in the controller?
Your idea sounds perfectly legitimate. You can set an instance variable in each controller action, or perhaps in a before_filter to cover multiple controller actions at once. After the views are compiled from the controller actions they are then yielded into the layout and any instance variables defined in the controller will be referenced when compiling the layout. So, yeah, supply any action-specific behavior via instance variables.
Related
I have a navigation bar (in fact two) and I use a before action in some controllers to fill it's dynamic data (the second bar may not exist in some), I've seen a lot of complains about not passing a lot of instance variables to views, and all of them suggested passing locals in render. I've been wondering using a instance variable to generate these stuff in the main layout is a good idea or not, and if it's not, how should I do this, render seems to overwrite the default view and I use the data in the main layout only
I not sure that I understand well your question. But for some of my menus I use something like that in my layouts:
<%= yield(:menu_top) %>
and I use
content_for :menu_top
to generate content in this area.
For exemple:
<%= content_for :menu_top do %>
<li>my specific content or var</li>
<% end %>
Here is the rails guide for content_for: link
I am new to Ruby on Rails. I know that for each controller you have a specific views folder that holds all of it's views. I also know there is the layout folder for the layouts.
But what if I have a bit of a template that keeps popping up in many templates across the system but it's not a footer or header or otherwise layout related.
I want to refer to it using the <%= render.... %> command but where should I put this template?
Is there a generally agreed upon location?
Can I just create a directory under views and store it there?
Rails will automatically look in 'views/application' and in the folder that contains the current parent view.
That said, you can place partials anywhere you like, and refer to them like so:
<%= render 'foo/bar' %>
As #apneadiving suggests, 'shared' is a good name for the folder.
<%= render 'shared/bar' %>
I suppose it should do justice to state what I think I know so far as well as what I've done:
1) I created the app and did my first db migration; I now have my dev, test and production databases. The dev db has a table called 'wines'.
2) I made a scaffold which created the necessary files.
3) The basic index/update/destroy methods are set up and I can browse the pages.
4) From what I gather, the ActiveRecord class "Wine" automatically inherits properties from the database? Each column is a property and each row in the table 'wines' is a potentially instantiated object which is called from the wine_controller script.
The problem I'm having now is that I want to create a common layout that all controllers use. The only things that will change will be the page title, potentially some <link> tags in the header, the <body> attributes (javascript onload events most likely) and whatever lies inside the <body> tag.
I find myself looking up functions that will do what I want (like "favicon_link_tag", "stylesheet_link_tag" and "auto_discovery_link_tag"...) but I can't find the right place to PUT them! I know this has something to do with my lack of understanding of how things are executed/inherited. For example if I were to declare #pageTitle in application_controller.rb and use #pageTitle in ApplicationHelper it won't work. Or even using "stylesheet_link_tag" in application_controller.rb throws an error. I'm just not getting something.
How does each thing relate to another in terms of chronological execution, scope, etc.?
In your "app/views" directory there is a folder called "layouts." By default there should be an "application.html.erb" file in there, but if there isn't you can create it.
Your "application" layout file is the default layout file used by any view. However, if you want a particular controller to use a different view, you can override this. See this railscast, and this one is helpful too.
The main thing to understand is the content from any particular view will show up wherever the yield method appears in your application layout. The main 'yield' block gets the view file specified by your controller action, but you can mark anything inside any view to be passed to another yield block instead. For instance, the "title" example you gave could be passed to the head of your application layout. See this railscast for a detailed example of that.
For more, you should read the Rails Guide, and you might want to consider picking up a Rails starter book.
I got my feet wet with "Beginning Rails 3," which was a phenomenal introduction to the framework. A couple days with that book and it was all making sense to me, and I was developing faster than I ever had before. Rails rocks once you get to know it, but it's definitely worth going through a book.
Please continue to ask questions, I'll help if I can :)
-EDIT- To answer your question about control flow, it basically works like this:
Your browser sends a GET request for a particular URL.
The router takes that request, matches it to a controller action, triggers that controller action, and provides the controller any parameters associated with the request. For instance: if you requested example.com/posts/123?color=red this would trigger the SHOW action of your posts_controller, and would pass {:color => 'red'} to the params hash. You would access that using params[:color]
The controller action does its thing, and when it's done it renders output. By default it renders whatever view is located in app/<controller_name>/<action_name>, and will whichever file matches the extension appropriate to the request (ie an AJAX request would trigger <action_name>.js.erb and a GET request would trigger <action_name>.html.erb.
You can override this using the render method, for example by passing render 'foo/bar' to render using the view for FooController, Bar action instead of your current action.
Note that no matter what you render, the data available to the view is whatever is in the specific controller action the router triggered, not the controller action that would 'normally' render that view.
The view file is parsed using the data from the controller that called it. If you have any content_for methods then the view code that is inside the content_for block will go where you tell it, otherwise everything else will go to the main YIELD block in your application layout (or whatever layout your controller specified instead).
The application layout is parsed, and the content from the view is inserted into the appropriate areas.
The page is served to the user.
That's a simplification in some ways, but I think it answers your question. Again, feel free to keep asking :)
I have several static files(pages), which are basically copies of my website pages source code, with the content changed.
These files support my website, (keeping the same format) in various ways.
For example the menu part is:-
<body>
<div id="menu">
<ul class="level1" id="root">
etc
etc. until
</ul>
</div>
Unfortunately every month or so my menu bar changes and I have to update each static file manually.
As each of my static files have the same menu.
Is it possible to have one menu file which can be updated and have the static files load them automatically.
I plan to have several more static files. So this would be a great help if someone can suggest how to accomplish this.
Oh yes. Use some javascript magic to load the menu bar upon page load and keep it in menu.html.
One solution may be to use a spider (wget --recursive) to download generated pages directly from your application. One command, and you have the full copy of your site. (just add some useful options, like --convert-links, for example).
The other option may be to write an after_filter in your controller, and write the generated content to a file (not always, but for example when you add a parameter ?refresh_copy=1). Maybe just turning on page caching would be suitable? But the problem will be that you will not be able to trigger the controller action so easily.
If you don't want the whole site copied, just add some specific routes or controllers (/mirrorable/...) and run the spider on them, or just access them manually (to trigger saving the content in the files).
I ended up creating one controller without a model.
rails g controller staticpages
I then created a layout file which imported the individual changes to the layout, via a "yield" tied to a "content_for" in the view files(static files(pages) in the "view of staticpages" (for example abbreviations, aboutthissite etc etc).
The rest of the static file loaded with the usual "yield" in the layout. Works a treat. No more updating the menu bar all done automatically.
To get to the correct static file I created a route using:-
match 'static/:static_page_name'=> 'staticpages#show' (or in rails 2.x:-
map.connect 'static/:static_page_name', :controller=> "staticpages", :action=> "show"
"static_page_name" variable accepted anything after "/static/" in the url and passed it to the controller "staticpages" in which I set up a show action containing:-
def show
#static_page_name = params[:static_page_name]
allowed_pages = %w(abbreviations aboutthissite etc, etc,)
if allowed_pages.include?(#static_page_name)
render #static_page_name
else
redirect_to '/' #redirects to homepage if link does not exists
end
end
I then only had to change the links in the website. (e.g.<%= link_to " About This Site ", '/static/aboutthissite' %>)
and viola! its all working.
On my previous projects built with usage of Zend Framework I extensively used Zend_view's "Action View" helper. It basically allows to initiate a separate cycle of request->dispatch ti action->view_rendering from a view script.
Here is the link to an appropriate page of zend framework reference guide (search for "Action View Helper").
This helper is quite a convenient way to work with widgetized content for example on pages with portal layout where you can stuff a page with different widgets (like advertising blocks, currency informers etc).
Although such an approach negatively affects response time of the page as it involves a lot of additional routing/dispatching activity, it allows to organizes widget code and views scripts into a rational structure. One widget is just a controller action, with linked view script.
Unfortunatelly, I have not found any similar view helpers in Rails.
Is there any way to elegantly solve this task in Rails?
In Rails, the render method of ActionController takes a Hash as arguments and outputs a simple string. You can use this in your view like so:
<%= render :partial => "shared/widgets/_#{widget.widgettype.name}", :collection => #current_user.widgets %>
In this case Rails will iterate through the list of #current_user.widgets, find a widget partials in "app/views/shared/widgets/_widgettypename.html.erb", and call the partial for each attached widget.
For further reading on Rails partials, see the ActionView::Partials documentation.
It seems that I've found an answer to my questions myself. It is "render_component" rails plugin. There is also a fork which apparently supports Rails3.