Riding the Rails: Aktiva menyobjekt

Fredrik W visade mig en riktigt stilig sak häromdagen på ett Rails-projekt vi håller på med. Att göra layouter och framför allt visa vilket menyobjekt som är “aktivt”, dvs vilken sida du är på just nu.

Lägg in denna helpern, i exempelvis application_helper.rb:

  
def menu_item(text, link, options = {:use_span => false, :only_controller => false})
   active = Rails.application.routes.recognize_path link
   text = content_tag("span", text) if options[:use_span]
     
   link_is_currently_active = options[:only_controller] ? params[:controller] == active[:controller] : params[:controller] == active[:controller] && params[:action] == active[:action]
    
   klass = link_is_currently_active ? "active" : ""
   return content_tag("li", link_to(text, link), :class => klass)
end
  
def menu(options = {}, &block)
  return content_tag("ul", options, &block)
end

Vi läser alltså av existerande routen och jämför den med menyobjektets. Så nu istället för att länk runt dig i applikationen med link_to så kan du nu använda blocket menu:

<% menu do %>
  <%= menu_item "Link 1", project_path(@project) %>
  <%= menu_item "Link 2", project_medias_path(@project) %>
<% end %>

Vips, så har vi nu fått en lista med det aktiva objektets klass som “active“.

Nu är det klart att detta är en väldigt begränsad lösning och kanske inte lämpar sig i större projekt med stora menystrukturer, men för enklare projekt fungerar detta alldeles utmärkt.

Använda Spotify MetaData API i Ruby

Spotify har släppt ett API för att kunna hämta information om låtar via deras Spotify-url:er. Nedan är ett exempel i Ruby på hur du kan hämta artist och låt. Anropas med ex. spotify:track:4KPU7XGqxo4UlMp3is7NBI

def getTitleFromSpotifyTrack(trackID)
    require 'net/http'
    require 'rexml/document'
    require 'rexml/xpath'

    res = Net::HTTP.get_response(URI.parse("http://ws.spotify.com/lookup/1/?uri=#{trackID}"))
    contents = res.body

    doc = REXML::Document.new contents

    track = REXML::XPath.first(doc,'/track/name/text()')
    artist = REXML::XPath.first(doc,'/track/artist/name/text()')

    return "#{artist} - #{track}"
  end