How to set link 'active' for multiple different routes in EmberJS - binding

I'd like to set the 'active' class on an Ember link-to helper for more than one route, where the routes are not nested.
ie. if I have a link to route1 I would like it to be active when the current route is route1 or route2.
Something, like:
{{#link-to 'route1' currentWhen="route1, route2"}}Things-N-Stuff{{/link-to}}
My next ideal scenario is set (or find) a boolean when the route is active and then do something like:
{{#link-to 'route1' class="isRoute1:active isRoute2:active"}}Not-as-good{{/link-to}}
But I'd rather pick it up for free. Perhaps there is a default isRoutename boolean that isn't in the docs yet...?
No answers yet. I ended up doing this:
{{#linkTo "things" tagName="li" href=false}}
<a {{bindAttr href="view.href"}} {{bindAttr class="isThingsLinkActive:active"}}>Things</a>
{{/linkTo}}
And then in the App.ApplicaitonController
isThingsLinkActive: function(){
return ['things.index','thing.index','stuff.index'].contains( this.get('currentPath') );
}.property('currentPath'),
It means I need to have something like thins in my app controller for each 'overloaded' link. Wouldn't it be cleaner to capture this entirely in the template using default flags/attributes generated by ember? I'm open to a more elegant solution... anyone?

According to the link-to#active documentation, you can do this by using a space delimited "currentWhen", but this requires Ember 1.8.
{{#link-to 'route1' currentWhen="route1 route2"}}Things-N-Stuff{{/link-to}}
This may also be a feature you can enable on earlier builds:
See 'ember-routing-multi-current-when' on https://github.com/emberjs/ember.js/blob/master/FEATURES.md
Alternatively, you can override the link-to helper with one of the methods described in this SO post:
Is there a way to pass an array to currentWhen in EmberJS?

Currently as of 3.2 the correct syntax is:
{{#link-to 'fruits.index' current-when="fruits.index apples.index"}}Link text{{/link-to}}
Sorry, tried to edit the original answer but the change is less than 6 characters.

Related

Ember: How to link to sections and actions (without nesting routes)

Let's say that I have a blog where each post can have several sections and comments and I'd like to use a hard-links to navigate and operate on this. There are several samples using some pseudo-code, of course they doesn't work, just demonstring my intends :)
Of course /blog.html#/posts/1 uses PostRoute, PostController etc and uses :post_id for finding object - that's obvoius.
How can I pass (and then access) additional params which doesn't change the controller but I can use them to navigation. ie /blog.html#/posts/1?section=123 should use the same route, controller and view as it was just Post, but I'd like to read the section and just navigate to section with #123
/blog.html#/posts/1/?comments=456 - actually should behave like section from point 1, but navigates to comment and optionally add some class to the container.
Other case: I'd like to go to section 123 AND additionally edit it with link like: /blog.html#/posts/1?section=123&action=edit. Now I'm using a button with an action like {{action editSection section}} and {{#if isEdit}} but I'd like to be able to reflect this in URL and also go to this state from URL (de facto my post can have several different modes not only preview/edit, therefore it should be accesible by the link).
I hope that cases makes sense, TBH I have no idea in which direction should I go. Tried with nested routes, but I'd like to avoid changing the controller. Also have no concept how to reflect the action in the URL...
I'm using Ember 1.1.2
You can use the model method of the route to handle such parameters, separate them from the model parameter and set the appropriate controller state.
Another approach would be to use nested routes that will render un-nested views(and controllers) - as explained towards the bottom here.

External link routes in rails

Simple enough. When were making a typical restful rails app we would keep all routes inside of our applicaiton. Very rarely would a path link to an external path. But if we were to do it, I'm wondering what the best way is.
A typical matching of home
match "home"=>"appcontroller#home"
If we were matching an external url to a variable of path. We might do something like the below?
First method
Routes.rb
match "external"=>"http:/www.google.ie"
Then in our html.erb
<%= link_to 'Google', external_path %>
Note this is not actually a legal way of doing things but something similar may exist. It seems very close to the current way of defining paths in rails but with an external landing.
Second method
Something that I've seen done elsewhere is to create a global variable for the external URL and use it in the link. EG.
in environment.rb or production.rb or whatever
#ext_path="http:/www.google.ie"
Then in our html.erb
<%= link_to 'Google', #ext_path %>
So to recap. Whats the best way to use external URLS in rails. Paths? Variables? Other?
Any input appreciated
I would have kept external links only in views. Because this links are not related to the any kind of logic of the application, and it's just an UI elements.
So, this way seems to me the best:
<%= link_to 'Google', "http://google.ie" %>
If you need to use this element many times, maybe it makes sense to bring this code into the helper, for example:
def search_engine_link
link_to 'Google', "http://google.ie"
end
And I really think that is's not very good place to introduce a more complex logic.
I'd probably use application-wide helpers wrapped around constants.
Helpers because I'd rather not see constants in templates, constants for environment-specific values.
I might use a hash to store the URLs: this keeps them more-tightly-coupled, and would allow environment-wide defaults, overriding per-environment as necessary.
The helpers could take symbols, or be generated from the hash keys, to generate xxx_path methods as happens with routes in routes.rb.
I found myself needing to do this because I had a link to an external site which I intended to make local in future.
In Rails 4 you can add this to config/routes.rb:
get '/contact',
to: redirect('http://www.example.com/contact.php'),
as: 'contact_us'
Which at the price of an extra redirect, lets you write:
<%= link_to "Contact us", contact_us_path %>
301-redirects
A note about use of redirect(...) in the routes file. Redirect generates a 301-redirect, which is a specific thing, Google describes it as...
If you need to change the URL of a page as it is shown in search
engine results, we recommend that you use a server-side 301 redirect.
This is the best way to ensure that users and search engines are
directed to the correct page. The 301 status code means that a page
has permanently moved to a new location.
So, using a 301-redirect in your routes for links to external websites may work, which it does, but the status information that is carried with that redirect is not correct.
If you've moved pages in your web app and want to tell the Google index (and everyone else) about it, then by all means use the redirect() to assure Google updates the index, but it's not optimal to use for standard external links out of your web app.

Rails 3.1 build GET form that creates a custom URL route that is SEO friendly

I would like to create custom SEO friendly routes similar to what is used by http://realestate.com.au For example the following page is shown by google when the search term "real estate melbourne" is used:
www.realestate.com.au/buy/in-melbourne,+vic+3000/list-1
I would like use the following format. mysite.com/trips/search/melbourne-to-sydney/01-01-2011
I have configured the routes in my routes.rb file to get it to pick up the correct parameters when a url is entered is this format.
routes.rb
match '/trips/search(/:fl(-to-:tl(/:tripdate)))' => 'trips#someaction'
My question is how do I setup a form in rails 3 to send a GET request using the above url structure. I have tried playing around with to_params though it seems to then change all my edit, show links etc which is not intended. I could build the link using javascript though I guess this would be a hacky option and the site would not work if javascript was disabled.
Is there a neat way to be able to create a GET submit form in Rails 3.1? The fields are select lists containing name and ids.
Thanks for your help.
This will help you immensely with the friendly URL portion
http://norman.github.com/friendly_id/file.Guide.html
https://github.com/norman/friendly_id

Using T4MVC in real project

T4MVC is cool, but I have a couple of issues integrating it in my project, any help is really appriciated:
I've got such warnings for all my actions (I use SnippetsBaseController as base class for all my controller classes:
Warning 26 'Snippets.Controllers.ErrorController.Actions' hides inherited member 'Snippets.Controllers.Base.SnippetsBaseController.Actions'. Use the new keyword if hiding was intended. C:\projects_crisp-source_crisp\crisp-snippets\Snippets\T4MVC.cs 481 32 Snippets
Is it possible to have strongly typed names of custom Routes, for example, I have route defined like this:
routes.MapRoute(
"Feed",
"feed/",
MVC.Snippets.Rss()
);
Is it possible to replace:
<%= Url.RouteUrl("Feed") %>
with something like:
<%= Url.RouteUrl(MVC.Routes.Feed) %>
Having strongly typed links to static files is really cool, but I use <base /> in my pages, so I don't need any URL processing, can I redefine
T4MVCHelpers.ProcessVirtualPath without tweaking the T4MVC.tt itself?
T4MVC always generate links with uppercased controller and action names, for example:
/Snippets/Add instead of /snippets/add. Is it possible to generate them lowercase?
Can you change your base controller class to be abstract? I think that'll fix it.
See this post which discusses this: http://forums.asp.net/t/1535567.aspx
If you look in t4mvc.settings.t4, you'll see a ProcessVirtualPathDefault method that you can change without touching the main .tt file.
See http://forums.asp.net/t/1532057.aspx. There is suggested fix in there, though it has not yet been submitted (but you can try it).
David

Fallback format in rails

for my CMs i want to be able to easily add new themes, my idea was to simply add a mime type for the new theme (so application.theme1.erb would work).
but for 99% of the themes im not going to want to change the views, well not all of them.
is there someway to have rails fall back on html if the themed view isnt present?
I'm pretty new to Rails, so this might not be a perfect answer:
you might want to try using querystring parameters as part of the route like described here:
http://guides.rubyonrails.org/routing.html#querystring-parameters
so eventually something like this would work
map.connect ':theme/:controller/:action/:id'
As I understand it, the theme would be available as params[:theme] in the controller. If no theme is specified you probably have to add another route like
map.connect '/:controller/:action/:id'
to handle that case.
In the i18n guide something similar is described for locales: http://guides.rubyonrails.org/i18n.html#setting-the-locale-from-the-url-params
Hope that helps.
It depends on how much of the layout you want to change with the themes.
If you build your HTML right, most of the things can be done through css. (changing fonts, colours, where the stuff show up)
Then it is quite easy to add just a theme parameter to style it.
If you don't want to do that, you can always create a separate layout for it, and assign that depending on the parameters passed in (or even set it as a session variable so you won't have it in the url).
Basically, for the default theme, you stick to the layouts/application.erb, then you have say layouts/theme1.erb which you then assign with a method
class ApplicationController
layout :decide_layout
def decide_layout
#session[:layout] || 'application'
end
end
Customizing the views would be possible just by doing something like this in your actions:
def my_action
render "my_action_#{#session[:layout]}" if #session[:layout]
end
if #session[:layout] is not set, it will render the default, otherwise it will render your themed view.
Of course, if you set the layout depending on user input, make sure to sanitize and check the layout parameter before.
I've just had this same problem with mobile_fu, which sets the format to :mobile for mobile requests.
It turns out that if an :action.:format.erb template isn't available, Rails will serve :action.rhtml as a replacement in any format.
I can't say whether this will work for layouts, but it certainly works for actions

Resources