Sinatra - Is a sitewide param possible? - ruby

I am building a Sinatra app with haml templates and was wondering if it is possible to implement a sitewide param of some sort. The idea, in my case, would be to allow for a different layout.haml to be able to be selected for every route without having to duplicate/rewrite every route in the app.
For example, I was wondering if it would be possible to be able to GET http://domain.com/route/:normal-params/?layout=layout_b, and be able to append ?template=template_choice to any route in the app and use the appropriate layout.
The only solution I can think of, which seems very inefficient, is to duplicate every single route to look for this parameter. I also feel like it could be achieved somehow with a Filter but am unsure how such a thing could be implemented.

You can specify which layout you want to load in your call to haml:
haml :post, :layout => params[:layout].to_sym
That way you can call http://domain.com/route/foo/bar?layout=layout_b and Sinatra will look for the appropriate layout named layout_b to render in.
You'll probably want to specify a default layout to render if none is provided as a URL parameter:
haml :post, :layout => (params[:layout] || "default").to_sym

Related

How to set humanized name of padrino module?

How are you.
I have just installed padrino framework admin panel.
And it shows several tabs in admin module.
I want to rename the labels. but how to do it?
This is view side code
<%= link_to project_module.human_name, url(project_module.path) %>
Here I can't set human_name of project_module.
And this is module definition in application.rb
access_control.roles_for :admin do |role|
role.project_module :accounts, '/accounts'
role.project_module :venues, '/venues'
role.project_module :shows, '/shows'
end
Now tabs labels are Accounts, Venues, Shows.
how to set them as Users, MyVenues, MyShows?
Thanks
Just seemed to hit this issue tonight as well. It seems that this is a slight bug that is in the core Padrino framework.
The standard navigation logic out of the box will never produce a proper localized text. It renders the output of function .humanize
https://github.com/padrino/padrino-framework/blob/8bd3796d45eae5e3f7dc52316c8c25c44563f8cd/padrino-admin/lib/padrino-admin/access_control.rb#L176
At best, the humanize function will upcase your text. See https://apidock.com/rails/String/humanize
You can replace the human_name reference with the I18n.t() localizable function:
%ul.nav.navbar-nav.pull-left
- project_modules.each do |project_module|
%li{:class => "navbar-module #{('active' if request.path_info =~ /^#{project_module.path}/)}"}
=link_to I18n.t(project_module.name), url(project_module.path)
See http://padrinorb.com/guides/features/localization/ for reference.
One note, the navigation is not model aware, so your translated text will need to be right under the locale reference in the yml file.
Ex.
en:
accounts: Users
venues: MyVenue
shows: MyShows
This should do the trick. Let me know if you have any questions.

How to dynamically transmit params in link_to ?

I need to use part of my application in iframe on another page. So I need to remove layout on these pages.
I added to ApplicationController
layout :current_layout
def current_layout
if params[:layout] == false.to_s
false
else
'main'
end
end
This works until user click on any link in navigation. So I need to add to every link_to in this part of application something like:
link_to 'store', store_path(params.merge({layout: params[:layout]})
I am wondering that maybe I can refactor that and maybe remove this params.merge from every link?
You could try something like this:
def my_path_helper(string, path_type, params)
link_to(string, polymorphic_path([path_type], params.merge({layout: params[:layout]})))
end
See the docs for polymorphic path here and also this answer that provides an example.
Is this what you were looking for?

Rendering a partial in the parent directory in Ramaze

How do I render a partial that's in a different directory (in my case, the parent) than the current view?
<%=render_partial :sidebar%> #looks in the current dir and works as expected
<%=render_partial "/view/sidebar"%> #doesn't work!
Thanks!
You have to specify the right controller that is responsible for the right view:
TheRightController.render_partial :sidebar
If you don't specify the controller class, render_* works for the current action (controller) only, except render_full that does real internal HTTP request.
So, the answer is: If you need shared templates, just create special controller, i.e. called Shared, without any action methods inside, just with many templates in an appropriate view folder and call Shared.render_partial.
Shared.render_partial works like internal request. It renders contents of the controller's action and even the action's method is executed. If you want to render just the view (without executing Shared's action method), use Shared.render_view instead.
Moreover, you can use the internal requesting to prepare some data in the Shared controller's method. For instance, if your sidebar consists of #articles, let's load them in the Shared's sidebar() method. You don't need to load #articles in any other controller that displays the sidebar! You only call "Shared.render_partial :sidebar" in there. This is how to build widget-like web with Ramaze :-)
I found following api in apidock.com, maybe useful for u
# Renders a collection of partials located in a view subfolder
# outside of our current controller. In this example we will be
# rendering app/views/shared/_note.r(html|xml) Inside the partial
# each element of #new_notes is available as the local var "note".
render :partial => "shared/note", :collection => #new_notes
#rebnoob may use (without view directory name, because Rails search on app/view directory)
<%= render "/sidebar" %>
instead of
<%=render_partial "/view/sidebar"%> #doesn't work!

Rails3: one controller many partials for form data submission

I am not sure if this is the best approach but I have a controller that originally I intended to control a show index that renders many partials on it (a header partial and then, has some if else magic to render different partials based on the step the user is in in filling out a form... a form has many sections across several pages). I think ultimately ajax is the way to go but I am not even to that point yet. I am not sure this is the right way to do it, so I guess that is what I am asking... is the many different partials to one controller the way ? or does each "page" of form data have to be broken out into its own controller? allowing the user to fill out form (check boxes, comment section) and click "next" passing the model of the data they are filling out along the way and saving that model in each next?
U may not need several controllers, but 1 controller with some actions may be a good start. =)
Then each action should load only the partial it needs. like u can give the action name to the partial, making easy to know which partial to render.
Or maybe u can try to use wicked.
There is a railscasts for it.
Well, you could use a method to decide which partial to render.
Use this example or do some meta programming.
class YourController < ApplicationController
def index
render :partial => partial_selector(param)
end
private
def partial_selector param
#logic to decide what partial do render
#returns the partial name
end
end

return to default layout behavior using a Proc

I'm adding unobtrusive ajax to my site, so I need to set the layout depending on the request type :
# app/controllers/application_controller.rb
layout Proc.new { |controller| controller.request.xhr? ? 'ajax' : 'application' }
# app/views/layout/ajax.html.erb
<%= render :partial => "shared/flash", :object => flash %>
<%= yield %>
But I also want to use nested layout and have my javascript deal with where to insert ajax retrieved content. According to the rails api layout nil force default layout behavior with inheritance, so I tried this :
layout Proc.new { |controller| controller.request.xhr? ? 'ajax' : nil }
Which doesn't work, I get no layout at all. The only piece of information I found is an old chat log saying that this, indeed, doesn't work due to the way Rails handle layout.
Is there a way to achieve this ?
Since a proc returning nil doesn't work, is their a way to set the layout on a condition beeing met (request.xhr? here). Something like layout_if.
Or should I just add
layout Proc.new { |controller| controller.request.xhr? ? 'ajax' : 'controller_name' }
to every controllers with a different layout ?
My ajax request actually return html, should I cheat a little and return those html elements in .xml files and use respond_to to set the layout ?
(This may be great, for another reason, having differents urls to access with and without layout content could allow for page cache, but there are other way to achieve this.)
Or maybe there is a way better solution.
Rails can do this automatically. For example you create 2 layouts(application.html.erb and application.js.erb). When request is xhr? it will use js(application.js.erb) layout, if standard request comes to the server rails will render application.html.erb.

Resources